[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]

"Linux Gazette...making Linux just a little more fun!"

Using ngrep

By Pat Eyler

Using ngrep


ngrep is a tool for watching network traffic. It is based on the libpcap library, which provides packet capturing functionality. ngrep allows regular expression style filters to be used to select traffic to be displayed.

ngrep is the first utility we'll discuss that doesn't ship on most linux systems. We'll talk about how to get and install it, how to start it up and use it, and more advanced use.

Getting & Installing ngrep

Source code for ngrep is available from as are some binary packages. I'll review installing the source, as the binary packages are fairly straight forward.

On a Redhat 6.2 system, you'll need to install libpcap before you can install ngrep. This package is available from As of this writing, the most recent version is libpcap-0.5.2.tar.gz. Once this is downloaded, I put things like this into /usr/local/src, you should do the following:

$ tar xvzf libpcap-0.5.2.tar.gz
$ cd libpcap_0_5rel2
$ ./configure
$ make
$ su
Password: ********
# make install-incl
# make install-man
# exit

Your next step is to build ngrep itself. ngrep source can be downloaded from After downloading it, do the following:

$ tar xzvf ngrep-1.38.tar.gz
$ cd ngrep
$ ./configure
$ make
$ su
Password: ********
# make install
# exit

Congratulations, at this point you should have a working copy of ngrep installed on your system.

Using ngrep

To start using ngrep you'll need to decide what pattern you want to search for. These can be either libpcap style descriptions of network traffic or GNU grep style regular expressions describing the contents of traffic. In the following example, we'll grab any packet containing the pattern "ssword" and display it in the alternative format (which I think is a lot more readable):

[root@cherry /root]# ngrep -x ssword
interface: eth0 (
match: ssword
T -> [AP]
  50 61 73 73 77 6f 72 64    3a 20                      Password:
59 received, 0 dropped
[root@cherry /root]# 

Each of the hash marks in the above example represent a packet not containing the pattern we're searching for, any packets containing the pattern are displayed.

In this example we followed the basic syntax of ngrep – ngrep <options> [pattern]. We used only the -x option, which sets the alternative display format.

Doing More with ngrep

There are a number of additional twists to the way that you can use ngrep. Chief among them is the ability to include libpcap style packet filtering. libpcap provides a fairly simple language for filtering traffic.

Filters are written by combining primitives with conjunctions (and and or). Primitives can be preceeded with the term not.

Primitives are normally formed with an id (which can be numeric or a symbolic name followed by one or more qualifiers. There are three kinds of qualifiers; type, direction, and protocol.

Type qualifiers describe what the id refers to. Allowed options are host, net, and port. If not type is given, the primitive defaults to host. Examples of type primitives are; host crashtestdummy, net 192.168.2, or port 80

Directional qualifiers indicate which direction traffic is flowing in. Allowable qualifiers are src and/or dst. Examples of direction primitives are: src cherry, dst mango, src or dst port http. This last example shows two qualifiers being used with a single id.

Protocol qualifiers limit the captured packets to those of a single protocol. In the absence of a protocol qualifier, all ip packets are captured (subject to other filtering rules). Protocols which can be fileter are tcp, udp, and icmp. You might use a protocol qualifier like icmp, or tcp dst port telnet.

Primitives can be negated and combined to develop more complex filters. If you wanted to see all traffic to rose except telnet and ftp-data, you could use the following filter host dst rose and not port telnet and not port ftp-data.

There are some command line switches that are worth noting as well. The following table shows the command line switches likely to be of the most use. As usual, check the man page for more detail.

Table 1. Command Line Switches for ngrep

-e Show empty packets.
-n [num] Match num packets, then exit.
-i [expression] Search for the regular expression without regard to case.
-v [expression] Search for packets not containing the regular expression.
-t Print a YYYY/MM/DD HH:MM:SS.UUUUUU timestamp on each matched packet.
-T display a +S.UUUUUU timestamp on each matched packet.
-x Show the packets in the alternate hex and ascii style.
-I [filename] Read from a pcap style dump named filename instead of live traffic.
-O filename Write output to a pcap style file named filename.
-D Mimic realtime by printing matched packets at their recorded timestamp.

Wrapping up ngrep

Using ngrep can help you quickly match and display packets during your troubleshooting. If you've got an application level problem, ngrep can help you isolate the problem.

For example, if I was trying to make a connection from cherry ( to cuke ( and the connection was failing, I might troubleshoot the problem like this:

Describe the symptoms: Cherry can not make a connection to hosts on remote network, but can connect to hosts on other networks. Other hosts on cherry's network can connect to hosts on the remote network.

Understand the environment: The hosts involved are cherry, rhubard (the gateway to the remote network), and cuke.

List hypotheses: My problems might be a misconfiguration of cherry, or of an intervening router.

Prioritize hypothesis & narrow focus: Because cuke seems to be the only host affected, we'll start looking there. If we can't solve the problem on cuke, we'll move to rhubarb.

Create a plan of attack: I can try to ping cuke from cherry while ngreping for traffic like this, ngrep host cherry to see what traffic I am sending.

Act on your plan: As we start pinging cuke, we see the following results in our ngrep session:

[root@cherry /root]# ngrep -e -x host
interface: eth0 (
filter: ip and ( host )
I -> 8:0
  eb 07 00 00 31 86 a7 39    5e cd 0e 00 08 09 0a 0b    ....1..9^.......
  0c 0d 0e 0f 10 11 12 13    14 15 16 17 18 19 1a 1b    ................
  1c 1d 1e 1f 20 21 22 23    24 25 26 27 28 29 2a 2b    .... !"#$%&'()*+
  2c 2d 2e 2f 30 31 32 33    34 35 36 37                ,-./01234567    
I -> 5:1
  c0 a8 01 0b 45 00 00 54    25 f2 00 00 40 01 d0 52    ....E..T%...@..R
  c0 a8 01 0a c0 a8 02 0a    08 00 dc 67 eb 07 00 00    ...........g....
  31 86 a7 39 5e cd 0e 00    08 09 0a 0b 0c 0d 0e 0f    1..9^...........
  10 11 12 13 14 15 16 17    18 19 1a 1b 1c 1d 1e 1f    ................
  20 21 22 23 24 25 26 27    28 29 2a 2b 2c 2d 2e 2f     !"#$%&'()*+,-./
  30 31 32 33 34 35 36 37    b4 04 01 00 06 00 00 00    01234567........
  00 10 00 00 01 00 00 00    e8 40 00 00                .........@..    
2 received, 0 dropped
[root@cherry /root]# 
This shows two packets. The first is an ICMP packet of Type 8 and Code 0, a ping request. It is destined for cuke. The second is and ICMP packet of Type 5 and Code 1 and ICMP Redirect. This is coming from Mango, the gateway to the rest of the world.

Test your results: We didn't expect to see mango involved at all, if we look at the ICMP Redirects being sent (using the -v switch), we can see that we're being redirected to the address, not rhubarb.

Apply results of test to hypothesis: If we're not sending our traffic to the right gateway it will never get to the right place. We should be able to solve this by adding a route to the network on cherry (a quick check of working hosts shows that this is the way they're configured). We'll probably want to fix the bad route on mango as well.

Iterate as needed: Once we've made the change and tested it, we know that it works and don't need to go any further.

Author and License

This document is a draft release of a section from a book called "Networking Linux: A Practical Guide to TCP/IP" being published by New Riders Publishing. This section is released under the OPL with no further terms, the Free Software Foundation has agreed that this constitutes a Free license. (Please see and for more information).

Because this document is a draft, there are likely errors, typos, and the like. If you see anything that you think should be changed, please let me know. I can be reached at

Copyright © 2000, Pat Eyler
Published in Issue 57 of Linux Gazette, September 2000

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]