mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
Update.
1999-10-27 Andreas Jaeger <aj@suse.de> * sysdeps/generic/ifreq.h: New file. * resolv/res_hconf.c: Add missing includes to get all prototypes. (_res_hconf_reorder_addrs): Rewrite. This never worked before. Reported by John DiMarco <jdd@cs.toronto.edu>. (_res_hconf_reorder_addrs): Made thread safe. (free_mem): New function, needed for malloc debugging. 1999-10-29 Andreas Jaeger <aj@suse.de> * sysdeps/unix/sysv/linux/if_index.c (opensock): Move function to ... * sysdeps/generic/opensock.c (__opensock): ...here in a new file. * sysdeps/unix/sysv/linux/if_index.c: Change all callers of opensock to use __opensock. * socket/Makefile (routines): Add opensock. * include/sys/socket.h (__opensock): Add prototype declaration.
This commit is contained in:
parent
26d63253e1
commit
f720d3d212
22
ChangeLog
22
ChangeLog
@ -1,3 +1,25 @@
|
||||
1999-10-27 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/generic/ifreq.h: New file.
|
||||
|
||||
* resolv/res_hconf.c: Add missing includes to get all prototypes.
|
||||
(_res_hconf_reorder_addrs): Rewrite. This never worked before.
|
||||
Reported by John DiMarco <jdd@cs.toronto.edu>.
|
||||
|
||||
(_res_hconf_reorder_addrs): Made thread safe.
|
||||
(free_mem): New function, needed for malloc debugging.
|
||||
|
||||
1999-10-29 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/if_index.c (opensock): Move function to ...
|
||||
* sysdeps/generic/opensock.c (__opensock): ...here in a new file.
|
||||
* sysdeps/unix/sysv/linux/if_index.c: Change all callers of
|
||||
opensock to use __opensock.
|
||||
|
||||
* socket/Makefile (routines): Add opensock.
|
||||
|
||||
* include/sys/socket.h (__opensock): Add prototype declaration.
|
||||
|
||||
1999-10-29 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h: Added missing
|
||||
|
@ -3,4 +3,9 @@
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __socket (int __domain, int __type, int __protocol) __THROW;
|
||||
|
||||
/* Return a socket of any type. The socket can be used in subsequent
|
||||
ioctl calls to talk to the kernel. */
|
||||
extern int __opensock (void) internal_function;
|
||||
|
||||
#endif
|
||||
|
@ -17,9 +17,9 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file provides a Linux /etc/host.conf compatible front end to
|
||||
the various name resolvers (/etc/hosts, named, NIS server, etc.).
|
||||
Though mostly compatibly, the following differences exist compared
|
||||
to the original implementation:
|
||||
the various name resolvers (/etc/hosts, named, NIS server, etc.).
|
||||
Though mostly compatibly, the following differences exist compared
|
||||
to the original implementation:
|
||||
|
||||
- new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK
|
||||
environment variable (i.e., `off', `nowarn', or `warn').
|
||||
@ -27,13 +27,19 @@ to the original implementation:
|
||||
- line comments can appear anywhere (not just at the beginning of
|
||||
a line)
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include "ifreq.h"
|
||||
#include "res_hconf.h"
|
||||
|
||||
#define _PATH_HOSTCONF "/etc/host.conf"
|
||||
@ -374,113 +380,118 @@ _res_hconf_init (void)
|
||||
}
|
||||
|
||||
|
||||
/* List of known interfaces. */
|
||||
static struct netaddr
|
||||
{
|
||||
int addrtype;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int32_t addr;
|
||||
u_int32_t mask;
|
||||
} ipv4;
|
||||
} u;
|
||||
} *ifaddrs;
|
||||
|
||||
/* We need to protect the dynamic buffer handling. */
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
/* Reorder addresses returned in a hostent such that the first address
|
||||
is an address on the local subnet, if there is such an address.
|
||||
Otherwise, nothing is changed. */
|
||||
Otherwise, nothing is changed.
|
||||
|
||||
Note that this function currently only handles IPv4 addresses. */
|
||||
|
||||
void
|
||||
_res_hconf_reorder_addrs (struct hostent *hp)
|
||||
{
|
||||
#if defined SIOCGIFCONF && defined SIOCGIFNETMASK
|
||||
static int num_ifs = -1; /* number of interfaces */
|
||||
static struct netaddr
|
||||
{
|
||||
int addrtype;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u_int32_t addr;
|
||||
u_int32_t mask;
|
||||
} ipv4
|
||||
} u;
|
||||
} *ifaddrs;
|
||||
int i, j;
|
||||
/* Number of interfaces. */
|
||||
static int num_ifs = -1;
|
||||
|
||||
/* Only reorder if we're supposed to. */
|
||||
if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
|
||||
return;
|
||||
|
||||
/* Can't deal with anything but IPv4 for now... */
|
||||
if (hp->h_addrtype != AF_INET)
|
||||
return; /* can't deal with anything but IPv4 for now... */
|
||||
return;
|
||||
|
||||
if (num_ifs <= 0)
|
||||
{
|
||||
struct ifconf ifs;
|
||||
struct ifreq *ifr;
|
||||
size_t size, num;
|
||||
int sd;
|
||||
|
||||
/* initialize interface table: */
|
||||
struct ifreq *ifr, *cur_ifr;
|
||||
int sd, num, i;
|
||||
/* Save errno. */
|
||||
int save = errno;
|
||||
|
||||
/* Initialize interface table. */
|
||||
|
||||
num_ifs = 0;
|
||||
|
||||
sd = __socket (AF_INET, SOCK_DGRAM, 0);
|
||||
sd = __opensock ();
|
||||
if (sd < 0)
|
||||
return;
|
||||
|
||||
/* Now get list of interfaces. Since we don't know how many
|
||||
interfaces there are, we keep increasing the buffer size
|
||||
until we have at least sizeof(struct ifreq) too many bytes.
|
||||
That implies that the ioctl() return because it ran out of
|
||||
interfaces, not memory */
|
||||
size = 0;
|
||||
ifs.ifc_buf = 0;
|
||||
do
|
||||
{
|
||||
size += 4 * sizeof (struct ifreq);
|
||||
ifs.ifc_buf = realloc (ifs.ifs_buf, size);
|
||||
if (ifs.ifc_buf == NULL)
|
||||
{
|
||||
close (sd);
|
||||
return;
|
||||
}
|
||||
ifs.ifc_len = size;
|
||||
if (__ioctl (sd, SIOCGIFCONF, &ifs) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
while (size - ifs.ifc_len < sizeof (struct ifreq));
|
||||
/* Get lock. */
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
num = ifs.ifc_len / sizeof (struct ifreq);
|
||||
/* Get a list of interfaces. */
|
||||
__ifreq (&ifr, &num);
|
||||
if (!ifr)
|
||||
goto cleanup;
|
||||
|
||||
ifaddrs = malloc (num * sizeof (ifaddrs[0]));
|
||||
if (!ifaddrs)
|
||||
goto cleanup;
|
||||
|
||||
ifr = ifs.ifc_req;
|
||||
for (i = 0; i < num; ++i)
|
||||
goto cleanup1;
|
||||
|
||||
/* Copy usable interfaces in ifaddrs structure. */
|
||||
for (cur_ifr = ifr, i = 0; i < num; ++cur_ifr, ++i)
|
||||
{
|
||||
if (ifr->ifr_addr.sa_family != AF_INET)
|
||||
if (cur_ifr->ifr_addr.sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
ifaddrs[num_ifs].addrtype = AF_INET;
|
||||
ifaddrs[num_ifs].u.ipv4.addr =
|
||||
((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
|
||||
|
||||
memcpy (&ifaddrs[num_ifs].u.ipv4.addr,
|
||||
&((struct sockaddr_in *)ifr->ifr_addr)->sin_addr, 4);
|
||||
|
||||
if (__ioctl (sd, SIOCGIFNETMASK, if) < 0)
|
||||
if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
|
||||
continue;
|
||||
memcpy (&ifaddrs[num_ifs].u.ipv4.mask,
|
||||
((struct sockaddr_in *)ifr->ifr_mask)->sin_addr, 4);
|
||||
|
||||
++num_ifs; /* now we're committed to this entry */
|
||||
ifaddrs[num_ifs].u.ipv4.mask =
|
||||
((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
|
||||
|
||||
/* Now we're committed to this entry. */
|
||||
++num_ifs;
|
||||
}
|
||||
/* just keep enough memory to hold all the interfaces we want: */
|
||||
/* Just keep enough memory to hold all the interfaces we want. */
|
||||
ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
|
||||
|
||||
cleanup1:
|
||||
__if_freereq (ifr);
|
||||
|
||||
cleanup:
|
||||
/* Release lock, preserve error value, and close socket. */
|
||||
save = errno;
|
||||
__libc_lock_unlock (lock);
|
||||
close (sd);
|
||||
free (ifs.ifc_buf);
|
||||
}
|
||||
|
||||
if (num_ifs == 0)
|
||||
return;
|
||||
|
||||
/* find an address for which we have a direct connection: */
|
||||
/* Find an address for which we have a direct connection. */
|
||||
for (i = 0; hp->h_addr_list[i]; ++i)
|
||||
{
|
||||
h_addr = (struct in_addr *) hp->h_addr_list[i];
|
||||
struct in_addr *haddr = (struct in_addr *) hp->h_addr_list[i];
|
||||
|
||||
for (j = 0; j < num_ifs; ++j)
|
||||
{
|
||||
if_addr = ifaddrs[j].u.ipv4.addr;
|
||||
if_netmask = ifaddrs[j].u.ipv4.mask;
|
||||
u_int32_t if_addr = ifaddrs[j].u.ipv4.addr;
|
||||
u_int32_t if_netmask = ifaddrs[j].u.ipv4.mask;
|
||||
|
||||
if (((h_addr->s_addr ^ if_addr) & if_netmask) == 0)
|
||||
if (((haddr->s_addr ^ if_addr) & if_netmask) == 0)
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
@ -537,3 +548,14 @@ _res_hconf_trim_domains (struct hostent *hp)
|
||||
for (i = 0; hp->h_aliases[i]; ++i)
|
||||
_res_hconf_trim_domain (hp->h_aliases[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Free all resources if necessary. */
|
||||
static void __attribute__ ((unused))
|
||||
free_mem (void)
|
||||
{
|
||||
if (ifaddrs != NULL)
|
||||
free (ifaddrs);
|
||||
}
|
||||
|
||||
text_set_element (__libc_subfreeres, free_mem);
|
||||
|
@ -26,6 +26,6 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \
|
||||
|
||||
routines := accept bind connect getpeername getsockname getsockopt \
|
||||
listen recv recvfrom recvmsg send sendmsg sendto \
|
||||
setsockopt shutdown socket socketpair isfdtype
|
||||
setsockopt shutdown socket socketpair isfdtype opensock
|
||||
|
||||
include ../Rules
|
||||
|
76
sysdeps/generic/ifreq.h
Normal file
76
sysdeps/generic/ifreq.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
Contributed by Andreas Jaeger <aj@suse.de>.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
||||
static inline void
|
||||
__ifreq (struct ifreq **ifreqs, int *num_ifs)
|
||||
{
|
||||
int fd = __opensock ();
|
||||
struct ifconf ifc;
|
||||
int rq_len;
|
||||
int nifs;
|
||||
# define RQ_IFS 4
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
*num_ifs = 0;
|
||||
*ifreqs = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ifc.ifc_buf = NULL;
|
||||
rq_len = RQ_IFS * sizeof (struct ifreq);
|
||||
do
|
||||
{
|
||||
ifc.ifc_len = rq_len;
|
||||
ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
|
||||
if (ifc.ifc_buf == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
if (ifc.ifc_buf)
|
||||
free (ifc.ifc_buf);
|
||||
|
||||
__close (fd);
|
||||
*num_ifs = 0;
|
||||
*ifreqs = NULL;
|
||||
return;
|
||||
}
|
||||
rq_len *= 2;
|
||||
}
|
||||
while (rq_len < sizeof (struct ifreq) + ifc.ifc_len);
|
||||
|
||||
nifs = ifc.ifc_len / sizeof (struct ifreq);
|
||||
|
||||
__close (fd);
|
||||
|
||||
*num_ifs = nifs;
|
||||
*ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
__if_freereq (struct ifreq *ifreqs)
|
||||
{
|
||||
free (ifreqs);
|
||||
}
|
70
sysdeps/generic/opensock.c
Normal file
70
sysdeps/generic/opensock.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <bits/libc-lock.h>
|
||||
|
||||
/* Return a socket of any type. The socket can be used in subsequent
|
||||
ioctl calls to talk to the kernel. */
|
||||
int internal_function
|
||||
__opensock (void)
|
||||
{
|
||||
/* Cache the last AF that worked, to avoid many redundant calls to
|
||||
socket(). */
|
||||
static int sock_af = -1;
|
||||
int fd = -1;
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
if (sock_af != -1)
|
||||
{
|
||||
fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
}
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (sock_af != -1)
|
||||
fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
#ifdef AF_INET
|
||||
fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
#ifdef AF_INET6
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
#ifdef AF_IPX
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
#ifdef AF_AX25
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
#ifdef AF_APPLETALK
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
return fd;
|
||||
}
|
@ -35,47 +35,6 @@ static int old_siocgifconf;
|
||||
# define old_siocgifconf 0
|
||||
#endif
|
||||
|
||||
/* Try to get a socket to talk to the kernel. */
|
||||
#if defined SIOCGIFINDEX || defined SIOCGIFNAME
|
||||
static int
|
||||
internal_function
|
||||
opensock (void)
|
||||
{
|
||||
/* Cache the last AF that worked, to avoid many redundant calls to
|
||||
socket(). */
|
||||
static int sock_af = -1;
|
||||
int fd = -1;
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
if (sock_af != -1)
|
||||
{
|
||||
fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
}
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (sock_af != -1)
|
||||
fd = __socket (sock_af, SOCK_DGRAM, 0);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int
|
||||
if_nametoindex (const char *ifname)
|
||||
@ -85,7 +44,7 @@ if_nametoindex (const char *ifname)
|
||||
return 0;
|
||||
#else
|
||||
struct ifreq ifr;
|
||||
int fd = opensock ();
|
||||
int fd = __opensock ();
|
||||
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
@ -124,7 +83,7 @@ if_nameindex (void)
|
||||
__set_errno (ENOSYS);
|
||||
return NULL;
|
||||
#else
|
||||
int fd = opensock ();
|
||||
int fd = __opensock ();
|
||||
struct ifconf ifc;
|
||||
unsigned int nifs, i;
|
||||
int rq_len;
|
||||
@ -235,7 +194,7 @@ if_indextoname (unsigned int ifindex, char *ifname)
|
||||
# endif
|
||||
int status;
|
||||
|
||||
fd = opensock ();
|
||||
fd = __opensock ();
|
||||
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
@ -285,7 +244,7 @@ void
|
||||
internal_function
|
||||
__protocol_available (int *have_inet, int *have_inet6)
|
||||
{
|
||||
int fd = opensock ();
|
||||
int fd = __opensock ();
|
||||
unsigned int nifs;
|
||||
int rq_len;
|
||||
struct ifconf ifc;
|
||||
|
Loading…
Reference in New Issue
Block a user