diff options
author | obrien <obrien@FreeBSD.org> | 1999-09-15 02:50:52 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-09-15 02:50:52 +0000 |
commit | 422815db966fe7dc38dfc5df2be5e83d5ea9f48c (patch) | |
tree | babaa2d3f02bbec865446438f974c81f18ae2607 /contrib/amd/libamu/wire.c | |
parent | c9384f1d982e4695904ef82271714a049cd32827 (diff) | |
download | FreeBSD-src-422815db966fe7dc38dfc5df2be5e83d5ea9f48c.zip FreeBSD-src-422815db966fe7dc38dfc5df2be5e83d5ea9f48c.tar.gz |
Virgin import of AMD (am-utils) v6.0.1
Diffstat (limited to 'contrib/amd/libamu/wire.c')
-rw-r--r-- | contrib/amd/libamu/wire.c | 443 |
1 files changed, 270 insertions, 173 deletions
diff --git a/contrib/amd/libamu/wire.c b/contrib/amd/libamu/wire.c index bd7b5ad..c8ed892 100644 --- a/contrib/amd/libamu/wire.c +++ b/contrib/amd/libamu/wire.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1998 Erez Zadok + * Copyright (c) 1997-1999 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -38,7 +38,7 @@ * * %W% (Berkeley) %G% * - * $Id: wire.c,v 1.1.1.1 1998/11/05 02:04:45 ezk Exp $ + * $Id: wire.c,v 1.5 1999/09/08 23:36:52 ezk Exp $ * */ @@ -61,6 +61,14 @@ #include <amu.h> +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif /* HAVE_IFADDRS_H */ + +#ifdef HAVE_IRS_H +# include <irs.h> +#endif /* HAVE_IRS_H */ + /* * List of locally connected networks */ @@ -78,16 +86,9 @@ static addrlist *localnets = NULL; # define IFF_LOOPBACK IFF_LOCAL_LOOPBACK #endif /* defined(IFF_LOCAL_LOOPBACK) && !defined(IFF_LOOPBACK) */ -#if defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) -# define SIZE(ifr) (MAX((ifr)->ifr_addr.sa_len, sizeof((ifr)->ifr_addr)) + sizeof(ifr->ifr_name)) -#else /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */ -# define SIZE(ifr) sizeof(struct ifreq) -#endif /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */ - #define C(x) ((x) & 0xff) #define GFBUFLEN 1024 -#define clist (ifc.ifc_ifcu.ifcu_req) -#define count (ifc.ifc_len/sizeof(struct ifreq)) +#define S2IN(s) (((struct sockaddr_in *)(s))->sin_addr.s_addr) /* return malloc'ed buffer. caller must free it */ @@ -101,7 +102,7 @@ print_wires(void) int bufcount = 0; int buf_size = 1024; - buf = malloc(1024); + buf = SALLOC(1024); if (!buf) return NULL; @@ -131,22 +132,262 @@ print_wires(void) } +static struct addrlist * +getwire_lookup(u_long address, u_long netmask, int ishost) +{ + struct addrlist *al; + u_long subnet; + char netNumberBuf[64]; + char buf[GFBUFLEN], *s; +#ifdef HAVE_IRS_H + struct nwent *np; +#else /* not HAVE_IRS_H */ + struct netent *np; +#endif /* not HAVE_IRS_H */ + + /* + * Add interface to local network singly linked list + */ + al = ALLOC(struct addrlist); + al->ip_addr = address; + al->ip_mask = netmask; + al->ip_net_name = NO_SUBNET; /* fill in a bit later */ + al->ip_net_num = "0.0.0.0"; /* fill in a bit later */ + al->ip_next = NULL; + + subnet = ntohl(address) & ntohl(netmask); + + if (ishost) + np = NULL; + else { +#ifdef HAVE_IRS_H + u_long mask = ntohl(netmask); + static struct irs_acc *irs_gen; + static struct irs_nw *irs_nw; + u_long net; + int maskbits; + u_char addr[4]; + + if (irs_gen == NULL) + irs_gen = irs_gen_acc(""); + if (irs_gen && irs_nw == NULL) + irs_nw = (*irs_gen->nw_map)(irs_gen); + net = ntohl(address) & (mask = ntohl(netmask)); + addr[0] = (0xFF000000 & net) >> 24; + addr[1] = (0x00FF0000 & net) >> 16; + addr[2] = (0x0000FF00 & net) >> 8; + addr[3] = (0x000000FF & net); + for (maskbits = 32; !(mask & 1); mask >>= 1) + maskbits--; + np = (*irs_nw->byaddr)(irs_nw, addr, maskbits, AF_INET); +#else /* not HAVE_IRS_H */ + np = getnetbyaddr(subnet, AF_INET); + /* + * Some systems (IRIX 6.4) cannot getnetbyaddr on networks such as + * "128.59.16.0". Instead, they need to look for the short form of + * the network, "128.59.16". So if the first getnetbyaddr failed, we + * shift the subnet way from zeros and try again. + */ + if (!np) { + u_long short_subnet = subnet; + while(short_subnet && (short_subnet & 0x000000ff) == 0) + short_subnet >>= 8; + np = getnetbyaddr(short_subnet, AF_INET); + if (np) + plog(XLOG_WARNING, "getnetbyaddr failed on 0x%x, succeeded on 0x%x", + (u_int) subnet, (u_int) short_subnet); + } +#endif /* not HAVE_IRS_H */ + } + + if ((subnet & 0xffffff) == 0) { + sprintf(netNumberBuf, "%lu", C(subnet >> 24)); + } else if ((subnet & 0xffff) == 0) { + sprintf(netNumberBuf, "%lu.%lu", + C(subnet >> 24), C(subnet >> 16)); + } else if ((subnet & 0xff) == 0) { + sprintf(netNumberBuf, "%lu.%lu.%lu", + C(subnet >> 24), C(subnet >> 16), + C(subnet >> 8)); + } else { + sprintf(netNumberBuf, "%lu.%lu.%lu.%lu", + C(subnet >> 24), C(subnet >> 16), + C(subnet >> 8), C(subnet)); + } + + /* fill in network number (string) */ + al->ip_net_num = strdup(netNumberBuf); + + if (np != NULL) + s = np->n_name; + else { + struct hostent *hp; + + subnet = address & netmask; + hp = gethostbyaddr((char *) &subnet, 4, AF_INET); + if (hp != NULL) + s = (char *) hp->h_name; + else + s = inet_dquad(buf, subnet); + } + + /* fill in network name (string) */ + al->ip_net_name = strdup(s); + + return (al); +} + + +/* + * Make a dotted quad from a 32bit IP address + * addr is in network byte order. + * sizeof(buf) needs to be at least 16. + */ +char * +inet_dquad(char *buf, u_long addr) +{ + addr = ntohl(addr); + sprintf(buf, "%ld.%ld.%ld.%ld", + ((addr >> 24) & 0xff), + ((addr >> 16) & 0xff), + ((addr >> 8) & 0xff), + ((addr >> 0) & 0xff)); + return buf; +} + + +/* + * Determine whether a network is on a local network + * (addr) is in network byte order. + */ +int +islocalnet(u_long addr) +{ + addrlist *al; +#ifdef DEBUG + char buf[16]; +#endif /* DEBUG */ + + for (al = localnets; al; al = al->ip_next) + if (((addr ^ al->ip_addr) & al->ip_mask) == 0) + return TRUE; + +#ifdef DEBUG + plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, addr)); +#endif /* DEBUG */ + + return FALSE; +} + + +/* + * Determine whether a network name is one of the local networks + * of a host. + */ +int +is_network_member(const char *net) +{ + addrlist *al; + + for (al = localnets; al; al = al->ip_next) + if (STREQ(net, al->ip_net_name) || STREQ(net, al->ip_net_num)) + return TRUE; + + return FALSE; +} + + +#ifdef HAVE_GETIFADDRS +void +getwire(char **name1, char **number1) +{ + addrlist *al = NULL, *tail = NULL; + struct ifaddrs *ifaddrs, *ifap; +#ifndef HAVE_FIELD_STRUCT_IFADDRS_IFA_NEXT + int count = 0, i; +#endif /* not HAVE_FIELD_STRUCT_IFADDRS_IFA_NEXT */ + + ifaddrs = NULL; +#ifdef HAVE_FIELD_STRUCT_IFADDRS_IFA_NEXT + if (getifaddrs(&ifaddrs) < 0) + goto out; + + for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next) { +#else /* not HAVE_FIELD_STRUCT_IFADDRS_IFA_NEXT */ + if (getifaddrs(&ifaddrs, &count) < 0) + goto out; + + for (i = 0,ifap = ifaddrs; i < count; ifap++, i++) { +#endif /* HAVE_FIELD_STRUCT_IFADDRS_IFA_NEXT */ + + if (!ifap || !ifap->ifa_addr || ifap->ifa_addr->sa_family != AF_INET) + continue; + + /* + * If the interface is a loopback, or its not running + * then ignore it. + */ + if ((ifap->ifa_flags & IFF_LOOPBACK) != 0) + continue; + if ((ifap->ifa_flags & IFF_RUNNING) == 0) + continue; + + if ((ifap->ifa_flags & IFF_POINTOPOINT) == 0) + al = getwire_lookup(S2IN(ifap->ifa_addr), S2IN(ifap->ifa_netmask), 0); + else + al = getwire_lookup(S2IN(ifap->ifa_dstaddr), 0xffffffff, 1); + + /* append to the end of the list */ + if (!localnets) { + localnets = tail = al; + tail->ip_next = NULL; + } else { + tail->ip_next = al; + tail = al; + } + } + +out: + if (ifaddrs) + XFREE(ifaddrs); + + if (localnets) { + *name1 = localnets->ip_net_name; + *number1 = localnets->ip_net_num; + } else { + *name1 = NO_SUBNET; + *number1 = "0.0.0.0"; + } +} + +#else /* not HAVE_GETIFADDRS */ + +#if defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) +# define SIZE(ifr) (MAX((ifr)->ifr_addr.sa_len, sizeof((ifr)->ifr_addr)) + sizeof(ifr->ifr_name)) +#else /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */ +# define SIZE(ifr) sizeof(struct ifreq) +#endif /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */ + +#define clist (ifc.ifc_ifcu.ifcu_req) +#define count (ifc.ifc_len/sizeof(struct ifreq)) + + void getwire(char **name1, char **number1) { - struct hostent *hp; - struct netent *np; struct ifconf ifc; struct ifreq *ifr; caddr_t cp, cplim; - u_long address, netmask, subnet; - char buf[GFBUFLEN], *s; int fd = -1; + u_long address; + addrlist *al = NULL, *tail = NULL; + char buf[GFBUFLEN]; +#if 0 u_long net; u_long mask; u_long subnetshift; - char netNumberBuf[64]; - addrlist *al = NULL, *tail = NULL; + char buf[GFBUFLEN], *s; +#endif #ifndef SIOCGIFFLAGS /* if cannot get interface flags, return nothing */ @@ -194,8 +435,8 @@ getwire(char **name1, char **number1) if (ifr->ifr_addr.sa_family != AF_INET) continue; - else - address = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + + address = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; /* * Get interface flags @@ -225,23 +466,17 @@ getwire(char **name1, char **number1) (ifr->ifr_flags & IFF_UP) == 0) continue; - /* - * Get the netmask of this interface - */ - if (ioctl(fd, SIOCGIFNETMASK, (caddr_t) ifr) < 0) - continue; + if ((ifr->ifr_flags & IFF_POINTOPOINT) == 0) { + /* + * Get the netmask of this interface + */ + if (ioctl(fd, SIOCGIFNETMASK, (caddr_t) ifr) < 0) + continue; - netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + al = getwire_lookup(address, S2IN(&ifr->ifr_addr), 0); + } else + al = getwire_lookup(address, 0xffffffff, 1); - /* - * Add interface to local network singly linked list - */ - al = ALLOC(struct addrlist); - al->ip_addr = address; - al->ip_mask = netmask; - al->ip_net_name = NO_SUBNET; /* fill in a bit later */ - al->ip_net_num = "0.0.0.0"; /* fill in a bit later */ - al->ip_next = NULL; /* append to the end of the list */ if (!localnets) { localnets = tail = al; @@ -250,86 +485,6 @@ getwire(char **name1, char **number1) tail->ip_next = al; tail = al; } - - /* - * Figure out the subnet's network address - */ - subnet = address & netmask; - -#ifdef IN_CLASSA - subnet = htonl(subnet); - - if (IN_CLASSA(subnet)) { - mask = IN_CLASSA_NET; - subnetshift = 8; - } else if (IN_CLASSB(subnet)) { - mask = IN_CLASSB_NET; - subnetshift = 8; - } else { - mask = IN_CLASSC_NET; - subnetshift = 4; - } - - /* - * If there are more bits than the standard mask - * would suggest, subnets must be in use. - * Guess at the subnet mask, assuming reasonable - * width subnet fields. - * XXX: Or-in at least 1 byte's worth of 1s to make - * sure the top bits remain set. - */ - while (subnet & ~mask) - mask = (mask >> subnetshift) | 0xff000000; - - net = subnet & mask; - while ((mask & 1) == 0) - mask >>= 1, net >>= 1; - - /* - * Now get a usable name. - * First use the network database, - * then the host database, - * and finally just make a dotted quad. - */ - np = getnetbyaddr(net, AF_INET); - - /* the network address has been masked off */ - if ((subnet & 0xffffff) == 0) { - sprintf(netNumberBuf, "%lu", C(subnet >> 24)); - } else if ((subnet & 0xffff) == 0) { - sprintf(netNumberBuf, "%lu.%lu", - C(subnet >> 24), C(subnet >> 16)); - } else if ((subnet & 0xff) == 0) { - sprintf(netNumberBuf, "%lu.%lu.%lu", - C(subnet >> 24), C(subnet >> 16), - C(subnet >> 8)); - } else { - sprintf(netNumberBuf, "%lu.%lu.%lu.%lu", - C(subnet >> 24), C(subnet >> 16), - C(subnet >> 8), C(subnet)); - } - - /* fill in network number (string) */ - al->ip_net_num = strdup(netNumberBuf); - -#else /* not IN_CLASSA */ - /* This is probably very wrong. */ - np = getnetbyaddr(subnet, AF_INET); -#endif /* not IN_CLASSA */ - - if (np) - s = np->n_name; - else { - subnet = address & netmask; - hp = gethostbyaddr((char *) &subnet, 4, AF_INET); - if (hp) - s = (char *) hp->h_name; - else - s = inet_dquad(buf, subnet); - } - - /* fill in network name (string) */ - al->ip_net_name = strdup(s); } out: @@ -343,62 +498,4 @@ out: *number1 = "0.0.0.0"; } } - - -/* - * Make a dotted quad from a 32bit IP address - * addr is in network byte order. - * sizeof(buf) needs to be at least 16. - */ -char * -inet_dquad(char *buf, u_long addr) -{ - addr = ntohl(addr); - sprintf(buf, "%ld.%ld.%ld.%ld", - ((addr >> 24) & 0xff), - ((addr >> 16) & 0xff), - ((addr >> 8) & 0xff), - ((addr >> 0) & 0xff)); - return buf; -} - - -/* - * Determine whether a network is on a local network - * (addr) is in network byte order. - */ -int -islocalnet(u_long addr) -{ - addrlist *al; -#ifdef DEBUG - char buf[16]; -#endif /* DEBUG */ - - for (al = localnets; al; al = al->ip_next) - if (((addr ^ al->ip_addr) & al->ip_mask) == 0) - return TRUE; - -#ifdef DEBUG - plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, addr)); -#endif /* DEBUG */ - - return FALSE; -} - - -/* - * Determine whether a network name is one of the local networks - * of a host. - */ -int -is_network_member(const char *net) -{ - addrlist *al; - - for (al = localnets; al; al = al->ip_next) - if (STREQ(net, al->ip_net_name) || STREQ(net, al->ip_net_num)) - return TRUE; - - return FALSE; -} +#endif /* not HAVE_GETIFADDRS */ |