From: Phil Blundell Date: Sat, 14 Nov 1998 10:37:04 +0000 (+0000) Subject: Rework socket handling again. Rather than X-Git-Tag: v1.60~185 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d2c31233e3cb25a905fe11a8dd0e6c9f441a333;p=platform%2Fupstream%2Fnet-tools.git Rework socket handling again. Rather than 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. --- diff --git a/ifconfig.c b/ifconfig.c index 14b9e82..1d1f467 100644 --- a/ifconfig.c +++ b/ifconfig.c @@ -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); } diff --git a/interface.c b/interface.c index 0b1bdc8..53c0827 100644 --- a/interface.c +++ b/interface.c @@ -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 diff --git a/lib/af.c b/lib/af.c index b732de6..c9b79e9 100644 --- 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) { diff --git a/lib/ax25.c b/lib/ax25.c index 506a132..0260a0f 100644 --- a/lib/ax25.c +++ b/lib/ax25.c @@ -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 */ diff --git a/lib/ddp.c b/lib/ddp.c index 014e9e4..81f4eb3 100644 --- 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 diff --git a/lib/econet.c b/lib/econet.c index 4ba7668..faf0246 100644 --- a/lib/econet.c +++ b/lib/econet.c @@ -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 }; diff --git a/lib/inet.c b/lib/inet.c index 7da5b6a..e35c504 100644 --- a/lib/inet.c +++ b/lib/inet.c @@ -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 */ diff --git a/lib/inet6.c b/lib/inet6.c index 076bfc5..564de85 100644 --- a/lib/inet6.c +++ b/lib/inet6.c @@ -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" }; diff --git a/lib/ipx.c b/lib/ipx.c index dfd8873..09bbb3c 100644 --- 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 diff --git a/lib/net-support.h b/lib/net-support.h index 2b97d5f..435d511 100644 --- a/lib/net-support.h +++ b/lib/net-support.h @@ -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); diff --git a/lib/rose.c b/lib/rose.c index fe14fd6..7c6b753 100644 --- a/lib/rose.c +++ b/lib/rose.c @@ -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 */ diff --git a/lib/unix.c b/lib/unix.c index f7b98bb..50d3bac 100644 --- a/lib/unix.c +++ b/lib/unix.c @@ -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, }; diff --git a/sockets.c b/sockets.c index e185ae5..dfacb83 100644 --- 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 #include #include @@ -8,66 +14,13 @@ #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; } - -