Rework socket handling again. Rather than
authorPhil Blundell <philb@gnu.org>
Sat, 14 Nov 1998 10:37:04 +0000 (10:37 +0000)
committerPhil Blundell <philb@gnu.org>
Sat, 14 Nov 1998 10:37:04 +0000 (10:37 +0000)
issuing ioctls to a random socket and just
hoping, we do our best to pick the right one
for the address family in use.  This should
fix a bug reported for 1.47 where a command like
"ifconfig eth0 broadcast 1.0.0.255" picked on the
AF_APPLETALK socket and so didn't work.

Quite an invasive fix but hopefully the right one.
Andi, can you take a look since this is stuff you've
been working on recently.

13 files changed:
ifconfig.c
interface.c
lib/af.c
lib/ax25.c
lib/ddp.c
lib/econet.c
lib/inet.c
lib/inet6.c
lib/ipx.c
lib/net-support.h
lib/rose.c
lib/unix.c
sockets.c

index 14b9e82..1d1f467 100644 (file)
@@ -478,6 +478,7 @@ main(int argc, char **argv)
   struct ifreq ifr;
   int goterr = 0, didnetmask = 0;
   char **spp;
+  int fd;
 #if HAVE_AFINET6
   extern struct aftype inet6_aftype;
   struct sockaddr_in6 sa6;
@@ -738,7 +739,7 @@ main(int argc, char **argv)
        }
        memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
               sizeof(struct sockaddr));
-       if (ioctl(skfd, SIOCSIFBRDADDR, &ifr) < 0) {
+       if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {
          fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
                  strerror(errno));
          goterr = 1;
@@ -761,7 +762,7 @@ main(int argc, char **argv)
       }
       memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
             sizeof(struct sockaddr));
-      if (ioctl(skfd, SIOCSIFDSTADDR, &ifr) < 0) {
+      if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
        fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
                strerror(errno));
        goterr = 1;
@@ -780,8 +781,8 @@ main(int argc, char **argv)
        spp++;
        continue;
       }
-         didnetmask++;
-         goterr = set_netmask(skfd, &ifr, &sa);
+      didnetmask++;
+      goterr = set_netmask(ap->fd, &ifr, &sa);
       spp++;
       continue;
     }
@@ -907,9 +908,9 @@ main(int argc, char **argv)
       } else {
        prefix_len = 0;
       }
-                 host[(sizeof host)-1] = 0; 
-                 strncpy(host, *spp, (sizeof host)-1);
-     if (inet6_aftype.input(1, host, (struct sockaddr *)&sa6) < 0) {
+      host[(sizeof host)-1] = 0; 
+      strncpy(host, *spp, (sizeof host)-1);
+      if (inet6_aftype.input(1, host, (struct sockaddr *)&sa6) < 0) {
        inet6_aftype.herror(host);
        goterr = 1;
        spp++;
@@ -918,7 +919,15 @@ main(int argc, char **argv)
       memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
             sizeof(struct in6_addr));
       
-      if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {
+      fd = get_socket_for_af(AF_INET6);
+      if (fd < 0) {
+       fprintf(stderr, _("No support for INET6 on this system.\n"));
+       goterr = 1;
+       spp++;
+       continue;
+      }
+
+      if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
        perror("SIOGIFINDEX");
        goterr = 1;
        spp++;
@@ -927,9 +936,8 @@ main(int argc, char **argv)
 
       ifr6.ifr6_ifindex = ifr.ifr_ifindex;
       ifr6.ifr6_prefixlen = prefix_len;
-      if (ioctl(inet6_sock, SIOCSIFADDR, &ifr6) < 0) {
-       fprintf(stderr, "SIOCSIFADDR: %s\n",
-               strerror(errno));
+      if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
+       perror("SIOCSIFADDR");
        goterr = 1;
       }
       spp++;
@@ -945,8 +953,8 @@ main(int argc, char **argv)
       } else {
        prefix_len = 0;
       }
-                 host[(sizeof host)-1] = 0; 
-                 strncpy(host, *spp, (sizeof host)-1);
+      host[(sizeof host)-1] = 0; 
+      strncpy(host, *spp, (sizeof host)-1);
       if (inet6_aftype.input(1, host, (struct sockaddr *)&sa6) < 0) {
        inet6_aftype.herror(host);
        goterr = 1;
@@ -956,7 +964,15 @@ main(int argc, char **argv)
       memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
             sizeof(struct in6_addr));
       
-      if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {
+      fd = get_socket_for_af(AF_INET6);
+      if (fd < 0) {
+       fprintf(stderr, _("No support for INET6 on this system.\n"));
+       goterr = 1;
+       spp++;
+       continue;
+      }
+
+      if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
        perror("SIOGIFINDEX");
        goterr = 1;
        spp++;
@@ -966,7 +982,7 @@ main(int argc, char **argv)
       ifr6.ifr6_ifindex = ifr.ifr_ifindex;
       ifr6.ifr6_prefixlen = prefix_len;
 #ifdef SIOCDIFADDR
-      if (ioctl(inet6_sock, SIOCDIFADDR, &ifr6) < 0) {
+      if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
        fprintf(stderr, "SIOCDIFADDR: %s\n",
                strerror(errno));
        goterr = 1;
@@ -987,8 +1003,8 @@ main(int argc, char **argv)
       } else {
        prefix_len = 0;
       }
-                 host[(sizeof host)-1] = 0; 
-                 strncpy(host, *spp, (sizeof host)-1);
+      host[(sizeof host)-1] = 0; 
+      strncpy(host, *spp, (sizeof host)-1);
       if (inet6_aftype.input(1, host, (struct sockaddr *)&sa6) < 0) {
        inet6_aftype.herror(host);
        goterr = 1;
@@ -998,7 +1014,15 @@ main(int argc, char **argv)
       memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
             sizeof(struct in6_addr));
       
-      if (ioctl(inet6_sock, SIOGIFINDEX, &ifr) < 0) {
+      fd = get_socket_for_af(AF_INET6);
+      if (fd < 0) {
+       fprintf(stderr, _("No support for INET6 on this system.\n"));
+       goterr = 1;
+       spp++;
+       continue;
+      }
+
+      if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
        perror("SIOGIFINDEX");
        goterr = 1;
        spp++;
@@ -1008,7 +1032,7 @@ main(int argc, char **argv)
       ifr6.ifr6_ifindex = ifr.ifr_ifindex;
       ifr6.ifr6_prefixlen = prefix_len;
       
-      if (ioctl(inet6_sock, SIOCSIFDSTADDR, &ifr6) < 0) {
+      if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {
        fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
                strerror(errno));
        goterr = 1;
@@ -1022,20 +1046,20 @@ main(int argc, char **argv)
        host[(sizeof host)-1] = '\0'; 
     strncpy(host, *spp, (sizeof host)-1);
 
-       /* FIXME: sa is too small for INET6 addresses, inet6 should use that too, 
-                         broadcast is unexpected */ 
-       if (ap->getmask) { 
-               switch (ap->getmask(host, &sa, NULL)) {
-               case -1: usage(); break; 
-               case 1:  
-                       if (didnetmask) usage(); 
-
-                       goterr = set_netmask(skfd, &ifr, &sa); 
-                       didnetmask++; 
-                       break;
-               }
-       }
-
+    /* FIXME: sa is too small for INET6 addresses, inet6 should use that too, 
+       broadcast is unexpected */ 
+    if (ap->getmask) { 
+      switch (ap->getmask(host, &sa, NULL)) {
+      case -1: usage(); break; 
+      case 1:  
+       if (didnetmask) usage(); 
+       
+       goterr = set_netmask(skfd, &ifr, &sa); 
+       didnetmask++; 
+       break;
+      }
+    }
+    
     if (ap->input(0, host, &sa) < 0) {
       ap->herror(host);
       usage();
@@ -1047,20 +1071,31 @@ main(int argc, char **argv)
       switch (ap->af) {
 #if HAVE_AFINET
       case AF_INET:
-       r = ioctl(inet_sock, SIOCSIFADDR, &ifr);
+       fd = get_socket_for_af(AF_INET);
+       if (fd < 0) {
+         fprintf(stderr, _("No support for INET on this system.\n"));
+         exit(1);
+       }
+       r = ioctl(fd, SIOCSIFADDR, &ifr);
        break;
 #endif
 #if HAVE_AFECONET
       case AF_ECONET:
-       r = ioctl(ec_sock, SIOCSIFADDR, &ifr);
+       fd = get_socket_for_af(AF_ECONET);
+       if (fd < 0) {
+         fprintf(stderr, _("No support for ECONET on this system.\n"));
+         exit(1);
+       }
+       r = ioctl(fd, SIOCSIFADDR, &ifr);
        break;
 #endif
       default:
-       printf(_("Don't know how to set addresses for this family.\n"));
+       fprintf(stderr, 
+               _("Don't know how to set addresses for this family.\n"));
        exit(1);
       }
       if (r < 0) {
-       fprintf(stderr, "SIOCSIFADDR: %s\n", strerror(errno));
+       perror("SIOCSIFADDR");
        goterr = 1;
       }
     }
@@ -1068,8 +1103,5 @@ main(int argc, char **argv)
     spp++;
   }
 
-  /* Close the socket. */
-  (void) close(skfd);
-
   return(goterr);
 }
index 0b1bdc8..53c0827 100644 (file)
@@ -4,7 +4,7 @@
    10/1998 partly rewriten by Andi Kleen to support interface list.   
                   I don't claim that the list operations are efficient @).  
 
-   $Id: interface.c,v 1.7 1998/10/31 09:55:42 philip Exp $
+   $Id: interface.c,v 1.8 1998/11/14 10:37:06 philip Exp $
  */
 
 #include "config.h"
@@ -100,19 +100,12 @@ static int if_readconf(void)
        struct ifreq *ifr; 
        int n, err = -1;  
 
-       int sk; 
-       sk = socket(PF_INET, SOCK_DGRAM, 0); 
-       if (sk < 0) { 
-               perror(_("error opening inet socket"));
-               return -1; 
-       }
-
        ifc.ifc_buf = NULL;
        for (;;) { 
                ifc.ifc_len = sizeof(struct ifreq) * numreqs; 
                ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len); 
                
-               if (ioctl(sk, SIOCGIFCONF, &ifc) < 0) { 
+               if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { 
                        perror("SIOCGIFCONF");
                        goto out; 
                }
@@ -141,7 +134,6 @@ static int if_readconf(void)
 
 out:
        free(ifc.ifc_buf);  
-       close(sk);
        return err;  
 }
 
@@ -326,6 +318,7 @@ int
 if_fetch(char *ifname, struct interface *ife)
 {
   struct ifreq ifr;
+  int fd;
 
   strcpy(ifr.ifr_name, ifname);
   if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1);
@@ -393,60 +386,67 @@ if_fetch(char *ifname, struct interface *ife)
 #endif
 
 #if HAVE_AFINET
-  strcpy(ifr.ifr_name, ifname);
-  if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFDSTADDR, &ifr) < 0)
-    memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
-  else 
-    ife->dstaddr = ifr.ifr_dstaddr;
+  fd = get_socket_for_af(AF_INET);
+  if (fd >= 0) {
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0)
+      memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
+    else 
+      ife->dstaddr = ifr.ifr_dstaddr;
 
-  strcpy(ifr.ifr_name, ifname);
-  if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFBRDADDR, &ifr) < 0)
-    memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
-  else 
-    ife->broadaddr = ifr.ifr_broadaddr;
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
+      memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
+    else 
+      ife->broadaddr = ifr.ifr_broadaddr;
 
-  strcpy(ifr.ifr_name, ifname);
-  if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFNETMASK, &ifr) < 0)
-    memset(&ife->netmask, 0, sizeof(struct sockaddr));
-  else 
-    ife->netmask = ifr.ifr_netmask;
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
+      memset(&ife->netmask, 0, sizeof(struct sockaddr));
+    else 
+      ife->netmask = ifr.ifr_netmask;
 
-  strcpy(ifr.ifr_name, ifname);
-  if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) 
-    memset(&ife->addr, 0, sizeof(struct sockaddr));
-  else 
-    ife->addr = ifr.ifr_addr;
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) 
+      memset(&ife->addr, 0, sizeof(struct sockaddr));
+    else 
+      ife->addr = ifr.ifr_addr;
+  }
 #endif
-  
+    
 #if HAVE_AFATALK
   /* DDP address maybe ? */
-  strcpy(ifr.ifr_name, ifname);
-  if (ddp_sock >= 0 && ioctl(ddp_sock, SIOCGIFADDR, &ifr) == 0) {
-    ife->ddpaddr=ifr.ifr_addr;
-    ife->has_ddp=1;
+  fd = get_socket_for_af(AF_APPLETALK);
+  if (fd >= 0) {
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
+      ife->ddpaddr=ifr.ifr_addr;
+      ife->has_ddp=1;
+    }
   }
 #endif
 
 #if HAVE_AFIPX  
   /* Look for IPX addresses with all framing types */
-  strcpy(ifr.ifr_name, ifname);
-  if (ipx_sock >= 0) {
-    if (!ipx_getaddr(ipx_sock, IPX_FRAME_ETHERII, &ifr)) {
+  fd = get_socket_for_af(AF_IPX);
+  if (fd >= 0) {
+    strcpy(ifr.ifr_name, ifname);
+    if (!ipx_getaddr(fd, IPX_FRAME_ETHERII, &ifr)) {
       ife->has_ipx_bb=1;
       ife->ipxaddr_bb=ifr.ifr_addr;
     }
     strcpy(ifr.ifr_name, ifname);
-    if (!ipx_getaddr(ipx_sock, IPX_FRAME_SNAP, &ifr)) {
+    if (!ipx_getaddr(fd, IPX_FRAME_SNAP, &ifr)) {
       ife->has_ipx_sn=1;
       ife->ipxaddr_sn=ifr.ifr_addr;
     }
     strcpy(ifr.ifr_name, ifname);
-    if(!ipx_getaddr(ipx_sock, IPX_FRAME_8023, &ifr)) {
+    if(!ipx_getaddr(fd, IPX_FRAME_8023, &ifr)) {
       ife->has_ipx_e3=1;
       ife->ipxaddr_e3=ifr.ifr_addr;
     }
     strcpy(ifr.ifr_name, ifname);
-    if(!ipx_getaddr(ipx_sock, IPX_FRAME_8022, &ifr)) {
+    if(!ipx_getaddr(fd, IPX_FRAME_8022, &ifr)) {
       ife->has_ipx_e2=1;
       ife->ipxaddr_e2=ifr.ifr_addr;
     }
@@ -455,10 +455,13 @@ if_fetch(char *ifname, struct interface *ife)
 
 #if HAVE_AFECONET
   /* Econet address maybe? */
-  strcpy(ifr.ifr_name, ifname);
-  if (ec_sock >= 0 && ioctl(ec_sock, SIOCGIFADDR, &ifr) == 0) {
-    ife->ecaddr = ifr.ifr_addr;
-    ife->has_econet = 1;
+  fd = get_socket_for_af(AF_ECONET);
+  if (fd >= 0) {
+    strcpy(ifr.ifr_name, ifname);
+    if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
+      ife->ecaddr = ifr.ifr_addr;
+      ife->has_econet = 1;
+    }
   }
 #endif
 
index b732de6..c9b79e9 100644 (file)
--- a/lib/af.c
+++ b/lib/af.c
@@ -71,7 +71,7 @@ extern        struct aftype   ec_aftype;
 
 static short sVafinit = 0;
 
-static struct aftype *aftypes[] = {
+struct aftype *aftypes[] = {
 #if HAVE_AFUNIX
   &unix_aftype,
 #endif
@@ -207,6 +207,22 @@ get_afntype(int af)
   return(NULL);
 }
 
+/* Check our protocol family table for this family and return its socket */
+int
+get_socket_for_af(int af)
+{
+  struct aftype **afp;
+
+  if (!sVafinit)
+    afinit ();
+  
+  afp = aftypes;
+  while (*afp != NULL) {
+       if ((*afp)->af == af) return (*afp)->fd;
+       afp++;
+  }
+  return -1;
+}
 
 int aftrans_opt(const char *arg)
 {
index 506a132..0260a0f 100644 (file)
@@ -199,7 +199,9 @@ struct hwtype ax25_hwtype = {
 struct aftype ax25_aftype = {
   "ax25",      NULL, /*"AMPR AX.25",*/         AF_AX25,        7,
   AX25_print,  AX25_sprint,            AX25_input,     AX25_herror,    
-  NULL
+  NULL,                NULL,           NULL,
+  -1,
+  "/proc/net/ax25"
 };
 
 #endif /* HAVE_xxAX25 */
index 014e9e4..81f4eb3 100644 (file)
--- a/lib/ddp.c
+++ b/lib/ddp.c
@@ -54,7 +54,9 @@ ddp_sprint(struct sockaddr *sap, int numeric)
 struct aftype ddp_aftype = {
   "ddp",       NULL, /*"Appletalk DDP",*/      AF_APPLETALK,   0,
   ddp_print,   ddp_sprint,             NULL,           NULL,
-  NULL/*DDP_rprint*/
+  NULL/*DDP_rprint*/,  NULL,   NULL,
+  -1,
+  "/proc/net/appletalk"
 };
 
 #endif
index 4ba7668..faf0246 100644 (file)
@@ -78,6 +78,8 @@ ec_input(int type, char *bufp, struct sockaddr *sap)
 struct aftype ec_aftype = {
   "ec",        NULL,   AF_ECONET,      0,
   ec_print,    ec_sprint,      ec_input,       NULL,
+  NULL,                NULL,           NULL,
+  -1,
   NULL
 };
 
index 7da5b6a..e35c504 100644 (file)
@@ -287,7 +287,9 @@ struct aftype inet_aftype = {
   "inet",      NULL, /*"DARPA Internet",*/     AF_INET,        sizeof(unsigned long),
   INET_print,  INET_sprint,            INET_input,     INET_reserror,  
   NULL/*INET_rprint*/, NULL/*INET_rinput*/,
-  INET_getnetmask 
+  INET_getnetmask,
+  -1,
+  NULL
 };
 
 #endif /* HAVE_AFINET || HAVE_AFINET6 */
index 076bfc5..564de85 100644 (file)
@@ -155,7 +155,10 @@ INET6_input(int type, char *bufp, struct sockaddr *sap)
 struct aftype inet6_aftype = {
   "inet6",     NULL, /*"IPv6",*/       AF_INET6,       sizeof(struct in6_addr),
   INET6_print, INET6_sprint,           INET6_input,    INET6_reserror, 
-  INET6_rprint,        INET6_rinput
+  INET6_rprint,        INET6_rinput,           NULL,
+
+  -1,
+  "/proc/net/if_inet6"
 };
 
 
index dfd8873..09bbb3c 100644 (file)
--- a/lib/ipx.c
+++ b/lib/ipx.c
@@ -174,7 +174,9 @@ IPX_input(int type, char *bufp, struct sockaddr *sap)
 struct aftype ipx_aftype = {
   "ipx",       NULL, /*"IPX",*/                AF_IPX, 0,
   IPX_print,   IPX_sprint,             IPX_input,              NULL,
-  NULL/*IPX_rprint*/
+  NULL/*IPX_rprint*/,  NULL, NULL,
+  -1,
+  "/proc/net/ipx"
 };
 
 #endif
index 2b97d5f..435d511 100644 (file)
@@ -45,10 +45,13 @@ struct aftype {
   int          (*rinput)       (int typ, int ext, char **argv);
 
   /* may modify src */ 
-  int          (*getmask)  (char *src, struct sockaddr *mask, char *name);     
+  int          (*getmask)  (char *src, struct sockaddr *mask, char *name);
 
+  int          fd;
+  char         *flag_file; 
 };
 
+extern struct aftype *aftypes[];
 
 /* This structure defines hardware protocols and their handlers. */
 struct hwtype {
@@ -70,6 +73,8 @@ extern struct aftype  *get_afntype(int type);
 
 extern int             getargs(char *string, char *arguments[]);
 
+extern int             get_socket_for_af(int af);
+
 extern void            getroute_init(void);
 extern void            setroute_init(void);
 extern void            activate_init(void);
index fe14fd6..7c6b753 100644 (file)
@@ -136,7 +136,9 @@ struct hwtype rose_hwtype = {
 struct aftype rose_aftype = {
   "rose",      NULL, /*"AMPR ROSE",*/          AF_ROSE,        10,
   ROSE_print,  ROSE_sprint,            ROSE_input,     ROSE_herror,    
-  NULL
+  NULL,                NULL,           NULL,
+  -1,
+  "/proc/net/rose"
 };
 
 #endif /* HAVE_xxROSE */
index f7b98bb..50d3bac 100644 (file)
@@ -84,7 +84,9 @@ UNIX_sprint(struct sockaddr *sap, int numeric)
 struct aftype unix_aftype = {
   "unix",      NULL, /*"UNIX Domain",*/                AF_UNIX,        0,
   UNIX_print,  UNIX_sprint,            NULL,           NULL,
-  NULL
+  NULL,                NULL,           NULL,
+  -1,
+  "/proc/net/unix"
 };
 #endif /* HAVE_AFUNIX */
 
@@ -92,5 +94,5 @@ struct aftype unix_aftype = {
 struct aftype unspec_aftype = {
   "unspec",    NULL, /*"UNSPEC",*/             AF_UNSPEC,      0,
   UNSPEC_print,        UNSPEC_sprint,          NULL,           NULL,   
-  NULL
+  NULL,
 };
index e185ae5..dfacb83 100644 (file)
--- a/sockets.c
+++ b/sockets.c
@@ -1,5 +1,11 @@
 /* sockets.c. Rewriten by Andi Kleen. Subject to the GPL. */
 
+/* philb 14/11/98: we now stash the socket file descriptor inside
+   the `aftype' structure rather than keeping it in a pile of separate
+   variables.  This is necessary so that "ifconfig eth0 broadcast ..."
+   issues ioctls to the right socket for the address family in use;
+   picking one at random doesn't always work.  */
+
 #include <sys/socket.h>
 #include <stdio.h>
 #include <unistd.h>
 #include "sockets.h"
 #include "intl.h"
 #include "util.h"
+#include "net-support.h"
 
 int skfd = -1;         /* generic raw socket desc.     */
-#if HAVE_AFIPX
-int     ipx_sock = -1;                 /* IPX socket                   */
-#endif
-#if HAVE_AFAX25
-int ax25_sock = -1;                    /* AX.25 socket                 */
-#endif
-#if HAVE_AFROSE
-int rose_sock = -1;                    /* Rose socket                  */
-#endif
-#if HAVE_AFINET
-int inet_sock = -1;                    /* INET socket                  */
-#endif
-#if HAVE_AFINET6
-int inet6_sock = -1;                   /* INET6 socket                 */
-#endif
-#if HAVE_AFATALK
-int ddp_sock = -1;                     /* Appletalk DDP socket         */
-#endif
-#if HAVE_AFECONET
-int ec_sock = -1;                      /* Econet socket                */
-#endif
-
-
-struct fam_sock {
-       int *varp;
-       int  family;
-       char *flag_file; 
-};
-
-static struct fam_sock sockets[] = { 
-       { &skfd, AF_INET, NULL }, 
-#if HAVE_AFIPX
-       { &ipx_sock, AF_IPX, "/proc/net/ipx" }, 
-#endif
-#if HAVE_AFAX25
-       { &ax25_sock, AF_AX25, "/proc/net/ax25" }, 
-#endif
-#if HAVE_AFROSE
-       { &rose_sock, AF_ROSE, "/proc/net/rose" }, 
-#endif
-#if HAVE_AFINET
-       { &inet_sock, AF_INET, NULL },
-#endif
-#if HAVE_AFINET6
-       { &inet6_sock, AF_INET6, "/proc/net/if_inet6" },  
-#endif
-#if HAVE_AFATALK
-       { &ddp_sock, AF_APPLETALK, "/proc/net/appletalk" },
-#endif
-#if HAVE_AFECONET
-       { &ec_sock, AF_ECONET, NULL }, /* XXX */  
-#endif
-       { 0 } 
-}; 
 
 int sockets_open(int family)
 {
-       struct fam_sock *sk;
+       struct aftype **aft;
        int sfd = -1; 
        static int force = -1; 
 
@@ -78,24 +31,25 @@ int sockets_open(int family)
                if (access("/proc",R_OK))
                        force = 1;
        }
-       for (sk = &sockets[0]; sk->varp; sk++) {
-               if (family && family != sk->family)
+       for (aft = aftypes; *aft; aft++) {
+               struct aftype *af = *aft;
+               if (af->af == AF_UNSPEC)
+                       continue;
+               if (family && family != af->af)
                        continue; 
-               if (*(sk->varp) != -1) {
-                       sfd = *(sk->varp);
+               if (af->fd != -1) {
+                       sfd = af->fd;
                        continue;
                }
                /* Check some /proc file first to not stress kmod */ 
-               if (!force && sk->flag_file) { 
-                       if (access(sk->flag_file, R_OK))
+               if (!force && af->flag_file) { 
+                       if (access(af->flag_file, R_OK))
                                continue; 
                }
-               sfd = socket(sk->family, SOCK_DGRAM, 0);
-               *(sk->varp) = sfd; 
+               sfd = socket(af->af, SOCK_DGRAM, 0);
+               af->fd = sfd; 
        } 
        if (sfd < 0)  
                fprintf(stderr, _("No usable address families found.\n"));
        return sfd;
 }
-
-