Commit ab2b00fd authored by Andreas Schmidt's avatar Andreas Schmidt

Merge branch 'develop'

parents 8293e674 d8ad1570
Pipeline #2321 passed with stages
in 1 minute and 26 seconds
......@@ -54,7 +54,7 @@ test:prrt_functional:
tags:
- bash
script:
- exec ./bin/prrtTests
- exec ./prrtTests
test:prrt_python_bindings:
stage: test
......
[submodule "prrt/xlap"]
path = prrt/xlap
url = ../../as/X-Lap.git
url = ../X-Lap.git
......@@ -3,11 +3,11 @@ project (PRRT)
option(PRRT_TESTS "Build tests" OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_C_FLAGS "-O2 -Wall -std=gnu11 -D_GNU_SOURCE" )
set(CMAKE_C_FLAGS "-O2 -Wall -std=gnu11 -D_GNU_SOURCE -fPIC" )
set(CMAKE_CXX_FLAGS "-fstack-protector -fstack-protector-all -Wall -std=gnu++11 -D_GNU_SOURCE" )
set(CMAKE_CXX_FLAGS_DEBUG "-O2 -Wall -ggdb" )
set(CMAKE_CXX_FLAGS_RELEASE "-Os -Wall" )
......
......@@ -8,6 +8,7 @@
* Clock synchronization between sending stack and receiving stack
* Applications can specify packet-level expiration times
* Different receive modes for ASAP and time-synchronized operation
* Passive measurement of propagation delay, bottleneck data rate and packet loss rate
* Packet-level timing analysis using [X-Lap](http://xlap.larn.systems)
* [Hardware timestamping support](https://git.nt.uni-saarland.de/LARN/PRRT/wikis/hardware-timestamping)
......@@ -25,7 +26,7 @@ import prrt
port = int(sys.argv[1])
s = prrt.PrrtSocket(port=port, isSender=False)
s = prrt.PrrtSocket(port=port)
while True:
d = s.recv()
......@@ -44,7 +45,7 @@ import prrt
host = sys.argv[1]
port = int(sys.argv[2])
s = prrt.PrrtSocket(port=port, isSender=True)
s = prrt.PrrtSocket(port=port)
s.connect(host, port)
for i in range(10):
......
PRRT Dissector for Wireshark
============================
Installation
------------
* Download Wireshark Source Code: https://www.wireshark.org/
apt-get install qt-sdk libgtk-3-dev libpcap-dev
tar xvjf wireshark-1.10.2.tar.bz2
./configure
* Copy `packet-prrt.c` to `epan/dissectors`.
* Add a line `packet-prrt.c \` in `DISSECTOR_SRC` of `epan/dissectors/Makefile.common`.
* Call make in the root folder. You can now start wireshark using `./wireshark`.
This tutorial will show you how to apply the dissector of PRRT in your wireshark.
What our PRRT dissector can do?
Our PRRT dissector can dissector the following PRRT packets: data, repeated data, redundancy, pre-sent redundancy, feedback and channel feedback. By now it can basically display the header info of PRRT packets. The sophistical display and advanced features will be supported later.
How to use it?
To use this dissector in the wireshark basically you need to perform the following steps:
0. Download the source code of wireshark and extract it.
1. Copy our dissector code (packet-prrt.c) to the directory epan/dissectors/ of the source code.
2. Add a line "packet-prrt.c \" in DISSECTOR_SRC of epan/dissectors/Makefile.common, so that we can compile our dissector code.
3. This step is optional and for advanced usage.
If you want our dissector to call subdissectors for some purposes (e.g. using mp2t to parse the payload as MPEG TS.), you need to register the subdissector by adding the following _pattern_ line in the handoff function of the subdissector:
heur_dissector_add("prrt", heuristic_dissect_method, protocol_id);
e.g. add the line in the function proto_reg_handoff_mp2t() of packet-mp2t.c for parsing PRRT payload as MPEG TS.
heur_dissector_add("prrt", heur_dissect_mp2t, proto_mp2t);
NOTE : The subdissector called by PRRT dissector at the moment must support heuristic dissecting.
NOTE : By now we provide two dissector files respectively for two wireshark versions (1.4.6 and 1.6.1), because different version of wireshark provides different methods used in the dissector code. Even the dissector code for the version 1.4.6 is compatible with wireshark 1.6.1, we still recommand you use the dissector code for the version 1.6.1 and wireshark 1.6.1, since the later version of wireshark would not support the old method any more.
The following is fully commands under a specific scenario (see the prerequisite), you may follow, to install wireshark and apply our dissector code. For installation you can choose 1.a or 1.b depending on the version of wireshark you prefer to.
0. Prerequisite :
+ Linux OS : ubuntu 10.04 or later.
+ wireshark 1.4.6 or wireshark 1.6.1.
+ libgtk2.0-dev, bison, automake1.9 and libpcap. (Maybe more dependencies required.)
1.a Installation (wireshark 1.4.6)
sudo apt-get source wireshark-dev
sudo chown -R your_account:your_account wireshark-1.4.6/
mkdir wireshark-installed
svn co https://projects.nt.uni-saarland.de/svn/prrt-dissector
cp prrt-dissector/wireshark-1.4.6/packet-prrt.c wireshark-1.4.6/epan/dissectors/
cd wireshark-1.4.6
./configure --prefix=$PWD/../wireshark-installed/
make -j 2
make install
2.b Installation (wireshark 1.6.1)
download wireshark 1.6.1 from the www.wireshark.org
tar -xjvf wireshark-1.6.1.tar.bz2
mkdir wireshark-installed
svn co https://projects.nt.uni-saarland.de/svn/prrt-dissector
cp prrt-dissector/wireshark-1.6.1/packet-prrt.c wireshark-1.6.1/epan/dissectors/
cd wireshark-1.6.1
./configure --prefix=$PWD/../wireshark-installed/
make -j 2
make install
3. Running the wireshark
sudo ../wireshark-installed/bin/wireshark
/* packet-prrt.c
* Routines for PRRT (Predictably Reliable Real-time Transport) dissection
* http://www.nt.uni-saarland.de/projects/prrt/
* Copyright 2011, Yongtao Shuai <shuai@nt.uni-saarland.de>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
* is a dissector file; if you just copied this from README.developer,
* don't bother with the "Copied from" - you don't even need to put
* in a "Copied from" if you copied an existing dissector, especially
* if the bulk of the code in the new dissector is your code)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if 0
/* Include only as needed */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include <glib.h>
#include <epan/packet.h>
#include <epan/prefs.h>
/* IF PROTO exposes code to other dissectors, then it must be exported
in a header file. If not, a header file is not needed at all. */
/* #include "packet-prrt.h" */
/* Forward declaration we need below (if using proto_reg_handoff...
as a prefs callback) */
void proto_reg_handoff_prrt(void);
/* Label the packet types and map to names. */
static const value_string packet_type_names[] = {
{ 0, "Data" },
{ 1, "Repeated Data" },
{ 2, "Redundancy" },
{ 3, "Feedback" },
{ 4, "Pre-sent Redundancy" },
{ 5, "Channel Feedback" }
};
/* Initialize the protocol and registered fields */
static int proto_prrt = -1;
/* The following three fields are in the header of general PRRT packet (data or redundancy). */
static int hf_prrt_packet_type = -1; /* guint8 : 8bit determine data packet or redundancy packet. */
static int hf_prrt_priority = -1; /* guint8 : 8bit packet priority */
static int hf_prrt_index = -1; /* guint16 : 16bit packet index within coding block */
/* The following five fields are in the header of PRRT data packet (packet type: 0 or 1). */
static int hf_prrt_seqnum = -1; /* guint16 : 16bit sequence number of the packet */
static int hf_prrt_group_rtt = -1; /* guint16 : 16bit group RTT estimated by the sender (multicast) */
static int hf_prrt_timeout = -1; /* guint16 : 16bit packet timeout (ms), after which the packet expires. */
static int hf_prrt_fb_timeout = -1; /* guint16 : 16bit timeout (ms) of receiver feedback for this packet */
static int hf_prrt_timestamp = -1; /* guint32 : 32bit time when this packet was allocated (us) */
/* The following three fields are in the header of PRRT redundancy packet (packet type: 2 or 4). */
static int hf_prrt_sn_base = -1; /* guint16 : 16bit the number of the first data packet in the block */
static int hf_prrt_n = -1; /* guint8 : 8bit the overall number of packets in the block */
static int hf_prrt_k = -1; /* guint8 : 8bit the number of information packets in the block */
/* The payload of PRRT data packet, redundancy packet, pre-send redundancy packet. */
static int hf_prrt_payload = -1; /* payload with arbitrary length, depending on the support of UDP. */
/* The following four fields are in the header of PRRT feedback packet and channel feedback packet. */
static int hf_prrt_receiver_addr = -1; /* 32 bits IP address of the receiver */
static int hf_prrt_rtt_probe = -1; /* 32 bits timestamp of most recent data packet plus delay since reception of this packet. */
static int hf_prrt_plr = -1; /* 32 bits packet loss rate measured at the receiver. */
static int hf_prrt_bw_est = -1; /* 32 bits bandwidth estimated at the receiver. */
/* The following two fields are the payload of PRRT feedback packet (packet type: 3). */
static int hf_prrt_packet_no = -1; /* 16 bits packet no of the first lost packet. */
static int hf_prrt_retr_round = -1; /* 16 bits retransmission round of the first lost. (first transmission is 0.) */
/* The following two fields are the payload of PRRT channel feedback packet (packet type: 5). */
static int hf_prrt_res_plr = -1; /* 32 bits residual packet loss rate. */
static int hf_prrt_channel_plr = -1; /* 16 bits original packet loss rate. */
static int hf_prrt_corr = -1; /* 16 bits correlation coefficient (for GE channel model). */
/* Global sample preference ("controls" display of numbers) */
static gboolean gPREF_HEX = FALSE;
/* Global sample port pref */
static guint gPORT_PREF = 5004;
/* A UDP port for which we are dissecting traffic. */
static guint prrt_port = 5004;
/* Initialize the subtree pointers */
static gint ett_prrt = -1;
/* Code to actually dissect the packets */
static int
dissect_prrt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Keep track of where we are in the packet dissection. */
gint offset = 0;
guint len = 0; /* Store the length of the packet. */
/* Hold the actual value of the packet type. */
guint8 packet_type = 0;
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *prrt_tree;
/* Get the first byte for the actual value of the packet type. */
packet_type = tvb_get_guint8(tvb, 0);
/* Get the length of the packet. */
len = tvb_length(tvb);
/* First, if at all possible, do some heuristics to check if the packet cannot
* possibly belong to your protocol. This is especially important for
* protocols directly on top of TCP or UDP where port collisions are
* common place (e.g., even though your protocol uses a well known port,
* someone else may set up, for example, a web server on that port which,
* if someone analyzed that web server's traffic in Wireshark, would result
* in Wireshark handing an HTTP packet to your dissector). For example:
*/
/* TODO Check that there's enough data */
if (len < 8) /* your protocol's smallest packet size */
return 0;
/* Get some values from the packet header, probably using tvb_get_*() */
/* TODO if ( ) */ /* these values are not possible in PROTONAME */
/* This packet does not appear to belong to PROTONAME.
* Return 0 to give another dissector a chance to dissect it.
*/
/*return 0;*/
if (0 == packet_type) {
if (len <= 16)
return 0;
}
else if (1 == packet_type) {
if (len <= 16)
return 0;
}
else if (2 == packet_type) {
if (len <= 8)
return 0;
}
else if (3 == packet_type) {
if (24 < len || len < 20)
return 0;
}
else if (4 == packet_type) {
if (len <= 8)
return 0;
}
else if (5 == packet_type) {
if (28 < len || len < 20)
return 0;
}
else {
/* Unknown packet type, the packet doesn't belong to PRRT. */
return 0;
}
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PRRT");
/* This field shows up as the "Info" column in the display; you should use
it, if possible, to summarize what's in the packet, so that a user looking
at the list of packets can tell what type of packet it is. See section 1.5
for more information.
If you are setting the column to a constant string, use "col_set_str()",
as it's more efficient than the other "col_set_XXX()" calls.
If you're setting it to a string you've constructed, or will be
appending to the column later, use "col_add_str()".
"col_add_fstr()" can be used instead of "col_add_str()"; it takes
"printf()"-like arguments. Don't use "col_add_fstr()" with a format
string of "%s" - just use "col_add_str()" or "col_set_str()", as it's
more efficient than "col_add_fstr()".
If you will be fetching any data from the packet before filling in
the Info column, clear that column first, in case the calls to fetch
data from the packet throw an exception because they're fetching data
past the end of the packet, so that the Info column doesn't have data
left over from the previous dissector; do
*/
col_clear(pinfo->cinfo, COL_INFO);
/* col_set_str(pinfo->cinfo, COL_INFO, "PRRT Summary Request"); */
/* A protocol dissector may be called in 2 different ways - with, or
without a non-null "tree" argument.
If the proto_tree argument is null, Wireshark does not need to use
the protocol tree information from your dissector, and therefore is
passing the dissector a null "tree" argument so that it doesn't
need to do work necessary to build the protocol tree.
In the interest of speed, if "tree" is NULL, avoid building a
protocol tree and adding stuff to it, or even looking at any packet
data needed only if you're building the protocol tree, if possible.
Note, however, that you must fill in column information, create
conversations, reassemble packets, build any other persistent state
needed for dissection, and call subdissectors regardless of whether
"tree" is NULL or not. This might be inconvenient to do without
doing most of the dissection work; the routines for adding items to
the protocol tree can be passed a null protocol tree pointer, in
which case they'll return a null item pointer, and
"proto_item_add_subtree()" returns a null tree pointer if passed a
null item pointer, so, if you're careful not to dereference any null
tree or item pointers, you can accomplish this by doing all the
dissection work. This might not be as efficient as skipping that
work if you're not building a protocol tree, but if the code would
have a lot of tests whether "tree" is null if you skipped that work,
you might still be better off just doing all that work regardless of
whether "tree" is null or not.
Note also that there is no guarantee, the first time the dissector is
called, whether "tree" will be null or not; your dissector must work
correctly, building or updating whatever state information is
necessary, in either case. */
if (tree) {
/* NOTE: The offset and length values in the call to
"proto_tree_add_item()" define what data bytes to highlight in the hex
display window when the line in the protocol tree display
corresponding to that item is selected.
Supplying a length of -1 is the way to highlight all data from the
offset to the end of the packet. */
/* create display subtree for the protocol */
ti = proto_tree_add_item(tree, proto_prrt, tvb, 0, -1, ENC_NA); /* TODO network order->use false instead of ENC_NA (Not Applicable) */
prrt_tree = proto_item_add_subtree(ti, ett_prrt);
/* add an item to the subtree, see section 1.6 for more information */
proto_tree_add_item(prrt_tree, hf_prrt_packet_type, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_priority, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_index, tvb, offset, 2, FALSE);
offset += 2;
if (packet_type == 0) {
/* We are dissecting PRRT data packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT data packet");
proto_tree_add_item(prrt_tree, hf_prrt_seqnum, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_group_rtt, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_timeout, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_fb_timeout, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_timestamp, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
else if (packet_type == 1) {
/* We are dissecting PRRT redundancy data packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT repeated data packet");
proto_tree_add_item(prrt_tree, hf_prrt_seqnum, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_group_rtt, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_timeout, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_fb_timeout, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_timestamp, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
else if (packet_type == 2) {
/* We are dissecting PRRT redundancy packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT redundancy packet");
proto_tree_add_item(prrt_tree, hf_prrt_sn_base, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_n, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_k, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
else if (packet_type == 3) {
/* We are dissecting PRRT feedback packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT feedback packet");
proto_tree_add_item(prrt_tree, hf_prrt_receiver_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_rtt_probe, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_plr, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_bw_est, tvb, offset, 4, FALSE);
offset += 4;
if (len == 24) {
proto_tree_add_item(prrt_tree, hf_prrt_packet_no, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_retr_round, tvb, offset, 2, FALSE);
offset += 2;
}
else {
/* TODO handle no feedback block. */
if (0 < len -offset) {
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
}
}
else if (packet_type == 4) {
/* We are dissecting PRRT pre-sent redundancy packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT pre-sent redundancy packet");
proto_tree_add_item(prrt_tree, hf_prrt_sn_base, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_n, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_k, tvb, offset, 1, FALSE);
offset += 1;
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
else if (packet_type == 5) {
/* We are dissecting PRRT channel feedback packet. */
col_set_str(pinfo->cinfo, COL_INFO, "PRRT redundancy data packet");
proto_tree_add_item(prrt_tree, hf_prrt_receiver_addr, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_rtt_probe, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_plr, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_bw_est, tvb, offset, 4, FALSE);
offset += 4;
if (len == 28) {
proto_tree_add_item(prrt_tree, hf_prrt_res_plr, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(prrt_tree, hf_prrt_channel_plr, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(prrt_tree, hf_prrt_corr, tvb, offset, 2, FALSE);
offset += 2;
}
else {
/* TODO handle no channel feedback block. */
if (0 < len -offset) {
proto_tree_add_item(prrt_tree, hf_prrt_payload, tvb, offset, len - offset, FALSE);
offset += len - offset;
}
}
}
else {
/* Should not happen. */
}
}
/* If this protocol has a sub-dissector call it here, see section 1.8 */
/* Return the amount of data this dissector was able to dissect */
return tvb_length(tvb);
}
/* Register the protocol with Wireshark */
/* this format is require because a script is used to build the C function
that calls all the protocol registration.
*/
void
proto_register_prrt(void)
{
module_t *prrt_module;
/* Setup list of header fields See Section 1.6.1 for details*/
static hf_register_info hf[] = {
{ &hf_prrt_packet_type,
{ "Packet Type", "prrt.base.packettype",
FT_UINT8, BASE_DEC, VALS(packet_type_names), 0x0,
"Packet type field in PRRT base header", HFILL }
},
{ &hf_prrt_priority,
{ "Packet Priority", "prrt.base.packetpriority",
FT_UINT8, BASE_DEC, NULL, 0x0,
"Packet priority field in PRRT base header", HFILL }
},
{ &hf_prrt_index,
{ "Packet Index", "prrt.base.packetindex",
FT_UINT16, BASE_DEC, NULL, 0x0,
"Packet index (within coding block) field in PRRT base header", HFILL }
},
{ &hf_prrt_seqnum,
{ "Packet Sequence Number", "prrt.data.packetseqnum",
FT_UINT16, BASE_DEC, NULL, 0x0,
"Sequence number of PRRT data packet in PRRT data header", HFILL }
},
{ &hf_prrt_group_rtt,
{ "Group RTT (ms)", "prrt.data.grouprtt",
FT_UINT16, BASE_DEC, NULL, 0x0,
"Group RTT (ms) in PRRT data header", HFILL }
},
{ &hf_prrt_timeout,
{ "Packet Timeout (ms)", "prrt.data.timeout",
FT_UINT16, BASE_DEC, NULL, 0x0,
"Timeout (ms) of the packet in PRRT data header", HFILL }
},
{ &hf_prrt_fb_timeout,
{ "Feedback Timeout (ms)", "prrt.data.fbtimeout",
FT_UINT16, BASE_DEC, NULL, 0x0,
"Timeout (ms) of the receiver feedback for this packet in PRRT data header", HFILL }
},
{ &hf_prrt_timestamp,
{ "Packet Timestamp (us)", "prrt.data.timestamp",
FT_UINT32, BASE_DEC, NULL, 0x0,
"(Allocated) Timestamp (us) of the packet in PRRT data header", HFILL }
},
{ &hf_prrt_sn_base,
{ "Based Serial Number", "prrt.redundancy.snbase",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The number of first data packet in block, stored in PRRT redundancy data header", HFILL }
},
{ &hf_prrt_n,
{ "Code Length (n)", "prrt.redundancy.n",
FT_UINT8, BASE_DEC, NULL, 0x0,
"The overall number of packets in the block, stored in PRRT redundancy data header", HFILL }
},
{ &hf_prrt_k,
{ "Information Length (k)", "prrt.redundancy.k",
FT_UINT8, BASE_DEC, NULL, 0x0,
"The number of information packets in the block, stored in PRRT redundancy data header", HFILL }
},
{ &hf_prrt_payload,
{ "Payload of PRRT", "prrt.payload",
FT_NONE, BASE_NONE, NULL, 0x0,
"The payload of the PRRT packet", HFILL }
},
{ &hf_prrt_receiver_addr,
{ "Receiver IP", "prrt.feedback.ipaddr",
FT_IPv4, BASE_NONE, NULL, 0x0,
"The IP address of the receiver, stored in general PRRT feedback header", HFILL }
},
{ &hf_prrt_rtt_probe,
{ "RTT Probe", "prrt.feedback.rttprobe",
FT_UINT32, BASE_DEC, NULL, 0x0,
"The timestamp of most recent data packet plus delay since reception of this packet, stored in general PRRT feedback header", HFILL }
},