memset(d, 0, sizeof(struct lu_dict));
if (s->s_name != NULL) d->name = strdup(s->s_name);
- sprintf(str, "%u", s->s_port);
+ sprintf(str, "%u", ntohl(s->s_port));
d->port = strdup(str);
if (s->s_proto != NULL) d->protocol = strdup(s->s_proto);
while (a != NULL)
{
next = a->ai_next;
+ if (a->ai_addr != NULL) free(a->ai_addr);
if (a->ai_canonname != NULL) free(a->ai_canonname);
free(a);
a = next;
gai_serv(const char *servname, const struct addrinfo *hints, struct addrinfo **res)
{
struct lu_dict *list, *d;
- int port, proto, family, socktype, setcname, wantv4, wantv6;
+ int proto, family, socktype, setcname, wantv4, wantv6;
+ unsigned short port;
char *loopv4, *loopv6;
struct addrinfo *a;
struct in_addr a4;
/* We only want records with port and protocol specified */
if ((d->port == NULL) || (d->protocol == NULL)) continue;
- port = atoi(d->port);
+ port = htons(atoi(d->port));
proto = IPPROTO_UDP;
socktype = SOCK_DGRAM;
if (!strcasecmp(d->protocol, "tcp"))
}
static void
-gai_node_pp(const char *nodename, int port, int proto, int family, int setcname, struct addrinfo **res)
+gai_node_pp(const char *nodename, unsigned short port, int proto, int family, int setcname, struct addrinfo **res)
{
struct lu_dict *list, *d;
int i, wantv4, wantv6, a_list_count, socktype;
gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
{
struct lu_dict *srv_list, *node_list, *s, *n;
- int numerichost, family, port, proto, setcname;
+ int numerichost, family, proto, setcname;
int wantv4, wantv6, i, j, gotmx, p_list_count;
+ unsigned short port;
char *cname;
struct sockaddr **p_list;
struct sockaddr_in *sa4;
if (s->port == NULL) continue;
if (s->protocol == NULL) continue;
- i = atoi(s->port);
+ i = htons(atoi(s->port));
j = IPPROTO_UDP;
if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP;
gai_node_pp(s->target, i, j, family, setcname, res);
if (s->port == NULL) continue;
if (s->protocol == NULL) continue;
- i = atoi(s->port);
+ i = htons(atoi(s->port));
j = IPPROTO_UDP;
if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP;
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
+#include <unistd.h>
#define forever for (;;)
static struct passwd _pw = { 0 };
static FILE *_pfp;
static int _pwStayOpen;
+static int _pwFileFormat = 1;
static void
free_pw()
parseUser(char *data)
{
char **tokens;
+ int ntokens;
if (data == NULL) return NULL;
tokens = tokenize(data, ":");
- if (listLength(tokens) != 10)
+ ntokens = listLength(tokens);
+ if (( _pwFileFormat && (ntokens != 10)) ||
+ (!_pwFileFormat && (ntokens != 7)))
{
freeList(tokens);
return NULL;
free(tokens[2]);
_pw.pw_gid = atoi(tokens[3]);
free(tokens[3]);
- _pw.pw_class = tokens[4];
- _pw.pw_change = atoi(tokens[5]);
- free(tokens[5]);
- _pw.pw_expire = atoi(tokens[6]);
- free(tokens[6]);
- _pw.pw_gecos = tokens[7];
- _pw.pw_dir = tokens[8];
- _pw.pw_shell = tokens[9];
+
+ if (_pwFileFormat)
+ {
+ _pw.pw_class = tokens[4];
+ _pw.pw_change = atoi(tokens[5]);
+ free(tokens[5]);
+ _pw.pw_expire = atoi(tokens[6]);
+ free(tokens[6]);
+ _pw.pw_gecos = tokens[7];
+ _pw.pw_dir = tokens[8];
+ _pw.pw_shell = tokens[9];
+ }
+ else
+ {
+ _pw.pw_class = copyString("");
+ _pw.pw_change = 0;
+ _pw.pw_expire = 0;
+ _pw.pw_gecos = tokens[4];
+ _pw.pw_dir = tokens[5];
+ _pw.pw_shell = tokens[6];
+ }
free(tokens);
{
if (_pfp == NULL)
{
- _pfp = fopen(_PATH_MASTERPASSWD, "r");
+ char *pwFile;
+ if (geteuid() == 0)
+ {
+ pwFile = _PATH_MASTERPASSWD;
+ }
+ else
+ {
+ pwFile = _PATH_PASSWD;
+ _pwFileFormat = 0;
+ }
+ _pfp = fopen(pwFile, "r");
if (_pfp == NULL)
{
- perror(_PATH_MASTERPASSWD);
+ perror(pwFile);
return(0);
}
}
{
int res;
+ if (name == NULL) return -1;
+
if (_lu_running())
{
if ((res = lu_initgroups(name, basegid)))
return (NULL);
}
+#ifdef NOTDEF
+/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */
p_datalen *= BYTES_PER_XDR_UNIT;
+#endif
xdrmem_create(&p_xdr, p_data, p_datalen,
XDR_DECODE);
if (!xdr_int(&p_xdr, &p_nentries))
if (global_free == 1) return;
- free(global_s.s_name);
+ if (global_s.s_name != NULL) free(global_s.s_name);
+ global_s.s_name = NULL;
+
+ if (global_s.s_proto != NULL) free(global_s.s_proto);
+ global_s.s_proto = NULL;
aliases = global_s.s_aliases;
if (aliases != NULL)
{
while (*aliases != NULL) free(*aliases++);
free(global_s.s_aliases);
+ global_s.s_aliases = NULL;
}
global_free = 1;
global_s.s_aliases[len] = NULL;
- global_s.s_proto = lu_s->s_proto;
+ if (lu_s->s_proto != NULL) global_s.s_proto = strdup(lu_s->s_proto);
global_s.s_port = lu_s->s_port;
global_free = 0;
PROJECTVERSION = 2.8
PROJECT_TYPE = Component
-HFILES = clib.h mm.h ni.h ni_util.h
+HFILES = clib.h mm.h ni.h ni_util.h sys_interfaces.h
CFILES = multi_call.c ni_error.c ni_glue.c ni_pwdomain.c ni_useful.c\
- ni_util.c
+ ni_util.c sys_interfaces.c
OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nibind_prot.x\
ni_prot.x
{
DYNAMIC_CODE_GEN = YES;
FILESTABLE = {
- H_FILES = (clib.h, mm.h, ni.h, ni_util.h);
- OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c);
+ H_FILES = (clib.h, mm.h, ni.h, ni_util.h, sys_interfaces.h);
+ OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c, sys_interfaces.c);
OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, nibind_prot.x, ni_prot.x);
PUBLIC_HEADERS = (ni.h, ni_util.h);
};
#include <net/if.h>
#include <ctype.h>
#include "clib.h"
+#include "sys_interfaces.h"
+
+#define LOCAL_PORT 1033
#define NI_TIMEOUT_SHORT 5 /* 5 second timeout for transactions */
#define NI_TIMEOUT_LONG 60 /* 60 second timeout for writes */
/* Hack for determining if an IP address is a broadcast address. -GRS */
/* Note that addr is network byte order (big endian) - BKM */
-
+
#define IS_BROADCASTADDR(addr) (((unsigned char *) &addr)[0] == 0xFF)
#ifndef INADDR_LOOPBACK
}
-/*
- * Is the NetInfo binder running?
- */
-static int
-nibind_up(
- ni_private *ni
- )
-{
- int sock;
- struct sockaddr_in sin;
- int res;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0) {
- return (0);
- }
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PMAPPORT);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- bzero(sin.sin_zero, sizeof(sin.sin_zero));
- res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
- close(sock);
- if (res != 0) {
- return (0);
- }
- sin.sin_port = htons(pmap_getport(&sin, NIBIND_PROG, NIBIND_VERS,
- IPPROTO_TCP));
- if (sin.sin_port == 0) {
- return (0);
- }
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0) {
- return (0);
- }
- res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
- close(sock);
- return (res == 0);
-}
-
-
static void
createauth(
ni_private *ni
* Connect to a given address/tag
*/
static int
-connectit(
- ni_private *ni
- )
+connectit(ni_private *ni)
{
struct sockaddr_in sin;
int sock;
struct timeval tv;
enum clnt_stat stat;
nibind_getregister_res res;
-
+
+ sock = -1;
bzero(&sin, sizeof(sin));
sin.sin_port = 0;
sin.sin_family = AF_INET;
- sin.sin_addr = ni->addrs[0];
- ni_settimeout(ni, ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec);
- fixtimeout(&tv, ni->tv_sec, NI_TRIES);
- sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec,
- NI_TRIES, IPPROTO_UDP);
- if (sock < 0) {
- return (0);
- }
- cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv,
- &sock);
- if (cl == NULL) {
- close(sock);
- return (0);
- }
+
tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
tv.tv_usec = 0;
- stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0],
- xdr_nibind_getregister_res, &res, tv);
- clnt_destroy(cl);
- close(sock);
- if (stat != RPC_SUCCESS || res.status != NI_OK) {
- return (0);
- }
+ ni_settimeout(ni, tv.tv_sec);
+ fixtimeout(&tv, ni->tv_sec, NI_TRIES);
+
/*
- * Found the address, now connect to it.
+ * If connecting to local domain, try using the "well-known" port first.
*/
- sin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port);
- sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES,
- IPPROTO_TCP);
- if (sock < 0) {
- return (0);
+ if (!strcmp(ni->tags[0], "local"))
+ {
+ interface_list_t *ilist;
+
+ ilist = sys_interfaces();
+ if (sys_is_my_address(ilist, &ni->addrs[0]))
+ {
+ sin.sin_port = htons(LOCAL_PORT);
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, IPPROTO_TCP);
+ }
+ sys_interfaces_release(ilist);
+ }
+
+ /*
+ * If connecting to a domain other than the local domain,
+ * or if connection to local didn't work with local's well-known port,
+ * then go through portmap & nibindd to find the port and connect.
+ */
+ if (sock < 0)
+ {
+ sin.sin_port = 0;
+ sin.sin_addr = ni->addrs[0];
+
+ sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec, NI_TRIES, IPPROTO_UDP);
+ if (sock < 0) return (0);
+
+ cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv, &sock);
+ if (cl == NULL)
+ {
+ close(sock);
+ return (0);
+ }
+
+ tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
+ tv.tv_usec = 0;
+
+ stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0], xdr_nibind_getregister_res, &res, tv);
+ clnt_destroy(cl);
+ close(sock);
+ if (stat != RPC_SUCCESS || res.status != NI_OK) return (0);
+
+ sin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port);
+ sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, IPPROTO_TCP);
}
+
+ if (sock < 0) return (0);
+
cl = clnttcp_create(&sin, NI_PROG, NI_VERS, &sock, 0, 0);
- if (cl == NULL) {
+ if (cl == NULL)
+ {
close(sock);
return (0);
}
+
clnt_control(cl, CLSET_TIMEOUT, &tv);
ni->tc = cl;
ni->tsock = sock;
ni->tport = getmyport(sock);
createauth(ni);
- (void) fcntl(ni->tsock, F_SETFD, 1);
+ fcntl(ni->tsock, F_SETFD, 1);
return (1);
}
}
-static unsigned long
-sys_netmask(void)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char buf[1024]; /* XXX */
- int i, len, ifreq_size, offset, sockaddr_size, size;
- int sock;
- struct sockaddr_in *sin;
- unsigned long n_addr;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (sock < 0) return (htonl(IN_CLASSA_NET));
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- close(sock);
- return (htonl(IN_CLASSA_NET));
- }
-
- ifreq_size = sizeof(struct ifreq);
- sockaddr_size = sizeof(struct sockaddr);
-
- offset = 0;
- len = ifc.ifc_len / ifreq_size;
- for (i = 0; i < len; i++)
- {
- ifr = (struct ifreq *)(ifc.ifc_buf + offset);
- offset += IFNAMSIZ;
- offset += sockaddr_size;
-
- size = ifr->ifr_addr.sa_len;
- if (size > sockaddr_size) offset += (size - sockaddr_size);
-
- if (ifr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
-
- sin = (struct sockaddr_in *)&ifr->ifr_addr;
- if ((ifr->ifr_flags & IFF_UP) &&
- !(ifr->ifr_flags & IFF_LOOPBACK) &&
- (sin->sin_addr.s_addr != 0))
- {
- ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
- n_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- close(sock);
- return (n_addr);
- }
- }
-
- close(sock);
- return (htonl(IN_CLASSA_NET));
-}
-
-
-static unsigned long
-sys_address(void)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char buf[1024]; /* XXX */
- int i, len, ifreq_size, offset, sockaddr_size, size;
- int sock;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (sock < 0)
- {
- return (htonl(INADDR_LOOPBACK));
- }
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- close(sock);
- return (htonl(INADDR_LOOPBACK));
- }
-
- ifreq_size = sizeof(struct ifreq);
- sockaddr_size = sizeof(struct sockaddr);
-
- offset = 0;
- len = ifc.ifc_len / ifreq_size;
- for (i = 0; i < len; i++)
- {
- ifr = (struct ifreq *)(ifc.ifc_buf + offset);
- offset += IFNAMSIZ;
- offset += sockaddr_size;
-
- size = ifr->ifr_addr.sa_len;
- if (size > sockaddr_size) offset += (size - sockaddr_size);
-
- if (ifr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue;
-
- if ((ifr->ifr_flags & IFF_UP) && (!(ifr->ifr_flags & IFF_LOOPBACK)))
- {
- close(sock);
- return (((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr);
- }
- }
-
- close(sock);
- return (htonl(INADDR_LOOPBACK));
-}
-
-
/*
* Returns a client handle to the NetInfo server, if it's running
*/
{
int printed = 0;
- if (!nibind_up(ni)) {
- return (0);
- }
ni->naddrs = 1;
ni->addrs = (struct in_addr *)malloc(sizeof(struct in_addr));
ni->addrs[0].s_addr = htonl(INADDR_LOOPBACK);
ni->tags = (ni_name *)malloc(sizeof(ni_name));
ni->tags[0] = ni_name_dup("local");
ni->whichwrite = 0;
- while (!connectit(ni)) {
- if (!printed) {
+
+ while (!connectit(ni))
+ {
+ if (!printed)
+ {
syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping");
printed++;
}
+
sleep(NI_SLEEPTIME);
/* wait forever */
}
- if (printed) {
+
+ if (printed)
+ {
syslog(LOG_ERR, "NetInfo connection to local domain waking");
}
+
return (1);
}
struct in_addr tmp_addr;
ni_name tmp_tag;
+ if (a == b) return;
+
tmp_addr = ni->addrs[a];
tmp_tag = ni->tags[a];
}
+/*
+ * shuffle addresses
+ */
+static void
+shuffle(ni_private *ni)
+{
+ int *shuffle;
+ int i, j;
+ int rfd;
+
+ if (ni->naddrs <= 1) return;
+
+ rfd = open("/dev/random", O_RDONLY, 0);
+ shuffle = (int *)malloc(ni->naddrs * sizeof(int));
+ for (i = 0; i < ni->naddrs; i++) shuffle[i] = i;
+ for (i = 0, j = ni->naddrs; j > 0; i++, j--) {
+ unsigned int rEnt;
+ long rVal;
+ int tEnt;
+
+ /* get a random number */
+ if ((rfd < 0) ||
+ (read(rfd, &rVal, sizeof(rVal)) != sizeof(rVal))) {
+ /* if we could not read from /dev/random */
+ static int initialized = 0;
+ if (!initialized)
+ {
+ srandom(gethostid() ^ time(NULL));
+ initialized++;
+ }
+ rVal = random();
+ }
+
+ rEnt = (unsigned int)rVal % j; /* pick one of the remaining entries */
+ tEnt = shuffle[rEnt]; /* grab the random entry */
+ shuffle[rEnt] = shuffle[j-1]; /* the last entry moves to the random slot */
+ shuffle[j-1] = tEnt; /* the last slot gets the random entry */
+ ni_swap(ni, rEnt, j-1); /* and swap the actual NI addresses */
+ }
+ free(shuffle);
+ if (rfd > 0) (void)close(rfd);
+ return;
+}
+
+
static int
rebind(
ni_private *ni
int printed = 0;
int nlocal;
int nnetwork;
- unsigned long myaddr;
- unsigned long mynetmask;
- unsigned long mynetwork;
+ interface_list_t *ilist;
int i;
if (ni->naddrs == 1) {
* all other servers are next
*/
- myaddr = sys_address();
- mynetmask = sys_netmask();
- mynetwork = myaddr & mynetmask;
+ ilist = sys_interfaces();
+
+ /*
+ * shuffle addresses
+ */
+ shuffle(ni);
/*
* move local servers to the head of the list
*/
nlocal = 0;
for (i = nlocal; i < ni->naddrs; i++) {
- if ((ni->addrs[i].s_addr == myaddr) ||
- (ni->addrs[i].s_addr == htonl(INADDR_LOOPBACK)))
+ if (sys_is_my_address(ilist, &ni->addrs[i]))
{
ni_swap(ni, nlocal, i);
nlocal++;
*/
nnetwork = nlocal;
for (i = nnetwork; i < ni->naddrs; i++) {
- if (((ni->addrs[i].s_addr & mynetmask) == mynetwork) ||
+ if (sys_is_my_network(ilist, &ni->addrs[i]) ||
IS_BROADCASTADDR(ni->addrs[i].s_addr))
{
ni_swap(ni, nnetwork, i);
}
}
+ sys_interfaces_release(ilist);
+
stuff.ni = ni;
for (;;) {
/*
)
{
int sock;
-
+ int reuse = 1;
+
/*
* If no port number given ask the pmap for one
*/
return (-1);
}
(void)bindresvport(sock, (struct sockaddr_in *)0);
+ setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int));
if (proto == IPPROTO_TCP) {
if (connect(sock, (struct sockaddr *)raddr,
sizeof(*raddr)) < 0) {
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
+#include "sys_interfaces.h"
extern char *inet_ntoa();
static const char NAME_SERVES[] = "serves";
static const char NAME_UNKNOWN[] = "###UNKNOWN###";
-typedef struct
-{
- char name[IFNAMSIZ];
- short flags;
- struct in_addr addr;
- struct in_addr mask;
- struct in_addr netaddr;
- struct in_addr bcast;
-} interface_t;
-
-typedef struct
-{
- unsigned int count;
- interface_t *interface;
-} interface_list_t;
-
-static interface_list_t *my_interfaces = NULL;
-
-static interface_list_t *
-sys_interfaces(void)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char buf[1024]; /* XXX */
- int offset, addrlen, extra, delta;
- int sock;
- interface_t *iface;
-
- if (my_interfaces != NULL) return my_interfaces;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (sock < 0) return NULL;
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- close(sock);
- return NULL;
- }
-
- my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
- my_interfaces->count = 0;
- my_interfaces->interface = NULL;
-
- delta = sizeof(struct ifreq);
- addrlen = delta - IFNAMSIZ;
- extra = 0;
-
- offset = 0;
-
- while (offset <= ifc.ifc_len)
- {
- ifr = (struct ifreq *)(ifc.ifc_buf + offset);
-
-#ifndef _NO_SOCKADDR_LENGTH_
- extra = ifr->ifr_addr.sa_len - addrlen;
- if (extra < 0) extra = 0;
-#endif
-
- offset = offset + delta + extra;
-
- if (ifr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
-
- my_interfaces->count++;
- if (my_interfaces->count == 1)
- {
- my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t));
- }
- else
- {
- my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t));
- }
-
- iface = &(my_interfaces->interface[my_interfaces->count - 1]);
- memset(iface, 0, sizeof(interface_t));
-
- memmove(iface->name, ifr->ifr_name, IFNAMSIZ);
- iface->flags = ifr->ifr_ifru.ifru_flags;
- iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
- iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr;
- iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr);
- }
-
- close(sock);
- return my_interfaces;
-}
-
static ni_name
escape_domain(ni_name name)
{
return NULL;
}
-static int
-sys_is_my_address(struct in_addr *a)
-{
- int i;
- interface_list_t *l;
-
- l = sys_interfaces();
- if (l == NULL) return 0;
-
- for (i = 0; i < l->count; i++)
- {
- if (a->s_addr == l->interface[i].addr.s_addr) return 1;
- }
- return 0;
-}
-
static char *
ni_domainof(void *ni, void *parent)
{
return dom;
}
- if (sys_is_my_address(&(addr.sin_addr)))
+ ilist = sys_interfaces();
+ if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
+ if (sys_is_my_address(ilist, &(addr.sin_addr)))
{
/* Try all my non-loopback interfaces */
- ilist = sys_interfaces();
- if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
-
for (i = 0; i < ilist->count; i++)
{
if (ilist->interface[i].addr.s_addr == htonl(INADDR_LOOPBACK)) continue;
if (dom != NULL)
{
ni_name_free(&tag);
+ sys_interfaces_release(ilist);
return dom;
}
}
}
+ sys_interfaces_release(ilist);
dom = malloc(strlen(tag) + 256);
sprintf(dom, "%s@%s", tag, inet_ntoa(addr.sin_addr.s_addr));
char *component;
/* look for <tag>@<address> in last component of domain */
- start = domain;
- while ((slash = escindex(start, '/')) != NULL) {
+ start = (char *)domain;
+ while ((slash = (char *)escindex(start, '/')) != NULL) {
/* found a slash, keep looking for the last one */
start = slash + 1;
}
nl = el.ni_entrylist_val[i].names;
+ found = 0;
for (j = 0; j < nl->ni_namelist_len; j++)
{
- found = 0;
if (regexec(cexp, nl->ni_namelist_val[j], 0, NULL, 0) != 0) continue;
-
found = 1;
break;
}
--- /dev/null
+/*
+ * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "sys_interfaces.h"
+
+__private_extern__ interface_list_t *
+sys_interfaces(void)
+{
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ char buf[1024]; /* XXX */
+ int offset, addrlen, extra, delta;
+ int sock;
+ interface_t *iface;
+ interface_list_t *my_interfaces;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if (sock < 0) return NULL;
+
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+
+ if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
+ {
+ close(sock);
+ return NULL;
+ }
+
+ my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
+ my_interfaces->count = 0;
+ my_interfaces->interface = NULL;
+
+ delta = sizeof(struct ifreq);
+ addrlen = delta - IFNAMSIZ;
+ extra = 0;
+
+ offset = 0;
+
+ while (offset <= ifc.ifc_len)
+ {
+ ifr = (struct ifreq *)(ifc.ifc_buf + offset);
+
+#ifndef _NO_SOCKADDR_LENGTH_
+ extra = ifr->ifr_addr.sa_len - addrlen;
+ if (extra < 0) extra = 0;
+#endif
+
+ offset = offset + delta + extra;
+
+ if (ifr->ifr_addr.sa_family != AF_INET) continue;
+ if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
+
+ my_interfaces->count++;
+ if (my_interfaces->count == 1)
+ {
+ my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t));
+ }
+ else
+ {
+ my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t));
+ }
+
+ iface = &(my_interfaces->interface[my_interfaces->count - 1]);
+ memset(iface, 0, sizeof(interface_t));
+
+ memmove(iface->name, ifr->ifr_name, IFNAMSIZ);
+ iface->flags = ifr->ifr_ifru.ifru_flags;
+ iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
+ ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
+ iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
+ iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr;
+ iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr);
+ }
+
+ close(sock);
+ return my_interfaces;
+}
+
+__private_extern__ void
+sys_interfaces_release(interface_list_t *l)
+{
+ if (l == NULL) return;
+
+ if (l->interface != NULL) free(l->interface);
+ free(l);
+}
+
+__private_extern__ int
+sys_is_my_address(interface_list_t *l, struct in_addr *a)
+{
+ int i;
+
+ if (l == NULL) return 0;
+
+ for (i = 0; i < l->count; i++)
+ {
+ if (a->s_addr == l->interface[i].addr.s_addr) return 1;
+ }
+ return 0;
+}
+
+__private_extern__ int
+sys_is_my_network(interface_list_t *l, struct in_addr *a)
+{
+ int i;
+
+ if (l == NULL) return 0;
+
+ for (i = 0; i < l->count; i++)
+ {
+ if ((a->s_addr & l->interface[i].mask.s_addr) ==
+ l->interface[i].netaddr.s_addr) return 1;
+
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __SYS_INTERFACES__
+#define __SYS_INTERFACES__
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+typedef struct
+{
+ char name[IFNAMSIZ];
+ short flags;
+ struct in_addr addr;
+ struct in_addr mask;
+ struct in_addr netaddr;
+ struct in_addr bcast;
+} interface_t;
+
+typedef struct
+{
+ unsigned int count;
+ interface_t *interface;
+} interface_list_t;
+
+interface_list_t * sys_interfaces(void);
+void sys_interfaces_release(interface_list_t *l);
+int sys_is_my_address(interface_list_t *l, struct in_addr *a);
+int sys_is_my_network(interface_list_t *l, struct in_addr *a);
+
+#endif /* __SYS_INTERFACES__ */
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
-static char *rcsid = "$Id: svc.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+static char *rcsid = "$Id: svc.c,v 1.3 2001/08/23 01:25:01 ajn Exp $";
#endif
/*
maskp = (u_long *)readfds->fds_bits;
- for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
+ for (sock = 0; sock <= svc_maxfd; sock += NFDBITS) {
for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+ if ((sock + bit) > (svc_maxfd + 1))
+ /* if we're past our sockets */
+ return;
/* sock has input waiting */
xprt = xports[sock + bit - 1];
if (xprt == NULL)