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.
Source code for ngrep is available from http://www.packetfactory.net/Projects/ngrep/ 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 http://www.tcpdump.org/release. 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 http://www.packetfactory.net/Projects/ngrep. 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.
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 (192.168.1.0/255.255.255.0) match: ssword ################################ T 192.168.1.20:23 -> 192.168.1.10:1056 [AP] 50 61 73 73 77 6f 72 64 3a 20 Password: #########################exit 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.
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. |
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 (192.168.1.10) to cuke (192.168.2.10) 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:
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.
[root@cherry /root]# ngrep -e -x host 192.168.1.10 interface: eth0 (192.168.1.0/255.255.255.0) filter: ip and ( host 192.168.1.10 ) # I 192.168.1.10 -> 192.168.2.10 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 192.168.1.1 -> 192.168.1.10 5:1 c0 a8 01 0b 45 00 00 54 25 f2 00 00 40 01 d0 52 ....E..T%[email protected] 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 .........@.. exit 2 received, 0 dropped [root@cherry /root]#
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 192.168.1.11 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 192.168.2.0/24 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.
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 www.opencontent.org and www.gnu.org 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 [email protected].