aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Blundell <philb@gnu.org>1998-11-14 10:37:04 +0000
committerPhil Blundell <philb@gnu.org>1998-11-14 10:37:04 +0000
commit3d2c31233e3cb25a905fe11a8dd0e6c9f441a333 (patch)
treec210699181c8a475db01835bf632a0050f8d9326
parentUpdate for snapshot (diff)
downloadnet-tools-3d2c31233e3cb25a905fe11a8dd0e6c9f441a333.tar.gz
net-tools-3d2c31233e3cb25a905fe11a8dd0e6c9f441a333.tar.bz2
net-tools-3d2c31233e3cb25a905fe11a8dd0e6c9f441a333.zip
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.
-rw-r--r--ifconfig.c112
-rw-r--r--interface.c93
-rw-r--r--lib/af.c18
-rw-r--r--lib/ax25.c4
-rw-r--r--lib/ddp.c4
-rw-r--r--lib/econet.c2
-rw-r--r--lib/inet.c4
-rw-r--r--lib/inet6.c5
-rw-r--r--lib/ipx.c4
-rw-r--r--lib/net-support.h7
-rw-r--r--lib/rose.c4
-rw-r--r--lib/unix.c6
-rw-r--r--sockets.c84
13 files changed, 187 insertions, 160 deletions
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 <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
@@ -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;
}
-
-