1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <inttypes.h>
#include <string.h>
#include <isc/buffer.h>
#include <isc/util.h>
#include <dns/rdata.h>
#include <dns/rdatastruct.h>
#include <dns/soa.h>
static uint32_t
decode_uint32(unsigned char *p) {
return (((uint32_t)p[0] << 24) + ((uint32_t)p[1] << 16) +
((uint32_t)p[2] << 8) + ((uint32_t)p[3] << 0));
}
static void
encode_uint32(uint32_t val, unsigned char *p) {
p[0] = (uint8_t)(val >> 24);
p[1] = (uint8_t)(val >> 16);
p[2] = (uint8_t)(val >> 8);
p[3] = (uint8_t)(val >> 0);
}
static uint32_t
soa_get(dns_rdata_t *rdata, int offset) {
INSIST(rdata->type == dns_rdatatype_soa);
/*
* Locate the field within the SOA RDATA based
* on its position relative to the end of the data.
*
* This is a bit of a kludge, but the alternative approach of
* using dns_rdata_tostruct() and dns_rdata_fromstruct() would
* involve a lot of unnecessary work (like building domain
* names and allocating temporary memory) when all we really
* want to do is to get 32 bits of fixed-sized data.
*/
INSIST(rdata->length >= 20);
INSIST(offset >= 0 && offset <= 16);
return (decode_uint32(rdata->data + rdata->length - 20 + offset));
}
isc_result_t
dns_soa_buildrdata(const dns_name_t *origin, const dns_name_t *contact,
dns_rdataclass_t rdclass, uint32_t serial, uint32_t refresh,
uint32_t retry, uint32_t expire, uint32_t minimum,
unsigned char *buffer, dns_rdata_t *rdata) {
dns_rdata_soa_t soa;
isc_buffer_t rdatabuf;
REQUIRE(origin != NULL);
REQUIRE(contact != NULL);
memset(buffer, 0, DNS_SOA_BUFFERSIZE);
isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE);
soa.common.rdtype = dns_rdatatype_soa;
soa.common.rdclass = rdclass;
soa.mctx = NULL;
soa.serial = serial;
soa.refresh = refresh;
soa.retry = retry;
soa.expire = expire;
soa.minimum = minimum;
dns_name_init(&soa.origin, NULL);
dns_name_clone(origin, &soa.origin);
dns_name_init(&soa.contact, NULL);
dns_name_clone(contact, &soa.contact);
return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_soa, &soa,
&rdatabuf));
}
uint32_t
dns_soa_getserial(dns_rdata_t *rdata) {
return (soa_get(rdata, 0));
}
uint32_t
dns_soa_getrefresh(dns_rdata_t *rdata) {
return (soa_get(rdata, 4));
}
uint32_t
dns_soa_getretry(dns_rdata_t *rdata) {
return (soa_get(rdata, 8));
}
uint32_t
dns_soa_getexpire(dns_rdata_t *rdata) {
return (soa_get(rdata, 12));
}
uint32_t
dns_soa_getminimum(dns_rdata_t *rdata) {
return (soa_get(rdata, 16));
}
static void
soa_set(dns_rdata_t *rdata, uint32_t val, int offset) {
INSIST(rdata->type == dns_rdatatype_soa);
INSIST(rdata->length >= 20);
INSIST(offset >= 0 && offset <= 16);
encode_uint32(val, rdata->data + rdata->length - 20 + offset);
}
void
dns_soa_setserial(uint32_t val, dns_rdata_t *rdata) {
soa_set(rdata, val, 0);
}
void
dns_soa_setrefresh(uint32_t val, dns_rdata_t *rdata) {
soa_set(rdata, val, 4);
}
void
dns_soa_setretry(uint32_t val, dns_rdata_t *rdata) {
soa_set(rdata, val, 8);
}
void
dns_soa_setexpire(uint32_t val, dns_rdata_t *rdata) {
soa_set(rdata, val, 12);
}
void
dns_soa_setminimum(uint32_t val, dns_rdata_t *rdata) {
soa_set(rdata, val, 16);
}
|