This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

How to print field labels with values

0

Hi,

I am trying to print some fields from a capture.

tshark -te -T fields -E separator=/s -E quote=n  -e frame.number -e frame.time_epoch -e udp.srcport -r file

I get output which is free-form, like :

41 1305113271.649346000 2123

What I need is a name=value pair in the lines. How can I achieve the following:

frame=41 time=1305113271.649346000 udp.srcport=2123 ...

As you can see, in the output I want, I need the field name with every entry.

How can I achieve this?

edit:

The above excerpt of a highly simplified version of the fields which are needed. In reality, there are about 20 fields and many of them are specific to the messages type. So, I cannot really depend upon the order of the fields and such. If there is no way from tshark to provide it, it doesn't work for me. I need the ouput to be parseable so that I can process about 100GB of captures.

asked 25 Aug '15, 15:44

Prateek's gravatar image

Prateek
6113
accept rate: 0%

edited 26 Aug '15, 06:21

Based on comments so far, it is clear to me that there is no option built into tshark to do what I want. I have accepted one of the answers. However, I will implement the same logic in the python script which I have for processing those files.

(29 Aug '15, 08:20) Prateek

2 Answers:

0

How about just using an awk script, assuming the columns are predictable in the output (no cases of two values in one column). Something like:

tshark -T fields -E separator=/s -E quote=n  -e frame.number -e frame.time_epoch -e udp.srcport -r file | awk '{ $1 = "frame.number" $1; $2 = "time=" $2; $3 = "udp.srcport" $3; print }'

answered 25 Aug '15, 23:14

Quadratic's gravatar image

Quadratic
1.9k6928
accept rate: 13%

Although your answer solves the issue for simple cases, it does not solve the problem for me. There are more fields and some of them are specific to the request/response or message type. I need the output to be parseable so that I can process efficiently with python. If I have to post process with awk anyway, then I would rather do it in python itself. I wanted not to depend upon the order of fields.

(26 Aug '15, 06:23) Prateek

For fields which depend on context (like message type or request/response), the tshark output there should output null-valued cells in a case where an attribute doesn't exist in a given packet, so the column order and number should be dependably fixed either way.

If the objective is to have the attribute and value presented in each cell of output within the confines of tshark itself without post-processing, it might be possible with a Lua script though I don't believe it's possible purely within the existing tshark binary itself.

Some specific protocols such as Diameter support a "-z" option to do kind of what you're looking for, though those are protocol-specific.

(26 Aug '15, 21:32) Quadratic

0

What I need is a name=value pair in the lines. How can I achieve the following: frame=41 time=1305113271.649346000 udp.srcport=2123 ...

Well, as tshark does not have such a funtionality, you can either pre-process the output with awk (as mentioned by @Quadratic), or with Perl (see below), OR do the processing in your Python code, similar to what I've done in Perl, which is totally independent on the number of fields and their order.

tshark -nr http.pcap -T fields -e frame.number -e ip.src -e ip.dst -E separator=; -E header=y

Output:

frame.number;ip.src;ip.dst
1;192.168.90.55;216.34.181.60
2;192.168.90.55;216.34.181.60
3;192.168.90.55;86.58.179.120
4;192.168.90.55;23.212.211.172
5;192.168.90.55;92.122.98.7
6;192.168.90.55;92.122.98.7
7;192.168.90.55;92.122.98.7
8;192.168.90.55;216.34.181.134
9;192.168.90.55;92.122.98.7

Now, run that through the Perl script:

tshark -nr http.pcap -T fields -e frame.number -e ip.src -e ip.dst -E separator=; -E header=y | perl reformat.pl

Output:

frame.number=1 ip.src=192.168.90.55 ip.dst=216.34.181.60
frame.number=2 ip.src=192.168.90.55 ip.dst=216.34.181.60
frame.number=3 ip.src=192.168.90.55 ip.dst=86.58.179.120
frame.number=4 ip.src=192.168.90.55 ip.dst=23.212.211.172
frame.number=5 ip.src=192.168.90.55 ip.dst=92.122.98.7
frame.number=6 ip.src=192.168.90.55 ip.dst=92.122.98.7
frame.number=7 ip.src=192.168.90.55 ip.dst=92.122.98.7
frame.number=8 ip.src=192.168.90.55 ip.dst=216.34.181.134
frame.number=9 ip.src=192.168.90.55 ip.dst=92.122.98.7

Of course you can also quote the field values, if there are spaces in the field values.

tshark -nr http.pcap -T fields -e frame.number -e ip.src -e ip.dst -E separator=; -E header=y -E quote=s | perl reformat.pl

frame.number='1' ip.src='192.168.90.55' ip.dst='216.34.181.60'
frame.number='2' ip.src='192.168.90.55' ip.dst='216.34.181.60'
frame.number='3' ip.src='192.168.90.55' ip.dst='86.58.179.120'
frame.number='4' ip.src='192.168.90.55' ip.dst='23.212.211.172'
frame.number='5' ip.src='192.168.90.55' ip.dst='92.122.98.7'
frame.number='6' ip.src='192.168.90.55' ip.dst='92.122.98.7'
frame.number='7' ip.src='192.168.90.55' ip.dst='92.122.98.7'
frame.number='8' ip.src='192.168.90.55' ip.dst='216.34.181.134'

Perl script:

my @header;
my $line;

BEGIN { chomp($line = <stdin>); @header = split(';',$line); }

while (<stdin>) { chomp($line = $_);

my @fields = split(&#39;;&#39;,$line);

foreach my $i (0 .. $#fields) {
    print &quot;$header[$i]=$fields[$i] &quot;; 
}
print &quot;\n&quot;;

}

Hint: The in the code it’s STDIN, however OSQA formates it to lowercase (stdin) for whatever reason. So, if you copy-paste the code, please replace stdin with STDIN.

Regards
Kurt

answered 28 Aug ‘15, 09:08

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

edited 28 Aug ‘15, 09:36