Packet Capturing with TCPDUMP command in linux

Sarath Pillai's picture
tcpdump packet capture linux

In this tutorial we will be looking into a very well known tool in Linux system administrators tool box. Some times during troubleshooting this tool proves to be very helpful. With the help of this tool you can analyze the packet before it reaches the application stack. And some times detect why the server is not responding to a ping request, why an application is not responding to a certain machine etc etc.

Its no tool other than TCPDUMP. Tcpdump is a very powerful tool because of its strength in capturing packets based on different parameters given. It operates on network layer, so will be able to capture all the packets in and out of the machine. You can use tcpdump to capture and save the packets to a file to analyse it later.

TCPDUMP uses Libpcap(a c/c++ library that's used for packet capturing.)

There are other tools out there which does the same job of packet capture/analyzing like wireshark, but tcpdump keeps all the captures raw. Which means its shows us the raw data it captures as it is.

Things to understand before we go ahead.

  1.     tcpdump works in network layer
  2.     a network packet header consists of sender,destination,state information and other flag informations.
  3.     TCPDUMP only captures the first 96bytes of data from the packet by default.

TCPDUMP can be downloaded from here

Most of the linux distributions these days comes preloaded with tcpdump tool. But you need to be root or sudo permissions to run the tool.

Checking if TCPDUMP is already installed on the machine.

 

[root@myvm ~]# rpm -qa | grep tcpdump
tcpdump-3.9.4-15.el5

the above command searches the rpm database and greps for tcpdump package. 

The advantage of using TCPDUMP over other packet analyzers is that you will need to understand a certain protocol in TCP in its detailed form. Otherwise deciphering the raw data captured by tcpdump is quite difficult without the understanding of TCP protocols.

Hence using TCPDUMP in a way will keep yourself updated about how a certain protocol communicates over the wire.

Lets have a look at some of the basic options available in TCPDUMP, and then will go into further options.

-i  option in tcpdump

this option is used to specify the interface. Using this option we can tell tcpdump to capture packets that's coming towards a particular interface. For example

[root@myvm ~]# tcpdump -i lo
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes

Its clear from the above command that tcpdump is only listening on loopback interface for packets. And as mentioned before, the output clearly says that its capturing only 96bytes of the packet.

[root@myvm ~]# tcpdump -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

the above command will dump all the packets thats destined towards eth0 interface. TCPDUMP output will be very fast, and will fill the screen if you got lot of connections.

 

-n option in tcpdump

 

if you do not use tcpdump with -n option, all the sender and destination host address will be in "name" format, which means all ip's will be displayed with hostnames.

Using -n option with tcpdump will disable name lookup. This will display all the output in sender and reciever's IP address format.

-c option in tcpdump

by using -c option you can specify the number of packets that needs to be captured. For example if you only want to capture 2 packets you will do something as shown below.

[root@myvm ~]# tcpdump -n -c 2 -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
01:55:55.393805 IP 172.16.140.41.5910 > 172.16.134.85.51907: . 31288437:31292817(4380) ack 3681524545 win 71
01:55:55.394626 IP 172.16.134.85.51907 > 172.16.140.41.5910: . ack 2920 win 1053
2 packets captured
4 packets received by filter
0 packets dropped by kernel

as shown in the above command and its result you can clearly see that we told tcpdump to only capture 2 packets from eth0 interface using -c option.

-s option in tcpdump

 

as mentioned earlier by default tcpdump only captures the firs 96bytes of a packet. But suppose you need to capture packets in its full size then you need to pass the size option -s with its argument.

You can either use -s0 option to capture the whole packet or use number of bytes with -s argument.

[root@myvm ~]# tcpdump -s0 -n -c 2 -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
01:58:31.011304 IP 172.16.134.85.51907 > 172.16.140.41.5910: P 3681527491:3681527497(6) ack 32290881 win 776
01:58:31.011312 IP 172.16.140.41.5910 > 172.16.134.85.51907: . ack 6 win 71
2 packets captured
2 packets received by filter
0 packets dropped by kernel

as you can see from the above output, its clearly mentioned that capture size is 65535 bytes instead of 96 bytes(the capture size is made bold in the output of the above command)

-e option in tcpdump

from all the above output we till now saw, the output only showed us information about the sender and receivers ip address. Suppose you want the mac address of the sender and reciever then you can include -e option.

See our example output below.

[root@myvm ~]# tcpdump -s0 -e -n -c 2 -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
02:00:10.545520 1a:e5:ad:00:b5:20 > Broadcast, ethertype IPv4 (0x0800), length 92: 172.16.140.20.netbios-ns > 172.16.140.255.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
02:00:10.546598 00:15:17:8d:0c:9c > 46:0a:98:3d:41:b1, ethertype IPv4 (0x0800), length 210: 172.16.140.41.56153 > 172.16.140.33.49155: P 1489870205:1489870349(144) ack 2064846002 win 96 <nop,nop,timestamp 1157179149 382990921>
2 packets captured
4 packets received by filter
0 packets dropped by kernel

from the above output shown you can see the MAC address in the output(Mac addressess are made bold in the output)

-vvv option for more verbose output in tcpdump

If you want your tcpdumpt output to show you more verbose information like, show all the flags, and headers in tcp we can use verbose options.

-v for little more packet information,-vv for further more, and -vvv option for even more information. An example output is shown below

[root@myvm ~]# tcpdump -s0 -vvv -e -n -c 2 -i eth0
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
02:02:21.671828 00:15:17:83:0c:9c > 00:23:47:4c:97:00, ethertype IPv4 (0x0800), length 4434: (tos 0x0, ttl  64, id 20588, offset 0, flags [DF], proto: TCP (6), length: 4420) 172.16.140.41.5910 > 172.16.134.85.51907: ., cksum 0x7bd6 (incorrect (-> 0x2515), 34181155:34185535(4380) ack 3681533777 win 71
02:02:21.672181 00:23:47:4c:97:00 > 00:15:17:83:0c:9c, ethertype IPv4 (0x0800), length 338: (tos 0x10, ttl  59, id 34117, offset 0, flags [DF], proto: TCP (6), length: 324) 172.17.4.111.ssh > 172.16.140.41.58728: P, cksum 0x4294 (correct), 4107752623:4107752895(272) ack 2150369028 win 33148 <nop,nop,timestamp 2658690172 1157308260>
2 packets captured
3 packets received by filter
0 packets dropped by kernel

-S option in tcpdump

this option in tcpdump can be used for showing absolute sequence numbers. Now what is sequence number?

Sequence number is used in TCP, to identify the number of packets send or recieved. Whenever a machine initiates a TCP connection it informs the other side about its sequence number during the three way handshake.

With the help of the sequence number's the receiver and the sender comes to know how much data has been transferred.

TCPDUMP even show these sequence numbers. Using -S option will shown the abosolute tcp sequence numbers rather than relative with previous packets.

-w option used in tcpdump

using this -w option we can capture the output and save all the output to a specified file. This file can be later analyzed with the help of tools like editcap.

using .pcap extention to the filename is advisable as this makes it readable by other packet analyzers.

[root@myvm ~]#  tcpdump -w sampletcpdump.pcap -s0 -vvv -e -n -c 2 -i eth0
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
2 packets captured
5 packets received by filter
0 packets dropped by kernel

Dont read the file by opening it thorugh cat or vim...because you will not be able to read it.smiley

-r option used in tcpdump

in order to read the file we just captured we  need to use -r option with tcpdump command and passing filename as the argument to the command.

[root@myvm ~]# tcpdump -r sampletcpdump.pcap
reading from file sampletcpdump.pcap, link-type EN10MB (Ethernet)
02:04:04.712709 IP 172.16.134.150.50438 > m1-sv-xbox2.5919: P 1245960226:1245960232(6) ack 671383339 win 64701
02:04:04.712724 IP myvm.5919 > 172.16.134.150.50438: . ack 6 win 46

Display packets for a particular port using TCPDUMP

 

Till now in all above shown example we got all the packets towards all ports and were from random protocols, whatever the tool got during the capture, it showed those things.

Now in case if you want to capture the packets thats coming towards port 22 of one server.

[root@myvm ~]# tcpdump -s0 -vvv -e -n -c 2 -i eth0 port 22
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
02:09:33.185445 00:23:47:4c:97:00 > 00:15:17:83:0c:9c, ethertype IPv4 (0x0800), length 338: (tos 0x10, ttl  59, id 5386, offset 0, flags [DF], proto: TCP (6), length: 324) 172.16.0.111.ssh > 172.16.140.41.58728: P, cksum 0xacee (correct), 4107814047:4107814319(272) ack 2150369076 win 33148 <nop,nop,timestamp 2659121792 1157739776>
02:09:33.185453 00:15:17:83:0c:9c > 00:23:47:4c:97:00, ethertype IPv4 (0x0800), length 66: (tos 0x10, ttl  64, id 46661, offset 0, flags [DF], proto: TCP (6), length: 52) 172.16.140.41.58728 > 172.16.0.111.ssh: ., cksum 0x49c9 (correct), 1:1(0) ack 272 win 501 <nop,nop,timestamp 1157741788 2659121792>
2 packets captured
2 packets received by filter
0 packets dropped by kernel

you can clearly see from the above output that all the packets captured with the port 22 option are for ssh.

Ignoring Packets with TCPDUMP

If you want to ignore the packets coming towards port 80 and show all rest of the packets then you can do that by using the same port option but in a different way.

Lets look at an example to do that with tcpdump

[root@myvm ~]# tcpdump -i eth0 -n -c 5 'port !80'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
02:11:30.822544 arp who-has 192.168.0.152 (Broadcast) tell 192.168.0.152
02:11:30.875907 IP 172.16.140.41.5910 > 172.16.134.85.51907: . 44976382:44982222(5840) ack 3681551939 win 71
02:11:30.876707 IP 172.16.134.85.51907 > 172.16.140.41.5910: . ack 2920 win 1791
02:11:30.876724 IP 172.16.140.41.5910 > 172.16.134.85.51907: . 5840:8760(2920) ack 1 win 71
02:11:30.877604 IP 172.16.134.85.51907 > 172.16.140.41.5910: . ack 5840 win 1780
5 packets captured
6 packets received by filter
0 packets dropped by kernel

By doing the above thing your will screen will be dumped with all the traffic other than the traffic towards port 80.

show packets towards a particular host

Suppose you are trouble shooting something and only interested in knowing the traffic towards or from a particular host. In that case you can ask tcpdump to only show packets for that host, by the following command.

[root@slashroot ~]# tcpdump -i eth0 -c 5 host 192.168.159.128

host option can be used to do that. Always using -c option for specifying no of packets to capture is a good idea, other wise your screen will be dumped with all packets captured.

Show packets from source with tcpdump

Now you can even go further by only asking to show packets with a particular source address. This can be done by the following command.
 

[root@slashroot ~]# tcpdump -i eth0 -c 5 src host 192.168.159.128

 

So you just need to put "src" option along with the host option for doing that as shown above.

Similarly you can do for destination as shown below.

 

[root@slashroot ~]# tcpdump -i eth0 -c 5 dst host 192.168.159.128

Filtering protocols using tcpdump command

You can easily get information about packets of a certain protocol with the help of tcpdump. Without filtering tcpdump output with relevant options and arguments, the packets of interest can get lost in the huge amount of output dumped by tcpdump.

Lets see how can we look at the packets with certain protocols in it. Doing that is quite simple, you need to just pass the protocol name as argument after the command.

[root@slashroot ~]# tcpdump -i eth0 icmp
 

OR

[root@slashroot ~]# tcpdump -i eth0 tcp
 

OR

[root@slashroot ~]# tcpdump -i eth0 udp
 

OR

[root@slashroot ~]# tcpdump -i eth0 arp

Capture icmp traffic for some MAC address

using the below option and format you can easily match icmp traffic for a particular mac address. You can further filter the output of tcpdump with some interesting operators that can be used with the command.

  1. && or "and"
  2. || or "or"

lets see how can we use those options in tcpdump.

 

[root@slashroot ~]# tcpdump -i eth0 '((icmp) and ((ether dst host 00:0C:29:93:A0:52)))'

the above command will show only icmp traffic for the destination MAC address 00:0C:29:93:A0:52.

For more traffic analysis go to my post on analyze network traffic using tcpdump

 
Rate this article: 
Average: 3.8 (230 votes)

Comments

Useful post

This is the best information i found about tcpdump ever...

nice description... very good

I just love slash root. Very helpful for all types of linux related issues. God bless you.

This is a great article and thanks to whomever put it all together. I haven't have a chance to read through the entire article but what I have read is very helpful. I understand this is an old 2012 article but it does provide some of the assistance I need. Not having gone through the entire article I did look for specific phrases to see if it might have what I'm looking for.

I'm having difficulty with lost packets and not sure what the cause is. It doesn't happen all the time and jumps from one end point in a vlan to another. I think it may be an AV thing (more on that in a other rant).

What I run is tcpdump -nnei ethx vlan xxx -c 500 to get a short stack of packets to analyze. I can see that it is dropping packets but I need to know how to spot the dropped packets when I run this command. Or do I need to run a different command?

What I am seeing in one of the sections of the packets is win 0 or length 0, common sense tells me that is the red flag. I also do not see syn but lots of seq and acks. Not sure what this means.

Any help would be appreciated.

Thanks
Frank

Very useful info . Thanks for posting

Thanks for useful commands

For a single ip we know the command to be:

tcpdump -i eth0 host <ip address>

But what about capturing traffic for whole network like:

tcpdump -i eth0 172.16.0.0 255.255.0.0

How shall I make that work?

Hi Vijay - The following should work:

tcpdump -i eth0 net 172.16.0.0/16

Good luck!

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.