tshark stopping criteria - tshark

I need to stop tshark (command line equi of wireshark) after a certain condition is met.
From the tshark man pages, I found that stopping condition can be applied with respect to duration, files, file size and multiple files mode.
Is there any stopping condition I can apply through capture filter so that tshark stops capturing.
ex: Upon receiving a TCP SYN packet from a particular port number (condition applied in capture filter), tshark stops capturing.
Please answer this riddle.

You can pipe the output to head and pick the first frame that matches your query but you also need to disable output buffering (stdbuf is part of coreutils)
e.g (Linux)
stdbuf -i0 -o0 -e0 tshark -r file.pcap -Y 'sctp.verification_tag == 0x2552' | head -1
Mac:
gstdbuf -i0 -o0 -e0 tshark -r file.pcap -Y 'tcp.flags.syn == 1 && tcp.port == 80' | head -1

When Wireshark 4.0.0 was released about 1 month ago, they changed how "-a" behaves in comparison to how "-c" behaves, and now "-a packets:1" does exactly what you want (5 years after your original question šŸ˜‚).
From their documentation:
-a|--autostop
Specify a criterion that specifies when TShark is to stop writing to a capture file. The criterion is of the form test:value, where test is one of:
- *duration:value* ...
- *files:value* ...
- *filesize:value* ...
- *packets:value* switch to the next file after it contains value packets. **This does not include any packets that do not pass the display filter**, so it may differ from -c.
Although this fix was done ~8 months ago (see their commit), it seems that they intended it for the 4.0 branch only, since non of the 3.6 branch have received this fix (including version 3.6.10 which is still being developed).

Related

Silencing "guessed channel layout" for FFmpeg

Does anyone know what parameters I can run FFmpeg under to silence console messages about guessing channel layouts for input streams?
That message is a warning. To suppress all warnings, the loglevel should be < 24, so e.g. ffmpeg -v 16 -i in.wav out.mp3.
You can also disable performing the action of guessing (not just its announcement) by the input option of -guess_layout_max i.e. ffmpeg -guess_layout_max 0 -i in.wav out.mp3. The issue with this is that the output won't be flagged with a channel layout. You can correct this by explicitly setting output channels option -ac N where N is the number of channels in the output.

Delays between requests in wget

I want to download web using wget, but to make it more like a real user I would like to make small random delays between requests.
I'm executing wget via cmd.
You can add the below code into your command line which adds a ten second wait in between server requests.
-w 10
And you can also include
--random-wait
Into your command line with -w option which will vary the wait by 0.5 and 1.5 times the value you provide here.
Perfect, adding "-w 3" on the front end of a recursive download prevented the server from becoming overloaded.
as in
wget -w 3 -m -np -c -R "index.html*" "http://example.com.whatever/public/files/"
wait 3
mirroring to recurse all folder depths, and use source timestamps
no parent upward traversal
continue partially downloads
reject any files named index.html
target host URL with the desired recursive files and folders
hope this helps someone else

Compare file sizes and download if they're different via wget

I'm downloading some .mp3 files (all legal) via wget :
wget -r -nc files.myserver.com
I have to stop the download sometimes and at that times the file is partially downloaded. For example a 10 minutes record.mp3 file become 4 minutes record.mp3 file. It's playing correctly but incomplete.
If I use the same command above, because the record.mp3 file is already exist in my local computer wget skips that file although it isn't complete.
I wonder if there is a way to check the file sizes and if the file size in the remote server and local computer isn't same re-download it. (I've learned the --spider command gives the file size but is there any other command that automatically check the file sizes and download or not).
I would go with wget's -N option for timestamping, but note that wget will only compare the file sizes if you also specify the --no-if-modified-since option. Without it, incomplete files are indeed skipped on the next run because they receive a timestamp of the current time, which is newer than that on the server.
The reason is probably that with only -N, a GET request is sent for the file with the If-Modified-Since field set. The server responds with either 200 or 304, but the 304 doesn't contain the file size so wget can't check it.
With --no-if-modified-since wget sends a HEAD request instead to get the timestamp and file size, and checks both.
What I use for recursive download of a folder:
wget -T 300 -nv -t 1 -r -nd -np -l 1 -N --no-if-modified-since -P $my_folder $my_url
With:
-T 300: Set the network timeout to 300 seconds
-nv: Turn off verbose without being completely quiet
-t 1: Set number of tries to 1
-r: Turn on recursive retrieving
-nd: Do not create a hierarchy of directories when retrieving recursively
-np: Do not ever ascend to the parent directory when retrieving recursively
-l 1: Specify recursion maximum depth 1
-N: Turn on time-stamping
--no-if-modified-since: Do not send If-Modified-Since header in ā€˜-Nā€™ mode, send preliminary HEAD request instead
You may try the -c option to continue the download of partially downloaded files, however the manual gives an explicit warning:
You need to be especially careful of this when using -c in conjunction
with -r, since every file will be considered as an "incomplete
download" candidate.
While there is no perfect solution to this problem you could try to use -N option to turn on timestamping. This might prevent errors when the file has changed on the server but only if the server supports timestamping and partial downloads. Try it and see how it goes.
wget -r -N -c files.myserver.com
If you need check if file was partially downloaded (has different size) or updated on remote server by timestamp and must be in this case updated locally you need use -N option.
Here some additional info about -N (--timestamping) option from Wget docs:
If the local file does not exist, or the sizes of the files do not match, Wget will download the remote file no matter what the
time-stamps say.
Added From: https://www.gnu.org/software/wget/manual/wget.html (Chapter: 5 Time-Stamping)

grep command to print follow-up lines after a match

how to use "grep" command to find a match and to print followup of 10 lines from the match. this i need to get some error statements from log files. (else need to download use match for log time and then copy the content). Instead of downloading bulk size files i need to run a command to get those number of lines.
A default install of Solaris 10 or 11 will have the /usr/sfw/bin file tree. Gnu grep - /usr/sfw/bin/ggrep is there. ggrep supports /usr/sfw/bin/ggrep -A 10 [pattern] [file] which does what you want.
Solaris 9 and older may not have it. Or your system may not have been a default install. Check.
Suppose, you have a file /etc/passwd and want to filter user "chetan"
Please try below command:
cat /etc/passwd | /usr/sfw/bin/ggrep -A 2 'chetan'
It will print the line with letter "chetan" and the next two lines as well.
-- Tested in Solaris 10 --

tshark export FIX messages

The Objective
I'm trying to achieve the following:
capture network traffic containing a conversation in the FIX protocol
extract the individual FIX messages from the network traffic into a "nice" format, e.g. CSV
do some data analysis on the exported "nice" format data
I have achieved this by:
using pcap to capture the network traffic
using tshark to print the relevant data as a CSV
using Python (pandas) to analyse the data
The Problem
The problem is that some of the captured TCP packets contain more than one FIX message, which means that when I do the export to CSV using tshark I don't get a FIX message per line. This makes consuming the CSV difficult.
This is the tshark commandline I'm using to extract the relevant FIX fields as CSV is:
tshark -r dump.pcap \
-R \'(fix.MsgType[0]=="G" or fix.MsgType[0]=="D" or fix.MsgType[0]=="8" or \ fix.MsgType[0]=="F") and fix.ClOrdID != "0"\' \
-Tfields -Eseparator=, -Eoccurrence=l -e frame.time_relative \
-e fix.MsgType -e fix.SenderCompID \
-e fix.SenderSubID -e fix.Symbol -e fix.Side \
-e fix.Price -e fix.OrderQty -e fix.ClOrdID \
-e fix.OrderID -e fix.OrdStatus'
Note that I'm currently using "-Eoccurrence=l" to get just the last occurrence of a named field in the case where there is more than one occurrence of a field in the packet. This is not an acceptable solution as information will get thrown away when there are multiple FIX messages in a packet.
This is what I expect to see per line in the exported CSV file (fields from one FIX message):
16.508949000,D,XXX,XXX,YTZ2,2,97480,34,646427,,
This is what I see when there is more than one FIX message (three is this case) in a TCP packet and the commandline flag "-Eoccurrence=a" is used:
16.515886000,F,F,G,XXX,XXX,XXX,XXX,XXX,XXX,XTZ2,2,97015,22,646429,646430,646431,323180,323175,301151,
The Question
Is there a way (not necessarily using tshark) to extract each individual, protocol specific message from a pcap file?
Better Solution
Using tcpflow allows this to be done properly without leaving the commandline.
My current approach is to use something like:
tshark -nr <input_file> -Y'fix' -w- | tcpdump -r- -l -w- | tcpflow -r- -C -B
tcpflow ensures that the TCP stream is followed, so no FIX messages are missed (in the case where a single TCP packet contains more than 1 FIX message). -C writes to the console and -B ensures binary output. This approach is not unlike following a TCP stream in Wireshark.
The FIX delimiters are preserved which means that I can do some handy grepping on the output, e.g.
... | tcpflow -r- -C -B | grep -P "\x0135=8\x01"
to extract all the execution reports. Note the -P argument to grep which allows the very powerful perl regex.
A (Previous) Solution
I'm using Scapy (see also Scapy Documentation, The Very Unofficial Dummies Guide to Scapy) to read in a pcap file and extract each individual FIX message from the packets.
Below is the basis of the code I'm using:
from scapy.all import *
def ExtractFIX(pcap):
"""A generator that iterates over the packets in a scapy pcap iterable
and extracts the FIX messages.
In the case where there are multiple FIX messages in one packet, yield each
FIX message individually."""
for packet in pcap:
if packet.haslayer('Raw'):
# Only consider TCP packets which contain raw data.
load = packet.getlayer('Raw').load
# Ignore raw data that doesn't contain FIX.
if not 'FIX' in load:
continue
# Replace \x01 with '|'.
load = re.sub(r'\x01', '|', load)
# Split out each individual FIX message in the packet by putting a
# ';' between them and then using split(';').
for subMessage in re.sub(r'\|8=FIX', '|;8=FIX', load).split(';'):
# Yield each sub message. More often than not, there will only be one.
assert subMessage[-1:] == '|'
yield subMessage
else:
continue
pcap = rdpcap('dump.pcap')
for fixMessage in ExtractFIX(pcap):
print fixMessage
I would still like to be able to get other information from the "frame" layer of the network packet, in particular the relative (or reference) time. Unfortunately, this doesn't seem to be available from the Scapy packet object - it's topmost layer is the Ether layer as shown below.
In [229]: pcap[0]
Out[229]: <Ether dst=00:0f:53:08:14:81 src=24:b6:fd:cd:d5:f7 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=215 id=16214 flags=DF frag=0L ttl=128 proto=tcp chksum=0xa53d src=10.129.0.25 dst=10.129.0.115 options=[] |<TCP sport=2634 dport=54611 seq=3296969378 ack=2383325407 dataofs=8L reserved=0L flags=PA window=65319 chksum=0x4b73 urgptr=0 options=[('NOP', None), ('NOP', None), ('Timestamp', (581177, 2013197542))] |<Raw load='8=FIX.4.0\x019=0139\x0135=U\x0149=XXX\x0134=110169\x015006=20\x0150=XXX\x0143=N\x0152=20121210-00:12:13\x01122=20121210-00:12:13\x015001=6\x01100=SFE\x0155=AP\x015009=F3\x015022=45810\x015023=3\x015057=2\x0110=232\x01' |>>>>
In [245]: pcap[0].summary()
Out[245]: 'Ether / IP / TCP 10.129.0.25:2634 > 10.129.0.115:54611 PA / Raw'