How to debug networks with tcpdump, ping on Linux
Nowadays, I learned a lot about network debugging through my recent hobby of providing free internet access to everybody (in my local area) through Freifunk.
Looking at the backbone, many things can happen which are unusual in typical networks. For example, we have asymmetric routing, where packets can come in from one supernode, are routed to the client and the response is then sent through a different router.
In such situations it is needed to have a good tooling at hand.
Most tools is quite basic and already known like ip
, ping
, mtr
, dig
and tcpdump
- but you can do a lot with them.
Basic debugging
One way to debug this is:
- start mtr to a target address and see where it ends
- login into the last known hop and see if your traffic arrives there using
tcpdump -i INTF host SRC_HOST
- check which path this packet will take using something like
ip r get ipv6::addr from src::addr
- check if packet is leaving the host on the expected interface using
tcpdump -i INTF
- repeat for other systems until the problem source is found
If a firewall exists, one can use it to log catched/dropped packets (temporary of course). This is especially helpful if a firewall rule might be wrong, if packets are dropped which are needed.
Unknown source
If the source of our package is unknown it might be helpful to filter with tcpdump -i INTF icmp6
to see only ICMP packets like ping.
Looking into the available routes on the host is often very helpful: ip -6 r
or looking at the iptables configuration: ip6tables-save
In some cases rules can interplay also ip rule show
.
If ping does not work with the external ip address, it might help to test with a local or link-local ip address, by looking at ip a
and pinging with the found one.
Link-Local IPv6 Neighbour Discovery
To see if a neighbour is found on a given ipv6 address, one can use ndisc6:
ndisc6 ipv6::addr eth0
which answers with the found ip address of the neighbour, which should be correct too.
If the neighbour is not found, one can look into the neighbour list here and search for the ipv6 address:
ip -6 n
maybe check if it works through link local address:
ping fe80::4c09:f0ff:fe26:381%eth0
(don’t forget the %intf
which is always needed when handling link-local addresses)
On a bridge configured by proxmox, it might be impossible to have a link-local connection.
This can be solved by resetting the disable_ipv6
flag:
sysctl net.ipv6.conf.tap148i0.disable_ipv6=0
ndisc6 fe80::4c09:f0ff:fe26:381 tap148i0
tcpdump -i tap148i0 icmp6
ip a show tap148i0
I then checked if it at least works when I manually set the ipv6 neighbour like:
ip -6 n replace 2a00:fe0:43::148 dev eth0 lladdr 4e:09:f0:26:03:81 router REACHABLE
which did work - but did not clear up why it did not work before. As often, a reboot helped for now. But I really wish that I won’t see such network problems any time soon..