tcpdump of udp packets containing data - linux

Running linux ubuntu.
Essentially, why is this command a syntax error: -
tcpdump -i eth0 -n udp -X -v -s 1514 'tcp[40:4] = 0x31323334'
Which should show udp packets with '1234' at the 40th byte.
I mean, I get that udp isn't a tcp packet, but the logic should still work. Given it doesn't how can I write this?

try the following:
tcpdump -i eth0 -X -v -s 1514 'udp[40:4] = 0x31323334'
Afaik, proto relop filters should match only the protocol you specify, -n udp should not be needed.

tcpdump is confused what to take as filtering parameter. When you've explicitly used udp, then it captures all the udp packets or if you want particular udp packet then you can specify the offset. So, based on what you need either specify udp with offset or simply udp if you want to capture all the udp packets. Something like below should meet your requirement:
tcpdump -i eth0 -n -X -v -s 1514 'udp[40:4] = 0x31323334'

Related

Linux: how to get network stats on tcp (ie excluding udp)?

I've been using /sys/class/net/eno1/statistics/rx_bytes and tx_bytes to gather stats on my network interface. The trouble is, that network has a device (a Silicon Dust HDHOMERUN HDTV tuner) which constantly streams UDP packets at a very high rate that I don't want to monitor. I'd like to remove that traffic from the monitor - perhaps by only looking at TCP packets.
Is there any way to separate out the TCP and UDP stats?
netstat -st gives some info but it's somewhat cryptic - just how big is a 'segment'? The MTU? The man page is silent on that.
$ netstat -st | grep 'segments received'
25449056 segments received
1683 bad segments received
$ netstat -st | grep 'segments sent out'
37860139 segments sent out
Based on this answer from serverfault. If you are using iptables you can add a rule to each of the INPUT and OUTPUT chains which will count every packet which carries TCP in the payload. It is possible that you will need to invoke every iptables command with sudo.
Create the rules:
# Match all TCP-carrying packets incoming on 'eno1' iface
iptables -I INPUT -i eno1 -p tcp
# Match all TCP-carrying packets outgoing through 'eno1' iface
iptables -I OUTPUT -o eno1 -p tcp
Afterwards, you can use iptables -nvxL INPUT or OUTPUT to be presented with the number of bytes processed by the rule:
Chain INPUT (policy ACCEPT 9387 packets, 7868103 bytes)
pkts bytes target prot opt in out source destination
10582 9874623 tcp -- eno1 * 0.0.0.0/0 0.0.0.0/0
In case you already have other rules defined it might be handy to create a separate chain entirely. This is also described in the answer i referenced, though you also want the -i and -o options in the in/out chains respectively. These allow you to filter on a single interface (use -i for INPUT and -o for OUTPUT).
iptables -N count_in # create custom chain named 'count_in'
iptables -A count_in -j RETURN # append RETURN action to chain 'count_in'
iptables -I INPUT -j count_in # insert chain at the top of chain INPUT
iptables -I count_in 1 -i eno1 -p tcp # insert rule that matches all tcp packets on eno1
# and has no action (does nothing)
iptables -nvxL count_in # list chain 'count_in' rules
I am not sure whether the "bytes" counter includes the IP header, or just the TCP segment bytes but it is still probably the closest metric to what you want to measure (TCP-only rx/tx bytes).
Additionally keep in mind that oftentimes rules defined with iptables are not actually saved and will get deleted on a system reboot. To enable them persistently on every reboot you may use the iptables-save and iptables-restore commands. To learn their usage you should probably look in your Linux distro's documentation as well as iptables manual.
Finally, AFAIK iptables is considered legacy by now and it is being slowly replaced by nftables. I myself still have iptables installed in my system by default. If you want to switch/are already using nftables, then you need to translate above commands to the syntax supported by the nft command. There is a utility called iptables-translate available which may help with this. It's purpose is to translate old iptables commands to equivalent nft commands. I mention this mostly for the sake of completeness, you should be just fine using iptables for your particular task if you have it installed.
You can use iptraf-ng.
Install with:
sudo apt install iptraf-ng
This will give you statistics per protocol (IPv4/IPv6/TCP/UDP/ICMP/...) on a specific interface:
sudo iptraf-ng -d eth0
You can also use this to have details per ports:
sudo iptraf-ng -s eth0

what is the correct tshark capture filter option for the DHCP frame?

I am trying to capture the DHCP frames for analysis using the following command in my mac book.
sudo tshark -i en0 -f "port 67 or port 68" -a duration:300 -w /tmp/dump.pcap
I use the following command to get all the fields of all protocols in the packet but it is not printing any value. Is the capture filter option for the DHCP frame is correct? Any help is appreciated?
sudo tshark -T text -r /tmp/dump.pcap -V
Answer
Yes, your commands are OK. Maybe no DHCP packets arrived and therefore not captured. Try to force a DHCP activity by commands in second teminal window of the same device:
sudo dhclient -r
sudo dhclient
Warning: Do not apply these commands if you are connected remotely. First command releases the IP address and your connection will be interrupted without a possibility to put second command and get address back remotely.
Some details concerning data capture
The thsark filters have the same syntax as Wireshark.
Threre exist 2 (or 3) filter types:
capture filter, -f tshark option: It selects which packets will be captured and which not. This is useful e.g. for getting lower capture file size.
display filter, -Y tshark option: It selects which packets will be displayed from all captured ones.
You can combine both types.
Examples:
tshark -i eth0 -n -Y "ip.addr==8.8.8.8"
tshark -i eth0 -n -Y "ip.addr==8.8.8.8" -f "udp port 53"
tshark -i eth0 -n -Y "ip.addr==8.8.8.8 and udp.port==53"
All packets are captured, but only the 8.8.8.8 IP address packets are displayed.
Only the DNS packets are captured, and only the 8.8.8.8 IP address packets from captured are displayed.
All packets are captured, but only the 8.8.8.8 IP address packets having UDP port 53 (i.e. DNS) are displayed. Compare different syntax of the port filtering between the display and the capture filters in line above.
All other options like -a, -b, -w, -s can be applied too.
The tcpdump application is usefull too. It is available in most Linux systems even very small or special. It does not have a display filter option. Only capture filters can be applied. Other options are missing: -a, -b ...
sudo tcpdump -i eth0 -w /tmp/dhcp.pcap "udp port 67 or udp port 68"

Why can't capture rewritten packet

I'm using tcpdump and tcpreplay in ubuntu for capturing packet and resending(with rewriting and openwrt for ap mode in raspberry pi.
My problem is that I cannot capture resent packet.
This is my network :
A ----> B(RPI) -----------> C
192.168.0.199 eth0. wlan0 | 192.168.2.172
192.168.0.100 192.168.2.1 |
------------> D
192.168.2.222
I sent packet(using nping) from A to B, and used portforwarding
nping in A :
nping --udp --dest-port 7777 --dest-ip 192.168.0.100
portforwarding in B using iptables :
iptables -t nat -A PREROUTING -i eth0 --dport 7777 -j DNAT --to 192.168.2.222
So, I done here.
And I write this in D
tcpdump -i wlan0 dst port 7777 -w packet.pcap
tcprewrite -i packet.pcap -o packet_rewrite.pcap -D 192.168.2.222:192.168.2.172
tcpreplay -i wlan0 --topspeed packet_rewrite.pcap
But, in C, I cannot capture modified packet...
tcpdump dst port 7777
I really want to know why i can't...please let me know
and i'm really sorry my explain is not good....
further search.. I captured packets in B (wlan0)
Because i edited packet's source mac to my ubuntu wlan mac address...
But as before, I cannot capture packets in C...
This is captured packets in B
and even replayed packet didn't pass iptables...
I solved!!!!!!!!!!!!!!
I had to change dmac to C's mac address....I was stupid....

tcpdump does not display packets seen by Wireshark

The host (seen below) receives DNS requests from another host on the same network. It has port UDP/53 closed, still the packets are displayed by Wireshark.
Indeed, the are requests sent to 192.168.16.2 on port UDP/53, so the expression should be right:
tcpdump -v -s0 udp and dst port 53 and dst 192.168.16.2
If I do:
tcpdump -v -s0 udp
the DNS requests aren't displayed either.
Why doesn't tcpdump display the DNS requests, and how can I make it display them?
If your machine has several network interfaces, then you also need to set the interface to listen on using the -i option.
Your expression would then read:
tcpdump -v -s0 -i eth1 udp and dst port 53 and dst 192.168.16.2

How to display all data using tcpdump?

I am capturing network traffic by using tcpdump. The problem is: I can't see all capture data when the package is too long. For example, when the tcp frame length is more than 500, I just see 100-200 or less. How to display all frame data(500+)?
I have tried add -vv and -vvv parameter. This is my current command:
tcpdump -i eth1 tcp and host 10.27.13.14 and port 6973 -vv -X -c 1000
Add -s0 parameter:
tcpdump -i eth1 tcp and host 10.27.13.14 and port 6973 -s0 -vv -X -c 1000

Resources