From 359f287f5157e24e483c8fdd6b54a0ba7b4701dc Mon Sep 17 00:00:00 2001 From: ume Date: Mon, 2 May 2005 09:34:07 +0000 Subject: teach IPv6 to async DNS resolver in ypserv: - query AAAA RR on ipnodes.byname query. - query .ip6.arpa. on ipnodes.byaddr query. --- usr.sbin/ypserv/yp_dnslookup.c | 67 +++++++++++++++++++++++++++++------------- usr.sbin/ypserv/yp_extern.h | 4 +-- usr.sbin/ypserv/yp_server.c | 17 ++++++++--- 3 files changed, 61 insertions(+), 27 deletions(-) (limited to 'usr.sbin/ypserv') diff --git a/usr.sbin/ypserv/yp_dnslookup.c b/usr.sbin/ypserv/yp_dnslookup.c index a5c8eab..75c3820 100644 --- a/usr.sbin/ypserv/yp_dnslookup.c +++ b/usr.sbin/ypserv/yp_dnslookup.c @@ -69,12 +69,15 @@ parse(struct hostent *hp) { static char result[MAXHOSTNAMELEN * 2]; int len,i; - struct in_addr addr; + char addr[46]; if (hp == NULL) return(NULL); - len = 16 + strlen(hp->h_name); + if (inet_ntop(hp->h_addrtype, hp->h_addr, addr, sizeof(addr)) == NULL) + return(NULL); + + len = strlen(addr) + 1 + strlen(hp->h_name); for (i = 0; hp->h_aliases[i]; i++) len += strlen(hp->h_aliases[i]) + 1; len++; @@ -83,10 +86,7 @@ parse(struct hostent *hp) return(NULL); bzero(result, sizeof(result)); - - bcopy(hp->h_addr, &addr, sizeof(struct in_addr)); - snprintf(result, sizeof(result), "%s %s", inet_ntoa(addr), hp->h_name); - + snprintf(result, sizeof(result), "%s %s", addr, hp->h_name); for (i = 0; hp->h_aliases[i]; i++) { strcat(result, " "); strcat(result, hp->h_aliases[i]); @@ -95,7 +95,7 @@ parse(struct hostent *hp) return ((char *)&result); } -#define MAXPACKET 1024 +#define MAXPACKET (64*1024) #define DEF_TTL 50 #define BY_DNS_ID 1 @@ -116,7 +116,9 @@ struct circleq_dnsentry { unsigned short prot_type; char **domain; char *name; - struct in_addr addr; + int addrtype; + int addrlen; + uint32_t addr[4]; /* IPv4 or IPv6 */ TAILQ_ENTRY(circleq_dnsentry) links; }; @@ -386,8 +388,9 @@ yp_run_dnsq(void) if (hent != NULL) { if (q->type == T_PTR) { - hent->h_addr = (char *)&q->addr.s_addr; - hent->h_length = sizeof(struct in_addr); + hent->h_addr = (char *)q->addr; + hent->h_addrtype = q->addrtype; + hent->h_length = q->addrlen; } } @@ -408,7 +411,7 @@ yp_run_dnsq(void) * Queue and transmit an asynchronous DNS hostname lookup. */ ypstat -yp_async_lookup_name(struct svc_req *rqstp, char *name) +yp_async_lookup_name(struct svc_req *rqstp, char *name, int af) { register struct circleq_dnsentry *q; socklen_t len; @@ -431,7 +434,7 @@ yp_async_lookup_name(struct svc_req *rqstp, char *name) if ((q = yp_malloc_dnsent()) == NULL) return(YP_YPERR); - q->type = T_A; + q->type = (af == AF_INET) ? T_A : T_AAAA; q->ttl = DEF_TTL; q->xprt = rqstp->rq_xprt; q->ypvers = rqstp->rq_vers; @@ -463,13 +466,14 @@ yp_async_lookup_name(struct svc_req *rqstp, char *name) * Queue and transmit an asynchronous DNS IP address lookup. */ ypstat -yp_async_lookup_addr(struct svc_req *rqstp, char *addr) +yp_async_lookup_addr(struct svc_req *rqstp, char *addr, int af) { register struct circleq_dnsentry *q; - char buf[MAXHOSTNAMELEN]; + char buf[MAXHOSTNAMELEN], *qp; + uint32_t abuf[4]; /* IPv4 or IPv6 */ + u_char *uaddr = (u_char *)abuf; socklen_t len; - int a, b, c, d; - int type; + int type, n; /* Check for SOCK_DGRAM or SOCK_STREAM -- we need to know later */ type = -1; @@ -488,10 +492,29 @@ yp_async_lookup_addr(struct svc_req *rqstp, char *addr) if ((q = yp_malloc_dnsent()) == NULL) return(YP_YPERR); - if (sscanf(addr, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) - return(YP_NOKEY); - - snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", d, c, b, a); + switch (af) { + case AF_INET: + if (inet_aton(addr, (struct in_addr *)uaddr) != 1) + return(YP_NOKEY); + snprintf(buf, sizeof(buf), "%u.%u.%u.%u.in-addr.arpa", + (uaddr[3] & 0xff), (uaddr[2] & 0xff), + (uaddr[1] & 0xff), (uaddr[0] & 0xff)); + len = INADDRSZ; + break; + case AF_INET6: + if (inet_pton(af, addr, uaddr) != 1) + return(YP_NOKEY); + qp = buf; + for (n = IN6ADDRSZ - 1; n >= 0; n--) { + qp += (size_t)sprintf(qp, "%x.%x.", uaddr[n] & 0xf, + (uaddr[n] >> 4) & 0xf); + } + strlcat(buf, "ip6.arpa", sizeof(buf)); + len = IN6ADDRSZ; + break; + default: + return(YP_YPERR); + } if (debug) yp_error("DNS address is: %s", buf); @@ -513,7 +536,9 @@ yp_async_lookup_addr(struct svc_req *rqstp, char *addr) return(YP_YPERR); } - inet_aton(addr, &q->addr); + memcpy(q->addr, uaddr, len); + q->addrlen = len; + q->addrtype = af; q->name = strdup(buf); TAILQ_INSERT_HEAD(&qhead, q, links); pending++; diff --git a/usr.sbin/ypserv/yp_extern.h b/usr.sbin/ypserv/yp_extern.h index 553e296..2e574b6 100644 --- a/usr.sbin/ypserv/yp_extern.h +++ b/usr.sbin/ypserv/yp_extern.h @@ -111,5 +111,5 @@ extern unsigned long svcudp_get_xid(SVCXPRT *); extern int yp_init_resolver(void); extern void yp_run_dnsq(void); extern void yp_prune_dnsq(void); -extern ypstat yp_async_lookup_name(struct svc_req *, char *); -extern ypstat yp_async_lookup_addr(struct svc_req *, char *); +extern ypstat yp_async_lookup_name(struct svc_req *, char *, int); +extern ypstat yp_async_lookup_addr(struct svc_req *, char *, int); diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c index e6d82d6..8bd658b 100644 --- a/usr.sbin/ypserv/yp_server.c +++ b/usr.sbin/ypserv/yp_server.c @@ -166,9 +166,10 @@ ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp) #ifdef DB_CACHE if (result.stat != YP_TRUE && (yp_testflag(argp->map, argp->domain, YP_INTERDOMAIN) || - (strstr(argp->map, "hosts") && do_dns))) { + ((strstr(argp->map, "hosts") || strstr(argp->map, "ipnode")) && do_dns))) { #else - if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) { + if (do_dns && result.stat != YP_TRUE && + (strstr(argp->map, "hosts") || strstr(argp->map, "ipnode"))) { #endif char nbuf[YPMAXRECORD]; @@ -180,9 +181,17 @@ ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp) yp_error("doing DNS lookup of %s", nbuf); if (!strcmp(argp->map, "hosts.byname")) - result.stat = yp_async_lookup_name(rqstp, nbuf); + result.stat = yp_async_lookup_name(rqstp, nbuf, + AF_INET); else if (!strcmp(argp->map, "hosts.byaddr")) - result.stat = yp_async_lookup_addr(rqstp, nbuf); + result.stat = yp_async_lookup_addr(rqstp, nbuf, + AF_INET); + else if (!strcmp(argp->map, "ipnodes.byname")) + result.stat = yp_async_lookup_name(rqstp, nbuf, + AF_INET6); + else if (!strcmp(argp->map, "ipnodes.byaddr")) + result.stat = yp_async_lookup_addr(rqstp, nbuf, + AF_INET6); if (result.stat == YP_TRUE) return(NULL); -- cgit v1.1