From: Apple Date: Thu, 23 Aug 2001 01:25:01 +0000 (+0000) Subject: Libinfo-89.tar.gz X-Git-Tag: mac-os-x-101^0 X-Git-Url: https://git.saurik.com/apple/libinfo.git/commitdiff_plain/a0865d6380e4ae001b2f00dbe4199477660b93d4?hp=c6f155da1354232bd502882ef0490c98819efdf0 Libinfo-89.tar.gz --- diff --git a/gen.subproj/getaddrinfo.c b/gen.subproj/getaddrinfo.c index bce133f..0d105ea 100644 --- a/gen.subproj/getaddrinfo.c +++ b/gen.subproj/getaddrinfo.c @@ -478,7 +478,7 @@ gai_files(struct lu_dict *q, struct lu_dict **list) 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); @@ -665,6 +665,7 @@ freeaddrinfo(struct addrinfo *a) 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; @@ -1053,7 +1054,8 @@ static int 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; @@ -1097,7 +1099,7 @@ gai_serv(const char *servname, const struct addrinfo *hints, struct addrinfo **r /* 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")) @@ -1320,7 +1322,7 @@ gai_nodeserv_lookupd(const char *nodename, const char *servname, const struct ad } 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; @@ -1425,8 +1427,9 @@ static int 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; @@ -1466,7 +1469,7 @@ gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo * 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); @@ -1518,7 +1521,7 @@ gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo * 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; diff --git a/gen.subproj/getpwent.c b/gen.subproj/getpwent.c index a9f4798..0f2d8c4 100644 --- a/gen.subproj/getpwent.c +++ b/gen.subproj/getpwent.c @@ -36,6 +36,7 @@ #include #include #include +#include #define forever for (;;) @@ -46,6 +47,7 @@ static struct passwd _pw = { 0 }; static FILE *_pfp; static int _pwStayOpen; +static int _pwFileFormat = 1; static void free_pw() @@ -223,11 +225,14 @@ struct passwd * 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; @@ -241,14 +246,27 @@ parseUser(char *data) 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); @@ -284,10 +302,20 @@ setpwent() { 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); } } diff --git a/lookup.subproj/lu_group.c b/lookup.subproj/lu_group.c index 5022f9c..2ec8e03 100644 --- a/lookup.subproj/lu_group.c +++ b/lookup.subproj/lu_group.c @@ -362,6 +362,8 @@ initgroups(const char *name, int basegid) { int res; + if (name == NULL) return -1; + if (_lu_running()) { if ((res = lu_initgroups(name, basegid))) diff --git a/lookup.subproj/lu_protocol.c b/lookup.subproj/lu_protocol.c index f3c0e4b..f2c346f 100644 --- a/lookup.subproj/lu_protocol.c +++ b/lookup.subproj/lu_protocol.c @@ -235,7 +235,10 @@ lu_getprotoent() 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)) diff --git a/lookup.subproj/lu_service.c b/lookup.subproj/lu_service.c index 2fd3e2a..4dc60e5 100644 --- a/lookup.subproj/lu_service.c +++ b/lookup.subproj/lu_service.c @@ -60,13 +60,18 @@ freeold(void) 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; @@ -91,7 +96,7 @@ convert_s(_lu_servent *lu_s) 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; diff --git a/netinfo.subproj/Makefile b/netinfo.subproj/Makefile index baf2315..ea95aa2 100644 --- a/netinfo.subproj/Makefile +++ b/netinfo.subproj/Makefile @@ -12,10 +12,10 @@ NAME = netinfo 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 diff --git a/netinfo.subproj/PB.project b/netinfo.subproj/PB.project index ecd1da8..789dee7 100644 --- a/netinfo.subproj/PB.project +++ b/netinfo.subproj/PB.project @@ -1,8 +1,8 @@ { 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); }; diff --git a/netinfo.subproj/ni_glue.c b/netinfo.subproj/ni_glue.c index 0a22e74..751cd93 100644 --- a/netinfo.subproj/ni_glue.c +++ b/netinfo.subproj/ni_glue.c @@ -34,6 +34,9 @@ #include #include #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 */ @@ -44,7 +47,7 @@ /* 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 @@ -117,46 +120,6 @@ getmyport( } -/* - * 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 @@ -203,9 +166,7 @@ ni_settimeout( * Connect to a given address/tag */ static int -connectit( - ni_private *ni - ) +connectit(ni_private *ni) { struct sockaddr_in sin; int sock; @@ -213,54 +174,82 @@ connectit( 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); } @@ -305,118 +294,6 @@ ni_needwrite( } -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 */ @@ -425,26 +302,30 @@ connectlocal(ni_private *ni) { 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); } @@ -546,6 +427,8 @@ ni_swap( struct in_addr tmp_addr; ni_name tmp_tag; + if (a == b) return; + tmp_addr = ni->addrs[a]; tmp_tag = ni->tags[a]; @@ -585,6 +468,51 @@ eachresult( } +/* + * 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 @@ -596,9 +524,7 @@ rebind( 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) { @@ -614,17 +540,19 @@ rebind( * 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++; @@ -636,7 +564,7 @@ rebind( */ 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); @@ -644,6 +572,8 @@ rebind( } } + sys_interfaces_release(ilist); + stuff.ni = ni; for (;;) { /* @@ -2220,7 +2150,8 @@ socket_open( ) { int sock; - + int reuse = 1; + /* * If no port number given ask the pmap for one */ @@ -2240,6 +2171,7 @@ socket_open( 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) { diff --git a/netinfo.subproj/ni_pwdomain.c b/netinfo.subproj/ni_pwdomain.c index c872cc8..9d9c541 100644 --- a/netinfo.subproj/ni_pwdomain.c +++ b/netinfo.subproj/ni_pwdomain.c @@ -44,6 +44,7 @@ #include #include #include +#include "sys_interfaces.h" extern char *inet_ntoa(); @@ -53,99 +54,6 @@ static const char NAME_IP_ADDRESS[] = "ip_address"; 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) { @@ -221,22 +129,6 @@ finddomain(void *ni, struct in_addr addr, ni_name tag) 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) { @@ -257,12 +149,11 @@ 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; @@ -272,10 +163,12 @@ ni_domainof(void *ni, void *parent) 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)); diff --git a/netinfo.subproj/ni_useful.c b/netinfo.subproj/ni_useful.c index a3d3df6..eaed642 100644 --- a/netinfo.subproj/ni_useful.c +++ b/netinfo.subproj/ni_useful.c @@ -123,8 +123,8 @@ ni_relopen( char *component; /* look for @
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; } diff --git a/netinfo.subproj/ni_util.c b/netinfo.subproj/ni_util.c index 2f6f81d..1f881e9 100644 --- a/netinfo.subproj/ni_util.c +++ b/netinfo.subproj/ni_util.c @@ -498,11 +498,10 @@ ni_search(void *handle, ni_id *dir, ni_name name, ni_name expr, int flags, ni_en 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; } diff --git a/netinfo.subproj/sys_interfaces.c b/netinfo.subproj/sys_interfaces.c new file mode 100644 index 0000000..d04f3e0 --- /dev/null +++ b/netinfo.subproj/sys_interfaces.c @@ -0,0 +1,141 @@ +/* + * 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 +#include +#include +#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; +} diff --git a/netinfo.subproj/sys_interfaces.h b/netinfo.subproj/sys_interfaces.h new file mode 100644 index 0000000..154ac5b --- /dev/null +++ b/netinfo.subproj/sys_interfaces.h @@ -0,0 +1,55 @@ +/* + * 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 +#include +#include +#include +#include + +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__ */ diff --git a/rpc.subproj/svc.c b/rpc.subproj/svc.c index fffefc0..a559c03 100644 --- a/rpc.subproj/svc.c +++ b/rpc.subproj/svc.c @@ -53,7 +53,7 @@ #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 /* @@ -411,8 +411,11 @@ svc_getreqset(readfds) 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)