Get the actual chosen route to a host

Hi. I have a second dnsmasq instance (on another port) and when it calls a certain upstream DNS I need the OS to use a non-default routing table:

openwrt -> 8.8.8.8 : lookup routing table "mytable"
other clients -> 8.8.8.8 : lookup default routing tables

For certain reasons I don't want dnsmasq to explicitly bind the socket before sending the upstream lookup. So I don't add the suffix @tun0 to the upstream config directive:

port=54
server=8.8.8.8
#...

I noticed that busybox nslookup, traceroute, ping, and dnsmasq behave differently. See these commands:

# Terminal 1
tcpdump -nn -vv -i tun0 "host 8.8.8.8"

# Terminal 2
tcpdump -nn -vv -i eth0.2 "host 8.8.8.8"

# Terminal 3
ip rule add from 0.0.0.0/32 table mytable
ip route add default via 10.8.0.5 table mytable
# pings go via tun0
ping 8.8.8.8
# dnsmasq upstream lookups go via tun0
nslookup testhost1.se 127.0.0.1:54
# nslookup lookups go via eth0.2
nslookup testhost1.se 8.8.8.8

# traceroute packets go via eth0.2 (with default args)
traceroute -n 8.8.8.8
# 1  10.82.206.5  2.630 ms  3.504 ms  3.672 ms

# traceroute packets go via tun0 (with altered source)
traceroute -s 0.0.0.0 -n 8.8.8.8
# 1  10.8.0.1  45.387 ms  48.790 ms  48.528 ms

The only explanation I have is nslookup and traceroute bind the socket to one of the interfaces before sending a packet and dnsmasq and ping don't bind it and let the os bind it automatically. When the route rules are checked the dnsmasq connection to upstream has source address 0.0.0.0 and the nslookup connection to the same host has source 10.8.x.x.

I was able to troubleshoot it with tcpdump, but tcpdump is a huge package and occupies half of my flash memory on the router. Is it possible to get similar forensic analysis with iproute2 itself? ip route get 8.8.8.8 isn't useful because it won't consider the rules I added.

ip route get <destination> from <src_interface_IP>

3 Likes

This really works for local interface IPs. Is it possible to simulate routing of forwarded packets? The last command fails:

root@OpenWrt:~# ip route get 8.8.8.8 from 0.0.0.0
8.8.8.8 via 10.8.0.5 dev tun0  src 10.8.0.14
root@OpenWrt:~# ip route get 8.8.8.8 from 192.168.43.1
8.8.8.8 from 192.168.43.1 via 10.82.206.5 dev eth0.2
root@OpenWrt:~# ip route get 8.8.8.8 from 192.168.43.100
ip: RTNETLINK answers: Network unreachable

Yes.

  • Perform traceroute/mtr/etc. (i.e. forward test packets) from host 192.168.43.100

(assuming there's a reason your interface has a different route)

  • assign the IP (/32) temporally to the interface and perform the test
1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.