xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/rpz/dnsrps.c (revision 901e7e84758515fbf39dfc064cb0b45ab146d8b0)
1 /*	$NetBSD: dnsrps.c,v 1.7 2023/01/25 21:43:26 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(0) if dnsrps is available or dlopen() msg if not
18  * -p		print the path to dnsrpzd configured in dnsrps so that
19  *		    dnsrpzd can be run by a setup.sh script.
20  *		    Exit(1) if dnsrps is not available
21  * -n domain	print the serial number of a domain to check if a new
22  *		    version of a policy zone has been transferred to dnsrpzd.
23  *		    Exit(1) if dnsrps is not available
24  * -w sec.ond	wait for seconds, because `sleep 0.1` is not portable
25  */
26 
27 #include <errno.h>
28 #include <inttypes.h>
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 
38 #include <isc/print.h>
39 #include <isc/util.h>
40 
41 #ifdef USE_DNSRPS
42 #define LIBRPZ_LIB_OPEN DNSRPS_LIB_OPEN
43 #include <dns/librpz.h>
44 
45 librpz_t *librpz;
46 #else  /* ifdef USE_DNSRPS */
47 typedef struct {
48 	char c[120];
49 } librpz_emsg_t;
50 #endif /* ifdef USE_DNSRPS */
51 
52 static bool
53 link_dnsrps(librpz_emsg_t *emsg);
54 
55 #define USAGE "usage: [-ap] [-n domain] [-w sec.onds]\n"
56 
57 int
58 main(int argc, char **argv) {
59 #ifdef USE_DNSRPS
60 	char cstr[sizeof("zone ") + 1024 + 10];
61 	librpz_clist_t *clist;
62 	librpz_client_t *client;
63 	librpz_rsp_t *rsp;
64 	uint32_t serial;
65 #endif /* ifdef USE_DNSRPS */
66 	double seconds;
67 	librpz_emsg_t emsg;
68 	char *p;
69 	int i;
70 
71 	while ((i = getopt(argc, argv, "apn:w:")) != -1) {
72 		switch (i) {
73 		case 'a':
74 			if (!link_dnsrps(&emsg)) {
75 				printf("I:%s\n", emsg.c);
76 				return (1);
77 			}
78 			return (0);
79 
80 		case 'p':
81 			if (!link_dnsrps(&emsg)) {
82 				fprintf(stderr, "## %s\n", emsg.c);
83 				return (1);
84 			}
85 #ifdef USE_DNSRPS
86 			printf("%s\n", librpz->dnsrpzd_path);
87 #else  /* ifdef USE_DNSRPS */
88 			UNREACHABLE();
89 #endif /* ifdef USE_DNSRPS */
90 			return (0);
91 
92 		case 'n':
93 			if (!link_dnsrps(&emsg)) {
94 				fprintf(stderr, "## %s\n", emsg.c);
95 				return (1);
96 			}
97 #ifdef USE_DNSRPS
98 			/*
99 			 * Get the serial number of a policy zone from
100 			 * a running dnsrpzd daemon.
101 			 */
102 			clist = librpz->clist_create(&emsg, NULL, NULL, NULL,
103 						     NULL, NULL);
104 			if (clist == NULL) {
105 				fprintf(stderr, "## %s: %s\n", optarg, emsg.c);
106 				return (1);
107 			}
108 			snprintf(cstr, sizeof(cstr),
109 				 "zone %s; dnsrpzd \"\";"
110 				 " dnsrpzd-sock dnsrpzd.sock;"
111 				 " dnsrpzd-rpzf dnsrpzd.rpzf",
112 				 optarg);
113 			client = librpz->client_create(&emsg, clist, cstr,
114 						       true);
115 			if (client == NULL) {
116 				fprintf(stderr, "## %s\n", emsg.c);
117 				return (1);
118 			}
119 
120 			rsp = NULL;
121 			if (!librpz->rsp_create(&emsg, &rsp, NULL, client, true,
122 						false) ||
123 			    rsp == NULL)
124 			{
125 				fprintf(stderr, "## %s\n", emsg.c);
126 				librpz->client_detach(&client);
127 				return (1);
128 			}
129 
130 			if (!librpz->soa_serial(&emsg, &serial, optarg, rsp)) {
131 				fprintf(stderr, "## %s\n", emsg.c);
132 				librpz->client_detach(&client);
133 				return (1);
134 			}
135 			librpz->rsp_detach(&rsp);
136 			librpz->client_detach(&client);
137 			printf("%u\n", serial);
138 #else  /* ifdef USE_DNSRPS */
139 			UNREACHABLE();
140 #endif /* ifdef USE_DNSRPS */
141 			return (0);
142 
143 		case 'w':
144 			seconds = strtod(optarg, &p);
145 			if (seconds <= 0 || *p != '\0') {
146 				fputs(USAGE, stderr);
147 				return (1);
148 			}
149 			usleep((int)(seconds * 1000.0 * 1000.0));
150 			return (0);
151 
152 		default:
153 			fputs(USAGE, stderr);
154 			return (1);
155 		}
156 	}
157 	fputs(USAGE, stderr);
158 	return (1);
159 }
160 
161 static bool
162 link_dnsrps(librpz_emsg_t *emsg) {
163 #ifdef USE_DNSRPS
164 	librpz = librpz_lib_open(emsg, NULL, DNSRPS_LIBRPZ_PATH);
165 	if (librpz == NULL) {
166 		return (false);
167 	}
168 
169 	return (true);
170 #else  /* ifdef USE_DNSRPS */
171 	snprintf(emsg->c, sizeof(emsg->c), "DNSRPS not configured");
172 	return (false);
173 #endif /* ifdef USE_DNSRPS */
174 }
175