Packet Capturing with TCPDUMP command in 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.
- tcpdump works in network layer
- a network packet header consists of sender,destination,state information and other flag informations.
- TCPDUMP only captures the first 96bytes of data from the packet by default.
TCPDUMP can be downloaded from
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.
-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.
Lets see how to do that.
[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.
- && or "and"
- || 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