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