1*911793feSotto /* $OpenBSD: config.c,v 1.33 2020/04/12 14:20:56 otto Exp $ */
2f64d3c3cShenning
3f64d3c3cShenning /*
4f64d3c3cShenning * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5f64d3c3cShenning *
6f64d3c3cShenning * Permission to use, copy, modify, and distribute this software for any
7f64d3c3cShenning * purpose with or without fee is hereby granted, provided that the above
8f64d3c3cShenning * copyright notice and this permission notice appear in all copies.
9f64d3c3cShenning *
10f64d3c3cShenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11f64d3c3cShenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12f64d3c3cShenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13f64d3c3cShenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f64d3c3cShenning * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f64d3c3cShenning * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f64d3c3cShenning * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17f64d3c3cShenning */
18f64d3c3cShenning
19f64d3c3cShenning #include <sys/types.h>
20f64d3c3cShenning #include <sys/socket.h>
21f64d3c3cShenning #include <sys/stat.h>
22f64d3c3cShenning
2397c9f460Shenning #include <netinet/in.h>
2497c9f460Shenning
25f64d3c3cShenning #include <errno.h>
26f64d3c3cShenning #include <stdlib.h>
27f64d3c3cShenning #include <string.h>
28b98b0a5cSotto #include <resolv.h>
29f64d3c3cShenning #include <unistd.h>
30f64d3c3cShenning
31f64d3c3cShenning #include "ntpd.h"
32f64d3c3cShenning
33f8e1109cSkn struct ntp_addr *host_ip(const char *);
34b98b0a5cSotto int host_dns1(const char *, struct ntp_addr **, int);
35f64d3c3cShenning
3697c9f460Shenning static u_int32_t maxid = 0;
37bc58a738Sreyk static u_int32_t constraint_maxid = 0;
38*911793feSotto int non_numeric;
3997c9f460Shenning
402388a8b4Stedu void
host(const char * s,struct ntp_addr ** hn)41547afbf8Shenning host(const char *s, struct ntp_addr **hn)
42f64d3c3cShenning {
43f8e1109cSkn struct ntp_addr *h;
44f64d3c3cShenning
45f8e1109cSkn if (!strcmp(s, "*")) {
46f8e1109cSkn if ((h = calloc(1, sizeof(*h))) == NULL)
47005baf58Shenning fatal(NULL);
48f8e1109cSkn } else {
49*911793feSotto if ((h = host_ip(s)) == NULL) {
50*911793feSotto non_numeric = 1;
512388a8b4Stedu return;
52f8e1109cSkn }
53*911793feSotto }
546aaaa6e3Shenning
556aaaa6e3Shenning *hn = h;
56f64d3c3cShenning }
57f64d3c3cShenning
58204af22aShenning struct ntp_addr *
host_ip(const char * s)59f8e1109cSkn host_ip(const char *s)
60f64d3c3cShenning {
61f64d3c3cShenning struct addrinfo hints, *res;
62204af22aShenning struct ntp_addr *h = NULL;
63f64d3c3cShenning
64842d7e97Sbcook memset(&hints, 0, sizeof(hints));
65f8e1109cSkn hints.ai_family = AF_UNSPEC;
66f64d3c3cShenning hints.ai_socktype = SOCK_DGRAM; /*dummy*/
67f64d3c3cShenning hints.ai_flags = AI_NUMERICHOST;
68f64d3c3cShenning if (getaddrinfo(s, "0", &hints, &res) == 0) {
69f8e1109cSkn if (res->ai_family == AF_INET ||
70f8e1109cSkn res->ai_family == AF_INET6) {
71f8e1109cSkn if ((h = calloc(1, sizeof(*h))) == NULL)
72204af22aShenning fatal(NULL);
73f8e1109cSkn memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
74f8e1109cSkn }
75f64d3c3cShenning freeaddrinfo(res);
76f64d3c3cShenning }
77f64d3c3cShenning
78204af22aShenning return (h);
79f64d3c3cShenning }
807667fb33Shenning
81c0cb3bf1Sbcook void
host_dns_free(struct ntp_addr * hn)82c0cb3bf1Sbcook host_dns_free(struct ntp_addr *hn)
83c0cb3bf1Sbcook {
84c0cb3bf1Sbcook struct ntp_addr *h = hn, *tmp;
85c0cb3bf1Sbcook while (h) {
86c0cb3bf1Sbcook tmp = h;
87c0cb3bf1Sbcook h = h->next;
88c0cb3bf1Sbcook free(tmp);
89c0cb3bf1Sbcook }
90c0cb3bf1Sbcook }
91c0cb3bf1Sbcook
92547afbf8Shenning int
host_dns1(const char * s,struct ntp_addr ** hn,int notauth)93b98b0a5cSotto host_dns1(const char *s, struct ntp_addr **hn, int notauth)
947667fb33Shenning {
957667fb33Shenning struct addrinfo hints, *res0, *res;
96547afbf8Shenning int error, cnt = 0;
97204af22aShenning struct ntp_addr *h, *hh = NULL;
987667fb33Shenning
99842d7e97Sbcook memset(&hints, 0, sizeof(hints));
100f8e1109cSkn hints.ai_family = AF_UNSPEC;
10197c9f460Shenning hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
1026a6b450eSotto hints.ai_flags = AI_ADDRCONFIG;
1037667fb33Shenning error = getaddrinfo(s, NULL, &hints, &res0);
10496959c71Shenning if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
10596959c71Shenning return (0);
106547afbf8Shenning if (error) {
107547afbf8Shenning log_warnx("could not parse \"%s\": %s", s,
108547afbf8Shenning gai_strerror(error));
109547afbf8Shenning return (-1);
110547afbf8Shenning }
1117667fb33Shenning
112b683bdcaSdtucker for (res = res0; res && cnt < MAX_SERVERS_DNS; res = res->ai_next) {
1137667fb33Shenning if (res->ai_family != AF_INET &&
1147667fb33Shenning res->ai_family != AF_INET6)
1157667fb33Shenning continue;
116f8e1109cSkn if ((h = calloc(1, sizeof(*h))) == NULL)
117204af22aShenning fatal(NULL);
118f8e1109cSkn memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
119b98b0a5cSotto h->notauth = notauth;
1207667fb33Shenning
121204af22aShenning h->next = hh;
122204af22aShenning hh = h;
123547afbf8Shenning cnt++;
1247667fb33Shenning }
1257667fb33Shenning freeaddrinfo(res0);
1267667fb33Shenning
127547afbf8Shenning *hn = hh;
128547afbf8Shenning return (cnt);
1297667fb33Shenning }
13097c9f460Shenning
131b98b0a5cSotto int
host_dns(const char * s,int synced,struct ntp_addr ** hn)132c9addb91Sotto host_dns(const char *s, int synced, struct ntp_addr **hn)
133b98b0a5cSotto {
134b98b0a5cSotto int error, save_opts;
135b98b0a5cSotto
136b98b0a5cSotto log_debug("trying to resolve %s", s);
137b98b0a5cSotto error = host_dns1(s, hn, 0);
138c9addb91Sotto if (!synced && error <= 0) {
139b98b0a5cSotto log_debug("no luck, trying to resolve %s without checking", s);
140b98b0a5cSotto save_opts = _res.options;
141b98b0a5cSotto _res.options |= RES_USE_CD;
142b98b0a5cSotto error = host_dns1(s, hn, 1);
143b98b0a5cSotto _res.options = save_opts;
144b98b0a5cSotto }
145b98b0a5cSotto log_debug("resolve %s done: %d", s, error);
146b98b0a5cSotto return error;
147b98b0a5cSotto }
148b98b0a5cSotto
14997c9f460Shenning struct ntp_peer *
new_peer(void)15097c9f460Shenning new_peer(void)
15197c9f460Shenning {
15297c9f460Shenning struct ntp_peer *p;
15397c9f460Shenning
15497c9f460Shenning if ((p = calloc(1, sizeof(struct ntp_peer))) == NULL)
155009f3548Shenning fatal("new_peer calloc");
15697c9f460Shenning p->id = ++maxid;
15797c9f460Shenning
15897c9f460Shenning return (p);
15997c9f460Shenning }
160009f3548Shenning
161009f3548Shenning struct ntp_conf_sensor *
new_sensor(char * device)162009f3548Shenning new_sensor(char *device)
163009f3548Shenning {
164009f3548Shenning struct ntp_conf_sensor *s;
165009f3548Shenning
166009f3548Shenning if ((s = calloc(1, sizeof(struct ntp_conf_sensor))) == NULL)
167009f3548Shenning fatal("new_sensor calloc");
168009f3548Shenning if ((s->device = strdup(device)) == NULL)
169009f3548Shenning fatal("new_sensor strdup");
170009f3548Shenning
171009f3548Shenning return (s);
172009f3548Shenning }
173bc58a738Sreyk
174bc58a738Sreyk struct constraint *
new_constraint(void)175bc58a738Sreyk new_constraint(void)
176bc58a738Sreyk {
177bc58a738Sreyk struct constraint *p;
178bc58a738Sreyk
179bc58a738Sreyk if ((p = calloc(1, sizeof(struct constraint))) == NULL)
180bc58a738Sreyk fatal("new_constraint calloc");
181bc58a738Sreyk p->id = ++constraint_maxid;
182a257dd04Sreyk p->fd = -1;
183bc58a738Sreyk
184bc58a738Sreyk return (p);
185bc58a738Sreyk }
186bc58a738Sreyk
187