X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/67467c307203d29637f396afa605ac6577e1fb32..7be182d4906b34f434845222c75a1af1a1644733:/openbsd-compat/getrrsetbyname.c diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c index 1a4d9c14..785b2256 100644 --- a/openbsd-compat/getrrsetbyname.c +++ b/openbsd-compat/getrrsetbyname.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */ +/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */ /* * Copyright (c) 2001 Jakob Schlyter. All rights reserved. @@ -43,50 +43,35 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ + #include "includes.h" -#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME) +#ifndef HAVE_GETRRSETBYNAME -#include "getrrsetbyname.h" +#include +#include -#define ANSWER_BUFFER_SIZE 1024*64 - -struct dns_query { - char *name; - u_int16_t type; - u_int16_t class; - struct dns_query *next; -}; +#include +#include -struct dns_rr { - char *name; - u_int16_t type; - u_int16_t class; - u_int16_t ttl; - u_int16_t size; - void *rdata; - struct dns_rr *next; -}; +#include "getrrsetbyname.h" -struct dns_response { - HEADER header; - struct dns_query *query; - struct dns_rr *answer; - struct dns_rr *authority; - struct dns_rr *additional; -}; +#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO +extern int h_errno; +#endif -static struct dns_response *parse_dns_response(const char *, int); -static struct dns_query *parse_dns_qsection(const char *, int, const char **, - int); -static struct dns_rr *parse_dns_rrsection(const char *, int, const char **, - int); +/* We don't need multithread support here */ +#ifdef _THREAD_PRIVATE +# undef _THREAD_PRIVATE +#endif +#define _THREAD_PRIVATE(a,b,c) (c) -static void free_dns_query(struct dns_query *); -static void free_dns_rr(struct dns_rr *); -static void free_dns_response(struct dns_response *); +#ifndef HAVE__RES_EXTERN +struct __res_state _res; +#endif -static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); +/* Necessary functions and macros */ /* * Inline versions of get/put short/long. Pointer is advanced. @@ -128,6 +113,7 @@ static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); * Routines to insert/extract short/long's. */ +#ifndef HAVE__GETSHORT static u_int16_t _getshort(msgp) register const u_char *msgp; @@ -137,7 +123,11 @@ _getshort(msgp) GETSHORT(u, msgp); return (u); } +#elif defined(HAVE_DECL__GETSHORT) && (HAVE_DECL__GETSHORT == 0) +u_int16_t _getshort(register const u_char *); +#endif +#ifndef HAVE__GETLONG static u_int32_t _getlong(msgp) register const u_char *msgp; @@ -147,19 +137,65 @@ _getlong(msgp) GETLONG(u, msgp); return (u); } +#elif defined(HAVE_DECL__GETLONG) && (HAVE_DECL__GETLONG == 0) +u_int32_t _getlong(register const u_char *); +#endif + +/* ************** */ + +#define ANSWER_BUFFER_SIZE 1024*64 + +struct dns_query { + char *name; + u_int16_t type; + u_int16_t class; + struct dns_query *next; +}; + +struct dns_rr { + char *name; + u_int16_t type; + u_int16_t class; + u_int16_t ttl; + u_int16_t size; + void *rdata; + struct dns_rr *next; +}; + +struct dns_response { + HEADER header; + struct dns_query *query; + struct dns_rr *answer; + struct dns_rr *authority; + struct dns_rr *additional; +}; + +static struct dns_response *parse_dns_response(const u_char *, int); +static struct dns_query *parse_dns_qsection(const u_char *, int, + const u_char **, int); +static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, + int); + +static void free_dns_query(struct dns_query *); +static void free_dns_rr(struct dns_rr *); +static void free_dns_response(struct dns_response *); + +static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); int getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { + struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); int result; struct rrsetinfo *rrset = NULL; - struct dns_response *response; + struct dns_response *response = NULL; struct dns_rr *rr; struct rdatainfo *rdata; - unsigned int length, index_ans, index_sig; - char answer[ANSWER_BUFFER_SIZE]; + int length; + unsigned int index_ans, index_sig; + u_char answer[ANSWER_BUFFER_SIZE]; /* check for invalid class and type */ if (rdclass > 0xffff || rdtype > 0xffff) { @@ -180,23 +216,24 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, } /* initialize resolver */ - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { result = ERRSET_FAIL; goto fail; } #ifdef DEBUG - _res.options |= RES_DEBUG; + _resp->options |= RES_DEBUG; #endif /* DEBUG */ #ifdef RES_USE_DNSSEC /* turn on DNSSEC if EDNS0 is configured */ - if (_res.options & RES_USE_EDNS0) - _res.options |= RES_USE_DNSSEC; + if (_resp->options & RES_USE_EDNS0) + _resp->options |= RES_USE_DNSSEC; #endif /* RES_USE_DNSEC */ /* make query */ - length = res_query(hostname, rdclass, rdtype, answer, sizeof(answer)); + length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, + answer, sizeof(answer)); if (length < 0) { switch(h_errno) { case HOST_NOT_FOUND: @@ -234,24 +271,24 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, rrset->rri_ttl = response->answer->ttl; rrset->rri_nrdatas = response->header.ancount; +#ifdef HAVE_HEADER_AD /* check for authenticated data */ if (response->header.ad == 1) rrset->rri_flags |= RRSET_VALIDATED; +#endif /* copy name from answer section */ - length = strlen(response->answer->name); - rrset->rri_name = malloc(length + 1); + rrset->rri_name = strdup(response->answer->name); if (rrset->rri_name == NULL) { result = ERRSET_NOMEMORY; goto fail; } - strlcpy(rrset->rri_name, response->answer->name, length + 1); /* count answers */ rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, rrset->rri_rdtype); rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, - T_SIG); + T_RRSIG); /* allocate memory for answers */ rrset->rri_rdatas = calloc(rrset->rri_nrdatas, @@ -262,10 +299,12 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, } /* allocate memory for signatures */ - rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); - if (rrset->rri_sigs == NULL) { - result = ERRSET_NOMEMORY; - goto fail; + if (rrset->rri_nsigs > 0) { + rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } } /* copy answers & signatures */ @@ -279,7 +318,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, rdata = &rrset->rri_rdatas[index_ans++]; if (rr->class == rrset->rri_rdclass && - rr->type == T_SIG) + rr->type == T_RRSIG) rdata = &rrset->rri_sigs[index_sig++]; if (rdata) { @@ -293,6 +332,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, memcpy(rdata->rdi_data, rr->rdata, rr->size); } } + free_dns_response(response); *res = rrset; return (ERRSET_SUCCESS); @@ -300,6 +340,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, fail: if (rrset != NULL) freerrset(rrset); + if (response != NULL) + free_dns_response(response); return (result); } @@ -338,10 +380,10 @@ freerrset(struct rrsetinfo *rrset) * DNS response parsing routines */ static struct dns_response * -parse_dns_response(const char *answer, int size) +parse_dns_response(const u_char *answer, int size) { struct dns_response *resp; - const char *cp; + const u_char *cp; /* allocate memory for the response */ resp = calloc(1, sizeof(*resp)); @@ -403,7 +445,7 @@ parse_dns_response(const char *answer, int size) } static struct dns_query * -parse_dns_qsection(const char *answer, int size, const char **cp, int count) +parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) { struct dns_query *head, *curr, *prev; int i, length; @@ -449,7 +491,8 @@ parse_dns_qsection(const char *answer, int size, const char **cp, int count) } static struct dns_rr * -parse_dns_rrsection(const char *answer, int size, const char **cp, int count) +parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, + int count) { struct dns_rr *head, *curr, *prev; int i, length; @@ -564,4 +607,4 @@ count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) return (n); } -#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */ +#endif /* !defined(HAVE_GETRRSETBYNAME) */