75

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

2
  • 3
    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 <ip-address>" 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 9: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

11 Answers 11

65

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.

11
  • 1
    @Job in case we have an IP address how can we find which interface it uses. – Bionix1441 Nov 30 '17 at 9:51
  • 2
    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
  • 1
    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
  • 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
  • 4
    I get a line "default ... eth0" and a line "default ... wlan0". So which one is the real default? – AstroFloyd Jul 10 '19 at 7:44
39

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 '[^ ]*$'
5
  • 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
  • 3
    you don't need multiple pipes, just use route |awk '/^default/{print $NF}' – P.... Apr 30 '19 at 15:00
  • 1
    I get two lines: "eth0" and "wlan0", so I still don't know which one is active... – AstroFloyd Jul 10 '19 at 7: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 2:41
20

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 src (use grep for that)
ip route get "$host_ip" | grep -Po '(?<=(dev )).*(?= src| proto)'
4
  • 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 9 '20 at 17:28
12

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 -4 route ls | grep default | grep -Po '(?<=dev )(\S+)'
eth0
3
  • 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
11

One liner:

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

8
  • There's a dangling quote there. Doesn't work at all as-is – Krease Jan 24 '18 at 19:23
  • @Krease Author updated his answer – Vadim Kotov Jul 10 '18 at 16:07
  • @MarinosAn I guess it depends of the system... I needed to modify your snippet to used print $5 instead of print $3... – billy Jul 15 '20 at 11:21
  • @billy It would be good to provide your OS to keep here as a reference. – Marinos An Jul 15 '20 at 11:31
  • 2
    +1 for the ip route get 8.8.8.8, the rest doesn't work on ubuntu 18.04. I used something simpler: ip route get 8.8.8.8 | head -n1 | awk '{print $5}' – Marinos An Jul 16 '20 at 9:02
6

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.

7
  • Since OP doesn't want to be root, maybe you should give full path to the executable? – tshepang Jun 14 '11 at 7:21
  • Neither command requires elevated privileges. – jasonwryan Jun 14 '11 at 7:24
  • 1
    Ubuntu and Arch: both run with normal privileges (although on Ubuntu it is /sbin) – jasonwryan Jun 14 '11 at 7:50
  • 1
    @Shadur Not on my install of Ubuntu 10.10 and according to 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
  • 2
    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
4

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
1
  • [root@linux1 network-scripts]# route|grep default | awk '{print $8}' enp0s3 [root@linux1 network-scripts]# – Larry Catt Aug 17 '16 at 16:46
3

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 setup 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 succeds 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 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 will be routed through this interface (it is preferred by the lower metric), while the remainder of my traffic to nodes beyond my own will be routed through the wireless interface (wlan0) (it has a higher metric of 303, and is thus 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     
    TX: bytes  packets  errors  dropped carrier collsns 
    1190274    10745    0       0       0       0       
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     
    TX: bytes  packets  errors  dropped carrier collsns 
    49371      235      0       0       0       0       

It is easy to see that 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 mb connection, and eth1 only negotiated a 10 mb 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 setup automatically (depending on the OS), or manually, to reach the same external node by making/editing entries to the routing table.

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).
0

What he is asking is more like an automated way to performing a ping -I. You can use the ping -I . He wants it to be done automatically and show the network interface it is taking. The resolution should produce an output like this:

PING 8.8.8.8 (8.8.8.8) from 10.11.12.13 via enp192: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=18.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=17.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=117 time=17.7 ms*

Quite honestly, I am looking for the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.