diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2012-12-17 21:13:17 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2012-12-17 21:13:17 +0000 |
commit | ac836cfbe67d07e6ef610bb496dedd25ecbd6c9c (patch) | |
tree | 8e4873f5fe1da7a807d71a47519684669868bb02 /lib/libc/asr | |
parent | a2782a09b5d31ed9fef7895728f28d41d219e9b2 (diff) |
Allow gethostbyname() to accept a numeric IP string.
No lookup is done in this case.
regression reported by espie@
Diffstat (limited to 'lib/libc/asr')
-rw-r--r-- | lib/libc/asr/gethostnamadr_async.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/lib/libc/asr/gethostnamadr_async.c b/lib/libc/asr/gethostnamadr_async.c index 0283a77bd40..580f618613e 100644 --- a/lib/libc/asr/gethostnamadr_async.c +++ b/lib/libc/asr/gethostnamadr_async.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gethostnamadr_async.c,v 1.11 2012/11/24 18:58:49 eric Exp $ */ +/* $OpenBSD: gethostnamadr_async.c,v 1.12 2012/12/17 21:13:16 eric Exp $ */ /* * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> * @@ -27,6 +27,7 @@ #include "ypinternal.h" #endif +#include <ctype.h> #include <err.h> #include <errno.h> #include <stdlib.h> @@ -54,6 +55,7 @@ static struct hostent_ext *hostent_alloc(int); static int hostent_set_cname(struct hostent_ext *, const char *, int); static int hostent_add_alias(struct hostent_ext *, const char *, int); static int hostent_add_addr(struct hostent_ext *, const void *, size_t); +static struct hostent_ext *hostent_from_addr(int, const char *, const char *); static struct hostent_ext *hostent_file_match(FILE *, int, int, const char *, int); static struct hostent_ext *hostent_from_packet(int, int, char *, size_t); @@ -146,7 +148,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar) struct hostent_ext *h; int r, type, saved_errno; FILE *f; - char dname[MAXDNAME], *data; + char dname[MAXDNAME], *data, addr[16], *c; next: switch (as->as_state) { @@ -171,8 +173,29 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar) break; } - if (as->as_type == ASR_GETHOSTBYNAME) - async_set_state(as, ASR_STATE_NEXT_DOMAIN); + /* Name might be an IP address string */ + if (as->as_type == ASR_GETHOSTBYNAME) { + for (c = as->as.hostnamadr.name; *c; c++) + if (!isdigit(*c) && *c != '.' && *c != ':') + break; + if (*c == 0 && + inet_pton(as->as.hostnamadr.family, + as->as.hostnamadr.name, addr) == 1) { + h = hostent_from_addr(as->as.hostnamadr.family, + as->as.hostnamadr.name, addr); + if (h == NULL) { + ar->ar_errno = errno; + ar->ar_h_errno = NETDB_INTERNAL; + } + else { + ar->ar_hostent = &h->h; + ar->ar_h_errno = NETDB_SUCCESS; + } + async_set_state(as, ASR_STATE_HALT); + } + else + async_set_state(as, ASR_STATE_NEXT_DOMAIN); + } else async_set_state(as, ASR_STATE_NEXT_DB); break; @@ -382,6 +405,26 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar) } /* + * Create a hostent from a numeric address string. + */ +static struct hostent_ext * +hostent_from_addr(int family, const char *name, const char *addr) +{ + struct hostent_ext *h; + + if ((h = hostent_alloc(family)) == NULL) + return (NULL); + if (hostent_set_cname(h, name, 0) == -1) + goto fail; + if (hostent_add_addr(h, addr, h->h.h_length) == -1) + goto fail; + return (h); +fail: + free(h); + return (NULL); +} + +/* * Lookup the first matching entry in the hostfile, either by address or by * name depending on reqtype, and build a hostent from the line. */ |