1/* $OpenBSD: config.c,v 1.33 2020/04/12 14:20:56 otto Exp $ */ 2 3/* 4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20#include <sys/socket.h> 21#include <sys/stat.h> 22 23#include <netinet/in.h> 24 25#include <errno.h> 26#include <stdlib.h> 27#include <string.h> 28#include <resolv.h> 29#include <unistd.h> 30 31#include "ntpd.h" 32 33struct ntp_addr *host_ip(const char *); 34int host_dns1(const char *, struct ntp_addr **, int); 35 36static u_int32_t maxid = 0; 37static u_int32_t constraint_maxid = 0; 38int non_numeric; 39 40void 41host(const char *s, struct ntp_addr **hn) 42{ 43 struct ntp_addr *h; 44 45 if (!strcmp(s, "*")) { 46 if ((h = calloc(1, sizeof(*h))) == NULL) 47 fatal(NULL); 48 } else { 49 if ((h = host_ip(s)) == NULL) { 50 non_numeric = 1; 51 return; 52 } 53 } 54 55 *hn = h; 56} 57 58struct ntp_addr * 59host_ip(const char *s) 60{ 61 struct addrinfo hints, *res; 62 struct ntp_addr *h = NULL; 63 64 memset(&hints, 0, sizeof(hints)); 65 hints.ai_family = AF_UNSPEC; 66 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 67 hints.ai_flags = AI_NUMERICHOST; 68 if (getaddrinfo(s, "0", &hints, &res) == 0) { 69 if (res->ai_family == AF_INET || 70 res->ai_family == AF_INET6) { 71 if ((h = calloc(1, sizeof(*h))) == NULL) 72 fatal(NULL); 73 memcpy(&h->ss, res->ai_addr, res->ai_addrlen); 74 } 75 freeaddrinfo(res); 76 } 77 78 return (h); 79} 80 81void 82host_dns_free(struct ntp_addr *hn) 83{ 84 struct ntp_addr *h = hn, *tmp; 85 while (h) { 86 tmp = h; 87 h = h->next; 88 free(tmp); 89 } 90} 91 92int 93host_dns1(const char *s, struct ntp_addr **hn, int notauth) 94{ 95 struct addrinfo hints, *res0, *res; 96 int error, cnt = 0; 97 struct ntp_addr *h, *hh = NULL; 98 99 memset(&hints, 0, sizeof(hints)); 100 hints.ai_family = AF_UNSPEC; 101 hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ 102 hints.ai_flags = AI_ADDRCONFIG; 103 error = getaddrinfo(s, NULL, &hints, &res0); 104 if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) 105 return (0); 106 if (error) { 107 log_warnx("could not parse \"%s\": %s", s, 108 gai_strerror(error)); 109 return (-1); 110 } 111 112 for (res = res0; res && cnt < MAX_SERVERS_DNS; res = res->ai_next) { 113 if (res->ai_family != AF_INET && 114 res->ai_family != AF_INET6) 115 continue; 116 if ((h = calloc(1, sizeof(*h))) == NULL) 117 fatal(NULL); 118 memcpy(&h->ss, res->ai_addr, res->ai_addrlen); 119 h->notauth = notauth; 120 121 h->next = hh; 122 hh = h; 123 cnt++; 124 } 125 freeaddrinfo(res0); 126 127 *hn = hh; 128 return (cnt); 129} 130 131int 132host_dns(const char *s, int synced, struct ntp_addr **hn) 133{ 134 int error, save_opts; 135 136 log_debug("trying to resolve %s", s); 137 error = host_dns1(s, hn, 0); 138 if (!synced && error <= 0) { 139 log_debug("no luck, trying to resolve %s without checking", s); 140 save_opts = _res.options; 141 _res.options |= RES_USE_CD; 142 error = host_dns1(s, hn, 1); 143 _res.options = save_opts; 144 } 145 log_debug("resolve %s done: %d", s, error); 146 return error; 147} 148 149struct ntp_peer * 150new_peer(void) 151{ 152 struct ntp_peer *p; 153 154 if ((p = calloc(1, sizeof(struct ntp_peer))) == NULL) 155 fatal("new_peer calloc"); 156 p->id = ++maxid; 157 158 return (p); 159} 160 161struct ntp_conf_sensor * 162new_sensor(char *device) 163{ 164 struct ntp_conf_sensor *s; 165 166 if ((s = calloc(1, sizeof(struct ntp_conf_sensor))) == NULL) 167 fatal("new_sensor calloc"); 168 if ((s->device = strdup(device)) == NULL) 169 fatal("new_sensor strdup"); 170 171 return (s); 172} 173 174struct constraint * 175new_constraint(void) 176{ 177 struct constraint *p; 178 179 if ((p = calloc(1, sizeof(struct constraint))) == NULL) 180 fatal("new_constraint calloc"); 181 p->id = ++constraint_maxid; 182 p->fd = -1; 183 184 return (p); 185} 186 187