Linux get default interface

Get default outgoing IP address and interface on Linux

Suppose you have one or more network interfaces, and they have one or more assigned IP addresses, also called aliases. If you need to find out which IP address and interface will be used as a default “source” by your Linux box, you need to execute the following:

This, of course, assumes that 8.8.8.8 is not directly connected on your networks somehow. Since this is one of the Public Name Servers of Google, I think it is safe to assume so.

A sample output of the ip command follows:

8.8.8.8 via 10.0.2.2 dev eth0 src 10.0.2.15 cache

The output is pretty much self-explanatory — the route to “8.8.8.8” will originate from device “eth0”, the used source IP address will be “10.0.2.15”, and the next hop, the (default) gateway, will be “10.0.2.2”.

This method is 100% reliable. The man page of “ip” says that “this command gets a single route to a destination and prints its contents exactly as the kernel sees it”.

Share this:

Like this:

Author: Ivan Zahariev

An experienced Linux & IT enthusiast, Engineer by heart, Systems architect & developer.

5 thoughts on “ Get default outgoing IP address and interface on Linux ”

Hello! Thanks for the tip. 🙂 Nevertheless it does not work within an OpenVZ container. Is there a reliable way to get the second hop? (“traceroute -n -m 2 8.8.8.8” seems useless) Thanks.

root@us:~# uname -a Linux vz1.localdomain.tld 2.6.32-5-openvz-686 #1 SMP Tue Mar 8 23:30:33 UTC 2011 i686 GNU/Linux root@us:~# ifconfig venet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:127.0.0.1 P-t-P:127.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 RX packets:2062404822 errors:0 dropped:0 overruns:0 frame:0 TX packets:3481908787 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:4137966362 (3.8 GiB) TX bytes:2102324686 (1.9 GiB) venet0:0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:30.40.50.60 P-t-P:30.40.50.60 Bcast:0.0.0.0 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 venet0:1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:30.40.50.61 P-t-P:30.40.50.61 Bcast:0.0.0.0 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 root@us:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.0.2.1 0.0.0.0 255.255.255.255 UH 0 0 0 venet0 0.0.0.0 192.0.2.1 0.0.0.0 UG 0 0 0 venet0 root@us:~# ip route get 8.8.8.8 8.8.8.8 via 192.0.2.1 dev venet0 src 30.40.50.60 cache mtu 1500 advmss 1460 hoplimit 64

The default source IP is properly detected as “30.40.50.60” which belongs to “venet0:0”.
Note that I run the default OpenVZ guest configuration where containers have public IP addresses. If you are running your VZ guests behind a NAT, that’s a different story. The article here demonstrates how to get the default outgoing IP address of the machine (which may be a private one), not its real IP address if it’s behind a NAT. — Regarding the “traceroute” parsing — I don’t recommend it, since “traceroute” is making real network tests which could take a while. Here is an example on how to parse it though:

taurus:~# traceroute -n 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets 1 192.168.100.1 1.091 ms 1.381 ms 1.708 ms 2 85.1.2.129 6.825 ms 6.941 ms 7.030 ms 3 85.1.2.193 7.211 ms 7.324 ms 7.408 ms . and so on. taurus:~# traceroute -n 8.8.8.8|head -n3|tail -n1|egrep '^[[:space:]]*2'|awk '' 85.1.2.129

The “egrep” is there just as a sanity check that the “head|tail” commands really returned the second hop.

Читайте также:  Горячие клавиши громкость линукс

Hello! > “not its real IP address if it’s behind a NAT” That is the case: all VMs use venet and are “hidden” in a private network. And sadly, traceroute always returns the node primary IP adress, not the IP failover used by some containers. Anyway, thank you for your help! 🙂

🙂 You are welcome. It’s even theoretically impossible to find out the real IP address from the NAT’ed machine, since IP headers rewriting is done outside of the machine, at the router. The only solution if you want to figure this out from the local machine, is to query a remote server connected in Internet and ask it to echo your remote IP address. For example, I put the following PHP script at “http://www.famzah.net/temp/ip.php”:

$ curl http://www.famzah.net/temp/ip.php 85.1.2.145

Источник

How to find the default networking interface in linux?

I have seen this question: Linux C: how to know the default interface for internet access?, but it suggested parsing the output of a command, something which I do NOT want to do. I have also checked the source code of it and got completely lost in it. Could anyone just give me a snippet that would do this? All I want is the interface name. Here is my current (non-working) source code for the function, using libmnl:

bool get_default_interface(std::string* interface_name) < char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr* nlh = mnl_nlmsg_put_header(buf); struct ifinfomsg* ifm = (ifinfomsg*) mnl_nlmsg_get_payload(nlh); int len = nlh->nlmsg_len; struct rtmsg* r = (rtmsg*) NLMSG_DATA(nlh); struct rtattr* rta = RTM_RTA(r); struct nlattr* tb[IFLA_MAX + 1] = <>; mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb); //struct rtnexthop* nh = (rtnexthop*) RTA_DATA(tb[RTA_MULTIPATH]); if (r->rtm_dst_len) < return false; >std::cout

@ott—, I just want to disable the networking interface (so that the user cannot access the internet), but for that, I need to know the interface to disable.

2 Answers 2

This ought to do. I have taken it from «Bob» here, and have taken the liberty of adding a couple of missing includes and modifying the output. Basically you open a socket to query the routes, and the default interface is the one associated with the null destination address.

The code works on my 64-bit Linux.

> Destination Gateway Interface Source > 0.0.0.0 192.168.0.1 eth1 *.*.*.* > ^^^^^ here it is! > 127.0.0.0 *.*.*.* lo *.*.*.* > . #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUFSIZE 8192 struct route_info< u_int dstAddr; u_int srcAddr; u_int gateWay; char ifName[IF_NAMESIZE]; >; int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId) < struct nlmsghdr *nlHdr; int readLen = 0, msgLen = 0; do < /* Receive response from the kernel */ if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0) < perror("SOCK READ: "); return -1; >nlHdr = (struct nlmsghdr *)bufPtr; /* Check if the header is valid */ if((0 == NLMSG_OK(nlHdr, readLen)) || (NLMSG_ERROR == nlHdr->nlmsg_type)) < perror("Error in received packet"); return -1; >/* Check if it is the last message */ if (NLMSG_DONE == nlHdr->nlmsg_type) < break; >/* Else move the pointer to buffer appropriately */ bufPtr += readLen; msgLen += readLen; /* Check if its a multi part message; return if it is not. */ if (0 == (nlHdr->nlmsg_flags & NLM_F_MULTI)) < break; >> while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId)); return msgLen; > char *ntoa(int addr) < static char buffer[18]; sprintf(buffer, "%d.%d.%d.%d", (addr & 0x000000FF) , (addr & 0x0000FF00) >> 8, (addr & 0x00FF0000) >> 16, (addr & 0xFF000000) >> 24); return buffer; > /* For printing the routes. */ void printRoute(struct route_info *rtInfo) < /* Print Destination address */ printf("%s\t", rtInfo->dstAddr ? ntoa(rtInfo->dstAddr) : "0.0.0.0 "); /* Print Gateway address */ printf("%s\t", rtInfo->gateWay ? ntoa(rtInfo->gateWay) : "*.*.*.*"); /* Print Interface Name */ printf("%s\t", rtInfo->ifName); /* Print Source address */ printf("%s\n", rtInfo->srcAddr ? ntoa(rtInfo->srcAddr) : "*.*.*.*"); if (0 == rtInfo->dstAddr) < printf("\t\t\t^^^^^ here it is!\n"); >> /* For parsing the route info returned */ void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo) < struct rtmsg *rtMsg; struct rtattr *rtAttr; int rtLen; char *tempBuf = NULL; tempBuf = (char *)malloc(100); rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr); /* If the route is not for AF_INET or does not belong to main routing table then return. */ if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN)) return; /* get the rtattr field */ rtAttr = (struct rtattr *)RTM_RTA(rtMsg); rtLen = RTM_PAYLOAD(nlHdr); for (; RTA_OK(rtAttr,rtLen); rtAttr = RTA_NEXT(rtAttr,rtLen)) < switch(rtAttr->rta_type) < case RTA_OIF: if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName); break; case RTA_GATEWAY: rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr); break; case RTA_PREFSRC: rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr); break; case RTA_DST: rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr); break; > > printRoute(rtInfo); free(tempBuf); > int main() < struct nlmsghdr *nlMsg; struct route_info *rtInfo; char msgBuf[BUFSIZE]; int sock, len, msgSeq = 0; /* Create Socket */ if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) perror("Socket Creation: "); /* Initialize the buffer */ memset(msgBuf, 0, BUFSIZE); /* point the header and the msg structure pointers into the buffer */ nlMsg = (struct nlmsghdr *)msgBuf; /* Fill in the nlmsg header*/ nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message. nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table . nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump. nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet. nlMsg->nlmsg_pid = getpid(); // PID of process sending the request. /* Send the request */ if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)< printf("Write To Socket Failed. \n"); return -1; >/* Read the response */ if((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) < printf("Read From Socket Failed. \n"); return -1; >/* Parse and print the response */ rtInfo = (struct route_info *)malloc(sizeof(struct route_info)); // ADDED BY BOB /* THIS IS THE NETTSTAT -RL code I commented out the printing here and in parse routes */ printf("Destination\tGateway\tInterface\tSource\n"); for(;NLMSG_OK(nlMsg,len);nlMsg = NLMSG_NEXT(nlMsg,len)) < memset(rtInfo, 0, sizeof(struct route_info)); parseRoutes(nlMsg, rtInfo); >free(rtInfo); close(sock); return 0; > 

Источник

Читайте также:  Remove user linux from group

How to Change the Default Network Interface in Linux

This quick tutorial will show you how to set the default interface in Linux.

How to Change the Default Network Interface in Linux

The only way to enable network connection on a machine is through a network interface.

A network interface is a device or a point of connection between a device and a private or public network. In most cases, a network interface is a physical card such as a wireless adapter or network card.

However, this does not necessarily mean that a network interface should be a physical device. For example, the software implements a loopback adapter that is not physically visible and available on all devices.

Method 1 – Turn Off Adapters

The simplest way to set your default network interface is by disabling all other interfaces. For example, you can use the GUI network manager or the terminal in Linux.

Suppose you have a wireless adapter and you wish to use the Ethernet adapter; in that case, you can bring down the wifi adapter using the command:

sudo ifconfig wlan0 down sudo ifconfig eth0 up 

The above commands will shut down the wireless adapter and bring up the ethernet adapter.

That will force the system to switch to the available network.

NOTE: The above command requires sudo or root privileges with the net-tools package installed.

Method 2 – Use IP ROUTES

An unconventional method is to edit your routes and specify which devices to use as the default.

Start by using the command:

This command will show you the default gateway and the default interface. For example, below:

default via 192.168.0.1 dev wlan0 proto dhcp metric 100 169.254.0.0/16 dev wlan0 scope link metric 1000 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.10 metric 100 

In the above example, the default value is wlan0. To change this, we start by removing all the routes as

Читайте также:  Template os linux by zabbix agent active

This removes the default interface. Here’s an output:

169.254.0.0/16 dev wlan0 scope link metric 1000 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.10 metric 100 

To set the default interface, add the route using the command:

sudo ip route add default via 192.168.0.1 dev eth0 

Once executed successfully, you can list the default interface as:

default via 192.168.0.1 dev eth0 169.254.0.0/16 dev eth0 scope link metric 1000 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.10 metric 100 

Conclusion

That’s it for this one. This is a quick tutorial shows you how to modify the IP routes to specify your default interfaces.

If you enjoy our content, please consider buying us a coffee to support our work:

A highly-skilled software engineer with a passion for teaching and sharing knowledge. From development to hardware, get articles with high technical accuracy, clarity, and an engaging writing style.

Источник

Оцените статью
Adblock
detector