int gethostent_r(struct hostent* hptr, char* buffer, size_t buflen, struct hostent** result, int* h_errnop) { struct hostent_data* hed; struct hostent he; res_state statp; statp = __res_state(); if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (-1); } if ((hed = __hostent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (-1); } if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0) { return (-1); } if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { return (-1); } *result = hptr; return (0); }
int _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap) { const void *addr; socklen_t len; int af; char *buffer; size_t buflen; int *errnop, *h_errnop; struct hostent *hptr, he; struct hostent_data *hed; res_state statp; int error; addr = va_arg(ap, const void *); len = va_arg(ap, socklen_t); af = va_arg(ap, int); hptr = va_arg(ap, struct hostent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); *((struct hostent **)rval) = NULL; statp = __res_state(); if ((hed = __hostent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } _sethosthtent(0, hed); while ((error = gethostent_p(&he, hed, 0, statp)) == 0) if (he.h_addrtype == af && !bcmp(he.h_addr, addr, len)) { if (he.h_addrtype == AF_INET && statp->options & RES_USE_INET6) { _map_v4v6_address(he.h_addr, he.h_addr); he.h_length = IN6ADDRSZ; he.h_addrtype = AF_INET6; } break; } _endhosthtent(hed); if (error != 0) return (NS_NOTFOUND); if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct hostent **)rval) = hptr; return (NS_SUCCESS); }
static struct netent * fakeaddr(const char *name, int af, struct net_data *net_data) { struct pvt *pvt; const char *cp; u_long tmp; if (af != AF_INET) { /* XXX should support IPv6 some day */ errno = EAFNOSUPPORT; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } if (!isascii((unsigned char)(name[0])) || !isdigit((unsigned char)(name[0]))) return (NULL); for (cp = name; *cp; ++cp) if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.')) return (NULL); if (*--cp == '.') return (NULL); /* All-numeric, no dot at the end. */ tmp = inet_network(name); if (tmp == INADDR_NONE) { RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } /* Valid network number specified. * Fake up a netent as if we'd actually * done a lookup. */ freepvt(net_data); net_data->nw_data = malloc(sizeof (struct pvt)); if (!net_data->nw_data) { errno = ENOMEM; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt = net_data->nw_data; strncpy(pvt->name, name, MAXDNAME); pvt->name[MAXDNAME] = '\0'; pvt->netent.n_name = pvt->name; pvt->netent.n_addrtype = AF_INET; pvt->netent.n_aliases = pvt->aliases; pvt->aliases[0] = NULL; pvt->netent.n_net = tmp; return (&pvt->netent); }
int _ht_getnetbyname(void *rval, void *cb_data, va_list ap) { const char *name; char *buffer; size_t buflen; int *errnop, *h_errnop; struct netent *nptr, ne; struct netent_data *ned; char **cp; res_state statp; int error; name = va_arg(ap, const char *); nptr = va_arg(ap, struct netent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); statp = __res_state(); if ((ned = __netent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_UNAVAIL); } _setnethtent(ned->stayopen, ned); while ((error = getnetent_p(&ne, ned)) == 0) { if (strcasecmp(ne.n_name, name) == 0) break; for (cp = ne.n_aliases; *cp != 0; cp++) if (strcasecmp(*cp, name) == 0) goto found; } found: if (!ned->stayopen) _endnethtent(ned); if (error != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct netent **)rval) = nptr; return (NS_SUCCESS); }
int _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap) { #ifdef YP const void *addr; socklen_t len; int af; char *buffer; size_t buflen; int *errnop, *h_errnop; struct hostent *hptr, he; struct hostent_data *hed; res_state statp; addr = va_arg(ap, const void *); len = va_arg(ap, socklen_t); af = va_arg(ap, int); hptr = va_arg(ap, struct hostent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); *((struct hostent **)rval) = NULL; statp = __res_state(); if ((hed = __hostent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct hostent **)rval) = hptr; return (NS_SUCCESS); #else *((struct hostent **)rval) = NULL; return (NS_UNAVAIL); #endif }
struct hostent * _gethostbynisaddr(const void *addr, socklen_t len, int af) { #ifdef YP struct hostent *he; struct hostent_data *hed; u_long oresopt; int error; res_state statp; statp = __res_state(); if ((he = __hostent_init()) == NULL || (hed = __hostent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (NULL); } oresopt = statp->options; statp->options &= ~RES_USE_INET6; error = _gethostbynisaddr_r(addr, len, af, he, hed); statp->options = oresopt; return (error == 0) ? he : NULL; #else return (NULL); #endif }
int _ht_getnetbyaddr(void *rval, void *cb_data, va_list ap) { uint32_t net; int type; char *buffer; size_t buflen; int *errnop, *h_errnop; struct netent *nptr, ne; struct netent_data *ned; res_state statp; int error; net = va_arg(ap, uint32_t); type = va_arg(ap, int); nptr = va_arg(ap, struct netent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); statp = __res_state(); if ((ned = __netent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_UNAVAIL); } _setnethtent(ned->stayopen, ned); while ((error = getnetent_p(&ne, ned)) == 0) if (ne.n_addrtype == type && ne.n_net == net) break; if (!ned->stayopen) _endnethtent(ned); if (error != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct netent **)rval) = nptr; return (NS_SUCCESS); }
int _nis_getnetbyname(void *rval, void *cb_data, va_list ap) { #ifdef YP const char *name; char *buffer; size_t buflen; int *errnop, *h_errnop; struct netent *nptr, ne; struct netent_data *ned; res_state statp; name = va_arg(ap, const char *); nptr = va_arg(ap, struct netent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); statp = __res_state(); if ((ned = __netent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_UNAVAIL); } if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct netent **)rval) = nptr; return (NS_SUCCESS); #else return (NS_UNAVAIL); #endif }
int getnetent_r(struct netent *nptr, char *buffer, size_t buflen, struct netent **result, int *h_errnop) { struct netent_data *ned; struct netent ne; res_state statp; statp = __res_state(); if ((ned = __netent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (-1); } if (getnetent_p(&ne, ned) != 0) return (-1); if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return ((errno != 0) ? errno : -1); } *result = nptr; return (0); }
static struct net_data * init() { struct net_data *net_data; if (!(net_data = net_data_init(NULL))) goto error; if (!net_data->ho) { net_data->ho = (*net_data->irs->ho_map)(net_data->irs); if (!net_data->ho || !net_data->res) { error: errno = EIO; if (net_data && net_data->res) RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } (*net_data->ho->res_set)(net_data->ho, net_data->res, NULL); } return (net_data); }
static struct netent * nw_to_net(struct nwent *nwent, struct net_data *net_data) { struct pvt *pvt; u_long addr = 0; int i; int msbyte; if (!nwent || nwent->n_addrtype != AF_INET) return (NULL); freepvt(net_data); net_data->nw_data = malloc(sizeof (struct pvt)); if (!net_data->nw_data) { errno = ENOMEM; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt = net_data->nw_data; pvt->netent.n_name = nwent->n_name; pvt->netent.n_aliases = nwent->n_aliases; pvt->netent.n_addrtype = nwent->n_addrtype; /* * What this code does: Converts net addresses from network to host form. * * msbyte: the index of the most significant byte in the n_addr array. * * Shift bytes in significant order into addr. When all signicant * bytes are in, zero out bits in the LSB that are not part of the network. */ msbyte = nwent->n_length / 8 + ((nwent->n_length % 8) != 0 ? 1 : 0) - 1; for (i = 0; i <= msbyte; i++) addr = (addr << 8) | ((unsigned char *)nwent->n_addr)[i]; i = (32 - nwent->n_length) % 8; if (i != 0) addr &= ~((1 << (i + 1)) - 1); pvt->netent.n_net = addr; return (&pvt->netent); }
static int _getnetbynis(const char *name, char *map, int af, struct netent *ne, struct netent_data *ned) { char *p, *bp, *ep; char *cp, **q; char *result; int resultlen, len; char ypbuf[YPMAXRECORD + 2]; switch(af) { case AF_INET: break; default: case AF_INET6: errno = EAFNOSUPPORT; return (-1); } if (ned->yp_domain == (char *)NULL) if (yp_get_default_domain (&ned->yp_domain)) return (-1); if (yp_match(ned->yp_domain, map, name, strlen(name), &result, &resultlen)) return (-1); bcopy((char *)result, (char *)&ypbuf, resultlen); ypbuf[resultlen] = '\0'; free(result); result = (char *)&ypbuf; if ((cp = index(result, '\n'))) *cp = '\0'; cp = strpbrk(result, " \t"); *cp++ = '\0'; bp = ned->netbuf; ep = ned->netbuf + sizeof ned->netbuf; len = strlen(result) + 1; if (ep - bp < len) { RES_SET_H_ERRNO(__res_state(), NO_RECOVERY); return (-1); } strlcpy(bp, result, ep - bp); ne->n_name = bp; bp += len; while (*cp == ' ' || *cp == '\t') cp++; ne->n_net = inet_network(cp); ne->n_addrtype = AF_INET; q = ne->n_aliases = ned->net_aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q > &ned->net_aliases[_MAXALIASES - 1]) break; p = strpbrk(cp, " \t"); if (p != NULL) *p++ = '\0'; len = strlen(cp) + 1; if (ep - bp < len) break; strlcpy(bp, cp, ep - bp); *q++ = bp; bp += len; cp = p; } *q = NULL; return (0); }
int _nis_getnetbyaddr(void *rval, void *cb_data, va_list ap) { #ifdef YP uint32_t addr; int af; char *buffer; size_t buflen; int *errnop, *h_errnop; struct netent *nptr, ne; struct netent_data *ned; char *str, *cp; uint32_t net2; int nn; unsigned int netbr[4]; char buf[MAXDNAME]; res_state statp; addr = va_arg(ap, uint32_t); af = va_arg(ap, int); nptr = va_arg(ap, struct netent *); buffer = va_arg(ap, char *); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int *); h_errnop = va_arg(ap, int *); statp = __res_state(); if ((ned = __netent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_UNAVAIL); } if (af != AF_INET) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; errno = EAFNOSUPPORT; return (NS_UNAVAIL); } for (nn = 4, net2 = addr; net2; net2 >>= 8) { netbr[--nn] = net2 & 0xff; } switch (nn) { case 3: /* Class A */ sprintf(buf, "%u", netbr[3]); break; case 2: /* Class B */ sprintf(buf, "%u.%u", netbr[2], netbr[3]); break; case 1: /* Class C */ sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]); break; case 0: /* Class D - E */ sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1], netbr[2], netbr[3]); break; } str = (char *)&buf; cp = str + (strlen(str) - 2); while(!strcmp(cp, ".0")) { *cp = '\0'; cp = str + (strlen(str) - 2); } if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_netent(&ne, nptr, buffer, buflen) != 0) { *errnop = errno; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_RETURN); } *((struct netent **)rval) = nptr; return (NS_SUCCESS); #else return (NS_UNAVAIL); #endif /* YP */ }
int res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { ns_updrec *rrecp; u_char answer[PACKETSZ]; u_char *packet; struct zonegrp *zptr, tgrp; LIST(struct zonegrp) zgrps; int nzones = 0, nscount = 0, n; union res_sockaddr_union nsaddrs[MAXNS]; packet = malloc(NS_MAXMSG); if (packet == NULL) { DPRINTF(("malloc failed")); return (0); } /* Thread all of the updates onto a list of groups. */ INIT_LIST(zgrps); memset(&tgrp, 0, sizeof (tgrp)); for (rrecp = rrecp_in; rrecp; rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) { int nscnt; /* Find the origin for it if there is one. */ tgrp.z_class = rrecp->r_class; nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class, RES_EXHAUSTIVE, tgrp.z_origin, sizeof tgrp.z_origin, tgrp.z_nsaddrs, MAXNS); if (nscnt <= 0) { DPRINTF(("res_findzonecut failed (%d)", nscnt)); goto done; } tgrp.z_nscount = nscnt; /* Find the group for it if there is one. */ for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 && tgrp.z_class == zptr->z_class) break; /* Make a group for it if there isn't one. */ if (zptr == NULL) { zptr = malloc(sizeof *zptr); if (zptr == NULL) { DPRINTF(("malloc failed")); goto done; } *zptr = tgrp; zptr->z_flags = 0; INIT_LINK(zptr, z_link); INIT_LIST(zptr->z_rrlist); APPEND(zgrps, zptr, z_link); } /* Thread this rrecp onto the right group. */ APPEND(zptr->z_rrlist, rrecp, r_glink); } for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) { /* Construct zone section and prepend it. */ rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin, zptr->z_class, ns_t_soa, 0); if (rrecp == NULL) { DPRINTF(("res_mkupdrec failed")); goto done; } PREPEND(zptr->z_rrlist, rrecp, r_glink); zptr->z_flags |= ZG_F_ZONESECTADDED; /* Marshall the update message. */ n = res_nmkupdate(statp, HEAD(zptr->z_rrlist), packet, NS_MAXMSG); DPRINTF(("res_mkupdate -> %d", n)); if (n < 0) goto done; /* Temporarily replace the resolver's nameserver set. */ nscount = res_getservers(statp, nsaddrs, MAXNS); res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount); /* Send the update and remember the result. */ if (key != NULL) { #ifdef _LIBC DPRINTF(("TSIG is not supported\n")); RES_SET_H_ERRNO(statp, NO_RECOVERY); goto done; #else n = res_nsendsigned(statp, packet, n, key, answer, sizeof answer); #endif } else n = res_nsend(statp, packet, n, answer, sizeof answer); if (n < 0) { DPRINTF(("res_nsend: send error, n=%d (%s)\n", n, strerror(errno))); goto done; } if (((HEADER *)answer)->rcode == NOERROR) nzones++; /* Restore resolver's nameserver set. */ res_setservers(statp, nsaddrs, nscount); nscount = 0; } done: while (!EMPTY(zgrps)) { zptr = HEAD(zgrps); if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0) res_freeupdrec(HEAD(zptr->z_rrlist)); UNLINK(zgrps, zptr, z_link); free(zptr); } if (nscount != 0) res_setservers(statp, nsaddrs, nscount); free(packet); return (nzones); }
static int getnetent_p(struct netent *ne, struct netent_data *ned) { char *p, *bp, *ep; char *cp, **q; int len; char line[BUFSIZ + 1]; if (ned->netf == NULL && (ned->netf = fopen(_PATH_NETWORKS, "r")) == NULL) return (-1); again: p = fgets(line, sizeof line, ned->netf); if (p == NULL) return (-1); if (*p == '#') goto again; cp = strpbrk(p, "#\n"); if (cp != NULL) *cp = '\0'; bp = ned->netbuf; ep = ned->netbuf + sizeof ned->netbuf; ne->n_name = bp; cp = strpbrk(p, " \t"); if (cp == NULL) goto again; *cp++ = '\0'; len = strlen(p) + 1; if (ep - bp < len) { RES_SET_H_ERRNO(__res_state(), NO_RECOVERY); return (-1); } strlcpy(bp, p, ep - bp); bp += len; while (*cp == ' ' || *cp == '\t') cp++; p = strpbrk(cp, " \t"); if (p != NULL) *p++ = '\0'; ne->n_net = inet_network(cp); ne->n_addrtype = AF_INET; q = ne->n_aliases = ned->net_aliases; if (p != NULL) { cp = p; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q >= &ned->net_aliases[_MAXALIASES - 1]) break; p = strpbrk(cp, " \t"); if (p != NULL) *p++ = '\0'; len = strlen(cp) + 1; if (ep - bp < len) break; strlcpy(bp, cp, ep - bp); *q++ = bp; bp += len; cp = p; } } *q = NULL; return (0); }
static int gethostent_p(struct hostent* he, struct hostent_data* hed, int mapped, res_state statp) { char* p, *bp, *ep; char* cp, **q; int af, len; char hostbuf[BUFSIZ + 1]; if (!hed->hostf && !(hed->hostf = fopen(_PATH_HOSTS, "r"))) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } again: if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) { RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); return (-1); } if (*p == '#') { goto again; } cp = strpbrk(p, "#\n"); if (cp != NULL) { *cp = '\0'; } if (!(cp = strpbrk(p, " \t"))) { goto again; } *cp++ = '\0'; if (inet_pton(AF_INET6, p, hed->host_addr) > 0) { af = AF_INET6; len = IN6ADDRSZ; } else if (inet_pton(AF_INET, p, hed->host_addr) > 0) { if (mapped) { _map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr); af = AF_INET6; len = IN6ADDRSZ; } else { af = AF_INET; len = INADDRSZ; } } else { goto again; } hed->h_addr_ptrs[0] = (char*)hed->host_addr; hed->h_addr_ptrs[1] = NULL; he->h_addr_list = hed->h_addr_ptrs; he->h_length = len; he->h_addrtype = af; while (*cp == ' ' || *cp == '\t') { cp++; } bp = hed->hostbuf; ep = hed->hostbuf + sizeof hed->hostbuf; he->h_name = bp; q = he->h_aliases = hed->host_aliases; if ((p = strpbrk(cp, " \t")) != NULL) { *p++ = '\0'; } len = strlen(cp) + 1; if (ep - bp < len) { RES_SET_H_ERRNO(statp, NO_RECOVERY); return (-1); } strlcpy(bp, cp, ep - bp); bp += len; cp = p; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q >= &hed->host_aliases[_MAXALIASES - 1]) { break; } if ((p = strpbrk(cp, " \t")) != NULL) { *p++ = '\0'; } len = strlen(cp) + 1; if (ep - bp < len) { break; } strlcpy(bp, cp, ep - bp); *q++ = bp; bp += len; cp = p; } *q = NULL; RES_SET_H_ERRNO(statp, NETDB_SUCCESS); return (0); }
int _ht_gethostbyname(void* rval, void* cb_data, va_list ap) { const char* name; int af; char* buffer; size_t buflen; int* errnop, *h_errnop; struct hostent* hptr, he; struct hostent_data* hed; char** cp; res_state statp; int error; name = va_arg(ap, const char*); af = va_arg(ap, int); hptr = va_arg(ap, struct hostent*); buffer = va_arg(ap, char*); buflen = va_arg(ap, size_t); errnop = va_arg(ap, int*); h_errnop = va_arg(ap, int*); *((struct hostent**)rval) = NULL; statp = __res_state(); if ((hed = __hostent_data_init()) == NULL) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } _sethosthtent(0, hed); while ((error = gethostent_p(&he, hed, 0, statp)) == 0) { if (he.h_addrtype != af) { continue; } if (he.h_addrtype == AF_INET && statp->options & RES_USE_INET6) { _map_v4v6_address(he.h_addr, he.h_addr); he.h_length = IN6ADDRSZ; he.h_addrtype = AF_INET6; } if (strcasecmp(he.h_name, name) == 0) { break; } for (cp = he.h_aliases; *cp != 0; cp++) if (strcasecmp(*cp, name) == 0) { goto found; } } found: _endhosthtent(hed); if (error != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { *h_errnop = statp->res_h_errno; return (NS_NOTFOUND); } *((struct hostent**)rval) = hptr; return (NS_SUCCESS); }
/*% This function has to be reachable by res_data.c but not publically. */ int __res_vinit(res_state statp, int preinit) { register FILE *fp; register char *cp, **pp; register int n; char path[PATH_MAX]; char buf[BUFSIZ]; int nserv = 0; /*%< number of nameserver records read from file */ int haveenv = 0; int havesearch = 0; #ifdef RESOLVSORT int nsort = 0; char *net; #endif int dots; union res_sockaddr_union u[2]; int maxns = MAXNS; RES_SET_H_ERRNO(statp, 0); if (statp->_u._ext.ext != NULL) res_ndestroy(statp); if (!preinit) { statp->retrans = RES_TIMEOUT; statp->retry = RES_DFLRETRY; statp->options = RES_DEFAULT; res_rndinit(statp); statp->id = res_nrandomid(statp); } memset(u, 0, sizeof(u)); #ifdef USELOOPBACK u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); #else u[nserv].sin.sin_addr.s_addr = INADDR_ANY; #endif u[nserv].sin.sin_family = AF_INET; u[nserv].sin.sin_port = htons(NAMESERVER_PORT); #ifdef HAVE_SA_LEN u[nserv].sin.sin_len = sizeof(struct sockaddr_in); #endif nserv++; #ifdef HAS_INET6_STRUCTS #ifdef USELOOPBACK u[nserv].sin6.sin6_addr = in6addr_loopback; #else u[nserv].sin6.sin6_addr = in6addr_any; #endif u[nserv].sin6.sin6_family = AF_INET6; u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT); #ifdef HAVE_SA_LEN u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6); #endif nserv++; #endif statp->nscount = 0; statp->ndots = 1; statp->pfcode = 0; statp->_vcsock = -1; statp->_flags = 0; statp->qhook = NULL; statp->rhook = NULL; statp->_u._ext.nscount = 0; statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext)); if (statp->_u._ext.ext != NULL) { memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext)); statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr; strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa"); strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int"); } else { /* * Historically res_init() rarely, if at all, failed. * Examples and applications exist which do not check * our return code. Furthermore several applications * simply call us to get the systems domainname. So * rather then immediately fail here we store the * failure, which is returned later, in h_errno. And * prevent the collection of 'nameserver' information * by setting maxns to 0. Thus applications that fail * to check our return code wont be able to make * queries anyhow. */ RES_SET_H_ERRNO(statp, NETDB_INTERNAL); maxns = 0; } #ifdef RESOLVSORT statp->nsort = 0; #endif res_setservers(statp, u, nserv); #ifdef SOLARIS2 /* * The old libresolv derived the defaultdomain from NIS/NIS+. * We want to keep this behaviour */ { char buf[sizeof(statp->defdname)], *cp; int ret; if ((ret = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf))) > 0 && (unsigned int)ret <= sizeof(buf)) { if (buf[0] == '+') buf[0] = '.'; cp = strchr(buf, '.'); cp = (cp == NULL) ? buf : (cp + 1); strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); statp->defdname[sizeof(statp->defdname) - 1] = '\0'; } } #endif /* SOLARIS2 */ /* Allow user to override the local domain definition */ if ((cp = getenv("LOCALDOMAIN")) != NULL) { (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); statp->defdname[sizeof(statp->defdname) - 1] = '\0'; haveenv++; /* * Set search list to be blank-separated strings * from rest of env value. Permits users of LOCALDOMAIN * to still have a search list, and anyone to set the * one that they want to use as an individual (even more * important now that the rfc1535 stuff restricts searches) */ cp = statp->defdname; pp = statp->dnsrch; *pp++ = cp; for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { if (*cp == '\n') /*%< silly backwards compat */ break; else if (*cp == ' ' || *cp == '\t') { *cp = 0; n = 1; } else if (n) { *pp++ = cp; n = 0; havesearch = 1; } } /* null terminate last domain if there are excess */ while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') cp++; *cp = '\0'; *pp++ = 0; } #define MATCH(line, name) \ (!strncmp(line, name, sizeof(name) - 1) && \ (line[sizeof(name) - 1] == ' ' || \ line[sizeof(name) - 1] == '\t')) if (find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false, path, sizeof(path)) == B_OK) strlcat(path, "/network/resolv.conf", sizeof(path)); nserv = 0; if ((fp = fopen(path, "r")) != NULL) { /* read the config file */ while (fgets(buf, sizeof(buf), fp) != NULL) { /* skip comments */ if (*buf == ';' || *buf == '#') continue; /* read default domain name */ if (MATCH(buf, "domain")) { if (haveenv) /*%< skip if have from environ */ continue; cp = buf + sizeof("domain") - 1; while (*cp == ' ' || *cp == '\t') cp++; if ((*cp == '\0') || (*cp == '\n')) continue; strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); statp->defdname[sizeof(statp->defdname) - 1] = '\0'; if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL) *cp = '\0'; havesearch = 0; continue; } /* set search list */ if (MATCH(buf, "search")) { if (haveenv) /*%< skip if have from environ */ continue; cp = buf + sizeof("search") - 1; while (*cp == ' ' || *cp == '\t') cp++; if ((*cp == '\0') || (*cp == '\n')) continue; strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); statp->defdname[sizeof(statp->defdname) - 1] = '\0'; if ((cp = strchr(statp->defdname, '\n')) != NULL) *cp = '\0'; /* * Set search list to be blank-separated strings * on rest of line. */ cp = statp->defdname; pp = statp->dnsrch; *pp++ = cp; for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { if (*cp == ' ' || *cp == '\t') { *cp = 0; n = 1; } else if (n) { *pp++ = cp; n = 0; } } /* null terminate last domain if there are excess */ while (*cp != '\0' && *cp != ' ' && *cp != '\t') cp++; *cp = '\0'; *pp++ = 0; havesearch = 1; continue; } /* read nameservers to query */ if (MATCH(buf, "nameserver") && nserv < maxns) { struct addrinfo hints, *ai; char sbuf[NI_MAXSERV]; const size_t minsiz = sizeof(statp->_u._ext.ext->nsaddrs[0]); cp = buf + sizeof("nameserver") - 1; while (*cp == ' ' || *cp == '\t') cp++; cp[strcspn(cp, ";# \t\n")] = '\0'; if ((*cp != '\0') && (*cp != '\n')) { memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_NUMERICHOST; sprintf(sbuf, "%u", NAMESERVER_PORT); if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 && ai->ai_addrlen <= minsiz) { if (statp->_u._ext.ext != NULL) { memcpy(&statp->_u._ext.ext->nsaddrs[nserv], ai->ai_addr, ai->ai_addrlen); } if (ai->ai_addrlen <= sizeof(statp->nsaddr_list[nserv])) { memcpy(&statp->nsaddr_list[nserv], ai->ai_addr, ai->ai_addrlen); } else statp->nsaddr_list[nserv].sin_family = 0; freeaddrinfo(ai); nserv++; } } continue; } #ifdef RESOLVSORT if (MATCH(buf, "sortlist")) { struct in_addr a; cp = buf + sizeof("sortlist") - 1; while (nsort < MAXRESOLVSORT) { while (*cp == ' ' || *cp == '\t') cp++; if (*cp == '\0' || *cp == '\n' || *cp == ';') break; net = cp; while (*cp && !ISSORTMASK(*cp) && *cp != ';' && isascii(*cp) && !isspace((unsigned char)*cp)) cp++; n = *cp; *cp = 0; if (inet_aton(net, &a)) { statp->sort_list[nsort].addr = a; if (ISSORTMASK(n)) { *cp++ = n; net = cp; while (*cp && *cp != ';' && isascii(*cp) && !isspace((unsigned char)*cp)) cp++; n = *cp; *cp = 0; if (inet_aton(net, &a)) { statp->sort_list[nsort].mask = a.s_addr; } else { statp->sort_list[nsort].mask = net_mask(statp->sort_list[nsort].addr); } } else { statp->sort_list[nsort].mask = net_mask(statp->sort_list[nsort].addr); } nsort++; } *cp = n; } continue; } #endif if (MATCH(buf, "options")) { res_setoptions(statp, buf + sizeof("options") - 1, "conf"); continue; } } if (nserv > 0) statp->nscount = nserv; #ifdef RESOLVSORT statp->nsort = nsort; #endif (void) fclose(fp); } /* * Last chance to get a nameserver. This should not normally * be necessary */ #ifdef NO_RESOLV_CONF if(nserv == 0) nserv = get_nameservers(statp); #endif if (statp->defdname[0] == 0 && gethostname(buf, sizeof(statp->defdname) - 1) == 0 && (cp = strchr(buf, '.')) != NULL) strcpy(statp->defdname, cp + 1); /* find components of local domain that might be searched */ if (havesearch == 0) { pp = statp->dnsrch; *pp++ = statp->defdname; *pp = NULL; dots = 0; for (cp = statp->defdname; *cp; cp++) dots += (*cp == '.'); cp = statp->defdname; while (pp < statp->dnsrch + MAXDFLSRCH) { if (dots < LOCALDOMAINPARTS) break; cp = strchr(cp, '.') + 1; /*%< we know there is one */ *pp++ = cp; dots--; } *pp = NULL; #ifdef DEBUG if (statp->options & RES_DEBUG) { printf(";; res_init()... default dnsrch list:\n"); for (pp = statp->dnsrch; *pp; pp++) printf(";;\t%s\n", *pp); printf(";;\t..END..\n"); } #endif } if ((cp = getenv("RES_OPTIONS")) != NULL) res_setoptions(statp, cp, "env"); statp->options |= RES_INIT; return (statp->res_h_errno); }
static int _gethostbynis(const char *name, char *map, int af, struct hostent *he, struct hostent_data *hed) { char *p, *bp, *ep; char *cp, **q; char *result; int resultlen, size, addrok = 0; char ypbuf[YPMAXRECORD + 2]; res_state statp; statp = __res_state(); switch(af) { case AF_INET: size = NS_INADDRSZ; break; case AF_INET6: size = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } if (hed->yp_domain == (char *)NULL) if (yp_get_default_domain (&hed->yp_domain)) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } if (yp_match(hed->yp_domain, map, name, strlen(name), &result, &resultlen)) { RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); return (-1); } /* avoid potential memory leak */ bcopy((char *)result, (char *)&ypbuf, resultlen); ypbuf[resultlen] = '\0'; free(result); result = (char *)&ypbuf; if ((cp = strchr(result, '\n'))) *cp = '\0'; cp = strpbrk(result, " \t"); *cp++ = '\0'; he->h_addr_list = hed->h_addr_ptrs; he->h_addr = (char *)hed->host_addr; switch (af) { case AF_INET: addrok = inet_aton(result, (struct in_addr *)hed->host_addr); if (addrok != 1) break; if (statp->options & RES_USE_INET6) { _map_v4v6_address((char *)hed->host_addr, (char *)hed->host_addr); af = AF_INET6; size = NS_IN6ADDRSZ; } break; case AF_INET6: addrok = inet_pton(af, result, hed->host_addr); break; } if (addrok != 1) { RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); return (-1); } he->h_addr_list[1] = NULL; he->h_length = size; he->h_addrtype = af; while (*cp == ' ' || *cp == '\t') cp++; bp = hed->hostbuf; ep = hed->hostbuf + sizeof hed->hostbuf; he->h_name = bp; q = he->h_aliases = hed->host_aliases; p = strpbrk(cp, " \t"); if (p != NULL) *p++ = '\0'; size = strlen(cp) + 1; if (ep - bp < size) { RES_SET_H_ERRNO(statp, NO_RECOVERY); return (-1); } strlcpy(bp, cp, ep - bp); bp += size; cp = p; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q >= &hed->host_aliases[_MAXALIASES - 1]) break; p = strpbrk(cp, " \t"); if (p != NULL) *p++ = '\0'; size = strlen(cp) + 1; if (ep - bp < size) break; strlcpy(bp, cp, ep - bp); *q++ = bp; bp += size; cp = p; } *q = NULL; return (0); }
static struct hostent * fakeaddr(const char *name, int af, struct net_data *net_data) { struct pvt *pvt; freepvt(net_data); net_data->ho_data = malloc(sizeof (struct pvt)); if (!net_data->ho_data) { errno = ENOMEM; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt = net_data->ho_data; #ifndef __bsdi__ /* * Unlike its forebear(inet_aton), our friendly inet_pton() is strict * in its interpretation of its input, and it will only return "1" if * the input string is a formally valid(and thus unambiguous with * respect to host names) internet address specification for this AF. * * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now. */ if (inet_pton(af, name, pvt->addr) != 1) { #else /* BSDI XXX * We put this back to inet_aton -- we really want the old behavior * Long live 127.1... */ if ((af != AF_INET || inet_aton(name, (struct in_addr *)pvt->addr) != 1) && inet_pton(af, name, pvt->addr) != 1) { #endif RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } strncpy(pvt->name, name, NS_MAXDNAME); pvt->name[NS_MAXDNAME] = '\0'; if (af == AF_INET && (net_data->res->options & RES_USE_INET6) != 0U) { map_v4v6_address(pvt->addr, pvt->addr); af = AF_INET6; } pvt->host.h_addrtype = af; switch(af) { case AF_INET: pvt->host.h_length = NS_INADDRSZ; break; case AF_INET6: pvt->host.h_length = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt->host.h_name = pvt->name; pvt->host.h_aliases = pvt->aliases; pvt->aliases[0] = NULL; pvt->addrs[0] = (char *)pvt->addr; pvt->addrs[1] = NULL; pvt->host.h_addr_list = pvt->addrs; RES_SET_H_ERRNO(net_data->res, NETDB_SUCCESS); return (&pvt->host); } #ifdef grot /*%< for future use in gethostbyaddr(), for "SUNSECURITY" */ struct hostent *rhp; char **haddr; u_long old_options; char hname2[MAXDNAME+1]; if (af == AF_INET) { /* * turn off search as the name should be absolute, * 'localhost' should be matched by defnames */ strncpy(hname2, hp->h_name, MAXDNAME); hname2[MAXDNAME] = '\0'; old_options = net_data->res->options; net_data->res->options &= ~RES_DNSRCH; net_data->res->options |= RES_DEFNAMES; if (!(rhp = gethostbyname(hname2))) { net_data->res->options = old_options; RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } net_data->res->options = old_options; for (haddr = rhp->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; if (!*haddr) { RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } }