Port ifdown.c to FreeBSD. Patch from Guillem Jover and Debian.
authorPetter Reinholdtsen <pere@hungry.com>
Fri, 7 Feb 2014 17:55:37 +0000 (17:55 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Fri, 7 Feb 2014 17:55:37 +0000 (17:55 +0000)
git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@153 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/ifdown.c

index 50c5701d641ca298be2399ce2284366e68e3712e..73ad19f9b2f0fc0d54dcba759ca5a117df3e8520 100644 (file)
@@ -81,6 +81,7 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low
     from Johannes Truschnigg and Debian.
   * Fix typo in fstab-decode(8) font escape.  Patch from Bjarni Ingi
     Gislason and Debian.
     from Johannes Truschnigg and Debian.
   * Fix typo in fstab-decode(8) font escape.  Patch from Bjarni Ingi
     Gislason and Debian.
+  * Port ifdown.c to FreeBSD.  Patch from Guillem Jover and Debian.
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun Apr 11 11:28:55 CEST 2010
 
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun Apr 11 11:28:55 CEST 2010
 
index a2b3bc5da70cc41239b9fa7be61e06410f2695e8..d0ffe641c856f3b7cf9eade264c1612db3657510 100644 (file)
@@ -37,6 +37,23 @@ char *v_ifdown = "@(#)ifdown.c  1.11  02-Jun-1998  miquels@cistron.nl";
 
 #define MAX_IFS        64
 
 
 #define MAX_IFS        64
 
+/* XXX: Ideally this would get detected at configure time... */
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+    defined(__NetBSD__) || defined(__OpenBSD__)
+#define HAVE_SOCKADDR_SA_LEN 1
+#endif
+
+#ifndef _SIZEOF_ADDR_IFREQ
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define _SIZEOF_ADDR_IFREQ(ifr) \
+       ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
+        (sizeof((ifr).ifr_name) + (ifr).ifr_addr.sa_len) : \
+         sizeof(struct ifreq))
+#else
+#define _SIZEOF_ADDR_IFREQ(ifr) sizeof(struct ifreq)
+#endif
+#endif
+
 /*
  *     First, we find all shaper devices and down them. Then we
  *     down all real interfaces. This is because the comment in the
 /*
  *     First, we find all shaper devices and down them. Then we
  *     down all real interfaces. This is because the comment in the
@@ -45,10 +62,10 @@ char *v_ifdown = "@(#)ifdown.c  1.11  02-Jun-1998  miquels@cistron.nl";
  */
 int ifdown(void)
 {
  */
 int ifdown(void)
 {
-       struct ifreq ifr[MAX_IFS];
+       char ifr_buf[sizeof(struct ifreq) * MAX_IFS];
+       char *ifr_end;
        struct ifconf ifc;
        struct ifconf ifc;
-       int i, fd;
-       int numif;
+       int fd;
        int shaper;
 
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        int shaper;
 
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
@@ -56,8 +73,8 @@ int ifdown(void)
                perror("socket");
                return -1;
        }
                perror("socket");
                return -1;
        }
-       ifc.ifc_len = sizeof(ifr);
-       ifc.ifc_req = ifr;
+       ifc.ifc_len = sizeof(ifr_buf);
+       ifc.ifc_buf = ifr_buf;
 
        if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
                fprintf(stderr, "ifdown: ");
 
        if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
                fprintf(stderr, "ifdown: ");
@@ -65,42 +82,55 @@ int ifdown(void)
                close(fd);
                return -1;
        }
                close(fd);
                return -1;
        }
-       numif = ifc.ifc_len / sizeof(struct ifreq);
+       ifr_end = ifr_buf + ifc.ifc_len;
 
        for (shaper = 1; shaper >= 0; shaper--) {
 
        for (shaper = 1; shaper >= 0; shaper--) {
-               for (i = 0; i < numif; i++) {
+               char *ifr_next = ifr_buf;
+
+               while (ifr_next < ifr_end) {
+                       struct ifreq *ifr;
+                       int flags;
 
 
-                       if ((strncmp(ifr[i].ifr_name, "shaper", 6) == 0)
+                       ifr = (struct ifreq *)ifr_next;
+                       ifr_next += _SIZEOF_ADDR_IFREQ(*ifr);
+
+                       if ((strncmp(ifr->ifr_name, "shaper", 6) == 0)
                            != shaper) continue;
 
                            != shaper) continue;
 
-                       if (strcmp(ifr[i].ifr_name, "lo") == 0)
+                       if (strncmp(ifr->ifr_name, "lo", 2) == 0)
                                continue;
                                continue;
-                       if (strchr(ifr[i].ifr_name, ':') != NULL)
+                       if (strchr(ifr->ifr_name, ':') != NULL)
                                continue;
 
                        /* Read interface flags */
                                continue;
 
                        /* Read interface flags */
-                       if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) < 0) {
+                       if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0) {
                                fprintf(stderr, "ifdown: shutdown ");
                                fprintf(stderr, "ifdown: shutdown ");
-                               perror(ifr[i].ifr_name);
+                               perror(ifr->ifr_name);
                                continue;
                        }
                        /*
                         * Expected in <net/if.h> according to
                         * "UNIX Network Programming".
                         */
                                continue;
                        }
                        /*
                         * Expected in <net/if.h> according to
                         * "UNIX Network Programming".
                         */
-#ifdef ifr_flags
-# define IRFFLAGS      ifr_flags
-#else  /* Present on kFreeBSD */
-# define IRFFLAGS      ifr_flagshigh
+#ifdef ifr_flagshigh
+                       flags = (ifr->ifr_flags & 0xffff) |
+                               (ifr->ifr_flagshigh << 16);
+#else
+                       flags = ifr->ifr_flags;
+#endif
+                       if (flags & IFF_UP) {
+                               flags &= ~(IFF_UP);
+#ifdef ifr_flagshigh
+                               ifr->ifr_flags = flags & 0xffff;
+                               ifr->ifr_flagshigh = flags >> 16;
+#else
+                               ifr->ifr_flags = flags;
 #endif
 #endif
-                       if (ifr[i].IRFFLAGS & IFF_UP) {
-                               ifr[i].IRFFLAGS &= ~(IFF_UP);
-                               if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) {
+                               if (ioctl(fd, SIOCSIFFLAGS, ifr) < 0) {
                                        fprintf(stderr, "ifdown: shutdown ");
                                        fprintf(stderr, "ifdown: shutdown ");
-                                       perror(ifr[i].ifr_name);
+                                       perror(ifr->ifr_name);
                                }
                        }
                                }
                        }
-#undef IRFFLAGS
                }
        }
        close(fd);
                }
        }
        close(fd);