← retour aux snippets

ip: déterminer l'interface et la route vers une IP

Trouver l'interface, la gateway et l'adresse source utilisées pour joindre une IP cible.

bash network #ip#route#linux

objectif

Diagnostiquer par où sort un paquet vers une IP donnée: interface, gateway, table de routage et adresse source choisie.

code minimal

# afficher interface, via et source pour une destination
ip_route_info() {
  local dst="$1"
  [ -n "$dst" ] || { echo "usage: ip_route_info <ip/host>" >&2; return 2; }

  # si nom d'hôte, résoudre vers une IP (IPv4 en priorité)
  if [[ "$dst" != *:* && "$dst" != +([0-9.]) ]]; then
    dst="$(getent ahosts "$dst" | awk 'NR==1{print $1; exit}')"
    [ -n "$dst" ] || { echo "résolution échouée" >&2; return 3; }
  fi

  local line
  line="$(ip -o route get "$dst" 2>/dev/null)" || {
    echo "aucune route vers $dst" >&2; return 4; }

  awk '
    {
      for (i=1;i<=NF;i++) {
        if ($i=="dev") dev=$(i+1);
        if ($i=="src") src=$(i+1);
        if ($i=="via") via=$(i+1);
        if ($i=="table") table=$(i+1);
      }
      printf "dest=%s dev=%s src=%s via=%s table=%s
",
             $1, dev?dev:"-", src?src:"-", via?via:"-", table?table:"main";
    }' <<<"$line"
}

# usage
# ip_route_info 1.1.1.1
# ip_route_info data.pm

utilisation

# extraire l'interface de sortie
dev="$(ip_route_info 8.8.8.8 | awk -F'[ =]' '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')"
echo "interface: $dev"

# adresse source choisie par le noyau (utile pour firewall)
src="$(ip_route_info data.pm | awk -F'[ =]' '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')"
echo "src: $src"

# afficher la table utilisée
table="$(ip_route_info 9.9.9.9 | awk -F'[ =]' '{for(i=1;i<=NF;i++) if($i=="table"){print $(i+1); exit}}')"
ip route show table "$table"

variante(s) utile(s)

# forcer IPv6
ip -6 route get 2606:4700:4700::1111

# macOS: route -n get
route -n get 1.1.1.1 | awk '/interface:|gateway:|source:/{print}'

# afficher règles de policy routing
ip rule show

notes

  • nécessite iproute2. Sur systèmes minimalistes, installez le paquet iproute2.
  • ip -o route get simule exactement la sélection du noyau (interface, source, table).
  • pour des noms d’hôte, résolvez d’abord avec getent ahosts pour supporter IPv4/IPv6.