add getifaddrs(3) from bsdi. this is a magic function which lets you grab
interface addresses in a portable manner, without headache of SIOCGIFCONF or sysctl. it is in bsdi/openbsd/netbsd already. from kame tree (actually, mandatory for latest kame tree).
This commit is contained in:
parent
3b8a8567a1
commit
23ba01423e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=62606
@ -10,7 +10,7 @@ CLEANFILES= osreldate.h version vers.c
|
|||||||
SUBDIR= rpcsvc
|
SUBDIR= rpcsvc
|
||||||
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
|
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
|
||||||
dlfcn.h elf.h err.h fnmatch.h fstab.h \
|
dlfcn.h elf.h err.h fnmatch.h fstab.h \
|
||||||
fts.h glob.h grp.h strhash.h histedit.h ieeefp.h iso646.h \
|
fts.h glob.h grp.h strhash.h histedit.h ieeefp.h ifaddrs.h iso646.h \
|
||||||
limits.h link.h locale.h malloc.h memory.h mpool.h \
|
limits.h link.h locale.h malloc.h memory.h mpool.h \
|
||||||
ndbm.h netdb.h nl_types.h nlist.h objformat.h \
|
ndbm.h netdb.h nl_types.h nlist.h objformat.h \
|
||||||
paths.h pthread.h pthread_np.h pwd.h \
|
paths.h pthread.h pthread_np.h pwd.h \
|
||||||
|
56
include/ifaddrs.h
Normal file
56
include/ifaddrs.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1999
|
||||||
|
* Berkeley Software Design, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IFADDRS_H_
|
||||||
|
#define _IFADDRS_H_
|
||||||
|
|
||||||
|
struct ifaddrs {
|
||||||
|
struct ifaddrs *ifa_next;
|
||||||
|
char *ifa_name;
|
||||||
|
u_int ifa_flags;
|
||||||
|
struct sockaddr *ifa_addr;
|
||||||
|
struct sockaddr *ifa_netmask;
|
||||||
|
struct sockaddr *ifa_dstaddr;
|
||||||
|
void *ifa_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
|
||||||
|
* to be included it must be included before this header file.
|
||||||
|
*/
|
||||||
|
#ifndef ifa_broadaddr
|
||||||
|
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
extern int getifaddrs __P((struct ifaddrs **));
|
||||||
|
extern void freeifaddrs __P((struct ifaddrs *));
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c getaddrinfo.c \
|
SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c getaddrinfo.c \
|
||||||
gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
|
gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
|
||||||
getnameinfo.c \
|
getifaddrs.c getnameinfo.c \
|
||||||
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
|
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
|
||||||
getproto.c getprotoent.c getprotoname.c getservbyname.c \
|
getproto.c getprotoent.c getprotoname.c getservbyname.c \
|
||||||
getservbyport.c getservent.c herror.c inet_addr.c ifname.c \
|
getservbyport.c getservent.c herror.c inet_addr.c ifname.c \
|
||||||
@ -28,7 +28,7 @@ CFLAGS+=-DINET6
|
|||||||
|
|
||||||
.if ${LIB} == "c"
|
.if ${LIB} == "c"
|
||||||
MAN3+= addr2ascii.3 byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 \
|
MAN3+= addr2ascii.3 byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 \
|
||||||
getipnodebyname.3 \
|
getifaddrs.3 getipnodebyname.3 \
|
||||||
getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
|
getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
|
||||||
inet.3 inet6_option_space.3 inet6_rthdr_space.3 linkaddr.3 \
|
inet.3 inet6_option_space.3 inet6_rthdr_space.3 linkaddr.3 \
|
||||||
rcmd.3 resolver.3
|
rcmd.3 resolver.3
|
||||||
@ -44,6 +44,7 @@ MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
|
|||||||
gethostbyname.3 gethostbyname2.3 gethostbyname.3 gethostent.3 \
|
gethostbyname.3 gethostbyname2.3 gethostbyname.3 gethostent.3 \
|
||||||
gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \
|
gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \
|
||||||
gethostbyname.3 sethostent.3
|
gethostbyname.3 sethostent.3
|
||||||
|
MLINKS+=getifaddrs.3 freeifaddrs.3
|
||||||
MLINKS+=getipnodebyname.3 getipnodebyaddr.3 getipnodebyname.3 freehostent.3
|
MLINKS+=getipnodebyname.3 getipnodebyaddr.3 getipnodebyname.3 freehostent.3
|
||||||
MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
|
MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
|
||||||
getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
|
getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
|
||||||
|
163
lib/libc/net/getifaddrs.3
Normal file
163
lib/libc/net/getifaddrs.3
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
.\" $FreeBSD$
|
||||||
|
.\" $KAME: getifaddrs.3,v 1.4 2000/05/17 14:13:14 itojun Exp $
|
||||||
|
.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1995, 1999
|
||||||
|
.\" Berkeley Software Design, Inc. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.Dd "October 12, 1995"
|
||||||
|
.Dt GETIFADDRS 3
|
||||||
|
.Sh NAME
|
||||||
|
.Nm getifaddrs
|
||||||
|
.Nd get interface addresses
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Fd #include <sys/types.h>
|
||||||
|
.Fd #include <sys/socket.h>
|
||||||
|
.Fd #include <ifaddrs.h>
|
||||||
|
.Ft int
|
||||||
|
.Fn getifaddrs "struct ifaddrs **ifap"
|
||||||
|
.Ft void
|
||||||
|
.Fn freeifaddrs "struct ifaddrs *ifp"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn getifaddrs
|
||||||
|
function stores a reference to a linked list of the network interfaces
|
||||||
|
on the local machine in the memory referenced by
|
||||||
|
.Fa ifap .
|
||||||
|
The list consists of
|
||||||
|
.Nm ifaddrs
|
||||||
|
structures, as defined in the include file
|
||||||
|
.Aq Pa ifaddrs.h .
|
||||||
|
The
|
||||||
|
.Nm ifaddrs
|
||||||
|
structure contains at least the following entries:
|
||||||
|
.Bd -literal
|
||||||
|
struct ifaddrs *ifa_next; /* Pointer to next struct */
|
||||||
|
char *ifa_name; /* Interface name */
|
||||||
|
u_int ifa_flags; /* Interface flags */
|
||||||
|
struct sockaddr *ifa_addr; /* Interface address */
|
||||||
|
struct sockaddr *ifa_netmask; /* Interface netmask */
|
||||||
|
struct sockaddr *ifa_broadaddr; /* Interface broadcast address */
|
||||||
|
struct sockaddr *ifa_dstaddr; /* P2P interface destination */
|
||||||
|
void *ifa_data; /* Address specific data */
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_next
|
||||||
|
field contains a pointer to the next structure on the list.
|
||||||
|
This field is
|
||||||
|
.Dv NULL
|
||||||
|
in last structure on the list.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_name
|
||||||
|
field contains the interface name.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_flags
|
||||||
|
field contains the interface flags, as set by
|
||||||
|
.Xr ifconfig 8
|
||||||
|
utility.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_addr
|
||||||
|
field references either the address of the interface or the link level
|
||||||
|
address of the interface, if one exists, otherwise it is NULL.
|
||||||
|
(The
|
||||||
|
.Li sa_family
|
||||||
|
field of the
|
||||||
|
.Li ifa_addr
|
||||||
|
field should be consulted to determine the format of the
|
||||||
|
.Li ifa_addr
|
||||||
|
address.)
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_netmask
|
||||||
|
field references the netmask associated with
|
||||||
|
.Li ifa_addr ,
|
||||||
|
if one is set, otherwise it is NULL.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_broadaddr
|
||||||
|
field,
|
||||||
|
which should only be referenced for non-P2P interfaces,
|
||||||
|
references the broadcast address associated with
|
||||||
|
.Li ifa_addr ,
|
||||||
|
if one exists, otherwise it is NULL.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_dstaddr
|
||||||
|
field references the destination address on a P2P interface,
|
||||||
|
if one exists, otherwise it is NULL.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Li ifa_data
|
||||||
|
field references address family specific data. For
|
||||||
|
.Dv AF_LINK
|
||||||
|
addresses it contains a pointer to the
|
||||||
|
.Fa struct if_data
|
||||||
|
.Pq as defined in include file Aq Pa net/if.h
|
||||||
|
which contains various interface attributes and statistics.
|
||||||
|
For all other address families, it contains a pointer to the
|
||||||
|
.Fa struct ifa_data
|
||||||
|
.Pq as defined in include file Aq Pa net/if.h
|
||||||
|
which contains per-address interface statistics.
|
||||||
|
.Pp
|
||||||
|
The data returned by
|
||||||
|
.Fn getifaddrs
|
||||||
|
is dynamically allocated and should be freed using
|
||||||
|
.Fn freeifaddrs
|
||||||
|
when no longer needed.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Upon successful completion, a value of 0 is returned.
|
||||||
|
Otherwise, a value of -1 is returned and
|
||||||
|
.Va errno
|
||||||
|
is set to indicate the error.
|
||||||
|
.Sh ERRORS
|
||||||
|
The
|
||||||
|
.Fn getifaddrs
|
||||||
|
may fail and set
|
||||||
|
.Va errno
|
||||||
|
for any of the errors specified for the library routines
|
||||||
|
.Xr ioctl 2 ,
|
||||||
|
.Xr socket 2 ,
|
||||||
|
.Xr malloc 3
|
||||||
|
or
|
||||||
|
.Xr sysctl 3 .
|
||||||
|
.Sh BUGS
|
||||||
|
If both
|
||||||
|
.Aq Pa net/if.h
|
||||||
|
and
|
||||||
|
.Aq Pa ifaddrs.h
|
||||||
|
are being included,
|
||||||
|
.Aq Pa net/if.h
|
||||||
|
.Em must
|
||||||
|
be included before
|
||||||
|
.Aq Pa ifaddrs.h .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ioctl 2 ,
|
||||||
|
.Xr socket 2 ,
|
||||||
|
.Xr sysctl 3 ,
|
||||||
|
.Xr networking 4 ,
|
||||||
|
.Xr ifconfig 8
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
implementation first appeared in BSDI BSD/OS.
|
379
lib/libc/net/getifaddrs.c
Normal file
379
lib/libc/net/getifaddrs.c
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1999
|
||||||
|
* Berkeley Software Design, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* NOTE: SIOCGIFCONF case is not LP64 friendly. it also does not perform
|
||||||
|
* try-and-error for region size.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#ifdef NET_RT_IFLIST
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if !defined(AF_LINK)
|
||||||
|
#define SA_LEN(sa) sizeof(struct sockaddr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SA_LEN)
|
||||||
|
#define SA_LEN(sa) (sa)->sa_len
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SALIGN (sizeof(long) - 1)
|
||||||
|
#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
|
||||||
|
|
||||||
|
#ifndef ALIGNBYTES
|
||||||
|
/*
|
||||||
|
* On systems with a routing socket, ALIGNBYTES should match the value
|
||||||
|
* that the kernel uses when building the messages.
|
||||||
|
*/
|
||||||
|
#define ALIGNBYTES XXX
|
||||||
|
#endif
|
||||||
|
#ifndef ALIGN
|
||||||
|
#define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _BSDI_VERSION >= 199701
|
||||||
|
#define HAVE_IFM_DATA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _BSDI_VERSION >= 199802
|
||||||
|
#define HAVE_IFAM_DATA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
getifaddrs(struct ifaddrs **pif)
|
||||||
|
{
|
||||||
|
int icnt = 1;
|
||||||
|
int dcnt = 0;
|
||||||
|
int ncnt = 0;
|
||||||
|
#ifdef NET_RT_IFLIST
|
||||||
|
int mib[6];
|
||||||
|
size_t needed;
|
||||||
|
char *buf;
|
||||||
|
char *next;
|
||||||
|
struct ifaddrs *cif = 0;
|
||||||
|
char *p, *p0;
|
||||||
|
struct rt_msghdr *rtm;
|
||||||
|
struct if_msghdr *ifm;
|
||||||
|
struct ifa_msghdr *ifam;
|
||||||
|
struct sockaddr_dl *dl;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
struct ifaddrs *ifa, *ift;
|
||||||
|
u_short index = 0;
|
||||||
|
#else /* NET_RT_IFLIST */
|
||||||
|
char buf[1024];
|
||||||
|
int m, sock;
|
||||||
|
struct ifconf ifc;
|
||||||
|
struct ifreq *ifr;
|
||||||
|
struct ifreq *lifr;
|
||||||
|
#endif /* NET_RT_IFLIST */
|
||||||
|
int i;
|
||||||
|
size_t len, alen;
|
||||||
|
char *data;
|
||||||
|
char *names;
|
||||||
|
|
||||||
|
#ifdef NET_RT_IFLIST
|
||||||
|
mib[0] = CTL_NET;
|
||||||
|
mib[1] = PF_ROUTE;
|
||||||
|
mib[2] = 0; /* protocol */
|
||||||
|
mib[3] = 0; /* wildcard address family */
|
||||||
|
mib[4] = NET_RT_IFLIST;
|
||||||
|
mib[5] = 0; /* no flags */
|
||||||
|
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||||
|
return (-1);
|
||||||
|
if ((buf = malloc(needed)) == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
||||||
|
free(buf);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
|
||||||
|
rtm = (struct rt_msghdr *)next;
|
||||||
|
if (rtm->rtm_version != RTM_VERSION)
|
||||||
|
continue;
|
||||||
|
switch (rtm->rtm_type) {
|
||||||
|
case RTM_IFINFO:
|
||||||
|
ifm = (struct if_msghdr *)rtm;
|
||||||
|
if (ifm->ifm_addrs & RTA_IFP) {
|
||||||
|
index = ifm->ifm_index;
|
||||||
|
++icnt;
|
||||||
|
dl = (struct sockaddr_dl *)(ifm + 1);
|
||||||
|
dcnt += SA_RLEN((struct sockaddr *)dl) +
|
||||||
|
ALIGNBYTES;
|
||||||
|
#ifdef HAVE_IFM_DATA
|
||||||
|
dcnt += sizeof(ifm->ifm_data);
|
||||||
|
#endif /* HAVE_IFM_DATA */
|
||||||
|
ncnt += dl->sdl_nlen + 1;
|
||||||
|
} else
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
ifam = (struct ifa_msghdr *)rtm;
|
||||||
|
if (index && ifam->ifam_index != index)
|
||||||
|
abort(); /* this cannot happen */
|
||||||
|
|
||||||
|
#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD)
|
||||||
|
if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
|
||||||
|
break;
|
||||||
|
p = (char *)(ifam + 1);
|
||||||
|
++icnt;
|
||||||
|
#ifdef HAVE_IFAM_DATA
|
||||||
|
dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES;
|
||||||
|
#endif /* HAVE_IFAM_DATA */
|
||||||
|
/* Scan to look for length of address */
|
||||||
|
alen = 0;
|
||||||
|
for (p0 = p, i = 0; i < RTAX_MAX; i++) {
|
||||||
|
if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
|
||||||
|
== 0)
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr *)p;
|
||||||
|
len = SA_RLEN(sa);
|
||||||
|
if (i == RTAX_IFA) {
|
||||||
|
alen = len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
for (p = p0, i = 0; i < RTAX_MAX; i++) {
|
||||||
|
if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
|
||||||
|
== 0)
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr *)p;
|
||||||
|
len = SA_RLEN(sa);
|
||||||
|
if (i == RTAX_NETMASK && SA_LEN(sa) == 0)
|
||||||
|
dcnt += alen;
|
||||||
|
else
|
||||||
|
dcnt += len;
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* NET_RT_IFLIST */
|
||||||
|
ifc.ifc_buf = buf;
|
||||||
|
ifc.ifc_len = sizeof(buf);
|
||||||
|
|
||||||
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
return (-1);
|
||||||
|
i = ioctl(sock, SIOCGIFCONF, (char *)&ifc);
|
||||||
|
close(sock);
|
||||||
|
if (i < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ifr = ifc.ifc_req;
|
||||||
|
lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
|
||||||
|
|
||||||
|
while (ifr < lifr) {
|
||||||
|
struct sockaddr *sa;
|
||||||
|
|
||||||
|
sa = &ifr->ifr_addr;
|
||||||
|
++icnt;
|
||||||
|
dcnt += SA_RLEN(sa);
|
||||||
|
ncnt += sizeof(ifr->ifr_name) + 1;
|
||||||
|
|
||||||
|
ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
|
||||||
|
}
|
||||||
|
#endif /* NET_RT_IFLIST */
|
||||||
|
|
||||||
|
if (icnt + dcnt + ncnt == 1) {
|
||||||
|
*pif = NULL;
|
||||||
|
free(buf);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
|
||||||
|
if (data == NULL) {
|
||||||
|
free(buf);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ifa = (struct ifaddrs *)data;
|
||||||
|
data += sizeof(struct ifaddrs) * icnt;
|
||||||
|
names = data + dcnt;
|
||||||
|
|
||||||
|
memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
|
||||||
|
ift = ifa;
|
||||||
|
|
||||||
|
#ifdef NET_RT_IFLIST
|
||||||
|
index = 0;
|
||||||
|
for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
|
||||||
|
rtm = (struct rt_msghdr *)next;
|
||||||
|
if (rtm->rtm_version != RTM_VERSION)
|
||||||
|
continue;
|
||||||
|
switch (rtm->rtm_type) {
|
||||||
|
case RTM_IFINFO:
|
||||||
|
ifm = (struct if_msghdr *)rtm;
|
||||||
|
if (ifm->ifm_addrs & RTA_IFP) {
|
||||||
|
index = ifm->ifm_index;
|
||||||
|
dl = (struct sockaddr_dl *)(ifm + 1);
|
||||||
|
|
||||||
|
cif = ift;
|
||||||
|
ift->ifa_name = names;
|
||||||
|
ift->ifa_flags = (int)ifm->ifm_flags;
|
||||||
|
memcpy(names, dl->sdl_data, dl->sdl_nlen);
|
||||||
|
names[dl->sdl_nlen] = 0;
|
||||||
|
names += dl->sdl_nlen + 1;
|
||||||
|
|
||||||
|
ift->ifa_addr = (struct sockaddr *)data;
|
||||||
|
memcpy(data, dl, SA_LEN((struct sockaddr *)dl));
|
||||||
|
data += SA_RLEN((struct sockaddr *)dl);
|
||||||
|
|
||||||
|
#ifdef HAVE_IFM_DATA
|
||||||
|
/* ifm_data needs to be aligned */
|
||||||
|
ift->ifa_data = data = (void *)ALIGN(data);
|
||||||
|
memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
|
||||||
|
data += sizeof(ifm->ifm_data);
|
||||||
|
#else /* HAVE_IFM_DATA */
|
||||||
|
ift->ifa_data = NULL;
|
||||||
|
#endif /* HAVE_IFM_DATA */
|
||||||
|
|
||||||
|
ift = (ift->ifa_next = ift + 1);
|
||||||
|
} else
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
ifam = (struct ifa_msghdr *)rtm;
|
||||||
|
if (index && ifam->ifam_index != index)
|
||||||
|
abort(); /* this cannot happen */
|
||||||
|
|
||||||
|
if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
|
||||||
|
break;
|
||||||
|
ift->ifa_name = cif->ifa_name;
|
||||||
|
ift->ifa_flags = cif->ifa_flags;
|
||||||
|
ift->ifa_data = NULL;
|
||||||
|
p = (char *)(ifam + 1);
|
||||||
|
/* Scan to look for length of address */
|
||||||
|
alen = 0;
|
||||||
|
for (p0 = p, i = 0; i < RTAX_MAX; i++) {
|
||||||
|
if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
|
||||||
|
== 0)
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr *)p;
|
||||||
|
len = SA_RLEN(sa);
|
||||||
|
if (i == RTAX_IFA) {
|
||||||
|
alen = len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
for (p = p0, i = 0; i < RTAX_MAX; i++) {
|
||||||
|
if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
|
||||||
|
== 0)
|
||||||
|
continue;
|
||||||
|
sa = (struct sockaddr *)p;
|
||||||
|
len = SA_RLEN(sa);
|
||||||
|
switch (i) {
|
||||||
|
case RTAX_IFA:
|
||||||
|
ift->ifa_addr = (struct sockaddr *)data;
|
||||||
|
memcpy(data, p, len);
|
||||||
|
data += len;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTAX_NETMASK:
|
||||||
|
ift->ifa_netmask =
|
||||||
|
(struct sockaddr *)data;
|
||||||
|
if (SA_LEN(sa) == 0) {
|
||||||
|
memset(data, 0, alen);
|
||||||
|
data += alen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(data, p, len);
|
||||||
|
data += len;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTAX_BRD:
|
||||||
|
ift->ifa_broadaddr =
|
||||||
|
(struct sockaddr *)data;
|
||||||
|
memcpy(data, p, len);
|
||||||
|
data += len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_IFAM_DATA
|
||||||
|
/* ifam_data needs to be aligned */
|
||||||
|
ift->ifa_data = data = (void *)ALIGN(data);
|
||||||
|
memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data));
|
||||||
|
data += sizeof(ifam->ifam_data);
|
||||||
|
#endif /* HAVE_IFAM_DATA */
|
||||||
|
|
||||||
|
ift = (ift->ifa_next = ift + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
#else /* NET_RT_IFLIST */
|
||||||
|
ifr = ifc.ifc_req;
|
||||||
|
lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
|
||||||
|
|
||||||
|
while (ifr < lifr) {
|
||||||
|
struct sockaddr *sa;
|
||||||
|
|
||||||
|
ift->ifa_name = names;
|
||||||
|
names[sizeof(ifr->ifr_name)] = 0;
|
||||||
|
strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name));
|
||||||
|
while (*names++)
|
||||||
|
;
|
||||||
|
|
||||||
|
ift->ifa_addr = (struct sockaddr *)data;
|
||||||
|
sa = &ifr->ifr_addr;
|
||||||
|
memcpy(data, sa, SA_LEN(sa));
|
||||||
|
data += SA_RLEN(sa);
|
||||||
|
|
||||||
|
ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
|
||||||
|
ift = (ift->ifa_next = ift + 1);
|
||||||
|
}
|
||||||
|
#endif /* NET_RT_IFLIST */
|
||||||
|
if (--ift >= ifa) {
|
||||||
|
ift->ifa_next = NULL;
|
||||||
|
*pif = ifa;
|
||||||
|
} else {
|
||||||
|
*pif = NULL;
|
||||||
|
free(ifa);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freeifaddrs(struct ifaddrs *ifp)
|
||||||
|
{
|
||||||
|
free(ifp);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user