]> andersk Git - openssh.git/blobdiff - openbsd-compat/getrrsetbyname.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / openbsd-compat / getrrsetbyname.c
index 03637c9ef693c884469ef3d210f5aea9118018de..98876673d0027c8c624e141657a4fbbb6677953c 100644 (file)
@@ -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.
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
+
 #include "includes.h"
 
 #ifndef HAVE_GETRRSETBYNAME
 
-#include "getrrsetbyname.h"
-
-#define ANSWER_BUFFER_SIZE 1024*64
+#include <stdlib.h>
+#include <string.h>
 
-struct dns_query {
-       char                    *name;
-       u_int16_t               type;
-       u_int16_t               class;
-       struct dns_query        *next;
-};
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
-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 0xffff
+
+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 /* HAVE_GETRRSETBYNAME */
+#endif /* !defined(HAVE_GETRRSETBYNAME) */
This page took 0.110452 seconds and 4 git commands to generate.