Date created: 01/20/12 23:36:48. Last modified: 02/14/22 09:23:10

'tcpdump', 'editcap', & 'ngrep' - Notes


# CLI Args

tcpdump -nlXXS -i eth0 -As 0 -vvv host # -n Don't convert addresses (i.e., host addresses, port numbers, etc.) to names # -m Load SMI MIB module definitions from file module. # This option can be used several times to load several MIB modules into tcpdump # -l Make stdout line buffered. Useful if you want to see the data while capturing it # -X When parsing and printing, in addition to printing the headers of each packet, print the data of each packet (minus its link level header) in hex and ASCII
# - XX When parsing and printing, in addition to printing the headers of each packet, print the data of each packet, including its link level header, in hex and ASCII. # -S Print absolute rather than relative TCP sequence numbers # -i For specific interface to listen on # -A Print each packet (minus its link level header) in ASCII # -s 0 Snarf [snaplen] bytes of data from each packet rather than the default of 68. # 68 bytes is adequate for IP, ICMP, TCP and UDP but may truncate protocol information # from name server and NFS packets

# Display and output options

# Display HEX and ASCII
tcpdump -XX

# Display timestamps
tcpdump -tttt

# Display delta from last line/packet
tcpdump -ttt

# Rotate capture file every 10 seconds (file name needs to be unique, can input strftime(3) time format options but only with -G, not with -C)
sudo tcpdump -G 10 -w ./%Y-%m-%d--%H-%M-%S.pcap

# Rotate by file size (-C option appends a count to the file name, files will be called: tcp-port-80.pcap, tcp-port-80.pcap1, tcp-port-80.pcap2 etc.)
sudo tcpdump -i eth10 -s 65535 -w ./tcp-port-80.pcap -C 1G tcp and port 80

# To format for Wireshark limit the snaplen (-s) to 65k
sudo tcpdump -s 65535 -i eth3 -w ./Customer1-2014-04-15-001.pcap

# Run tcpdump remotely over SSH and redirect to local Wireshark
# Note: remote uses need "sudo" without password (or is root) so only god for lab/test
ssh root@ "tcpdump -s 0 -U -i eth0 -n -w - ip and not port 22" | wireshark -k -i -

# Layer 2/Ethernet

# Include link-layer headers (like MAC address for Ethernet)
tcpdump -e

# Specify a VLAN
tcpdump -i eth1 vlan 801 and host

# Specific Ethertype, e.g. dot1q VLAN tag:
tcpdump -i eth1 ether proto 0x8100
# ARP Ethertype
tcpdump -i eth1 ether proto 0x0806

# Filter by MAC
tcpdump ether host 00:11:22:33:44:55

# Use -p to NOT enter promiscuous mode, meaning "not for us" traffic isn't capture, multicast and broadcast is still captures
tcpdump -i eth0 -p

# Exclude Ethernet broadcast traffic
tcpdump -i eth0 not ether broadcast

# Layer 2.5 / PPPoE & MPLS

# PPPoE carrying ICMP:
# To match something inside PPPoE, look for a value at an offset within the Ethernet header.
# E.g. 14 byte Ethernet header + 8 byte PPPoE header, next IPv4 follows and the IP protocol ID is at
# the 9th byte (10th offset) within the IPv4 header, so check if the 14+8+9 offset == 1 to match IP protocol 1 for ICMP
tcpdump -i eth1 ether[31] = 1

# To filter for an MPLS VPN conversation (we need Tx and Rx labels)
sudo tcpdump -s 65535 -i eth3 '(mpls 67734) or (mpls 19353)'

sudo tcpdump -s 65535 -i eth3 '(mpls && icmp)'

sudo tcpdump -nlASX -e -vvv -s 0 -i eth3 '(mpls && icmp && host'

sudo tcpdump -nlASX -s 65535 -vvv -i eth3 '(mpls 52634 and (ip and (ip[1] & 0xfc) >> 2 > 0x01) and host and icmp)'

# Remember that when testing for MPLS label stacks, (mpls 123 && mpls 456) will move the the headers pointer along within tcpdump by 8 bytes.
# So for example, using '(mpls 123 && mpls 456) or (mpls 789)' will mean the second check is comparing 789 as the label value for the 2nd label in an alternate stack, it won't check from the bottom of the stack again.

# Layer 3 options

# Listen for a range of clients
tcpdump -i eth2:62 -vvv -n src net

# Capture IPv6 only
sudo tcpdump -i en0 ip6

# Any non-zero TOS/DSCP value
sudo tcpdump -s 65535 -i eth3 ip and ip[1]!=0

# To filter by specific DSCP value
# ip[1] This is IP header byte 1 (starts from 0, so 2nd byte)
# & 0xfc This is to logical AND with a bit mask for the first 6 bits (11111100)
# which are the DSCP bits, last 2 bits are ECN
# >> 2 To bit shift by 2 to compare only DSCP value (first 6 bits) to
# 0xc0, without bit shift you need to compare hex of DSCP + ECN
sudo tcpdump -s 65535 -i eth3 \(ip and \(ip[1] \& 0xfc\) >> 2 \> 0xc0\)
sudo tcpdump -s 65535 -i eth3 \(ip and \ip[1] \& 0xfc \> 0xc0\)
sudo tcpdump -s 65535 -i eth3 \(ip and \ip[1] \& 0xff \> 0xc0\)
sudo tcpdump -s 65535 -i eth3 -w DSCP-elam.pcap host and \(ip and \(ip[1] \& 0xfc\) >> 2 \> 0x0a\)

# This example matched DSCP decimal value 10 (which is AF11),
# matching the entire byte where ECN is 0 and DSCP is 0x0a (10 in decimal)
# is 0101 bit shifted left by 2 bits is 010100 (0x28)
sudo tcpdump -nelASX -s0 -i eth3 \(ip and \(ip[1] \& 0xff\) == 0x28\)

# This will match any DCSP marking, by doing > 0
(ip and (ip[1] & 0xfc) >> 2 > 0x00)

# Look for a specific TTL, which is 9th byte in IPv4 header
tcpdump ip and 'ip[8] == 254'

# Layer 4 options

# Use specific transport protocol and port number; tcpdump -nmlX -i eth0 -As 0 -vvv host and udp port 161

# Capture a range of ports, RADIUS for example
tcpdump -nlASX -s 0 -vvv -i em2 udp portrange 1812-1814 # Exclude a port (like your own SSH session) tcpdump not port 22 tcpdump -i eth1 port not 22 and host
# Capture ICMP only
tcpdump -nmlX -As 0 -vvv icmp
# ICMP echo request and reply only
tcpdump -n icmp and 'icmp[0] = 8 and icmp[0] = 0'
tcpdump -n icmp and icmp[icmptype] == icmp-echo and icmp[icmptype] == icmp-echoreply


To capture frames with the Ethernet FCS present (not all NICs support this):

sudo ethtool -K enp0s25 rx-fcs on



# Split a capture file into multipile smaller files, each 100,000 packets long
editcap -c 100000 large-lapture.pcap split-capture.pcap

# Delete a specific packet (packet num. 1000) from a capture file
editcap capture.pcap filtered.pcap 1000

# Delete a range of packets (pacet numbers 100-200) from a capture file
editcap capture.pcap filtered.pcap 100-200

# Delete a list of packets (the same syntax can be used with -r for keeping only the listed packets)
editcap capture.pcap filtered.pcap 1 5 10-20 30-40

# To remove all packets except the given range of packet numbers
editcap -r capture.pcap filtered.pcap 50-99

# Keep only the first 100 packets
editcap -r capture.pcap filtered.pcap 1-100

# Remove the first 30 bytes from all packets in the capture
editcap -C 30 capture.pcap filtered.pcap



# editcap can't merge files but mergecap can...
mergecap -w merged.pcap 10M-1.pcap 10M-2.pcap 10M-3.pcap



# Capture traffic form a specific SIP extension
ngrep -q -t -W byline -d any -w 12345 port 5060 or port 5070

# -q is be quiet (don't print packet reception hash marks)
# -t is print timestamp every time a packet is matched
# -W is set the dump format (normal, byline, single, none)
# Specify an alternate manner for displaying packets, when not in hexadecimal mode.  The byline mode honors embedded line‐feeds, wrapping text only when a linefeed is encountered
# -d is use specified device instead of the pcap default
# -w s word-regex (expression must match as a word)

# Capture HTTP traffic
ngrep -t -W byline -d eth1 tcp and port 80
# or
ngrep src host
# or 
ngrep host

# Capture traffic to/from a specific IP
ngrep -q -t -W byline -d any -w