106

I have eth0 and wlan0 according to ifconfig and I can ping google.com.

How can I find out (with a normal user, not root) what interface is active, as in, what interface did the ping (or whatever, ping is not mandatory) use?

I am using Ubuntu 11.04 or Fedora 14

fpmurphy
  • 4,636
LanceBaynes
  • 40,135
  • 97
  • 255
  • 351
  • 4
    The below solutions seem to want you to do the inferring yourself, which doesn't seem right. (And everybody's routing tables look incredibly straightforward!) While I'm looking for the Windows equivalent, it appears that "ip route get " will tell you which interface would be used if you were to attempt to connect to a given ip address. – mwardm Aug 25 '16 at 09:41
  • Related on Server Fault: Find interface for route to specific host (which is what I was looking for when I wound up here). – Wildcard Jul 12 '19 at 22:19

12 Answers12

79

You can use route to find your default route:

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     1      0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 eth0
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0

The Iface column in the line with destination default tells you which interface is used.

mtvec
  • 2,738
  • On Debian at least you need to do /sbin/route. – Faheem Mitha Jun 14 '11 at 09:00
  • @Faheem Because /sbin isn't in normal users' PATH environ. This is pretty standard in most distros, even though it's generally one of the first things sysadmins alter for their 'main' user. – Shadur-don't-feed-the-AI Jun 14 '11 at 11:07
  • @Shadur: that's not the case in Fedora (as of FC13 if I remember correctly) – nico Jun 14 '11 at 15:57
  • 1
    @Job in case we have an IP address how can we find which interface it uses. – Bionix1441 Nov 30 '17 at 09:51
  • 4
    This should not be the accepted answer. If iproute have been used to define custom routing rules route can't be used. @Torgeir have the wright answer. – Joseph Garrone Feb 20 '19 at 18:40
  • 2
    This answer is not correct. For example (and given the same routes displayed in the answer), if you ping 192.168.1.16 (a pc on your local network), the entry which starts with 192.168.1.0... is the route that will be used. Of course in this case it refers to the same Iface, but that is just because you have one interface on your machine. – kdehairy Apr 25 '19 at 19:27
  • @kdehairy: That's correct. However, the original answer asked about which interface would be used when pinging google.com and I'm pretty sure that's not going to be on the local network :-) – mtvec Apr 26 '19 at 11:01
  • 1
    @Job Even with google.com, if you have two routes each on a different interface, the match with the longer mask will be picked (not necessarily the default). All what default means, is that if no other route is found, let's consult this one :) – kdehairy Apr 27 '19 at 11:51
  • 5
    I get a line "default ... eth0" and a line "default ... wlan0". So which one is the real default? – AstroFloyd Jul 10 '19 at 07:44
  • 1
    I have same question "I get a line "default ... eth0" and a line "default ... wlan0". So which one is the real default?" – abhiarora Mar 16 '20 at 13:12
  • This doesn't work on mac OS. – Thagomizer May 13 '20 at 02:39
  • There could be multiple "defaults" if multiple NICs of a single server/pc are plugged into a switch wired to the gateway. – DanglingPointer Aug 09 '22 at 02:09
50

My version which is basically based on this and this:

route | grep '^default' | grep -o '[^ ]*$'

And this, experimentally, for macOS:

route -n get default | grep 'interface:' | grep -o '[^ ]*$'
  • 1
    is there a way for you to translate this for OSX? – John Allard Sep 28 '17 at 21:41
  • 2
    @JohnAllard: let me know if my update now gives correct answer there for macOS. – Ebrahim Byagowi Oct 10 '17 at 21:11
  • 5
    you don't need multiple pipes, just use route |awk '/^default/{print $NF}' – P.... Apr 30 '19 at 15:00
  • 2
    I get two lines: "eth0" and "wlan0", so I still don't know which one is active... – AstroFloyd Jul 10 '19 at 07:46
  • The mac OS suggestion worked for me, thanks! In my case, "netstat -rn" lists two default interfaces, since the machine has a wired and a wifi interface. It was useful to confirm which one has precedence. – Thagomizer May 13 '20 at 02:41
  • I know it has been said in the comments, but I think the answer should be edited to warn that these commands will sometimes output two lines (ex if there are multiple connections such as via ethernet and wifi). If someone's not expecting this and uses it in a script, could cause problems. – logidelic Apr 21 '22 at 16:22
  • There could be multiple "defaults" if multiple NICs of a single server/pc are plugged into a switch wired to the gateway – DanglingPointer Aug 09 '22 at 02:09
31

On GNU/Linux systems:

#!/bin/sh

host we want to "reach"

host=google.com

get the ip of that host (works with dns and /etc/hosts. In case we get

multiple IP addresses, we just want one of them

host_ip=$(getent ahosts "$host" | awk '{print $1; exit}')

only list the interface used to reach a specific host/IP. We only want the part

between dev and the remainder (use grep for that)

ip route get "$host_ip" | grep -Po '(?<=(dev ))(\S+)'

slhck
  • 473
Torgeir
  • 319
  • 3
    Please explain what these commands are doing. Also, you're probably pretty safe here, because you know what your values are, but, generally, you should quote shell variables references (unless you have a good reason not to, and you’re sure you know what you’re doing). – G-Man Says 'Reinstate Monica' Oct 30 '14 at 18:51
  • 1
    Done, to some extent. Only posted this because I could not find anything that did exactly this. Am using this as a custom fact in a puppet manifest... – Torgeir Oct 30 '14 at 20:15
  • Your answer is more correct if the host is an input argument to the script. As the route (and hence the interface) might be different for different ips. – kdehairy Apr 25 '19 at 19:52
  • My slight adjustment to the grep part: grep -Po '(?<= dev ).+?(?= (src|proto))' – Kevin Li May 09 '20 at 17:28
23

One liner:

ip route get 8.8.8.8 | sed -n 's/.*dev \([^\ ]*\).*/\1/p'

h0tw1r3
  • 823
  • 6
  • 10
15

Get the default network interface typically used to route to the "remaining" internet in opposite to DMZ, private network, VM host etc. which are usually routed explicitly.

$ ip route get 8.8.8.8 | sed -n 's/.* dev \([^\ ]*\) .*/\1/p'
eth0
h0tw1r3
  • 823
  • 6
  • 10
EugeneP
  • 159
  • 2
    it is not always the default route that gets you to where you want. Although the OP most probably is using the default route to get to the internet, this is a generalization and might not always hold true. A word of caution – MelBurslan Aug 10 '16 at 17:35
  • Sure, it is only default network interface. If there are multiple connections, one should not really speak about "connecting to the internet", but rather about network interface used for routing to the exact destination. – EugeneP Aug 22 '16 at 11:06
  • You do not need to use multiple pipes/greps , ip -4 route ls |awk '/^default/{print $5}' – P.... Apr 30 '19 at 15:01
  • There could be multiple "defaults" if multiple NICs of a single server/pc are plugged into a switch wired to the gateway – DanglingPointer Aug 09 '22 at 02:10
  • @DanglingPointer fixed. thanks for the comment. – h0tw1r3 Aug 10 '22 at 15:21
11

Different distros of Linux, Unix, some versions of Microsoft Windows, and many other Operating Systems are not limited to using just one network interface to reach the internet.  Many Operating Systems will detect more than one valid interface, capable of reaching the internet, and set up each of them for carrying traffic to the internet (specifically, gateways that ultimately connect to the internet).

If the OS tries to reach an external network and succeeds using eth0, it will add that interface to the routing table and tie it to that network.  If the OS tries to reach the same external network and also succeeds using eth1, it will also add that interface (eth1) into the routing table as an additional way to reach that same network.  Other posters thus far have not considered the importance of the metric values in a routing table.

My routing table, below, shows two different interfaces, eth0 and wlan0.  Both are up, both have been set automatically by the operating system as default routes to the gateway 192.168.1.1, and both have had a route built automatically by the operating system to the 192.168.1.X (i.e., 192.168.1.0/24) network.  This entire routing table was written automatically by the OS.  No edits to it were made by me. The difference shown here is that the wired ethernet interface (eth0) has a lower metric (202), and thus more of my traffic to nodes beyond my own network will be routed through this interface (it is preferred by the lower metric), while the remainder of my traffic to nodes beyond my network will be routed through the wireless interface (wlan0) (it has a higher metric of 303, and thus is less preferred by the OS).

pi@raspberrypi:~ $ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.1     0.0.0.0         UG    202    0        0 eth0
default         192.168.1.1     0.0.0.0         UG    303    0        0 wlan0
192.168.1.0     0.0.0.0         255.255.255.0   U     202    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     303    0        0 wlan0

Both interfaces are being used to reach "the internet", and their use is weighted by the "Metric" values, as can be seen in the bytes and packets statistics for eth0 and wlan0 below:

pi@raspberrypi:~ $ ip -s address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    0          0        0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0       
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether dc:a6:32:31:a2:c7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.195/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
       valid_lft 80787sec preferred_lft 69987sec
    inet6 fe80::2f3f:3f1d:8c35:a05e/64 scope link 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    14341060   22393    0       0       0       971                             ←—— high
    TX: bytes  packets  errors  dropped carrier collsns 
    1190274    10745    0       0       0       0                               ←—— high
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:31:a2:c8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.193/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0
       valid_lft 80787sec preferred_lft 69987sec
    inet6 fe80::4f31:5fcf:8f70:b5ca/64 scope link 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    4963408    7954     0       0       0       929                             ←—— lower
    TX: bytes  packets  errors  dropped carrier collsns 
    49371      235      0       0       0       0                               ←—— lower

As the annotations indicate, eth0 is being given more traffic by the OS.

Many Operating Systems will give a lower metric to a wired interface that has a faster connection, and a higher metric to a wired interface with a slower connection.  For example, if eth0 and eth1 both connect to the same node, but eth0 negotiated a 100 Mbs connection, and eth1 negotiated only a 10 Mbs connection, eth0 would be given a lower metric than eth1.  Similarly, many Operating Systems will give a lower metric to a wired interface, and a higher metric to a wireless interface.

More than one interface can be set up automatically (depending on the OS), or manually, to reach the same external node by making/editing entries to the routing table.


A minimally tested script to find the interface with the lowest metric as reported by route: [Added by G-Man]

route | awk '
        BEGIN           { min = -1 }
        $1 == "default" {
                            if (min < 0  ||  $5 < min) {
                                min   = $5
                                iface = $8
                            }
                        }
        END             {
                            if (iface == "") {
                                print "No \"default\" route found!" > "/dev/stderr"
                                exit 1
                            } else {
                                print iface
                                exit 0
                            }
                        }
        '

You might want to extend this to look at the "Flags"; i.e., $4.

Just Jeff
  • 111
  • 2
    This would be the best answer here for those with multiple NICs, which I believe should be everyone here if they are asking the OP's question? – DanglingPointer Aug 09 '22 at 02:07
5

Running ifconfig will give you the information you need.

The active interface will have an inet addr and will show a record of transmitted data, like so:

RX bytes:1930741 (1.8 Mb)  TX bytes:204768 (199.9 Kb)

You can also use the ip addr command and any inactive interfaces will be designated as having: NO-CARRIER.

jasonwryan
  • 73,126
  • Since OP doesn't want to be root, maybe you should give full path to the executable? – tshepang Jun 14 '11 at 07:21
  • Neither command requires elevated privileges. – jasonwryan Jun 14 '11 at 07:24
  • I checked that ifconfig runs ok with normal privileges, but on Debian (and I suppose Ubuntu), it's in /sbin, and that's not part of normal user path. Is your system different? – tshepang Jun 14 '11 at 07:35
  • 1
    Ubuntu and Arch: both run with normal privileges (although on Ubuntu it is /sbin) – jasonwryan Jun 14 '11 at 07:50
  • Neither ifconfig nor route requires privileges just to read out info, but both commands are in /sbin which isn't in the PATH environment of regular users by default. ip on the other hand is in /bin – Shadur-don't-feed-the-AI Jun 14 '11 at 11:06
  • 1
    @Shadur Not on my install of Ubuntu 10.10 and according to https://help.ubuntu.com/community/EnvironmentVariables the default $PATH is /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games: – jasonwryan Jun 14 '11 at 18:32
  • 3
    This won't necessarily help on a system with multiple interfaces, as the poster indicated having. A better answer is using the route command though that wouldn't necessarily be foolproof either due to routing. The default route does not have to be the one to get to the Internet though it may often be. – user1801810 Aug 10 '16 at 18:36
5

The command ip route ls will give a list of active routes and their sources:

caleburn: ~/ >ip route ls
192.168.10.0/24 dev eth0  proto kernel  scope link  src 192.168.10.7 
default via 192.168.10.254 dev eth0 
3

Use this command:

$ route | grep default | awk '{print $8}'
enp0s3
Pablo A
  • 2,712
1
Debian: apt-get install net-tools
Alpine: apk add net-tools
Arch Linux: pacman -S net-tools
CentOS: yum install net-tools
Fedora: dnf install net-tools
route | head -3 | tail -1 | tr -s " " | cut -d " " -f8

Debian: apt-get install iproute2
Alpine: apk add iproute2
Arch Linux: pacman -S iproute2
CentOS: yum install iproute2
Fedora: dnf install iproute2
OS X: brew install iproute2
ip route | head -1 | cut -d " " -f5
  • 1
    Thanks for posting an answer. Please consider adding some text to explain what each block of code / commands means. Although useful, your answer might be hard to understand for unexperienced users – Zé Loff Apr 07 '22 at 11:24
0

If your machine has multiple interfaces (which I assume), there is no one interface that will be used for connecting to the internet.

Depending on the destination you are connecting to, your system will consult the ip table (the one shown when you do route command) to find the next hope/router, when it does find one, it will use the interface associated with it.

That said, please refer to @torgeir's answer as it does exactly that:

  1. Given a domain (hardcoded as google.com, which is the only bad point in the answer)
  2. Resolves it's ip
  3. Consults the ip table for the route to use (and hence the interface).
kdehairy
  • 101
0

Even shorter one liner: ip route show default | cut -d " " -f 5

or

ip route show default | sed -n 's/.* dev \([^\ ]*\) .*/\1/p'

Anm
  • 113