1 /* $NetBSD: dnsrps.c,v 1.4 2020/05/24 19:46:18 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14 /* 15 * -a exit(0) if dnsrps is available or dlopen() msg if not 16 * -p print the path to dnsrpzd configured in dnsrps so that 17 * dnsrpzd can be run by a setup.sh script. 18 * Exit(1) if dnsrps is not available 19 * -n domain print the serial number of a domain to check if a new 20 * version of a policy zone has been transferred to dnsrpzd. 21 * Exit(1) if dnsrps is not available 22 * -w sec.ond wait for seconds, because `sleep 0.1` is not portable 23 */ 24 25 #include <errno.h> 26 #include <inttypes.h> 27 #include <stdbool.h> 28 #include <stdint.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <sys/stat.h> 33 #include <sys/types.h> 34 #include <unistd.h> 35 36 #include <isc/print.h> 37 #include <isc/util.h> 38 39 #ifdef USE_DNSRPS 40 #define LIBRPZ_LIB_OPEN DNSRPS_LIB_OPEN 41 #include <dns/librpz.h> 42 43 librpz_t *librpz; 44 #else /* ifdef USE_DNSRPS */ 45 typedef struct { 46 char c[120]; 47 } librpz_emsg_t; 48 #endif /* ifdef USE_DNSRPS */ 49 50 static bool 51 link_dnsrps(librpz_emsg_t *emsg); 52 53 #define USAGE "usage: [-ap] [-n domain] [-w sec.onds]\n" 54 55 int 56 main(int argc, char **argv) { 57 #ifdef USE_DNSRPS 58 char cstr[sizeof("zone ") + 1024 + 10]; 59 librpz_clist_t *clist; 60 librpz_client_t *client; 61 librpz_rsp_t *rsp; 62 uint32_t serial; 63 #endif /* ifdef USE_DNSRPS */ 64 double seconds; 65 librpz_emsg_t emsg; 66 char *p; 67 int i; 68 69 while ((i = getopt(argc, argv, "apn:w:")) != -1) { 70 switch (i) { 71 case 'a': 72 if (!link_dnsrps(&emsg)) { 73 printf("I:%s\n", emsg.c); 74 return (1); 75 } 76 return (0); 77 78 case 'p': 79 if (!link_dnsrps(&emsg)) { 80 fprintf(stderr, "## %s\n", emsg.c); 81 return (1); 82 } 83 #ifdef USE_DNSRPS 84 printf("%s\n", librpz->dnsrpzd_path); 85 #else /* ifdef USE_DNSRPS */ 86 INSIST(0); 87 ISC_UNREACHABLE(); 88 #endif /* ifdef USE_DNSRPS */ 89 return (0); 90 91 case 'n': 92 if (!link_dnsrps(&emsg)) { 93 fprintf(stderr, "## %s\n", emsg.c); 94 return (1); 95 } 96 #ifdef USE_DNSRPS 97 /* 98 * Get the serial number of a policy zone from 99 * a running dnsrpzd daemon. 100 */ 101 clist = librpz->clist_create(&emsg, NULL, NULL, NULL, 102 NULL, NULL); 103 if (clist == NULL) { 104 fprintf(stderr, "## %s: %s\n", optarg, emsg.c); 105 return (1); 106 } 107 snprintf(cstr, sizeof(cstr), 108 "zone %s; dnsrpzd \"\";" 109 " dnsrpzd-sock dnsrpzd.sock;" 110 " dnsrpzd-rpzf dnsrpzd.rpzf", 111 optarg); 112 client = librpz->client_create(&emsg, clist, cstr, 113 true); 114 if (client == NULL) { 115 fprintf(stderr, "## %s\n", emsg.c); 116 return (1); 117 } 118 119 rsp = NULL; 120 if (!librpz->rsp_create(&emsg, &rsp, NULL, client, true, 121 false) || 122 rsp == NULL) { 123 fprintf(stderr, "## %s\n", emsg.c); 124 librpz->client_detach(&client); 125 return (1); 126 } 127 128 if (!librpz->soa_serial(&emsg, &serial, optarg, rsp)) { 129 fprintf(stderr, "## %s\n", emsg.c); 130 librpz->client_detach(&client); 131 return (1); 132 } 133 librpz->rsp_detach(&rsp); 134 librpz->client_detach(&client); 135 printf("%u\n", serial); 136 #else /* ifdef USE_DNSRPS */ 137 INSIST(0); 138 ISC_UNREACHABLE(); 139 #endif /* ifdef USE_DNSRPS */ 140 return (0); 141 142 case 'w': 143 seconds = strtod(optarg, &p); 144 if (seconds <= 0 || *p != '\0') { 145 fputs(USAGE, stderr); 146 return (1); 147 } 148 usleep((int)(seconds * 1000.0 * 1000.0)); 149 return (0); 150 151 default: 152 fputs(USAGE, stderr); 153 return (1); 154 } 155 } 156 fputs(USAGE, stderr); 157 return (1); 158 } 159 160 static bool 161 link_dnsrps(librpz_emsg_t *emsg) { 162 #ifdef USE_DNSRPS 163 librpz = librpz_lib_open(emsg, NULL, DNSRPS_LIBRPZ_PATH); 164 if (librpz == NULL) { 165 return (false); 166 } 167 168 return (true); 169 #else /* ifdef USE_DNSRPS */ 170 snprintf(emsg->c, sizeof(emsg->c), "DNSRPS not configured"); 171 return (false); 172 #endif /* ifdef USE_DNSRPS */ 173 } 174