How do I get the default gateway in Linux given the destination?
Asked Answered
S

15

46

I'm trying to get the default gateway, using the destination 0.0.0.0.

I used the command netstat -rn | grep 0.0.0.0 and it returned this list:

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.9.9.17       0.0.0.0         255.255.255.255 UH        0 0          0 tun0
133.88.0.0      0.0.0.0         255.255.0.0     U         0 0          0 eth0
0.0.0.0         133.88.31.70    0.0.0.0         UG        0 0          0 eth0

My goal here is to ping the default gateway using the destination 0.0.0.0, which is 133.88.31.70, but this one returns a list because of using grep.

How do I get the default gateway only? I need it for my Bash script to determine whether the network connection is up or not.

Sperry answered 30/7, 2009 at 5:35 Comment(1)
ip route get lets you pass the host and will do a lookup for you.Macintosh
M
65

The ip route command from the iproute2 package can select routes without needing to use awk/grep, etc to do the selection.

To select the default route (from possibly many):

$ ip -4 route show default  # use -6 instead of -4 for ipv6 selection.
default via 172.28.206.254 dev wlp0s20f3 proto dhcp metric 600

To select the next hop for a particular interface:

$ ip -4 route list type unicast dev eth0 exact 0/0  # Exact specificity
default via 172.29.19.1 dev eth0

In case of multiple default gateways, you can select which one gets chosen as the next hop to a particular destination address:

$ ip route get $(dig +short google.com | tail -1)
173.194.34.134 via 172.28.206.254 dev wlan0  src 172.28.206.66 
    cache

You can then extract the value using sed/awk/grep, etc. Here is one example using bash's read builtin:

$ read _ _ gateway _ < <(ip route list match 0/0); echo "$gateway"
172.28.206.254
Mashhad answered 12/4, 2013 at 13:52 Comment(9)
I like this because ip already outputs the correct line. A slightly improved version based on this is: ip -4 route list 0/0 | cut -d ' ' -f 3Plafker
More compact is ip r l 0/0 | cut -f3 -d' 'Anode
What is the difference between ip route list 0/0 and ip route show to default, though?Mirabel
@tosh - technically, they are the same 0.0.0.0/0.0.0.0 is the default route -- as for the example ip route show to default or perhaps ip route show default would be more explicit, I will update.Mashhad
Why do these linux tools rarely provide a way to output just the information you want instead of having to awk sed grep cut? Why is there not just a simple -o/--output via flag to route so you do not have to worry about the output format changing.Mandibular
@Mandibular do they really need to tho? It's the beauty of Unix pipelines - the only output standard you need to honour as the tool author is plain text and it's up to the consumer to decide, on context, what tool to use to ingest that data.Mashhad
Yes because the tools will change what they output to stdout from release to release. If you specified a flag indicating output the x value and the x value no longer was a valid output they tool can give an failure exit code. If you are just using cut/awk to get the 4 column but the 4th column is no longer x then you may continue running your script with the wrong value. Fortunately in the case of ip it does at least provide a -json flag to output parsable json.Mandibular
Busybox ip route has no documented show command, but it works anyway. list is documented, though; and I get the same output running list default instead of show default.Urbannai
IPv6: ip -6 route get $(dig -t AAAA +short google.com | tail -1)Urbannai
N
64

You can get the default gateway using ip command like this:

IP=$(/sbin/ip route | awk '/default/ { print $3 }')
echo $IP
Nebulose answered 4/8, 2009 at 8:59 Comment(9)
What if there is more than one default gateway? Your script yields me 192.168.1.1 192.168.0.1, and this is true: I have two gateways to internet. But the main one is 192.168.1.1. Should the first default value be selected as the main (prioritary) one?Bismuthic
@SopalajodeArrierez In my opinion, you should select the gateway for the particular interface you're interested in, e.g. /sbin/ip route |grep '^default' | awk '/eth1/ {print $3}' when you want to know the gateway for eth1.Sentence
@KyleStrand There is a "metric" value for each route entry. The smaller one gets priority. Is there any way to use that value to find the default gateway?Coheman
@StarBrilliant There might be some way to do that with 'awk', but failing that I'd recommend just writing a small script that parses each line of output and searches for the smallest metric value.Sentence
@StarBrilliant Actually, if you know what column the "metric" will be in, sort will do most of the work. -k3,3 specifies (for instance) sorting by the third column, and -n indicates that the sort should be done numerically. You can then use head -1 to get only the first line, and get the relevant column (the gateway) using awk as in the answer.Sentence
@KyleStrand Wow. I didn't know sort can use a specific column!Coheman
@StarBrilliant Neither did I!Sentence
IP=$(/sbin/ip -6 route | awk '/default/ { print $3 }') echo $IP this is how to get the ipv6 Default Gateway in the linux shell.Cheddar
Why would you have a separate awk pass when you can ask ip route to give you specifically what you're looking for?Macintosh
F
8

works on any linux:

route -n|grep "UG"|grep -v "UGH"|cut -f 10 -d " "
Fears answered 23/2, 2014 at 12:57 Comment(1)
route -n | awk '$4 == "UG" {print $2}' for something using the same idea but less hackyHeadley
B
4

This simple perl script will do it for you.

#!/usr/bin/perl

$ns = `netstat -nr`;

$ns =~ m/0.0.0.0\s+([0-9]+.[0-9]+.[0-9]+.[0-9]+)/g;

print $1

Basically, we run netstat, save it to $ns. Then find the line that starts off with 0.0.0.0. Then the parentheses in the regex saves everything inside it into $1. After that, simply print it out.

If it was called null-gw.pl, just run it on the command like:

perl null-gw.pl

or if you need it inside a bash expression:

echo $(perl null-gw.pl)

Good luck.

Blanche answered 30/7, 2009 at 6:0 Comment(2)
thank you! =) I'll try it.. Atleast I do know how to program in Perl.Sperry
I know this is years old... the problem with your regex is it will match anything that has 0.0.0.0 followed by an ip address. this means if your gateway is 0.0.0.0 then it will return the genmask. Specifically, the "G" flag indicates a gateway. something like this would be more accurate: echo $(route -n | perl -ne 'print m/0.0.0.0\s+([0-9]+.[0-9]+.[0-9]+.[0-9]+)\s+0.0.0.0\s+\wG/g') there is no difference between netstat -nr and route -nGentlemanly
L
3

This is how I do it:

#!/bin/sh
GATEWAY_DEFAULT=$(ip route list | sed -n -e "s/^default.*[[:space:]]\([[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\).*/\1/p")
echo ${GATEWAY_DEFAULT}
Lade answered 23/7, 2012 at 23:50 Comment(0)
S
3

For a list of all default gateways, use mezgani's answer, duplicated (and slightly simplified) here:

/sbin/ip route | awk '/^default/ { print $3 }'

If you have multiple network interfaces configured simultaneously, this will print multiple gateways. If you want to select a single known network interface by name (e.g. eth1), simply search for that in addition to filtering for the ^default lines:

/sbin/ip route |grep '^default' | awk '/eth1/ {print $3}'

You can make a script that takes a single network-interface name as an argument and prints the associated gateway:

#!/bin/bash
if [[ $# -ne 1 ]]; then
    echo "ERROR: must specify network interface name!" >&2
    exit 1
fi
# The third argument of the 'default' line associated with the specified
# network interface is the Gateway.
# By default, awk does not set the exit-code to a nonzero status if a
# specified search string is not found, so we must do so manually.
/sbin/ip route | grep '^default' | awk "/$1/ {print \$3; found=1} END{exit !found}"

As noted in the comments, this has the advantage of setting a sensible exit-code, which may be useful in a broader programmatic context.

Sentence answered 25/4, 2016 at 21:53 Comment(0)
C
3

The following command returns the default route gateway IP on a Linux host using only bash and awk:

printf "%d.%d.%d.%d" $(awk '$2 == 00000000 && $7 == 00000000 { for (i = 8; i >= 2; i=i-2) { print "0x" substr($3, i-1, 2) } }' /proc/net/route)

This should even work if you have more than one default gateway as long as their metrics are different (and they should be..).

Catholic answered 27/9, 2018 at 5:17 Comment(1)
and if you want the interface name too: printf "%d.%d.%d.%d %s" $(awk '$2 == 00000000 && $7 == 00000000 { for (i = 8; i >= 2; i=i-2) { print "0x" substr($3, i-1, 2) } ; print $1}' /proc/net/route)Catholic
A
2

There are a lot of answers here already. Some of these are pretty distro specific. For those who found this post looking for a way to find the gateway, but not needing to use it in code/batch utilization (as I did)... try:

traceroute www.google.com

the first hop is your default gateway.

Astrogate answered 26/12, 2014 at 22:12 Comment(0)
F
1

Another perl thing:

$return = (split(" ", `ip route | grep default`))[2];<br>

Note: use these backticks before ip and after default

Feud answered 2/1, 2011 at 0:33 Comment(0)
B
1

netstat -rn | grep 0.0.0.0 | awk '{print $2}' | grep -v "0.0.0.0"

Blackcock answered 8/1, 2013 at 5:36 Comment(1)
0.0.0.0 is displayed if no gateway is set. If a gateway was set, this will not work.Dribble
S
1
#!/bin/bash

##################################################################3
# Alex Lucard
# June 13 2013
#
# Get the gateway IP address from the router and store it in the variable $gatewayIP
# Get the Router mac address and store it in the variable gatewayRouter
# Store your routers mac address in the variable homeRouterMacAddress
#

# If you need the gateway IP uncomment the next line to get the gateway address and store it in the variable gateWayIP
# gatewayIP=`sudo route -n | awk '/^0.0.0.0/ {print $2}'` 

homeRouterMacAddress="20:aa:4b:8d:cb:7e" # Store my home routers mac address in homeRouterMac.
gatewayRouter=`/usr/sbin/arp -a`

# This if statement will search your gateway router for the mac address you have in the variable homeRouterMacAddress
if `echo ${gatewayRouter} | grep "${homeRouterMacAddress}" 1>/dev/null 2>&1`
then
  echo "You are home"
else
  echo "You are away"
fi
Signorelli answered 14/6, 2013 at 4:38 Comment(0)
G
0

If you know that 0.0.0.0 is your expected output, and will be at the beginning of the line, you could use the following in your script:

IP=`netstat -rn | grep -e '^0\.0\.0\.0' | cut -d' ' -f2`

then reference the variable ${IP}.

It would be better to use awk instead of cut here... i.e.:

IP=`netstat -rn | grep -e '^0\.0\.0\.0' | awk '{print $2}'`
Guthry answered 4/8, 2009 at 7:40 Comment(2)
basic point of this approach, use an extended regexp, followed by cut to get your desired field. however, you could use awk as others have posted, but I have yet to learn the language.Guthry
@maxwelb You don't need grep with awk. E.g.: netstat -rn | awk '/^0\.0\.0\.0\./ {print $2}'.Like
C
0

use command below:

route -n | grep '^0\.0\.\0\.0[ \t]\+[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*[ \t]\+0\.0\.0\.0[ \t]\+[^ \t]*G[^ \t]*[ \t]' | awk '{print $2}'
Chiefly answered 8/2, 2012 at 4:51 Comment(0)
I
0

/sbin/route |egrep "^default" |cut -d' ' -f2-12 #and 'cut' to taste...

Infectious answered 1/2, 2013 at 18:8 Comment(0)
E
0

To get the NIC name that it's the default gateway use this command:

netstat -rn | grep UG | awk '{print $8}'
Extraneous answered 16/6, 2020 at 17:35 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.