diff options
author | dougb <dougb@FreeBSD.org> | 2011-07-16 10:49:33 +0000 |
---|---|---|
committer | dougb <dougb@FreeBSD.org> | 2011-07-16 10:49:33 +0000 |
commit | 387965661eaa775833b1e35b917f8e568ab7f5c6 (patch) | |
tree | cb160fa2acd93f24b5f5b9082cd3afc68396d51a /lib/export/samples/sample-update.c | |
parent | 499bf45e8f8ff10f88039acf04ae14976333a979 (diff) | |
download | FreeBSD-src-387965661eaa775833b1e35b917f8e568ab7f5c6.zip FreeBSD-src-387965661eaa775833b1e35b917f8e568ab7f5c6.tar.gz |
Vendor import of BIND 9.8.0-P4
Diffstat (limited to 'lib/export/samples/sample-update.c')
-rw-r--r-- | lib/export/samples/sample-update.c | 755 |
1 files changed, 755 insertions, 0 deletions
diff --git a/lib/export/samples/sample-update.c b/lib/export/samples/sample-update.c new file mode 100644 index 0000000..eef0a58 --- /dev/null +++ b/lib/export/samples/sample-update.c @@ -0,0 +1,755 @@ +/* + * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: sample-update.c,v 1.10 2010-12-09 00:54:34 marka Exp $ */ + +#include <config.h> + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <arpa/inet.h> + +#include <unistd.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> + +#include <isc/buffer.h> +#include <isc/lex.h> +#include <isc/lib.h> +#include <isc/mem.h> +#include <isc/parseint.h> +#include <isc/sockaddr.h> +#include <isc/util.h> + +#include <dns/callbacks.h> +#include <dns/client.h> +#include <dns/fixedname.h> +#include <dns/lib.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rdatalist.h> +#include <dns/rdataset.h> +#include <dns/rdatastruct.h> +#include <dns/rdatatype.h> +#include <dns/result.h> +#include <dns/secalg.h> +#include <dns/tsec.h> + +#include <dst/dst.h> + +static dns_tsec_t *tsec = NULL; +static const dns_rdataclass_t default_rdataclass = dns_rdataclass_in; +static isc_bufferlist_t usedbuffers; +static ISC_LIST(dns_rdatalist_t) usedrdatalists; + +static void setup_tsec(char *keyfile, isc_mem_t *mctx); +static void update_addordelete(isc_mem_t *mctx, char *cmdline, + isc_boolean_t isdelete, dns_name_t *name); +static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name); + +ISC_PLATFORM_NORETURN_PRE static void +usage(void) ISC_PLATFORM_NORETURN_POST; + +static void +usage(void) { + fprintf(stderr, "sample-update " + "[-a auth_server] " + "[-k keyfile] " + "[-p prerequisite] " + "[-r recursive_server] " + "[-z zonename] " + "(add|delete) \"name TTL RRtype RDATA\"\n"); + exit(1); +} + +int +main(int argc, char *argv[]) { + int ch; + struct addrinfo hints, *res; + int gai_error; + dns_client_t *client = NULL; + char *zonenamestr = NULL; + char *keyfilename = NULL; + char *prereqstr = NULL; + isc_sockaddrlist_t auth_servers; + char *auth_server = NULL; + char *recursive_server = NULL; + isc_sockaddr_t sa_auth, sa_recursive; + isc_sockaddrlist_t rec_servers; + isc_result_t result; + isc_boolean_t isdelete; + isc_buffer_t b, *buf; + dns_fixedname_t zname0, pname0, uname0; + size_t namelen; + dns_name_t *zname = NULL, *uname, *pname; + dns_rdataset_t *rdataset; + dns_rdatalist_t *rdatalist; + dns_rdata_t *rdata; + dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL; + isc_mem_t *umctx = NULL; + + while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) { + switch (ch) { + case 'k': + keyfilename = optarg; + break; + case 'a': + auth_server = optarg; + break; + case 'p': + prereqstr = optarg; + break; + case 'r': + recursive_server = optarg; + break; + case 'z': + zonenamestr = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc < 2) + usage(); + + /* command line argument validation */ + if (strcmp(argv[0], "delete") == 0) + isdelete = ISC_TRUE; + else if (strcmp(argv[0], "add") == 0) + isdelete = ISC_FALSE; + else { + fprintf(stderr, "invalid update command: %s\n", argv[0]); + exit(1); + } + + if (auth_server == NULL && recursive_server == NULL) { + fprintf(stderr, "authoritative or recursive server " + "must be specified\n"); + usage(); + } + + /* Initialization */ + ISC_LIST_INIT(usedbuffers); + ISC_LIST_INIT(usedrdatalists); + ISC_LIST_INIT(prereqlist); + ISC_LIST_INIT(auth_servers); + isc_lib_register(); + result = dns_lib_init(); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "dns_lib_init failed: %d\n", result); + exit(1); + } + result = isc_mem_create(0, 0, &umctx); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "failed to crate mctx\n"); + exit(1); + } + + result = dns_client_create(&client, 0); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "dns_client_create failed: %d\n", result); + exit(1); + } + + /* Set the authoritative server */ + if (auth_server != NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_NUMERICHOST; + gai_error = getaddrinfo(auth_server, "53", &hints, &res); + if (gai_error != 0) { + fprintf(stderr, "getaddrinfo failed: %s\n", + gai_strerror(gai_error)); + exit(1); + } + INSIST(res->ai_addrlen <= sizeof(sa_auth.type)); + memcpy(&sa_auth.type, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + sa_auth.length = res->ai_addrlen; + ISC_LINK_INIT(&sa_auth, link); + + ISC_LIST_APPEND(auth_servers, &sa_auth, link); + } + + /* Set the recursive server */ + if (recursive_server != NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_NUMERICHOST; + gai_error = getaddrinfo(recursive_server, "53", &hints, &res); + if (gai_error != 0) { + fprintf(stderr, "getaddrinfo failed: %s\n", + gai_strerror(gai_error)); + exit(1); + } + INSIST(res->ai_addrlen <= sizeof(sa_recursive.type)); + memcpy(&sa_recursive.type, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + sa_recursive.length = res->ai_addrlen; + ISC_LINK_INIT(&sa_recursive, link); + ISC_LIST_INIT(rec_servers); + ISC_LIST_APPEND(rec_servers, &sa_recursive, link); + result = dns_client_setservers(client, dns_rdataclass_in, + NULL, &rec_servers); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "set server failed: %d\n", result); + exit(1); + } + } + + /* Construct zone name */ + zname = NULL; + if (zonenamestr != NULL) { + namelen = strlen(zonenamestr); + isc_buffer_init(&b, zonenamestr, namelen); + isc_buffer_add(&b, namelen); + dns_fixedname_init(&zname0); + zname = dns_fixedname_name(&zname0); + result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) + fprintf(stderr, "failed to convert zone name: %d\n", + result); + } + + /* Construct prerequisite name (if given) */ + if (prereqstr != NULL) { + dns_fixedname_init(&pname0); + pname = dns_fixedname_name(&pname0); + evaluate_prereq(umctx, prereqstr, pname); + ISC_LIST_APPEND(prereqlist, pname, link); + prereqlistp = &prereqlist; + } + + /* Construct update name */ + ISC_LIST_INIT(updatelist); + dns_fixedname_init(&uname0); + uname = dns_fixedname_name(&uname0); + update_addordelete(umctx, argv[1], isdelete, uname); + ISC_LIST_APPEND(updatelist, uname, link); + + /* Set up TSIG/SIG(0) key (if given) */ + if (keyfilename != NULL) + setup_tsec(keyfilename, umctx); + + /* Perform update */ + result = dns_client_update(client, + default_rdataclass, /* XXX: fixed */ + zname, prereqlistp, &updatelist, + (auth_server == NULL) ? NULL : + &auth_servers, tsec, 0); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, + "update failed: %s\n", dns_result_totext(result)); + } else + fprintf(stderr, "update succeeded\n"); + + /* Cleanup */ + while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) { + while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) { + ISC_LIST_UNLINK(pname->list, rdataset, link); + dns_rdataset_disassociate(rdataset); + isc_mem_put(umctx, rdataset, sizeof(*rdataset)); + } + ISC_LIST_UNLINK(prereqlist, pname, link); + } + while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) { + while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) { + ISC_LIST_UNLINK(uname->list, rdataset, link); + dns_rdataset_disassociate(rdataset); + isc_mem_put(umctx, rdataset, sizeof(*rdataset)); + } + ISC_LIST_UNLINK(updatelist, uname, link); + } + while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) { + while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) { + ISC_LIST_UNLINK(rdatalist->rdata, rdata, link); + isc_mem_put(umctx, rdata, sizeof(*rdata)); + } + ISC_LIST_UNLINK(usedrdatalists, rdatalist, link); + isc_mem_put(umctx, rdatalist, sizeof(*rdatalist)); + } + while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) { + ISC_LIST_UNLINK(usedbuffers, buf, link); + isc_buffer_free(&buf); + } + if (tsec != NULL) + dns_tsec_destroy(&tsec); + isc_mem_destroy(&umctx); + dns_client_destroy(&client); + dns_lib_shutdown(); + + exit(0); +} + +/* + * Subroutines borrowed from nsupdate.c + */ +#define MAXWIRE (64 * 1024) +#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */ + +static char * +nsu_strsep(char **stringp, const char *delim) { + char *string = *stringp; + char *s; + const char *d; + char sc, dc; + + if (string == NULL) + return (NULL); + + for (; *string != '\0'; string++) { + sc = *string; + for (d = delim; (dc = *d) != '\0'; d++) { + if (sc == dc) + break; + } + if (dc == 0) + break; + } + + for (s = string; *s != '\0'; s++) { + sc = *s; + for (d = delim; (dc = *d) != '\0'; d++) { + if (sc == dc) { + *s++ = '\0'; + *stringp = s; + return (string); + } + } + } + *stringp = NULL; + return (string); +} + +static void +fatal(const char *format, ...) { + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} + +static inline void +check_result(isc_result_t result, const char *msg) { + if (result != ISC_R_SUCCESS) + fatal("%s: %s", msg, isc_result_totext(result)); +} + +static void +parse_name(char **cmdlinep, dns_name_t *name) { + isc_result_t result; + char *word; + isc_buffer_t source; + + word = nsu_strsep(cmdlinep, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read owner name\n"); + exit(1); + } + + isc_buffer_init(&source, word, strlen(word)); + isc_buffer_add(&source, strlen(word)); + result = dns_name_fromtext(name, &source, dns_rootname, 0, NULL); + check_result(result, "dns_name_fromtext"); + isc_buffer_invalidate(&source); +} + +static void +parse_rdata(isc_mem_t *mctx, char **cmdlinep, dns_rdataclass_t rdataclass, + dns_rdatatype_t rdatatype, dns_rdata_t *rdata) +{ + char *cmdline = *cmdlinep; + isc_buffer_t source, *buf = NULL, *newbuf = NULL; + isc_region_t r; + isc_lex_t *lex = NULL; + dns_rdatacallbacks_t callbacks; + isc_result_t result; + + while (cmdline != NULL && *cmdline != 0 && + isspace((unsigned char)*cmdline)) + cmdline++; + + if (cmdline != NULL && *cmdline != 0) { + dns_rdatacallbacks_init(&callbacks); + result = isc_lex_create(mctx, strlen(cmdline), &lex); + check_result(result, "isc_lex_create"); + isc_buffer_init(&source, cmdline, strlen(cmdline)); + isc_buffer_add(&source, strlen(cmdline)); + result = isc_lex_openbuffer(lex, &source); + check_result(result, "isc_lex_openbuffer"); + result = isc_buffer_allocate(mctx, &buf, MAXWIRE); + check_result(result, "isc_buffer_allocate"); + result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, + dns_rootname, 0, mctx, buf, + &callbacks); + isc_lex_destroy(&lex); + if (result == ISC_R_SUCCESS) { + isc_buffer_usedregion(buf, &r); + result = isc_buffer_allocate(mctx, &newbuf, r.length); + check_result(result, "isc_buffer_allocate"); + isc_buffer_putmem(newbuf, r.base, r.length); + isc_buffer_usedregion(newbuf, &r); + dns_rdata_reset(rdata); + dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); + isc_buffer_free(&buf); + ISC_LIST_APPEND(usedbuffers, newbuf, link); + } else { + fprintf(stderr, "invalid rdata format: %s\n", + isc_result_totext(result)); + isc_buffer_free(&buf); + exit(1); + } + } else { + rdata->flags = DNS_RDATA_UPDATE; + } + *cmdlinep = cmdline; +} + +static void +update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete, + dns_name_t *name) +{ + isc_result_t result; + isc_uint32_t ttl; + char *word; + dns_rdataclass_t rdataclass; + dns_rdatatype_t rdatatype; + dns_rdata_t *rdata = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdataset_t *rdataset = NULL; + isc_textregion_t region; + + /* + * Read the owner name. + */ + parse_name(&cmdline, name); + + rdata = isc_mem_get(mctx, sizeof(*rdata)); + if (rdata == NULL) { + fprintf(stderr, "memory allocation for rdata failed\n"); + exit(1); + } + dns_rdata_init(rdata); + + /* + * If this is an add, read the TTL and verify that it's in range. + * If it's a delete, ignore a TTL if present (for compatibility). + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (word == NULL || *word == 0) { + if (!isdelete) { + fprintf(stderr, "could not read owner ttl\n"); + exit(1); + } + else { + ttl = 0; + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } + } + result = isc_parse_uint32(&ttl, word, 10); + if (result != ISC_R_SUCCESS) { + if (isdelete) { + ttl = 0; + goto parseclass; + } else { + fprintf(stderr, "ttl '%s': %s\n", word, + isc_result_totext(result)); + exit(1); + } + } + + if (isdelete) + ttl = 0; + else if (ttl > TTL_MAX) { + fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", + word, TTL_MAX); + exit(1); + } + + /* + * Read the class or type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + parseclass: + if (word == NULL || *word == 0) { + if (isdelete) { + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } else { + fprintf(stderr, "could not read class or type\n"); + exit(1); + } + } + region.base = word; + region.length = strlen(word); + result = dns_rdataclass_fromtext(&rdataclass, ®ion); + if (result == ISC_R_SUCCESS) { + /* + * Now read the type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (word == NULL || *word == 0) { + if (isdelete) { + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } else { + fprintf(stderr, "could not read type\n"); + exit(1); + } + } + region.base = word; + region.length = strlen(word); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "'%s' is not a valid type: %s\n", + word, isc_result_totext(result)); + exit(1); + } + } else { + rdataclass = default_rdataclass; + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "'%s' is not a valid class or type: " + "%s\n", word, isc_result_totext(result)); + exit(1); + } + } + + parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata); + + if (isdelete) { + if ((rdata->flags & DNS_RDATA_UPDATE) != 0) + rdataclass = dns_rdataclass_any; + else + rdataclass = dns_rdataclass_none; + } else { + if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { + fprintf(stderr, "could not read rdata\n"); + exit(1); + } + } + + doneparsing: + + rdatalist = isc_mem_get(mctx, sizeof(*rdatalist)); + if (rdatalist == NULL) { + fprintf(stderr, "memory allocation for rdatalist failed\n"); + exit(1); + } + dns_rdatalist_init(rdatalist); + rdatalist->type = rdatatype; + rdatalist->rdclass = rdataclass; + rdatalist->covers = rdatatype; + rdatalist->ttl = (dns_ttl_t)ttl; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + ISC_LIST_APPEND(usedrdatalists, rdatalist, link); + + rdataset = isc_mem_get(mctx, sizeof(*rdataset)); + if (rdataset == NULL) { + fprintf(stderr, "memory allocation for rdataset failed\n"); + exit(1); + } + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); +} + +static void +make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive, + isc_boolean_t isrrset, dns_name_t *name) +{ + isc_result_t result; + char *word; + isc_textregion_t region; + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdataclass_t rdataclass; + dns_rdatatype_t rdatatype; + dns_rdata_t *rdata = NULL; + + /* + * Read the owner name + */ + parse_name(&cmdline, name); + + /* + * If this is an rrset prereq, read the class or type. + */ + if (isrrset) { + word = nsu_strsep(&cmdline, " \t\r\n"); + if (word == NULL || *word == 0) { + fprintf(stderr, "could not read class or type\n"); + exit(1); + } + region.base = word; + region.length = strlen(word); + result = dns_rdataclass_fromtext(&rdataclass, ®ion); + if (result == ISC_R_SUCCESS) { + /* + * Now read the type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (word == NULL || *word == 0) { + fprintf(stderr, "could not read type\n"); + exit(1); + } + region.base = word; + region.length = strlen(word); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "invalid type: %s\n", word); + exit(1); + } + } else { + rdataclass = default_rdataclass; + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "invalid type: %s\n", word); + exit(1); + } + } + } else + rdatatype = dns_rdatatype_any; + + rdata = isc_mem_get(mctx, sizeof(*rdata)); + if (rdata == NULL) { + fprintf(stderr, "memory allocation for rdata failed\n"); + exit(1); + } + dns_rdata_init(rdata); + + if (isrrset && ispositive) + parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata); + else + rdata->flags = DNS_RDATA_UPDATE; + + rdatalist = isc_mem_get(mctx, sizeof(*rdatalist)); + if (rdatalist == NULL) { + fprintf(stderr, "memory allocation for rdatalist failed\n"); + exit(1); + } + dns_rdatalist_init(rdatalist); + rdatalist->type = rdatatype; + if (ispositive) { + if (isrrset && rdata->data != NULL) + rdatalist->rdclass = rdataclass; + else + rdatalist->rdclass = dns_rdataclass_any; + } else + rdatalist->rdclass = dns_rdataclass_none; + rdatalist->covers = 0; + rdatalist->ttl = 0; + rdata->rdclass = rdatalist->rdclass; + rdata->type = rdatatype; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + ISC_LIST_APPEND(usedrdatalists, rdatalist, link); + + rdataset = isc_mem_get(mctx, sizeof(*rdataset)); + if (rdataset == NULL) { + fprintf(stderr, "memory allocation for rdataset failed\n"); + exit(1); + } + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); +} + +static void +evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name) { + char *word; + isc_boolean_t ispositive, isrrset; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (word == NULL || *word == 0) { + fprintf(stderr, "could not read operation code\n"); + exit(1); + } + if (strcasecmp(word, "nxdomain") == 0) { + ispositive = ISC_FALSE; + isrrset = ISC_FALSE; + } else if (strcasecmp(word, "yxdomain") == 0) { + ispositive = ISC_TRUE; + isrrset = ISC_FALSE; + } else if (strcasecmp(word, "nxrrset") == 0) { + ispositive = ISC_FALSE; + isrrset = ISC_TRUE; + } else if (strcasecmp(word, "yxrrset") == 0) { + ispositive = ISC_TRUE; + isrrset = ISC_TRUE; + } else { + fprintf(stderr, "incorrect operation code: %s\n", word); + exit(1); + } + + make_prereq(mctx, cmdline, ispositive, isrrset, name); +} + +static void +setup_tsec(char *keyfile, isc_mem_t *mctx) { + dst_key_t *dstkey = NULL; + isc_result_t result; + dns_tsectype_t tsectype; + + result = dst_key_fromnamedfile(keyfile, NULL, + DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, + &dstkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not read key from %s: %s\n", + keyfile, isc_result_totext(result)); + exit(1); + } + + if (dst_key_alg(dstkey) == DST_ALG_HMACMD5) + tsectype = dns_tsectype_tsig; + else + tsectype = dns_tsectype_sig0; + + result = dns_tsec_create(mctx, tsectype, dstkey, &tsec); + dst_key_free(&dstkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not create tsec: %s\n", + isc_result_totext(result)); + exit(1); + } +} |