0

I'm curious if ngrep can do inverted matched based on ports? I've tried something along the lines of:

ngrep -d any -v port 22
interface: any
filter: ( port 22 ) and (ip or ip6)

And although it says the filter is for 'port 22', it doesn't pick up any of the ports. Tried googling this for a couple of days, and haven't found a solution. Can anyone who is familiar with ngrep let me know if this is doable?

hobbes
  • 467
  • 1
  • 7
  • 22
  • What do you mean by "it says the filter is for 'port 21'"? The filter expression you wrote was "port 22", which should match packets for port *22*, not port *21*. –  Apr 27 '15 at 21:54
  • And what do you mean by "inverted matched"? Do you mean you want all packets *other* than the ones going to a particular port? –  Apr 27 '15 at 21:55
  • @GuyHarris I made an update, it should have said port 22 (not 21). And correct, I'm looking for all packets other than the ones going to a particular port. Reason being, I don't want to see my SSH traffic. – hobbes Apr 27 '15 at 23:16

1 Answers1

4

Wow. ngrep's command-line syntax really is a greasy hack.

The ngrep man page says:

ngrep {various flags} <match expression> <bpf filter>

without indicating how ngrep manages to tell what's part of the "match expression" and what's part of the "bpf filter".

The way it determines that is by:

  • taking the first shell token after the flag arguments, if present, as the "match expression" and, if there are any tokens after it, gluing them all together with spaces between them and making that the "bpf filter";
  • if it finds a "bpf filter", trying to compile it and:
  • if that succeeds, using what it found as the "match expression" and the "bpf filter";
  • if that fails, assuming there was no "match expression", taking all the tokens after the flag arguments, gluing them together to make the "bpf filter".

This means that if you do ngrep port 22, it first tries to use "port" as the "match expression" and "22" as the "bpf filter", which fails because "22" isn't a valid BPF filter, and then assumes that there isn't a "match expression" and that "port 22" is the "bpf filter", which works.

However, if you do ngrep not port 22, it first tries to use "not" as the "match expression" and "port 22" as the "bpf filter", which succeeds, so you end up with "not" as the filter with which it tries grepping and "port 22" as the BPF filter it hands to libpcap.

Sadly, ngrep has no way of saying "there's no match expression, there's just a BPF filter", so you have to do something such as ngrep "" not port 22, with an empty match expression to have it recognize "not port 22" as the BPF filter.

So, if you want to see all traffic except for traffic to port 22, try

ngrep -d any "" not port 22

-v affects the match expression, NOT the BPF filter; that means that the command you gave in your question will match only packets to or from port 22, not packets not to or from port 22. As you want the empty match expression to match all packets, rather than no packets, you would leave the -v flag out.

  • When I try '-v not port 22', it shows me port 22 traffic, which I'm assuming is because we're inverting a not statement. However, when I try using '-v not port 21', I don't see any traffic including port 22. interface: any filter: ( port 21 ) and (ip or ip6) don't match: not – hobbes Apr 28 '15 at 17:17
  • Another example, I'll use '-d any -v port 22' and get results: "filter: ( port 22 ) and (ip or ip6) ######...######", but when I use port 21, I get "filter: ( port 21 ) and (ip or ip6) ^Cexit 0 received, 0 dropped" – hobbes Apr 28 '15 at 17:24
  • OK, ngrep's command-line syntax is broken by design, so I've updated the answer to indicate what you really need here. –  Apr 28 '15 at 20:43
  • Wow, I am amazed that this works, and stunned that the syntax is that broken. I am incredibly grateful for your response (and patience)! – hobbes Apr 28 '15 at 22:34
  • Sorry about assuming sanity on the part of ngrep in my original answer. :-) –  Apr 28 '15 at 23:33