From 9f842088e30f4a2d8ad31a14f16370f917bcb389 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Wed, 30 Dec 2020 11:00:11 +0100 Subject: [PATCH] Implement get_first_ethernet() for Linux systems properly MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Use if_nameindex() for enumerating network interfaces and choose the first one with ARPHRD_ETHER ifr_hwaddr.sa_family. Signed-off-by: Pali Rohár --- pppd/sys-linux.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 6e14238..df5cebb 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -2101,10 +2101,43 @@ get_if_hwaddr(u_char *addr, char *name) * get_first_ethernet - return the name of the first ethernet-style * interface on this system. */ +static char first_ether_name[IF_NAMESIZE]; char * get_first_ethernet(void) { - return "eth0"; + struct if_nameindex *if_ni, *i; + struct ifreq ifreq; + int ret, sock_fd; + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + return NULL; + + if_ni = if_nameindex(); + if (!if_ni) { + close(sock_fd); + return NULL; + } + + first_ether_name[0] = 0; + + for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) { + memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); + strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name)); + ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); + if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) { + strlcpy(first_ether_name, i->if_name, sizeof(first_ether_name)); + break; + } + } + + if_freenameindex(if_ni); + close(sock_fd); + + if (!first_ether_name[0]) + return NULL; + + return first_ether_name; } /******************************************************************** -- 2.39.2