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

filter efficiencies

0

I was just wondering about how filters process and can I do things more efficiently with one filter vs another. Example:

1) tcp.flags.syn == 1 && tcp.flags.rst == 1

2) tcp[13] == 12

Does one work better/same/worse than two?

asked 19 Jun '17, 18:43

Antacus's gravatar image

Antacus
11112
accept rate: 0%


2 Answers:

0

It depends:

  • tcp.flags.rst == 1 is not valid. I guess you mean tcp.flags.reset == 1?
  • Your first filter will show packets where at least SYN AND RST are set. But other flags (e.g. Push, Fin) may also be set to 1
  • The second filter will only show packets where the value on TCP offset 13 is 12 (Only SYN AND ACK are set, all other flags are 0)

Therefore it's hard to say if one of the filter is better/worse than the other. It depends for what your're looking for. But one thing is clear: Both filters are not the same.

answered 20 Jun '17, 02:54

Uli's gravatar image

Uli
9031515
accept rate: 29%

Guess I should not have written an off the hip question. My original was more of a concept question on how does the code of wireshark process filters. You got me on details, which I am usually a stickler on :) So let me rewrite my original question :)

A) (conditional test #1) && (conditional test #2)

B) (conditional test #3) * where B) provides the same answer as A)

Not being a hard core coder it seems to me that logically test B) would be twice as fast as A) so where you can take the time to optimize filters. Think of a script which you have setup to pre-parse capture files and generate a report before you even open the capture file for the first time. Filters run inside repeating scripts which can be optimized to run faster should, imho.

I assume this question has been asked before but I am unable to locate an answer. There is a Performance page on the Wiki but it does not address this question.

(20 Jun '17, 05:25) Antacus
1

I realize this question was geared more for Wireshark display filters, but for capture filters, you can directly compare them by having tcpdump or dumpcap generate the bpf code if you specify the -d option. For example, if you run these two commands, you can see that they produce the exact same resulting bpf code:

dumpcap -i 2 -f "tcp[13]==6" -d
dumpcap -i 2 -f "tcp[tcpflags]==tcp-syn|tcp-rst" -d

Here's the output in either case:

(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 10
(002) ldb      [23]
(003) jeq      #0x6             jt 4    jf 10
(004) ldh      [20]
(005) jset     #0x1fff          jt 10   jf 6
(006) ldxb     4*([14]&0xf)
(007) ldb      [x + 27]
(008) jeq      #0x6             jt 9    jf 10
(009) ret      #262144
(010) ret      #0

If you generate the bfp code, it can help you determine if one capture filter is more efficient than another or if they differ in any way.

(20 Jun '17, 12:05) cmaynard ♦♦
1

Here's the output in either case

Not surprising, given that, in effect, "tcpflags" is a macro for "13" , "tcp-syn" is a macro for "0x02", "tcp-rst" is a macro for "0x04", and libpcap's BPF compiler's optimizer evaluates some expressions at compile time.

For display filters, there's a program dftest, which is part of the Wireshark source, and may be installed if Wireshark is; if, for example, you run dftest 'tcp.flags.syn == 1 && tcp.flags.reset == 1', it prints

Filter: "tcp.flags.syn == 1 && tcp.flags.reset == 1"

Constants:
00000 PUT_FVALUE        1 <FT_BOOLEAN> -> reg#2
00001 PUT_FVALUE        1 <FT_BOOLEAN> -> reg#3

Instructions: 00000 READ_TREE tcp.flags.syn -> reg#0 00001 IF-FALSE-GOTO 7 00002 ANY_EQ reg#0 == reg#2 00003 IF-FALSE-GOTO 7 00004 READ_TREE tcp.flags.reset -> reg#1 00005 IF-FALSE-GOTO 7 00006 ANY_EQ reg#1 == reg#3 00007 RETURN

which is the code that’s interpreted at run time by the display filter code. So you could use dftest on the two filter expressions to see what test instructions are generated.

Whether (conditional test #3) generates fewer instructions than (conditional test #1) && (conditional test #2) and, if so, how many fewer instructions are generated, depends on what the three conditional tests are.

(21 Jun ‘17, 00:50) Guy Harris ♦♦

Not surprising, given that, in effect, “tcpflags” is a macro for “13” , “tcp-syn” is a macro for “0x02”, “tcp-rst” is a macro for “0x04”,

Right, I was just illustrating the fact that tcp-syn|tcp-rst is equivalent to 6, and not 12, as Antacus originally wrote in the question. If the names are used instead of the number, then you can be assured of the correct value being used, so it’s generally better to use the names.

And thanks for mentioning dftest. I sometimes forget about it because for some unknown reason, it has never been packaged with the Wireshark Windows installer, and Windows is the platform I generally use.

And to compare Guy’s dftest output for the “tcp.flags.syn == 1 && tcp.flags.reset == 1” filter, here’s the dftest output for tcp.flags == 6:

Filter: “tcp.flags == 6”

Constants:
00000 PUT_FVALUE        6 <FT_UINT16> -> reg#1
Instructions:
00000 READ_TREE         tcp.flags -> reg#0
00001 IF-FALSE-GOTO     3
00002 ANY_EQ            reg#0 == reg#1
00003 RETURN

So clearly this filter is [slightly] more efficient.

I think Guy’s dftest portion of his comment should be the answer to this question.

(21 Jun ‘17, 11:16) cmaynard ♦♦

0

Others have already pointed out dftest and dumping BPF code for comparisons, but I'll give an answer from a different perspective...

In my experience, I haven't seen much difference in efficiency...but I work in customer support, so I usually go with the most easily understood filter.

Obviously, tcp.flags.syn==1 && tcp.flags.ack ==1 requires much less explanation on my part than would any filter like tcp[offset]==value.

So, if I'm writing (say) a tshark script that I won't have to explain to others, I might use the offset test...but if I'm doing anything for public consumption, I go with what folks are more likely to understand at first glance.

answered 22 Jun '17, 11:19

wesmorgan1's gravatar image

wesmorgan1
411101221
accept rate: 4%