Plugin flow timeout
Contents
Introduction
This tutorial introduces the flexible timeout programming of T2.
As outlined in the Flow mode tutorial,
the flow timeouts can be altered in a diverse way changing
constants in tranalyzer.h preferably via t2conf
.
Sometimes it is preferable to change the timeout depending on a state of a protocol,
like in, e.g., tcpStates,
which follows the TCP state machine of the sender and receiver.
Nevertheless, you can change timeouts of flows for any reason you like.
To facilitate the understanding of the subject we will implement a rudimentary version of tcpStates.
Getting started
Create folders for your data and results
If you have not created a separate data and results directory yet, please do it now. This will greatly facilitate your workflow:
mkdir ~/data ~/results
Reset tranalyzer2 and the plugins configuration
If you have followed the other tutorials, you may have modified some of the core and plugins configuration. To ensure your results match those in this tutorial, make sure to reset everything:
t2conf -a --reset
You can also clean all build files:
t2build -a -c
Empty the plugin folder
To ensure we are not left with some unneeded plugins or plugins which were built using different core configuration, it is safer to empty the plugins folder:
t2build -e -y
Are you sure you want to empty the plugin folder '/home/user/.tranalyzer/plugins' (y/N)? yes
Plugin folder emptied
Download the PCAP file
The PCAP file used in this tutorial can be downloaded here:
Please save it in your ~/data folder:
wget --no-check-certificate -P ~/data https://tranalyzer.com/download/data/faf-exercise.pcap
Build tranalyzer2 and the required plugins
For this tutorial, we will need to build the core (tranalyzer2) and the following plugins:
As you may have modified some of the automatically generated files, it is safer to use the -r
and -f
options.
...
BUILDING SUCCESSFUL
Source code
In this tutorial, we will extend tcpWin13.tar.gz, the final version of the previous tutorial (Plugin PCAP extraction).
If you are impatient, you can download the final version of the tcpWin plugin we will develop in this tutorial.
To use one of those plugins, just unpack it in the plugins folder of your T2 installation.
tranpl
tar -xf ~/Downloads/tcpWin13.tar.gz
And let t2_aliases
know about it:
source "$T2HOME/scripts/t2_aliases"
Adding timeout handlers in packet interrupt
In this tutorial. we build on the original window size counter, used in the previous plugin coding tutorials. I will talk you through all important elements.
First you need to implement a state machine following the protocol TCP. Sure, you could
just use the flags from the TCP header which are copied into the variable tcpFlags
below
and program the state machine depending on that information. But then you need to add
tcpFlags as a dependent plugin, and that add unnecessary complexity.
To make it simpler we define internal rudimentary states stored in tcpWinFlowP->state
which is an extract of the actual flags. Have a look at the state machine in the L4 packet interrupt below.
At the beginning of a new flow we are in state TCPWIN_STATE_NEW
.
If we do not see a SYN flag (TH_SYN
) we will directly move to the established TCPWIN_STATE_EST
state with a timeout TCPWIN_TMT_EST
.
TH_SYN
is defined in the core in tranalyzer2/src/proto/tcp.h.
Otherwise, a TCPWIN_STATE_BGN
state is entered with a different flow timeout.
If a flow is terminated via FIN or RST we move to state TCPWIN_STATE_ABRT
but leave the timeout at TCPWIN_TMT_EST
to capture packets coming after the RST
.
So this is all about handling timeouts with TCP. Now we want to terminate a flow if he exceeds a certain count of window size below threshold counts.
So if the windows zero count hits TCPWIN_THRES
in the TCPWIN_STATE_EST
state the flow timeout is greatly
reduced in the flow and its reverse flow, hence leading to a new flow for the next packet.
If you do not change the timeout of the reverse flow, it could be that the flow does not get removed, because always both flows have to meet the timeout criteria.
To allow better understanding of the core’s operation, I also added some packet mode output for certain variables.
So open tcpWin.c and start coding!
tcpWin
vi src/tcpWin.c
...
/*
* Static variables are only visible in this file
*/
// window size counts
static gwz_t gwz; // global window size structure
#if ALARM_MODE == 1
static uint32_t winAlarms; // Number of alarms
static uint32_t winThFlows; // Number of flows which created an alarm
#endif // ALARM_MODE == 1
static uint32_t winThCntG, winThCntG0; // Aggregated win threshold count and variable for the last threshold count
static uint8_t tcpWinStat; // Aggregated status
static uint8_t tcpWinState; // <--- Aggregated state.
...
/*
* Macros
*/
#define TCPWIN_SPKTMD_PRI_NONE() \
if (sPktFile) { \
fputs("0x%00" /* tcpWinStat */ SEP_CHR \ /* <-- */
"0x%00" /* tcpWinState */ SEP_CHR \ /* <-- */
/* tcpWinSize */ SEP_CHR \ /* <-- */
/* tcpWinThPktCnt */ SEP_CHR \ /* <-- */
/* tcpWinTimeout */ SEP_CHR \ /* <-- */
, sPktFile); \
}
...
void t2Init() {
// allocate struct for all flows and initialize to 0
(tcpWinFlows);
T2_PLUGIN_STRUCT_NEW
// Packet mode
if (sPktFile) {
// Note the trailing separators (SEP_CHR) // <--
("tcpWinStat" SEP_CHR // <--
fputs"tcpWinState" SEP_CHR // <--
"tcpWinSize" SEP_CHR // <--
"tcpWinThPktCnt" SEP_CHR // <--
"tcpWinTimeout" SEP_CHR // <--
, sPktFile);
}
// Global pointer for plugin dependencies
= &gwz;
gwzP }
...
void t2OnLayer4(packet_t *packet, unsigned long flowIndex) {
*flowP = &flows[flowIndex]; // <-- Removed const keyword
flow_t
if (flowP->l4Proto != L3_TCP) { // process only TCP
(); // Packet mode
TCPWIN_SPKTMD_PRI_NONEreturn; // go back to core
}
// only 1. frag packet will be processed
if (!t2_is_first_fragment(packet)) {
(); // Packet mode
TCPWIN_SPKTMD_PRI_NONEreturn; // go back to core
}
// get the reverse flow if it exists // <--
*revFlowP = NULL; // <--
flow_t *revTcpWinFlowP = NULL; // <--
tcpWinFlow_t // <--
if (FLOW_HAS_OPPOSITE(flowP)) { // <--
const unsigned long oppFlowIndex = flowP->oppositeFlowIndex; // <--
= &flows[oppFlowIndex]; // <--
revFlowP = &tcpWinFlows[oppFlowIndex]; // <--
revTcpWinFlowP } // <--
* const tcpWinFlowP = &tcpWinFlows[flowIndex];
tcpWinFlow_t const tcpHeader_t * const tcpHeader = TCP_HEADER(packet);
const uint32_t tcpWin = ntohs(tcpHeader->window);
if (tcpWin < TCPWIN_THRES) { // is the window size below the threshold?
->winThCnt++; // count the packet / flow
tcpWinFlowP++; // increment global packet counter
winThCntG(flowP, FL_ALARM); // Set the alarm bit in flow and global
T2_SET_STATUS// <-- Aggregation of tcpWinStat moved below
#if FORCE_MODE == 1
if (tcpWinFlowP->winThCnt > 1) T2_RM_FLOW(flowP);
#endif // FORCE_MODE == 1
}
// <-- Replace the remainder of the t2OnLayer4() callback with the code below
const uint8_t tcpFlags = tcpHeader->flags; // copy all TCP flags
->stat |= (tcpFlags & 0x1f); // extract only the main TCP flags (FIN, SYN, RST, PSH and ACK)
tcpWinFlowP
switch (tcpWinFlowP->state) { // internal simplified TCP connection state machine
case TCPWIN_STATE_NEW: // new flow
if (tcpFlags & TH_SYN) {
->timeout = TCPWIN_TMT_BGN;
flowP->state = TCPWIN_STATE_BGN;
tcpWinFlowPbreak;
}
if (!(tcpFlags & TH_ACK)) {
break;
}
->state = TCPWIN_STATE_EST;
tcpWinFlowP/*FALLTHRU*/
case TCPWIN_STATE_BGN: // begin state after 1. packet
->timeout = TCPWIN_TMT_EST;
flowP/*FALLTHRU*/
case TCPWIN_STATE_EST: // or established connection
if (tcpWinFlowP->stat & (TH_FIN | TH_RST)) {
->state = TCPWIN_STATE_ABRT;
tcpWinFlowP->timeout = TCPWIN_TMT_EST;
flowPbreak;
}
if (tcpWinFlowP->winThCnt < TCPWIN_FLWPRG) { // is wincount above threshold?
break;
}
// if win count threshold met, set abort conditions for flow and reverse flow
->stat |= TCPWIN_STAT_ABNRM; // set abort state
tcpWinFlowP->state = TCPWIN_STATE_ABRT; // set abort status flag
tcpWinFlowP->timeout = TCPWIN_TMT_ABRT; // set abort timeout
flowP
// do the same for the reverse flow if it exists
if (revFlowP) {
->state = TCPWIN_STATE_ABRT;
revTcpWinFlowP->timeout = TCPWIN_TMT_ABRT;
revFlowP}
/*FALLTHRU*/
case TCPWIN_STATE_ABRT: // abort either FIN or RST
->timeout = TCPWIN_TMT_ABRT;
flowPbreak;
default: // anything else do nothing
break;
}
->stat |= TCPWIN_STAT_THU; // set the status bit
tcpWinFlowP|= tcpWinFlowP->stat; // Aggregate all status
tcpWinStat |= tcpWinFlowP->state; // Aggregate all states
tcpWinState
// Packet mode
if (sPktFile) {
(sPktFile,
fprintf"0x%02" B2T_PRIX8 /* tcpWinStat */ SEP_CHR
"0x%02" B2T_PRIX8 /* tcpWinState */ SEP_CHR
"%" PRIu32 /* tcpWinSize */ SEP_CHR
"%" PRIu32 /* tcpWinThPktCnt */ SEP_CHR
"%f" /* tcpWinTimeout */ SEP_CHR
, tcpWinFlowP->stat
, tcpWinFlowP->state
, tcpWin
, tcpWinFlowP->winThCnt
, flowP->timeout);
}
}
...
Note the assignment of the reverse flowP
, revTcpWinFlowP
.
Always use the FLOW_HAS_OPPOSITE(flowP)
macro and assign only values to a reverse flow if it actually exists.
Defining flags, states and timeouts
If the window size hits zero for two times the timeout is set to TCPWIN_TMT_ABRT
= 1ms,
which mostly timeouts flows in our pcap.
The other states have timeouts above 1s, which might affect one flow, as we already know
from earlier experiments in the Flow Mode tutorial
that the traffic is bursty with interruptions for 3 seconds.
Open tcpWin.h in an editor now.
vi src/tcpWin.h
...
/* ========================================================================== */
/* ------------------------ USER CONFIGURATION FLAGS ------------------------ */
/* ========================================================================== */
#define TCPWIN_THRES 1 // TCP window size threshold undershoot flag
#define TCPWIN_FLWPRG 2 // <-- Threshold to abort a flow
#define TCPWIN_MINPKTS 50 // Summary file: minimal TCP packets seen to start saving process
#define TCPWIN_MAXWSCNT 100 // Summary file: maximal number of window size threshold count array elements
/* ========================================================================== */
/* ------------------------- DO NOT EDIT BELOW HERE ------------------------- */
/* ========================================================================== */
// plugin defines
// tcpWinStat status variable
// 0x01: FIN // <--
// 0x02: SYN // <--
// 0x04: RST // <--
// 0x08: PSH // <--
// 0x10: ACK // <--
#define TCPWIN_STAT_THU 0x40 // <-- TCP window size threshold undershoot
#define TCPWIN_STAT_ABNRM 0x80 // <--
// tcpWinState
#define TCPWIN_STATE_NEW 0x00 // <--
#define TCPWIN_STATE_BGN 0x01 // <--
#define TCPWIN_STATE_EST 0x02 // <--
#define TCPWIN_STATE_ABRT 0x04 // <--
// timeouts @ states
#define TCPWIN_TMT_NEW 10.0f // <-- 10 s
#define TCPWIN_TMT_BGN 2.2f // <-- 2.2 s
#define TCPWIN_TMT_EST 1.0f // <-- 1.0 s
#define TCPWIN_TMT_ABRT 0.001f // <-- 1 ms
// Structure
typedef struct {
[TCPWIN_MAXWSCNT]; // IP address array
ipAddr_t wzip #if SUBNET_ON != 0 && (AGGREGATIONFLAG & SUBNET) == 0
uint32_t sID [TCPWIN_MAXWSCNT]; // subnetID
#endif // SUBNET_ON != 0 && (AGGREGATIONFLAG & SUBNET) == 0
uint32_t tcpCnt[TCPWIN_MAXWSCNT]; // TCP packet count
float wzCnt [TCPWIN_MAXWSCNT]; // window size count
int wzi; // window size index
} gwz_t;
// Plugin structure
typedef struct { // always large variables first to limit memory fragmentation
uint32_t tcpWinInit; // initial window size
uint32_t winThCnt; // win undershoot count
uint8_t ttl; // TTL
uint8_t stat; // plugin flow status
uint8_t state; // <-- plugin flow state
} tcpWinFlow_t;
// plugin struct pointer for potential dependencies
extern tcpWinFlow_t *tcpWinFlows;
extern gwz_t *gwzP;
#endif // T2_TCPWIN_H_INCLUDED
Register timeouts with the core
At startup your timeouts have to be registered with the core, so that every flow is tested at each packet being received from an interface or the pcap. I also added some output for the packet mode that you can watch the timeouts controlling the flows. The code is shown below:
vi src/tcpWin.c
...
void t2Init() {
// allocate struct for all flows and initialize to 0
(tcpWinFlows);
T2_PLUGIN_STRUCT_NEW
// register timeouts // <--
(TCPWIN_TMT_NEW); // <--
timeout_handler_add(TCPWIN_TMT_BGN); // <--
timeout_handler_add(TCPWIN_TMT_EST); // <--
timeout_handler_add(TCPWIN_TMT_ABRT); // <--
timeout_handler_add
// Packet mode
if (sPktFile) {
("tcpWinStat" SEP_CHR // Note the trailing separators (SEP_CHR)
fputs"tcpWinState" SEP_CHR
"tcpWinSize" SEP_CHR
"tcpWinThPktCnt" SEP_CHR
"tcpWinTimeout" SEP_CHR
, sPktFile);
}
// Global pointer for plugin dependencies
= &gwz;
gwzP }
...
So that is it, define timeouts, add timeout handlers, program your state machine and set flow timeouts appropriately. The rest is flow and packet mode output.
Adding flow output and plugin report
Now I’m adding some global variables allowing us to assess the pcap from the end report and the flow file.
vi src/tcpWin.c
* t2PrintHeader() {
binary_value_t*bv = NULL;
binary_value_t
(bv, "tcpWinStat", "TCP window size threshold status");
BV_APPEND_H8(bv, "tcpWinState", "TCP window size state"); // <--
BV_APPEND_H8(bv, "tcpWinIpTTL" , "IP TTL");
BV_APPEND_U8(bv, "tcpInitWinSz", "TCP initial effective window size");
BV_APPEND_U32(bv, "tcpWinThCnt", "TCP window size threshold count");
BV_APPEND_U32(bv, "tcpWinSzThRt", "TCP packet count ratio below window size WINMIN threshold");
BV_APPEND_FLT
return bv;
}
...
void t2OnFlowTerminate(unsigned long flowIndex, outputBuffer_t *buf) {
const tcpWinFlow_t * const tcpWinFlowP = &tcpWinFlows[flowIndex];
* const bSFlowP = &bSFlow[flowIndex];
bSFlow_t
float f = 0.0;
if (bSFlowP->numTPkts) {
= (float)tcpWinFlowP->winThCnt/(float)bSFlowP->numTPkts;
f }
(buf, tcpWinFlowP->stat);
OUTBUF_APPEND_U8(buf, tcpWinFlowP->state); // <--
OUTBUF_APPEND_U8(buf, tcpWinFlowP->ttl);
OUTBUF_APPEND_U8
...
}
...
Finally a line for the internal aggregated state is added in the end report, see // <--
.
// add a endreport
void t2PluginReport(FILE *stream) {
if (winThCntG) {
(stream, plugin_name, tcpWinStat);
T2_FPLOG_AGGR_HEX(stream, plugin_name, tcpWinState); // <--
T2_FPLOG_AGGR_HEX
...
}
}
After you edited the skeleton code you should compare your implementation with tcpWin14.tar.gz. Now you are all set, compile tcpWin and invoke T2, also in packet mode.
t2build tcpWin
t2 -r ~/data/faf-exercise.pcap -w ~/results -s================================================================================ Tranalyzer 0.9.0 (Anteater), Cobra. PID: 98035, SID: 666 ================================================================================ [INF] Creating flows for L2, IPv4, IPv6 Active plugins: 01: basicFlow, 0.9.0 02: basicStats, 0.9.0 03: tcpWin, 0.9.0 04: txtSink, 0.9.0 [INF] IPv4 Ver: 5, Rev: 09082023, Range Mode: 0, subnet ranges loaded: 481663 (481.66 K) [INF] IPv6 Ver: 5, Rev: 09082023, Range Mode: 0, subnet ranges loaded: 41533 (41.53 K) Processing file: /home/wurst/data/faf-exercise.pcap Link layer type: Ethernet [EN10MB/1] Snapshot length: 65535 Dump start: 1258544215.37210000 sec (Wed 18 Nov 2009 11:36:55 UTC) Dump stop : 1258594491.683288000 sec (Thu 19 Nov 2009 01:34:51 UTC) Total dump duration: 50276.646078000 sec (13h 57m 56s) Finished processing. Elapsed time: 0.007994000 sec Finished unloading flow memory. Time: 0.008013000 sec Percentage completed: 100.00% Number of processed packets: 5902 (5.90 K) Number of processed bytes: 4993414 (4.99 M) Number of raw bytes: 4993414 (4.99 M) Number of pcap bytes: 5087870 (5.09 M) Number of IPv4 packets: 5902 (5.90 K) [100.00%] Number of A packets: 3534 (3.53 K) [59.88%] Number of B packets: 2368 (2.37 K) [40.12%] Number of A bytes: 4423242 (4.42 M) [88.58%] Number of B bytes: 570172 (570.17 K) [11.42%] Average A packet load: 1251.62 (1.25 K) Average B packet load: 240.78 -------------------------------------------------------------------------------- basicStats: Biggest L3 flow talker: 143.166.11.10 (US): 3012 (3.01 K) [51.03%] packets basicStats: Biggest L3 flow talker: 143.166.11.10 (US): 4148797 (4.15 M) [83.09%] bytes tcpWin: Aggregated tcpWinStat=0xdf tcpWin: Aggregated tcpWinState=0x07 tcpWin: Number of TCP winsize packets below threshold 1: 4 [0.07%] tcpWin: IP: 192.168.1.105, country: 07, org: Private network -------------------------------------------------------------------------------- Headers count: min: 3, max: 3, average: 3.00 Number of TCP packets: 5902 (5.90 K) [100.00%] Number of TCP bytes: 4993414 (4.99 M) [100.00%] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Number of processed flows: 94 Number of processed IPv4 flows: 94 [100.00%] Number of processed A flows: 48 [51.06%] Number of processed B flows: 46 [48.94%] Number of request flows: 47 [50.00%] Number of reply flows: 47 [50.00%] Total A/B flow asymmetry: 0.02 Total req/rply flow asymmetry: 0.00 Number of processed packets/flows: 62.79 Number of processed A packets/flows: 73.62 Number of processed B packets/flows: 51.48 Number of processed total packets/s: 0.12 Number of processed A+B packets/s: 0.12 Number of processed A packets/s: 0.07 Number of processed B packets/s: 0.05 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Number of average processed flows/s: 0.00 Average full raw bandwidth: 795 b/s Average full bandwidth : 792 b/s Max number of flows in memory: 12 [0.00%] Memory usage: 0.01 GB [0.12%] Aggregated flowStat=0x0402000000004000 [WRN] 1 alarms in 1 flows [1.06%] [INF] IPv4 flows [INF] IPAlarm
94 flows, normally the pcap produces 73 flows, so we see some effect of our dynamic timeout changes.
We have 4 events of window size hitting 0, and tcpWinStat
set to that effect: TCPWIN_ABNRM
& TCPWIN_THU
both set, so count
hit the threshold 2. Flow 44 was aborted with timeout value 1ms. flow 45 was terminated because he
passed the timeout=1.0s. And flow 47 contains the rest. The flow listing below shows you the split of
the original flow into three sub flows:
tawk 'port(49330)' ~/results/faf-exercise_flows.txt | tcol
%dir flowInd flowStat timeFirst timeLast duration numHdrDesc numHdrs hdrDesc srcMac dstMac ethType ethVlanID srcIP srcIPCC srcIPOrg srcPort dstIP dstIPCC dstIPOrg dstPort l4Proto tcpWinStat tcpWinState tcpWinThCnt
A 44 0x0400000000004000 1258594163.408285 1258594164.647755 1.239470 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell" 64334 6 0xd2 0x04 2
B 44 0x0400000000004001 1258594163.487027 1258594164.647545 1.160518 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:08:74:38:01:b4 0x0800 143.166.11.10 us "Dell" 64334 192.168.1.105 07 "Private network" 49330 6 0x1a 0x04 0
A 45 0x0400000000004000 1258594165.318635 1258594185.427506 20.108871 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:08:74:38:01:b4 0x0800 143.166.11.10 us "Dell" 64334 192.168.1.105 07 "Private network" 49330 6 0x19 0x04 0
B 45 0x0400000000004001 1258594165.319087 1258594185.427968 20.108881 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell" 64334 6 0x90 0x02 1
A 47 0x0400000000004000 1258594191.015208 1258594191.015208 0.000000 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell" 64334 6 0x94 0x04 1
Extract the packets from flow 44 around the win count hit 2. In packet 1422 the tcpWinThCnt
reaches two, the timeout is set
to 1ms and both A/B flows are removed. The next packet starts with findex
45 and detects another tcpWin
zero event.
tawk 'packet("1418-1426")' ~/results/faf-exercise_packets.txt | tcol
%dir flowInd flowStat timeFirst timeLast duration numHdrDesc numHdrs hdrDesc srcMac dstMac ethType vlanID srcIP srcIPCC srcIPOrg srcPort dstIP dstIPCC dstIPOrg dstPort l4Proto numPktsSnt numPktsRcvd numBytesSnt numBytesRcvd minPktSz maxPktSz avePktSize stdPktSize minIAT maxIAT aveIAT stdIAT pktps bytps pktAsm bytAsm tcpWinStat tcpWinIpTTL tcpInitWinSz tcpWinThCnt tcpWinSzThRt
A 44 0x0402000000004000 1258594163.408285000 1258594164.647755000 1.239470000 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell Technologies" 64334 6 49 89 0 120061 0 0 0 0 0 0.363767 0.02529531 0.05806321 39.53303 0 -0.2898551 -1 0xd2 128 8192 2 0.04081633
B 44 0x0400000000004001 1258594163.487027000 1258594164.647545000 1.160518000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:08:74:38:01:b4 0x0800 143.166.11.10 us "Dell Technologies" 64334 192.168.1.105 07 "Private network" 49330 6 89 49 120061 0 0 1380 1349 184.3238 0 0.363978 0.01303953 0.04444404 76.68989 103454.7 0.2898551 1 0x5a 111 8192 0 0
A 45 0x0400000000004000 1258594165.318635000 1258594185.427506000 20.108871000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:08:74:38:01:b4 0x0800 143.166.11.10 us "Dell Technologies" 64334 192.168.1.105 07 "Private network" 49330 6 3012 1464 4148797 0 0 1380 1377.423 49.75706 0 0.607386 0.006676252 0.02300617 149.7846 206316.8 0.3458445 1 0x59 111 64860 0 0
B 45 0x0402000000004001 1258594165.319087000 1258594185.427968000 20.108881000 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell Technologies" 64334 6 1464 3012 0 4148797 0 0 0 0 0 0.529166 0.01373558 0.03084774 72.80365 0 -0.3458445 -1 0x50 128 0 1 0.0006830601
A 47 0x0402000000004000 1258594191.015208000 1258594191.015208000 0.000000000 1 3 eth:ipv4:tcp 00:08:74:38:01:b4 00:19:e3:e7:5d:23 0x0800 192.168.1.105 07 "Private network" 49330 143.166.11.10 us "Dell Technologies" 64334 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0x54 128 0 1 1
Flow 10 with default timeout, see: flow mode tutorial got split
into four flows 10, 11, 13 and 16 because the EST
state timeout=1.0s was exceeded.
tawk 'port(1379)' ~/results/faf-exercise_flows.txt | tcol
%dir flowInd flowStat timeFirst timeLast duration numHdrDesc numHdrs hdrDesc srcMac dstMac ethType vlanID srcIP srcIPCC srcIPOrg srcPort dstIP dstIPCC dstIPOrg dstPort l4Proto numPktsSnt numPktsRcvd numBytesSnt numBytesRcvd minPktSz maxPktSz avePktSize stdPktSize minIAT maxIAT aveIAT stdIAT pktps bytps pktAsm bytAsm tcpWinStat tcpWinIpTTL tcpInitWinSz tcpWinThCnt tcpWinSzThRt
A 10 0x0400000000004000 1258562467.749142000 1258562467.900050000 0.150908000 1 3 eth:ipv4:tcp 00:0b:db:4f:6b:10 00:19:e3:e7:5d:23 0x0800 192.168.1.104 07 "Private network" 1379 63.245.221.11 us "Mozilla" 80 6 4 3 449 444 0 449 112.25 159.8441 0 0.144417 0.037727 0.05336915 26.50622 2975.323 0.1428571 0.005599104 0x5a 128 65535 0 0
B 10 0x0400000000004001 1258562467.754689000 1258562467.761692000 0.007003000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:0b:db:4f:6b:10 0x0800 63.245.221.11 us "Mozilla" 80 192.168.1.104 07 "Private network" 1379 6 3 4 444 449 0 444 148 170.8957 0 0.006751 0.002334333 0.002289841 428.3878 63401.4 -0.1428571 -0.005599104 0x5a 52 5840 0 0
A 11 0x0400000000004000 1258562477.713894000 1258562478.454425000 0.740531000 1 3 eth:ipv4:tcp 00:0b:db:4f:6b:10 00:19:e3:e7:5d:23 0x0800 192.168.1.104 07 "Private network" 1379 63.245.221.11 us "Mozilla" 80 6 8 13 1352 15162 0 455 169 185.5386 0 0.380024 0.09256638 0.09487616 10.80306 1825.717 -0.2380952 -0.8362601 0x58 128 65091 0 0
B 11 0x0400000000004001 1258562477.772691000 1258562478.454017000 0.681326000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:0b:db:4f:6b:10 0x0800 63.245.221.11 us "Mozilla" 80 192.168.1.104 07 "Private network" 1379 6 13 8 15162 1352 10 1380 1166.308 353.6241 0 0.426916 0.05240969 0.09705759 19.08044 22253.67 0.2380952 0.8362601 0x58 52 7504 0 0
A 13 0x0400000000004000 1258562501.432514000 1258562501.432514000 0.000000000 1 3 eth:ipv4:tcp 00:0b:db:4f:6b:10 00:19:e3:e7:5d:23 0x0800 192.168.1.104 07 "Private network" 1379 63.245.221.11 us "Mozilla" 80 6 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x50 128 65535 0 0
B 13 0x0400000000004001 1258562501.432305000 1258562501.432305000 0.000000000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:0b:db:4f:6b:10 0x0800 63.245.221.11 us "Mozilla" 80 192.168.1.104 07 "Private network" 1379 6 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x51 52 9648 0 0
A 16 0x0400000000004000 1258562509.633370000 1258562509.633370000 0.000000000 1 3 eth:ipv4:tcp 00:0b:db:4f:6b:10 00:19:e3:e7:5d:23 0x0800 192.168.1.104 07 "Private network" 1379 63.245.221.11 us "Mozilla" 80 6 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x51 128 65535 0 0
B 16 0x0400000000004001 1258562509.653962000 1258562509.653962000 0.000000000 1 3 eth:ipv4:tcp 00:19:e3:e7:5d:23 00:0b:db:4f:6b:10 0x0800 63.245.221.11 us "Mozilla" 80 192.168.1.104 07 "Private network" 1379 6 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x50 52 9648 0 0
As an exercise, change the TCPWIN_TMT_EST
to 4.0, what do you expect?
Then change the TCPWIN_FLWPRG
to 3. What do you expect?
Conclusion
You can download the final version of the tcpWin plugin.
The next tutorial will teach you how to implement a sink plugin.
Have fun experimenting!
See also
- Plugin programming cheatsheet
- The basics: your first flow plugin
- Plugin end report
- Plugin monitoring
- Plugin packet mode
- Plugin summary files
- Plugin geo labeling
- Plugin dependencies
- Plugin alarm mode
- Plugin force mode
- Plugin pcap extraction
- Plugin sink
- Developing Tranalyzer plugins in C++
- Developing Tranalyzer plugins in Rust