]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-linux.c
Deduplicate ether_to_eui64() implementation (#204)
[ppp.git] / pppd / sys-linux.c
index 6e1423808458c32f61e57293fdfcd486fffaeb29..6106467cc9844451f41764fead9cc2b4210ffabf 100644 (file)
@@ -467,6 +467,13 @@ int generic_establish_ppp (int fd)
     if (new_style_driver) {
        int flags;
 
+       /* If a ppp_fd is already open, close it first */
+       if (ppp_fd >= 0) {
+           close(ppp_fd);
+           remove_fd(ppp_fd);
+           ppp_fd = -1;
+       }
+
        /* Open an instance of /dev/ppp and connect the channel to it */
        if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
            error("Couldn't get channel number: %m");
@@ -2087,7 +2094,7 @@ get_if_hwaddr(u_char *addr, char *name)
 
        sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock_fd < 0)
-               return 0;
+               return -1;
        memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
        strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
        ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
@@ -2101,10 +2108,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;
 }
 
 /********************************************************************
@@ -3107,54 +3147,6 @@ sys_check_options(void)
     return 1;
 }
 
-#ifdef INET6
-/*
- * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
- *
- * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
- * that the system has a properly configured Ethernet interface for this
- * function to return non-zero.
- */
-int
-ether_to_eui64(eui64_t *p_eui64)
-{
-    struct ifreq ifr;
-    int skfd;
-    const unsigned char *ptr;
-
-    skfd = socket(PF_INET6, SOCK_DGRAM, 0);
-    if(skfd == -1)
-    {
-        warn("could not open IPv6 socket");
-        return 0;
-    }
-
-    strcpy(ifr.ifr_name, "eth0");
-    if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
-    {
-        close(skfd);
-        warn("could not obtain hardware address for eth0");
-        return 0;
-    }
-    close(skfd);
-
-    /*
-     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
-     */
-    ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
-    p_eui64->e8[0] = ptr[0] | 0x02;
-    p_eui64->e8[1] = ptr[1];
-    p_eui64->e8[2] = ptr[2];
-    p_eui64->e8[3] = 0xFF;
-    p_eui64->e8[4] = 0xFE;
-    p_eui64->e8[5] = ptr[3];
-    p_eui64->e8[6] = ptr[4];
-    p_eui64->e8[7] = ptr[5];
-
-    return 1;
-}
-#endif
-
 /********************************************************************
  *
  * get_time - Get current time, monotonic if possible.