getrrset.c revision 1200b067851fd29777e1154c41e85b9b041447bd
9e6de65c57eddc3790badaad3b9481aaaed18e03Brian Wellington/*
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 2000 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence * purpose with or without fee is hereby granted, provided that the above
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence * copyright notice and this permission notice appear in all copies.
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence */
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence
40e7c805a8f38ad9b20dd6c688496fc09fc971c2Mark Andrews/* $Id: getrrset.c,v 1.5 2000/12/21 00:27:53 bwelling Exp $ */
d09197467bbb156dccf0cbe72bb5c63480d5cfdcDavid Lawrence
d09197467bbb156dccf0cbe72bb5c63480d5cfdcDavid Lawrence#include <config.h>
d09197467bbb156dccf0cbe72bb5c63480d5cfdcDavid Lawrence
64ba6e4cc3a0ccf8c8c6349fa75b937ca9bad9a6Michael Graff#include <sys/types.h>
64ba6e4cc3a0ccf8c8c6349fa75b937ca9bad9a6Michael Graff#include <sys/socket.h>
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence#include <sys/un.h>
a03848252fa85734ca75beae3d0b01bb503c0a8bMark Andrews
dd57718608494835363244429432599aa15124a3Andreas Gustafsson#include <netinet/in.h>
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence
82a1986c04057804edf670bf5d59f716785af789Bob Halley#include <arpa/nameser.h>
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence#include <arpa/inet.h>
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence#include <string.h>
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence#include <errno.h>
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence#include <stdlib.h>
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence#include <lwres/lwres.h>
891a1bead8d02d29eb7b4993d7c0975047b0963dDavid Lawrence#include <lwres/net.h>
73d62a89f1493865c33c689b3ee3de91c74ad58eDavid Lawrence#include <lwres/netdb.h> /* XXX #include <netdb.h> */
73d62a89f1493865c33c689b3ee3de91c74ad58eDavid Lawrence
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence#include "assert_p.h"
cace8ff3bdf0d7f3501d1fb728f936d49a190471David Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic unsigned int
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrencelwresult_to_result(lwres_result_t lwresult) {
c80dde0676a7f36f65e0ad8d646bf505705fe64bDavid Lawrence switch (lwresult) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence default: return (ERRSET_FAIL);
c80dde0676a7f36f65e0ad8d646bf505705fe64bDavid Lawrence }
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence/*
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence * malloc / calloc functions that guarantee to only
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence * return NULL if there is an error, like they used
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence * to before the ANSI C committee broke them.
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence */
65bc8f2af875028fbccc88be77af5f396330d1a2Brian Wellington
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrencestatic void *
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrencesane_malloc(size_t size) {
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence if (size == 0)
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence size = 1;
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence return (malloc(size));
c4c843edb3f4c609e3552ee77a43400852400467David Lawrence}
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halleystatic void *
83e6eb0dfe7d3525dcf093f440e04e8971c4c5d2Brian Wellingtonsane_calloc(size_t number, size_t size) {
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence size_t len = number * size;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence void *mem = sane_malloc(len);
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence if (mem != NULL)
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence memset(mem, 0, len);
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence return (mem);
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence}
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrenceint
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrencelwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence unsigned int rdtype, unsigned int flags,
5d4f11b265c396d71ec2162a632e620425481a9eDavid Lawrence struct rrsetinfo **res)
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence{
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence lwres_context_t *lwrctx = NULL;
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence lwres_result_t lwresult;
a09c545af1ceb8eb6f3aa2bb6fae286208a72141David Lawrence lwres_grbnresponse_t *response = NULL;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence struct rrsetinfo *rrset = NULL;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence unsigned int i;
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence unsigned int lwflags;
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence unsigned int result;
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence if (rdclass > 0xffff || rdtype > 0xffff) {
cec7a04adc665a8c1029be008fd97c018c12c1b3David Lawrence result = ERRSET_INVAL;
a09c545af1ceb8eb6f3aa2bb6fae286208a72141David Lawrence goto fail;
a09c545af1ceb8eb6f3aa2bb6fae286208a72141David Lawrence }
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence /*
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence * Don't allow queries of class or type ANY
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence */
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence if (rdclass == 0xff || rdtype == 0xff) {
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence result = ERRSET_INVAL;
593d951248f799e90d30bc69bb89342000b012cdBob Halley goto fail;
82a1986c04057804edf670bf5d59f716785af789Bob Halley }
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence if (lwresult != LWRES_R_SUCCESS) {
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence result = lwresult_to_result(lwresult);
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence goto fail;
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence }
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence /*
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence * If any input flags were defined, lwflags would be set here
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence * based on them
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence */
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence UNUSED(flags);
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence lwflags = 0;
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence lwresult = lwres_getrdatabyname(lwrctx, hostname, rdclass, rdtype,
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence lwflags, &response);
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence if (lwresult != LWRES_R_SUCCESS) {
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrence result = lwresult_to_result(lwresult);
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence goto fail;
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence }
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence rrset = sane_malloc(sizeof(struct rrsetinfo));
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence if (rrset == NULL) {
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence result = ERRSET_NOMEMORY;
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence goto fail;
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence }
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence rrset->rri_name = NULL;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_rdclass = response->rdclass;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_rdtype = response->rdtype;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_ttl = response->ttl;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_flags = 0;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_nrdatas = 0;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_rdatas = NULL;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_nsigs = 0;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_sigs = NULL;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence rrset->rri_name = sane_malloc(response->realnamelen + 1);
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence if (rrset->rri_name == NULL) {
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence result = ERRSET_NOMEMORY;
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence goto fail;
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence }
f036af2c718147408d738081cdb0a564b981b4cdDavid Lawrence strncpy(rrset->rri_name, response->realname, response->realnamelen);
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley rrset->rri_name[response->realnamelen] = 0;
1630fce031f7a3e33f0579e477a3e17d1993e1f9Bob Halley
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews if ((response->flags & LWRDATA_VALIDATED) != 0)
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews rrset->rri_flags |= RRSET_VALIDATED;
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews rrset->rri_nrdatas = response->nrdatas;
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence sizeof(struct rdatainfo));
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence if (rrset->rri_rdatas == NULL) {
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence result = ERRSET_NOMEMORY;
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence goto fail;
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence }
bd1190c84b08e61a12789c54f083318c36449e5eDavid Lawrence for (i = 0; i < rrset->rri_nrdatas; i++) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
73d62a89f1493865c33c689b3ee3de91c74ad58eDavid Lawrence rrset->rri_rdatas[i].rdi_data =
bd1190c84b08e61a12789c54f083318c36449e5eDavid Lawrence sane_malloc(rrset->rri_rdatas[i].rdi_length);
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence if (rrset->rri_rdatas[i].rdi_data == NULL) {
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence result = ERRSET_NOMEMORY;
33950f0a0262f4d49528c4adcf8be42807fa2576David Lawrence goto fail;
84f8cc7e22cccde283627f6df6b8b74ec473cdc9David Lawrence }
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
bd1190c84b08e61a12789c54f083318c36449e5eDavid Lawrence rrset->rri_rdatas[i].rdi_length);
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence }
401fc772b1bf058a981e3c474fa6502f6ee0e2bfDavid Lawrence rrset->rri_nsigs = response->nsigs;
401fc772b1bf058a981e3c474fa6502f6ee0e2bfDavid Lawrence rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence sizeof(struct rdatainfo));
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence if (rrset->rri_sigs == NULL) {
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence result = ERRSET_NOMEMORY;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence goto fail;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence }
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence for (i = 0; i < rrset->rri_nsigs; i++) {
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence rrset->rri_sigs[i].rdi_length = response->siglen[i];
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence rrset->rri_sigs[i].rdi_data =
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence sane_malloc(rrset->rri_sigs[i].rdi_length);
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence if (rrset->rri_sigs[i].rdi_data == NULL) {
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence result = ERRSET_NOMEMORY;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence goto fail;
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence }
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
a571ebca8b8c472e775d518e82b7335f93ea25c4Andreas Gustafsson rrset->rri_sigs[i].rdi_length);
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence }
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence lwres_grbnresponse_free(lwrctx, &response);
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence lwres_context_destroy(&lwrctx);
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence *res = rrset;
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence return (ERRSET_SUCCESS);
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence fail:
a09c545af1ceb8eb6f3aa2bb6fae286208a72141David Lawrence if (rrset != NULL)
08e57545c2b1068080f5bf317224160426801406Brian Wellington lwres_freerrset(rrset);
7554feaef6057f5ea2926076900ac7634b911456Mark Andrews if (response != NULL)
40e7c805a8f38ad9b20dd6c688496fc09fc971c2Mark Andrews lwres_grbnresponse_free(lwrctx, &response);
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence if (lwrctx != NULL)
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence lwres_context_destroy(&lwrctx);
08e57545c2b1068080f5bf317224160426801406Brian Wellington return (result);
40e7c805a8f38ad9b20dd6c688496fc09fc971c2Mark Andrews
08e57545c2b1068080f5bf317224160426801406Brian Wellington}
08e57545c2b1068080f5bf317224160426801406Brian Wellington
0f5962ac3e4ef336faff68f1cb838505e64665e5David Lawrencevoid
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrencelwres_freerrset(struct rrsetinfo *rrset) {
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence unsigned int i;
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence for (i = 0; i < rrset->rri_nrdatas; i++) {
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence if (rrset->rri_rdatas[i].rdi_data == NULL)
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence break;
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence free(rrset->rri_rdatas[i].rdi_data);
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence }
b65f2ab14abb4b6ef906d7d02064fba158f07b1eDavid Lawrence free(rrset->rri_rdatas);
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence for (i = 0; i < rrset->rri_nsigs; i++) {
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence if (rrset->rri_sigs[i].rdi_data == NULL)
03052a178cb33b7d62ada0e34f1974e22bb98023David Lawrence break;
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence free(rrset->rri_sigs[i].rdi_data);
a03848252fa85734ca75beae3d0b01bb503c0a8bMark Andrews }
092b4e5359c5982a438e36ced3dbefc313f7fbfcDavid Lawrence free(rrset->rri_sigs);
f389bc2c9e9e434380e10221778b7b548612a67fDavid Lawrence free(rrset->rri_name);
a03848252fa85734ca75beae3d0b01bb503c0a8bMark Andrews}
40e7c805a8f38ad9b20dd6c688496fc09fc971c2Mark Andrews