now works with ip implementations that use sa_len in sockaddr
This commit is contained in:
87
interfaces.c
87
interfaces.c
@@ -30,8 +30,6 @@
|
|||||||
static char rcsid[] = "$Id$";
|
static char rcsid[] = "$Id$";
|
||||||
#endif /* lint */
|
#endif /* lint */
|
||||||
|
|
||||||
#define MAIN
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -86,6 +84,11 @@ static char rcsid[] = "$Id$";
|
|||||||
extern char *malloc __P((size_t));
|
extern char *malloc __P((size_t));
|
||||||
#endif /* !STDC_HEADERS && !__GNUC__ */
|
#endif /* !STDC_HEADERS && !__GNUC__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local prototypes
|
||||||
|
*/
|
||||||
|
static struct ifreq *next_if __P((struct ifreq *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
@@ -108,10 +111,10 @@ void load_interfaces()
|
|||||||
unsigned long localhost_mask;
|
unsigned long localhost_mask;
|
||||||
struct ifconf *ifconf;
|
struct ifconf *ifconf;
|
||||||
char ifconf_buf[sizeof(struct ifconf) + BUFSIZ];
|
char ifconf_buf[sizeof(struct ifconf) + BUFSIZ];
|
||||||
struct ifreq ifreq;
|
struct ifreq ifreq, *cur;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int sock, i, j;
|
int sock, n;
|
||||||
#ifdef _ISC
|
#ifdef _ISC
|
||||||
struct strioctl strioctl;
|
struct strioctl strioctl;
|
||||||
#endif /* _ISC */
|
#endif /* _ISC */
|
||||||
@@ -145,15 +148,14 @@ void load_interfaces()
|
|||||||
#endif /* _ISC */
|
#endif /* _ISC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find out how many interfaces exist
|
* get the maximum number of interfaces that *could* exist.
|
||||||
*/
|
*/
|
||||||
num_interfaces = ifconf->ifc_len / sizeof(struct ifreq);
|
n = ifconf->ifc_len / sizeof(struct ifreq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* malloc() space for interfaces array
|
* malloc() space for interfaces array
|
||||||
*/
|
*/
|
||||||
interfaces = (struct interface *) malloc(sizeof(struct interface) *
|
interfaces = (struct interface *) malloc(sizeof(struct interface) * n);
|
||||||
num_interfaces);
|
|
||||||
if (interfaces == NULL) {
|
if (interfaces == NULL) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
|
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
|
||||||
@@ -163,9 +165,11 @@ void load_interfaces()
|
|||||||
/*
|
/*
|
||||||
* for each interface, get the ip address and netmask
|
* for each interface, get the ip address and netmask
|
||||||
*/
|
*/
|
||||||
for (i = 0, j = 0; i < num_interfaces; i++) {
|
|
||||||
(void) strncpy(ifreq.ifr_name, ifconf->ifc_req[i].ifr_name,
|
cur = ifconf->ifc_req;
|
||||||
sizeof(ifreq.ifr_name));
|
do {
|
||||||
|
/* setup ifreq struct */
|
||||||
|
ifreq = *cur;
|
||||||
|
|
||||||
/* get the ip address */
|
/* get the ip address */
|
||||||
#ifdef _ISC
|
#ifdef _ISC
|
||||||
@@ -185,18 +189,15 @@ void load_interfaces()
|
|||||||
sin = (struct sockaddr_in *) &ifreq.ifr_addr;
|
sin = (struct sockaddr_in *) &ifreq.ifr_addr;
|
||||||
|
|
||||||
/* make sure we don't have a dupe (usually consecutive) */
|
/* make sure we don't have a dupe (usually consecutive) */
|
||||||
if (j > 0 && memcmp(&interfaces[j-1].addr, &(sin->sin_addr),
|
if (num_interfaces && interfaces[num_interfaces - 1].addr.s_addr ==
|
||||||
sizeof(sin->sin_addr)) == 0)
|
sin->sin_addr.s_addr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* store the ip address */
|
/* store the ip address */
|
||||||
(void) memcpy(&interfaces[j].addr, &(sin->sin_addr),
|
interfaces[num_interfaces].addr.s_addr = sin->sin_addr.s_addr;
|
||||||
sizeof(struct in_addr));
|
|
||||||
|
|
||||||
/* get the netmask */
|
/* get the netmask */
|
||||||
#ifdef SIOCGIFNETMASK
|
#ifdef SIOCGIFNETMASK
|
||||||
(void) strncpy(ifreq.ifr_name, ifconf->ifc_req[i].ifr_name,
|
|
||||||
sizeof(ifreq.ifr_name));
|
|
||||||
#ifdef _ISC
|
#ifdef _ISC
|
||||||
STRSET(SIOCGIFNETMASK, (caddr_t) &ifreq, sizeof(ifreq));
|
STRSET(SIOCGIFNETMASK, (caddr_t) &ifreq, sizeof(ifreq));
|
||||||
if (ioctl(sock, I_STR, (caddr_t) &strioctl) == 0) {
|
if (ioctl(sock, I_STR, (caddr_t) &strioctl) == 0) {
|
||||||
@@ -204,31 +205,30 @@ void load_interfaces()
|
|||||||
if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifreq) == 0) {
|
if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifreq) == 0) {
|
||||||
#endif /* _ISC */
|
#endif /* _ISC */
|
||||||
/* store the netmask */
|
/* store the netmask */
|
||||||
(void) memcpy(&interfaces[j].netmask, &(sin->sin_addr),
|
interfaces[num_interfaces].netmask.s_addr = sin->sin_addr.s_addr;
|
||||||
sizeof(struct in_addr));
|
|
||||||
} else {
|
} else {
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#endif /* SIOCGIFNETMASK */
|
#endif /* SIOCGIFNETMASK */
|
||||||
if (IN_CLASSC(interfaces[j].addr.s_addr))
|
if (IN_CLASSC(interfaces[num_interfaces].addr.s_addr))
|
||||||
interfaces[j].netmask.s_addr = htonl(IN_CLASSC_NET);
|
interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSC_NET);
|
||||||
else if (IN_CLASSB(interfaces[j].addr.s_addr))
|
else if (IN_CLASSB(interfaces[num_interfaces].addr.s_addr))
|
||||||
interfaces[j].netmask.s_addr = htonl(IN_CLASSB_NET);
|
interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSB_NET);
|
||||||
else
|
else
|
||||||
interfaces[j].netmask.s_addr = htonl(IN_CLASSA_NET);
|
interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSA_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* avoid localhost and friends */
|
/* avoid localhost and friends */
|
||||||
if ((interfaces[j].addr.s_addr & interfaces[j].netmask.s_addr) ==
|
if ((interfaces[num_interfaces].addr.s_addr &
|
||||||
localhost_mask)
|
interfaces[num_interfaces].netmask.s_addr) == localhost_mask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++j;
|
num_interfaces++;
|
||||||
}
|
} while ((cur = next_if(cur)) &&
|
||||||
|
(caddr_t) cur < (caddr_t) ifconf->ifc_req + ifconf->ifc_len);
|
||||||
|
|
||||||
/* if there were bogus entries, realloc the array */
|
/* if there were bogus entries, realloc the array */
|
||||||
if (i != j) {
|
if (n != num_interfaces) {
|
||||||
num_interfaces = j;
|
|
||||||
interfaces = (struct interface *) realloc(interfaces,
|
interfaces = (struct interface *) realloc(interfaces,
|
||||||
sizeof(struct interface) * num_interfaces);
|
sizeof(struct interface) * num_interfaces);
|
||||||
if (interfaces == NULL) {
|
if (interfaces == NULL) {
|
||||||
@@ -238,3 +238,30 @@ void load_interfaces()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
* next_if()
|
||||||
|
*
|
||||||
|
* This function returns a pointer to the next struct ifreq *
|
||||||
|
* in the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct ifreq *next_if(cur)
|
||||||
|
struct ifreq *cur;
|
||||||
|
{
|
||||||
|
struct ifreq *next;
|
||||||
|
u_char sa_len;
|
||||||
|
|
||||||
|
#ifdef HAVE_SA_LEN
|
||||||
|
sa_len = cur->ifr_addr.sa_len;
|
||||||
|
if (sa_len > sizeof(cur->ifr_ifru))
|
||||||
|
next = (struct ifreq *) ((caddr_t) cur + sizeof(cur->ifr_name) + sa_len);
|
||||||
|
else
|
||||||
|
#endif /* HAVE_SA_LEN */
|
||||||
|
next = (struct ifreq *) ((caddr_t) cur + sizeof(cur->ifr_name) + sizeof(cur->ifr_ifru));
|
||||||
|
|
||||||
|
return(next);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user