1 /* $NetBSD: feature-test.c,v 1.10 2023/01/25 21:43:24 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 #include <limits.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <unistd.h> 21 22 #include <isc/net.h> 23 #include <isc/print.h> 24 #include <isc/util.h> 25 26 #include <dns/edns.h> 27 28 #ifdef WIN32 29 #include <Winsock2.h> 30 #endif /* ifdef WIN32 */ 31 32 #ifndef _POSIX_HOST_NAME_MAX 33 #define _POSIX_HOST_NAME_MAX 255 34 #endif 35 36 static void 37 usage() { 38 fprintf(stderr, "usage: feature-test <arg>\n"); 39 fprintf(stderr, "args:\n"); 40 fprintf(stderr, "\t--edns-version\n"); 41 fprintf(stderr, "\t--enable-dnsrps\n"); 42 fprintf(stderr, "\t--enable-dnstap\n"); 43 fprintf(stderr, "\t--gethostname\n"); 44 fprintf(stderr, "\t--gssapi\n"); 45 fprintf(stderr, "\t--have-dlopen\n"); 46 fprintf(stderr, "\t--have-geoip2\n"); 47 fprintf(stderr, "\t--have-json-c\n"); 48 fprintf(stderr, "\t--have-libxml2\n"); 49 fprintf(stderr, "\t--ipv6only=no\n"); 50 fprintf(stderr, "\t--tsan\n"); 51 fprintf(stderr, "\t--with-dlz-filesystem\n"); 52 fprintf(stderr, "\t--with-idn\n"); 53 fprintf(stderr, "\t--with-lmdb\n"); 54 fprintf(stderr, "\t--with-zlib\n"); 55 } 56 57 int 58 main(int argc, char **argv) { 59 if (argc != 2) { 60 usage(); 61 return (1); 62 } 63 64 if (strcmp(argv[1], "--edns-version") == 0) { 65 #ifdef DNS_EDNS_VERSION 66 printf("%d\n", DNS_EDNS_VERSION); 67 #else /* ifdef DNS_EDNS_VERSION */ 68 printf("0\n"); 69 #endif /* ifdef DNS_EDNS_VERSION */ 70 return (0); 71 } 72 73 if (strcmp(argv[1], "--enable-dnsrps") == 0) { 74 #ifdef USE_DNSRPS 75 return (0); 76 #else /* ifdef USE_DNSRPS */ 77 return (1); 78 #endif /* ifdef USE_DNSRPS */ 79 } 80 81 if (strcmp(argv[1], "--enable-dnstap") == 0) { 82 #ifdef HAVE_DNSTAP 83 return (0); 84 #else /* ifdef HAVE_DNSTAP */ 85 return (1); 86 #endif /* ifdef HAVE_DNSTAP */ 87 } 88 89 if (strcmp(argv[1], "--gethostname") == 0) { 90 char hostname[_POSIX_HOST_NAME_MAX + 1]; 91 int n; 92 #ifdef WIN32 93 /* From InitSocket() */ 94 WORD wVersionRequested; 95 WSADATA wsaData; 96 int err; 97 98 wVersionRequested = MAKEWORD(2, 0); 99 err = WSAStartup(wVersionRequested, &wsaData); 100 if (err != 0) { 101 fprintf(stderr, "WSAStartup() failed: %d\n", err); 102 exit(1); 103 } 104 #endif /* ifdef WIN32 */ 105 106 n = gethostname(hostname, sizeof(hostname)); 107 if (n == -1) { 108 perror("gethostname"); 109 return (1); 110 } 111 fprintf(stdout, "%s\n", hostname); 112 #ifdef WIN32 113 WSACleanup(); 114 #endif /* ifdef WIN32 */ 115 return (0); 116 } 117 118 if (strcmp(argv[1], "--gssapi") == 0) { 119 #if defined(GSSAPI) 120 return (0); 121 #else /* if defined(GSSAPI) */ 122 return (1); 123 #endif /* if defined(GSSAPI) */ 124 } 125 126 if (strcmp(argv[1], "--have-dlopen") == 0) { 127 #if defined(HAVE_DLOPEN) && defined(ISC_DLZ_DLOPEN) 128 return (0); 129 #else /* if defined(HAVE_DLOPEN) && defined(ISC_DLZ_DLOPEN) */ 130 return (1); 131 #endif /* if defined(HAVE_DLOPEN) && defined(ISC_DLZ_DLOPEN) */ 132 } 133 134 if (strcmp(argv[1], "--have-geoip2") == 0) { 135 #ifdef HAVE_GEOIP2 136 return (0); 137 #else /* ifdef HAVE_GEOIP2 */ 138 return (1); 139 #endif /* ifdef HAVE_GEOIP2 */ 140 } 141 142 if (strcmp(argv[1], "--have-json-c") == 0) { 143 #ifdef HAVE_JSON_C 144 return (0); 145 #else /* ifdef HAVE_JSON_C */ 146 return (1); 147 #endif /* ifdef HAVE_JSON_C */ 148 } 149 150 if (strcmp(argv[1], "--have-libxml2") == 0) { 151 #ifdef HAVE_LIBXML2 152 return (0); 153 #else /* ifdef HAVE_LIBXML2 */ 154 return (1); 155 #endif /* ifdef HAVE_LIBXML2 */ 156 } 157 158 if (strcmp(argv[1], "--ipv6only=no") == 0) { 159 #ifdef WIN32 160 return (0); 161 #elif defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 162 int s; 163 int n = -1; 164 int v6only = -1; 165 socklen_t len = sizeof(v6only); 166 167 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 168 if (s >= 0) { 169 n = getsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 170 (void *)&v6only, &len); 171 close(s); 172 } 173 return ((n == 0 && v6only == 0) ? 0 : 1); 174 #else /* ifdef WIN32 */ 175 return (1); 176 #endif /* ifdef WIN32 */ 177 } 178 179 if (strcmp(argv[1], "--tsan") == 0) { 180 #if defined(__has_feature) 181 #if __has_feature(thread_sanitizer) 182 return (0); 183 #endif 184 #endif 185 #if __SANITIZE_THREAD__ 186 return (0); 187 #else 188 return (1); 189 #endif 190 } 191 192 if (strcmp(argv[1], "--with-dlz-filesystem") == 0) { 193 #ifdef DLZ_FILESYSTEM 194 return (0); 195 #else /* ifdef DLZ_FILESYSTEM */ 196 return (1); 197 #endif /* ifdef DLZ_FILESYSTEM */ 198 } 199 200 if (strcmp(argv[1], "--with-idn") == 0) { 201 #ifdef HAVE_LIBIDN2 202 return (0); 203 #else /* ifdef HAVE_LIBIDN2 */ 204 return (1); 205 #endif /* ifdef HAVE_LIBIDN2 */ 206 } 207 208 if (strcmp(argv[1], "--with-lmdb") == 0) { 209 #ifdef HAVE_LMDB 210 return (0); 211 #else /* ifdef HAVE_LMDB */ 212 return (1); 213 #endif /* ifdef HAVE_LMDB */ 214 } 215 216 if (strcmp(argv[1], "--with-zlib") == 0) { 217 #ifdef HAVE_ZLIB 218 return (0); 219 #else /* ifdef HAVE_ZLIB */ 220 return (1); 221 #endif /* ifdef HAVE_ZLIB */ 222 } 223 224 fprintf(stderr, "unknown arg: %s\n", argv[1]); 225 usage(); 226 return (1); 227 } 228