1 /* $NetBSD: ntp_restrict.c,v 1.13 2024/10/01 20:59:51 christos Exp $ */
2
3 /*
4 * ntp_restrict.c - determine host restrictions
5 */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdio.h>
11 #include <sys/types.h>
12
13 #include "ntpd.h"
14 #include "ntp_if.h"
15 #include "ntp_lists.h"
16 #include "ntp_stdlib.h"
17 #include "ntp_assert.h"
18
19 /*
20 * This code keeps a simple address-and-mask list of addressses we want
21 * to place restrictions on (or remove them from). The restrictions are
22 * implemented as a set of flags which tell you what matching addresses
23 * can't do. The list is sorted retrieve the restrictions most specific
24 * to the address.
25 *
26 * This was originally intended to restrict you from sync'ing to your
27 * own broadcasts when you are doing that, by restricting yourself from
28 * your own interfaces. It was also thought it would sometimes be useful
29 * to keep a misbehaving host or two from abusing your primary clock. It
30 * has been expanded, however, to suit the needs of those with more
31 * restrictive access policies.
32 */
33 #define MASK_IPV6_ADDR(dst, src, msk) \
34 do { \
35 int x; \
36 \
37 for (x = 0; x < (int)COUNTOF((dst)->s6_addr); x++) { \
38 (dst)->s6_addr[x] = (src)->s6_addr[x] \
39 & (msk)->s6_addr[x]; \
40 } \
41 } while (FALSE)
42
43 /*
44 * We allocate INC_RESLIST{4|6} entries to the free list whenever empty.
45 * Auto-tune these to be just less than 1KB (leaving at least 32 bytes
46 * for allocator overhead).
47 */
48 #define INC_RESLIST4 ((1024 - 32) / sizeof(struct restrict_4))
49 #define INC_RESLIST6 ((1024 - 32) / sizeof(struct restrict_6))
50
51 /*
52 * The restriction list
53 */
54 struct restrict_4 *restrictlist4;
55 struct restrict_6 *restrictlist6;
56 static size_t restrictcount; /* count in the restrict lists */
57
58 /*
59 * The free list and associated counters. Also some uninteresting
60 * stat counters.
61 */
62 static struct restrict_4 *resfree4; /* available entries (free list) */
63 static struct restrict_6 *resfree6;
64
65 static u_long res_calls;
66 static u_long res_found;
67 static u_long res_not_found;
68
69 /*
70 * Count number of restriction entries referring to RES_LIMITED, to
71 * control implicit activation/deactivation of the MRU monlist.
72 */
73 static u_long res_limited_refcnt;
74
75 /*
76 * Our default entries.
77 *
78 * We can make this cleaner with c99 support: see init_restrict().
79 */
80 static struct restrict_4 restrict_def4;
81 static struct restrict_6 restrict_def6;
82
83 /*
84 * "restrict source ..." enabled knob and restriction bits.
85 */
86 static int restrict_source_enabled;
87 static u_int32 restrict_source_rflags;
88 static u_short restrict_source_mflags;
89 static short restrict_source_ippeerlimit;
90
91 /*
92 * private functions
93 */
94 static struct restrict_4 * alloc_res4(void);
95 static struct restrict_6 * alloc_res6(void);
96 static void free_res4(struct restrict_4 *);
97 static void free_res6(struct restrict_6 *);
98 static inline void inc_res_limited(void);
99 static inline void dec_res_limited(void);
100 static struct restrict_4 * match_restrict4_addr(u_int32, u_short);
101 static struct restrict_6 * match_restrict6_addr(const struct in6_addr *,
102 u_short);
103 static inline int/*BOOL*/ mflags_sorts_before(u_short, u_short);
104 static int/*BOOL*/ res_sorts_before4(struct restrict_4 *,
105 struct restrict_4 *);
106 static int/*BOOL*/ res_sorts_before6(struct restrict_6 *,
107 struct restrict_6 *);
108
109 #ifdef DEBUG
110 /* dump_restrict() & dump_restricts() are DEBUG-only */
111
112 static void
dump_restrict(const struct restrict_info * ri,const char * as,const char * ms)113 dump_restrict(const struct restrict_info *ri, const char *as, const char *ms)
114 {
115 printf("%s/%s: hits %u ippeerlimit %hd mflags %s rflags %s",
116 as, ms, ri->count, ri->ippeerlimit,
117 mflags_str(ri->mflags),
118 rflags_str(ri->rflags));
119 if (ri->expire > 0) {
120 printf(" expire %u\n", ri->expire);
121 } else {
122 printf("\n");
123 }
124 }
125
126 /*
127 * dump_restrict - spit out a single restriction entry
128 */
129 static void
dump_restrict4(struct restrict_4 * res)130 dump_restrict4(
131 struct restrict_4 * res)
132 {
133 char as[INET6_ADDRSTRLEN];
134 char ms[INET6_ADDRSTRLEN];
135
136 struct in_addr sia, sim;
137
138 sia.s_addr = htonl(res->v4.addr);
139 sim.s_addr = htonl(res->v4.addr);
140 inet_ntop(AF_INET, &sia, as, sizeof as);
141 inet_ntop(AF_INET, &sim, ms, sizeof ms);
142
143 dump_restrict(&res->ri, as, ms);
144 }
145
146 static void
dump_restrict6(struct restrict_6 * res)147 dump_restrict6(
148 struct restrict_6 * res)
149 {
150 char as[INET6_ADDRSTRLEN];
151 char ms[INET6_ADDRSTRLEN];
152
153 inet_ntop(AF_INET6, &res->v6.addr, as, sizeof as);
154 inet_ntop(AF_INET6, &res->v6.mask, ms, sizeof ms);
155
156 dump_restrict(&res->ri, as, ms);
157 }
158
159
160 /*
161 * dump_restricts - spit out the 'restrict' entries
162 */
163 void
dump_restricts(void)164 dump_restricts(void)
165 {
166 struct restrict_4 * res4;
167 struct restrict_6 * res6;
168
169 /* Spit out the IPv4 list */
170 printf("dump_restricts: restrictlist4: %p\n", restrictlist4);
171 for (res4 = restrictlist4; res4 != NULL; res4 = res4->link) {
172 dump_restrict4(res4);
173 }
174
175 /* Spit out the IPv6 list */
176 printf("dump_restricts: restrictlist6: %p\n", restrictlist6);
177 for (res6 = restrictlist6; res6 != NULL; res6 = res6->link) {
178 dump_restrict6(res6);
179 }
180 }
181 #endif /* DEBUG - dump_restrict() / dump_restricts() */
182
183
184 /*
185 * init_restrict - initialize the restriction data structures
186 */
187 void
init_restrict(void)188 init_restrict(void)
189 {
190 /*
191 * The restriction lists end with a default entry with address
192 * and mask 0, which will match any entry. The lists are kept
193 * sorted by descending address followed by descending mask:
194 *
195 * address mask
196 * 192.168.0.0 255.255.255.0 kod limited noquery nopeer
197 * 192.168.0.0 255.255.0.0 kod limited
198 * 0.0.0.0 0.0.0.0 kod limited noquery
199 *
200 * The first entry which matches an address is used. With the
201 * example restrictions above, 192.168.0.0/24 matches the first
202 * entry, the rest of 192.168.0.0/16 matches the second, and
203 * everything else matches the third (default).
204 *
205 * Note this achieves the same result a little more efficiently
206 * than the documented behavior, which is to keep the lists
207 * sorted by ascending address followed by ascending mask, with
208 * the _last_ matching entry used.
209 *
210 * An additional wrinkle is we may have multiple entries with
211 * the same address and mask but differing match flags (mflags).
212 * We want to never talk to ourself, so RES_IGNORE entries for
213 * each local address are added by ntp_io.c with a host mask and
214 * both RESM_INTERFACE and RESM_NTPONLY set. We sort those
215 * entries before entries without those flags to achieve this.
216 * The remaining match flag is RESM_SOURCE, used to dynamically
217 * set restrictions for each peer based on the prototype set by
218 * "restrict source" in the configuration. We want those entries
219 * to be considered only when there is not a static host
220 * restriction for the address in the configuration, to allow
221 * operators to blacklist pool and manycast servers at runtime as
222 * desired using ntpq runtime configuration. Such static entries
223 * have no RESM_ bits set, so the sort order for mflags is first
224 * RESM_INTERFACE, then entries without RESM_SOURCE, finally the
225 * remaining.
226 */
227
228 restrict_def4.ri.ippeerlimit = -1; /* Cleaner if we have C99 */
229 restrict_def6.ri.ippeerlimit = -1; /* Cleaner if we have C99 */
230
231 LINK_SLIST(restrictlist4, &restrict_def4, link);
232 LINK_SLIST(restrictlist6, &restrict_def6, link);
233 restrictcount = 2;
234 }
235
236
237 static struct restrict_4 *
alloc_res4(void)238 alloc_res4(void)
239 {
240 const size_t count = INC_RESLIST4;
241 struct restrict_4* rl;
242 struct restrict_4* res;
243 const size_t cb = sizeof(*rl);
244 size_t i;
245
246 UNLINK_HEAD_SLIST(res, resfree4, link);
247 if (res != NULL) {
248 return res;
249 }
250 rl = eallocarray(count, cb);
251 /* link all but the first onto free list */
252 res = (void *)((char *)rl + (count - 1) * cb);
253 for (i = count - 1; i > 0; i--) {
254 LINK_SLIST(resfree4, res, link);
255 res = (void *)((char *)res - cb);
256 }
257 DEBUG_INSIST(rl == res);
258 /* allocate the first */
259 return res;
260 }
261
262
263 static struct restrict_6 *
alloc_res6(void)264 alloc_res6(void)
265 {
266 const size_t count = INC_RESLIST6;
267 struct restrict_6 * rl;
268 struct restrict_6 * res;
269 const size_t cb = sizeof(*rl);
270 size_t i;
271
272 UNLINK_HEAD_SLIST(res, resfree6, link);
273 if (res != NULL) {
274 return res;
275 }
276 rl = eallocarray(count, cb);
277 /* link all but the first onto free list */
278 res = (void *)((char *)rl + (count - 1) * cb);
279 for (i = count - 1; i > 0; i--) {
280 LINK_SLIST(resfree6, res, link);
281 res = (void *)((char *)res - cb);
282 }
283 DEBUG_INSIST(rl == res);
284 /* allocate the first */
285 return res;
286 }
287
288
289 static void
free_res6(struct restrict_6 * res)290 free_res6(struct restrict_6 * res)
291 {
292 struct restrict_6 * unlinked;
293
294 restrictcount--;
295 if (RES_LIMITED & res->ri.rflags) {
296 dec_res_limited();
297 }
298 UNLINK_SLIST(unlinked, restrictlist6, res, link, struct restrict_6);
299 INSIST(unlinked == res);
300 zero_mem(res, sizeof(*res));
301 LINK_SLIST(resfree6, res, link);
302 }
303
304 static void
free_res4(struct restrict_4 * res)305 free_res4(struct restrict_4 * res)
306 {
307 struct restrict_4 * unlinked;
308
309 restrictcount--;
310 if (RES_LIMITED & res->ri.rflags) {
311 dec_res_limited();
312 }
313 UNLINK_SLIST(unlinked, restrictlist4, res, link, struct restrict_4);
314 INSIST(unlinked == res);
315 zero_mem(res, sizeof(*res));
316 LINK_SLIST(resfree4, res, link);
317 }
318
319 static inline void
inc_res_limited(void)320 inc_res_limited(void)
321 {
322 if (0 == res_limited_refcnt) {
323 mon_start(MON_RES);
324 }
325 res_limited_refcnt++;
326 }
327
328
329 static inline void
dec_res_limited(void)330 dec_res_limited(void)
331 {
332 res_limited_refcnt--;
333 if (0 == res_limited_refcnt) {
334 mon_stop(MON_RES);
335 }
336 }
337
338
339 static struct restrict_4 *
match_restrict4_addr(u_int32 addr,u_short port)340 match_restrict4_addr(
341 u_int32 addr,
342 u_short port
343 )
344 {
345 struct restrict_4 * res;
346 struct restrict_4 * next;
347
348 for (res = restrictlist4; res != NULL; res = next) {
349 next = res->link;
350 if (res->ri.expire && res->ri.expire <= current_time) {
351 free_res4(res); /* zeroes the contents */
352 }
353 if ( res->v4.addr == (addr & res->v4.mask)
354 && ( !(RESM_NTPONLY & res->ri.mflags)
355 || NTP_PORT == port)) {
356
357 break;
358 }
359 }
360 return res;
361 }
362
363
364 static struct restrict_6 *
match_restrict6_addr(const struct in6_addr * addr,u_short port)365 match_restrict6_addr(
366 const struct in6_addr * addr,
367 u_short port
368 )
369 {
370 struct restrict_6 * res;
371 struct restrict_6 * next;
372 struct in6_addr masked;
373
374 for (res = restrictlist6; res != NULL; res = next) {
375 next = res->link;
376 if (res->ri.expire && res->ri.expire <= current_time) {
377 free_res6(res);
378 }
379 MASK_IPV6_ADDR(&masked, addr, &res->v6.mask);
380 if (ADDR6_EQ(&masked, &res->v6.addr)
381 && ( !(RESM_NTPONLY & res->ri.mflags)
382 || NTP_PORT == (int)port)) {
383
384 break;
385 }
386 }
387 return res;
388 }
389
390
391 /*
392 * match_restrict_entry - find an exact match on a restrict list.
393 *
394 * Exact match is addr, mask, and mflags all equal.
395 * In order to use more common code for IPv4 and IPv6, this routine
396 * requires the caller to populate a restrict_[46] with mflags and either
397 * the v4 or v6 address and mask as appropriate. Other fields in the
398 * input restrict_u are ignored.
399 */
400 static struct restrict_4 *
match_restrict4_entry(const struct restrict_4 * pmatch)401 match_restrict4_entry(
402 const struct restrict_4 * pmatch)
403 {
404 struct restrict_4 *res;
405
406 for (res = restrictlist4; res != NULL; res = res->link) {
407 if (res->ri.mflags == pmatch->ri.mflags &&
408 !memcmp(&res->v4, &pmatch->v4, sizeof(res->v4))) {
409 break;
410 }
411 }
412 return res;
413 }
414
415 static struct restrict_6 *
match_restrict6_entry(const struct restrict_6 * pmatch)416 match_restrict6_entry(
417 const struct restrict_6 * pmatch)
418 {
419 struct restrict_6 *res;
420
421 for (res = restrictlist6; res != NULL; res = res->link) {
422 if (res->ri.mflags == pmatch->ri.mflags &&
423 !memcmp(&res->v6, &pmatch->v6, sizeof(res->v6))) {
424 break;
425 }
426 }
427 return res;
428 }
429
430 /*
431 * mflags_sorts_before - common mflags sorting code
432 *
433 * See block comment in init_restrict() above for rationale.
434 */
435 static inline int/*BOOL*/
mflags_sorts_before(u_short m1,u_short m2)436 mflags_sorts_before(
437 u_short m1,
438 u_short m2
439 )
440 {
441 if ( (RESM_INTERFACE & m1)
442 && !(RESM_INTERFACE & m2)) {
443 return TRUE;
444 } else if ( !(RESM_SOURCE & m1)
445 && (RESM_SOURCE & m2)) {
446 return TRUE;
447 } else {
448 return FALSE;
449 }
450 }
451
452
453 /*
454 * res_sorts_before4 - compare IPv4 restriction entries
455 *
456 * Returns nonzero if r1 sorts before r2. We sort by descending
457 * address, then descending mask, then an intricate mflags sort
458 * order explained in a block comment near the top of this file.
459 */
460 static int/*BOOL*/
res_sorts_before4(struct restrict_4 * r1,struct restrict_4 * r2)461 res_sorts_before4(
462 struct restrict_4 *r1,
463 struct restrict_4 *r2
464 )
465 {
466 int r1_before_r2;
467
468 if (r1->v4.addr > r2->v4.addr) {
469 r1_before_r2 = TRUE;
470 } else if (r1->v4.addr < r2->v4.addr) {
471 r1_before_r2 = FALSE;
472 } else if (r1->v4.mask > r2->v4.mask) {
473 r1_before_r2 = TRUE;
474 } else if (r1->v4.mask < r2->v4.mask) {
475 r1_before_r2 = FALSE;
476 } else {
477 r1_before_r2 = mflags_sorts_before(r1->ri.mflags, r2->ri.mflags);
478 }
479
480 return r1_before_r2;
481 }
482
483
484 /*
485 * res_sorts_before6 - compare IPv6 restriction entries
486 *
487 * Returns nonzero if r1 sorts before r2. We sort by descending
488 * address, then descending mask, then an intricate mflags sort
489 * order explained in a block comment near the top of this file.
490 */
491 static int/*BOOL*/
res_sorts_before6(struct restrict_6 * r1,struct restrict_6 * r2)492 res_sorts_before6(
493 struct restrict_6* r1,
494 struct restrict_6* r2
495 )
496 {
497 int r1_before_r2;
498 int cmp;
499
500 cmp = ADDR6_CMP(&r1->v6.addr, &r2->v6.addr);
501 if (cmp > 0) { /* r1->addr > r2->addr */
502 r1_before_r2 = TRUE;
503 } else if (cmp < 0) { /* r2->addr > r1->addr */
504 r1_before_r2 = FALSE;
505 } else {
506 cmp = ADDR6_CMP(&r1->v6.mask, &r2->v6.mask);
507 if (cmp > 0) { /* r1->mask > r2->mask*/
508 r1_before_r2 = TRUE;
509 } else if (cmp < 0) { /* r2->mask > r1->mask */
510 r1_before_r2 = FALSE;
511 } else {
512 r1_before_r2 = mflags_sorts_before(r1->ri.mflags,
513 r2->ri.mflags);
514 }
515 }
516
517 return r1_before_r2;
518 }
519
520
521 /*
522 * restrictions - return restrictions for this host in *r4a
523 */
524 void
restrictions(sockaddr_u * srcadr,r4addr * r4a)525 restrictions(
526 sockaddr_u *srcadr,
527 r4addr *r4a
528 )
529 {
530 struct in6_addr *pin6;
531
532 DEBUG_REQUIRE(NULL != r4a);
533
534 res_calls++;
535
536 if (IS_IPV4(srcadr)) {
537 struct restrict_4 *match;
538 /*
539 * Ignore any packets with a multicast source address
540 * (this should be done early in the receive process,
541 * not later!)
542 */
543 if (IN_CLASSD(SRCADR(srcadr))) {
544 goto multicast;
545 }
546
547 match = match_restrict4_addr(SRCADR(srcadr),
548 SRCPORT(srcadr));
549 DEBUG_INSIST(match != NULL);
550 match->ri.count++;
551 /*
552 * res_not_found counts only use of the final default
553 * entry, not any "restrict default ntpport ...", which
554 * would be just before the final default.
555 */
556 if (&restrict_def4 == match)
557 res_not_found++;
558 else
559 res_found++;
560 r4a->rflags = match->ri.rflags;
561 r4a->ippeerlimit = match->ri.ippeerlimit;
562 } else {
563 struct restrict_6 *match;
564 DEBUG_REQUIRE(IS_IPV6(srcadr));
565
566 pin6 = PSOCK_ADDR6(srcadr);
567
568 /*
569 * Ignore any packets with a multicast source address
570 * (this should be done early in the receive process,
571 * not later!)
572 */
573 if (IN6_IS_ADDR_MULTICAST(pin6)) {
574 goto multicast;
575 }
576 match = match_restrict6_addr(pin6, SRCPORT(srcadr));
577 DEBUG_INSIST(match != NULL);
578 match->ri.count++;
579 if (&restrict_def6 == match)
580 res_not_found++;
581 else
582 res_found++;
583 r4a->rflags = match->ri.rflags;
584 r4a->ippeerlimit = match->ri.ippeerlimit;
585 }
586
587 return;
588
589 multicast:
590 r4a->rflags = RES_IGNORE;
591 r4a->ippeerlimit = 0;
592 }
593
594
595 #ifdef DEBUG
596 /* display string for restrict_op */
597 const char *
resop_str(restrict_op op)598 resop_str(restrict_op op)
599 {
600 switch (op) {
601 case RESTRICT_FLAGS: return "RESTRICT_FLAGS";
602 case RESTRICT_UNFLAG: return "RESTRICT_UNFLAG";
603 case RESTRICT_REMOVE: return "RESTRICT_REMOVE";
604 case RESTRICT_REMOVEIF: return "RESTRICT_REMOVEIF";
605 }
606 DEBUG_INVARIANT(!"bad restrict_op in resop_str");
607 return ""; /* silence not all paths return value warning */
608 }
609 #endif /* DEBUG */
610
611
612 /*
613 * hack_restrict - add/subtract/manipulate entries on the restrict list
614 */
615 int/*BOOL*/
hack_restrict(restrict_op op,sockaddr_u * resaddr,sockaddr_u * resmask,short ippeerlimit,u_short mflags,u_short rflags,u_int32 expire)616 hack_restrict(
617 restrict_op op,
618 sockaddr_u * resaddr,
619 sockaddr_u * resmask,
620 short ippeerlimit,
621 u_short mflags,
622 u_short rflags,
623 u_int32 expire
624 )
625 {
626 int bump_res_limited = FALSE;
627 struct restrict_4 match4, *res4 = NULL;
628 struct restrict_6 match6, *res6 = NULL;
629 struct restrict_info *ri;
630
631 #ifdef DEBUG
632 if (debug > 0) {
633 printf("hack_restrict: op %s addr %s mask %s",
634 resop_str(op), stoa(resaddr), stoa(resmask));
635 if (ippeerlimit >= 0) {
636 printf(" ippeerlimit %d", ippeerlimit);
637 }
638 printf(" mflags %s rflags %s", mflags_str(mflags),
639 rflags_str(rflags));
640 if (expire) {
641 printf("lifetime %u\n",
642 expire - (u_int32)current_time);
643 } else {
644 printf("\n");
645 }
646 }
647 #endif
648
649 if (NULL == resaddr) {
650 DEBUG_REQUIRE(NULL == resmask);
651 DEBUG_REQUIRE(RESTRICT_FLAGS == op);
652 DEBUG_REQUIRE(RESM_SOURCE & mflags);
653 restrict_source_rflags = rflags;
654 restrict_source_mflags = mflags;
655 restrict_source_ippeerlimit = ippeerlimit;
656 restrict_source_enabled = TRUE;
657 DPRINTF(1, ("restrict source template saved\n"));
658 return TRUE;
659 }
660
661
662 if (IS_IPV4(resaddr)) {
663 DEBUG_INVARIANT(IS_IPV4(resmask));
664 /*
665 * Get address and mask in host byte order for easy
666 * comparison as u_int32
667 */
668 ZERO(match4);
669 match4.v4.addr = SRCADR(resaddr);
670 match4.v4.mask = SRCADR(resmask);
671 match4.v4.addr &= match4.v4.mask;
672 match4.ri.mflags = mflags;
673 res4 = match_restrict4_entry(&match4);
674 ri = res4 ? &res4->ri : NULL;
675 } else {
676 DEBUG_INVARIANT(IS_IPV6(resaddr));
677 DEBUG_INVARIANT(IS_IPV6(resmask));
678 /*
679 * Get address and mask in network byte order for easy
680 * comparison as byte sequences (e.g. memcmp())
681 */
682 ZERO(match6);
683 match6.v6.mask = SOCK_ADDR6(resmask);
684 MASK_IPV6_ADDR(&match6.v6.addr, PSOCK_ADDR6(resaddr),
685 &match6.v6.mask);
686 match6.ri.mflags = mflags;
687 res6 = match_restrict6_entry(&match6);
688 ri = res6 ? &res6->ri : NULL;
689 }
690
691
692 switch (op) {
693
694 case RESTRICT_FLAGS:
695 /*
696 * Here we add bits to the rflags. If we already have
697 * this restriction modify it.
698 */
699 if (NULL != ri) {
700 if ( (RES_LIMITED & rflags)
701 && !(RES_LIMITED & ri->rflags)) {
702
703 bump_res_limited = TRUE;
704 }
705 ri->rflags |= rflags;
706 ri->expire = expire;
707 } else {
708 if (IS_IPV4(resaddr)) {
709 match4.ri.rflags = rflags;
710 match4.ri.expire = expire;
711 match4.ri.ippeerlimit = ippeerlimit;
712 res4 = alloc_res4();
713 memcpy(res4, &match4, sizeof(*res4));
714 LINK_SORT_SLIST(
715 restrictlist4, res4,
716 res_sorts_before4(res4, L_S_S_CUR()),
717 link, struct restrict_4);
718 } else {
719 match6.ri.rflags = rflags;
720 match6.ri.expire = expire;
721 match6.ri.ippeerlimit = ippeerlimit;
722 res6 = alloc_res6();
723 memcpy(res6, &match6, sizeof(*res6));
724 LINK_SORT_SLIST(
725 restrictlist6, res6,
726 res_sorts_before6(res6, L_S_S_CUR()),
727 link, struct restrict_6);
728 }
729 restrictcount++;
730 if (RES_LIMITED & rflags) {
731 bump_res_limited = TRUE;
732 }
733 }
734 if (bump_res_limited) {
735 inc_res_limited();
736 }
737 return TRUE;
738
739 case RESTRICT_UNFLAG:
740 /*
741 * Remove some bits from the rflags. If we didn't
742 * find this one, just return.
743 */
744 if (NULL == ri) {
745 DPRINTF(1, ("No match for %s %s removing rflags %s\n",
746 stoa(resaddr), stoa(resmask),
747 rflags_str(rflags)));
748 return FALSE;
749 }
750 if ( (RES_LIMITED & ri->rflags)
751 && (RES_LIMITED & rflags)) {
752 dec_res_limited();
753 }
754 ri->rflags &= ~rflags;
755 return TRUE;
756
757 case RESTRICT_REMOVE:
758 case RESTRICT_REMOVEIF:
759 /*
760 * Remove an entry from the table entirely if we
761 * found one. Don't remove the default entry and
762 * don't remove an interface entry unless asked.
763 */
764 if ( ri != NULL
765 && ( RESTRICT_REMOVEIF == op
766 || !(RESM_INTERFACE & ri->mflags))) {
767 if (res4 && res4 != &restrict_def4) {
768 free_res4(res4);
769 return TRUE;
770 }
771 if (res6 && res6 != &restrict_def6) {
772 free_res6(res6);
773 return TRUE;
774 }
775 }
776 DPRINTF(1, ("No match removing %s %s restriction\n",
777 stoa(resaddr), stoa(resmask)));
778 return FALSE;
779 }
780 /* notreached */
781 return FALSE;
782 }
783
784
785 /*
786 * restrict_source - maintains dynamic "restrict source ..." entries as
787 * peers come and go.
788 */
789 void
restrict_source(sockaddr_u * addr,int farewell,u_int32 lifetime)790 restrict_source(
791 sockaddr_u * addr,
792 int farewell, /* TRUE to remove */
793 u_int32 lifetime /* seconds, 0 forever */
794 )
795 {
796 sockaddr_u onesmask;
797 int/*BOOL*/ success;
798
799 if ( !restrict_source_enabled || SOCK_UNSPEC(addr)
800 || IS_MCAST(addr) || ISREFCLOCKADR(addr)) {
801 return;
802 }
803
804 REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr));
805
806 SET_HOSTMASK(&onesmask, AF(addr));
807 if (farewell) {
808 success = hack_restrict(RESTRICT_REMOVE, addr, &onesmask,
809 0, RESM_SOURCE, 0, 0);
810 if (success) {
811 DPRINTF(1, ("%s %s removed", __func__,
812 stoa(addr)));
813 } else {
814 msyslog(LOG_ERR, "%s remove %s failed",
815 __func__, stoa(addr));
816 }
817 return;
818 }
819
820 success = hack_restrict(RESTRICT_FLAGS, addr, &onesmask,
821 restrict_source_ippeerlimit,
822 restrict_source_mflags,
823 restrict_source_rflags,
824 lifetime > 0
825 ? lifetime + current_time
826 : 0);
827 if (success) {
828 DPRINTF(1, ("%s %s add/upd\n", __func__,
829 stoa(addr)));
830 } else {
831 msyslog(LOG_ERR, "%s %s failed", __func__, stoa(addr));
832 }
833 }
834
835
836 #ifdef DEBUG
837 /* Convert restriction RES_ flag bits into a display string */
838 const char *
rflags_str(u_short rflags)839 rflags_str(
840 u_short rflags
841 )
842 {
843 const size_t sz = LIB_BUFLENGTH;
844 char * rfs;
845
846 LIB_GETBUF(rfs);
847 rfs[0] = '\0';
848
849 if (rflags & RES_FLAKE) {
850 CLEAR_BIT_IF_DEBUG(RES_FLAKE, rflags);
851 append_flagstr(rfs, sz, "flake");
852 }
853
854 if (rflags & RES_IGNORE) {
855 CLEAR_BIT_IF_DEBUG(RES_IGNORE, rflags);
856 append_flagstr(rfs, sz, "ignore");
857 }
858
859 if (rflags & RES_KOD) {
860 CLEAR_BIT_IF_DEBUG(RES_KOD, rflags);
861 append_flagstr(rfs, sz, "kod");
862 }
863
864 if (rflags & RES_MSSNTP) {
865 CLEAR_BIT_IF_DEBUG(RES_MSSNTP, rflags);
866 append_flagstr(rfs, sz, "mssntp");
867 }
868
869 if (rflags & RES_LIMITED) {
870 CLEAR_BIT_IF_DEBUG(RES_LIMITED, rflags);
871 append_flagstr(rfs, sz, "limited");
872 }
873
874 if (rflags & RES_LPTRAP) {
875 CLEAR_BIT_IF_DEBUG(RES_LPTRAP, rflags);
876 append_flagstr(rfs, sz, "lptrap");
877 }
878
879 if (rflags & RES_NOMODIFY) {
880 CLEAR_BIT_IF_DEBUG(RES_NOMODIFY, rflags);
881 append_flagstr(rfs, sz, "nomodify");
882 }
883
884 if (rflags & RES_NOMRULIST) {
885 CLEAR_BIT_IF_DEBUG(RES_NOMRULIST, rflags);
886 append_flagstr(rfs, sz, "nomrulist");
887 }
888
889 if (rflags & RES_NOEPEER) {
890 CLEAR_BIT_IF_DEBUG(RES_NOEPEER, rflags);
891 append_flagstr(rfs, sz, "noepeer");
892 }
893
894 if (rflags & RES_NOPEER) {
895 CLEAR_BIT_IF_DEBUG(RES_NOPEER, rflags);
896 append_flagstr(rfs, sz, "nopeer");
897 }
898
899 if (rflags & RES_NOQUERY) {
900 CLEAR_BIT_IF_DEBUG(RES_NOQUERY, rflags);
901 append_flagstr(rfs, sz, "noquery");
902 }
903
904 if (rflags & RES_DONTSERVE) {
905 CLEAR_BIT_IF_DEBUG(RES_DONTSERVE, rflags);
906 append_flagstr(rfs, sz, "dontserve");
907 }
908
909 if (rflags & RES_NOTRAP) {
910 CLEAR_BIT_IF_DEBUG(RES_NOTRAP, rflags);
911 append_flagstr(rfs, sz, "notrap");
912 }
913
914 if (rflags & RES_DONTTRUST) {
915 CLEAR_BIT_IF_DEBUG(RES_DONTTRUST, rflags);
916 append_flagstr(rfs, sz, "notrust");
917 }
918
919 if (rflags & RES_SRVRSPFUZ) {
920 CLEAR_BIT_IF_DEBUG(RES_SRVRSPFUZ, rflags);
921 append_flagstr(rfs, sz, "srvrspfuz");
922 }
923
924 if (rflags & RES_VERSION) {
925 CLEAR_BIT_IF_DEBUG(RES_VERSION, rflags);
926 append_flagstr(rfs, sz, "version");
927 }
928
929 DEBUG_INVARIANT(!rflags);
930
931 if ('\0' == rfs[0]) {
932 append_flagstr(rfs, sz, "(none)");
933 }
934
935 return rfs;
936 }
937
938
939 /* Convert restriction match RESM_ flag bits into a display string */
940 const char *
mflags_str(u_short mflags)941 mflags_str(
942 u_short mflags
943 )
944 {
945 const size_t sz = LIB_BUFLENGTH;
946 char * mfs;
947
948 LIB_GETBUF(mfs);
949 mfs[0] = '\0';
950
951 if (mflags & RESM_NTPONLY) {
952 CLEAR_BIT_IF_DEBUG(RESM_NTPONLY, mflags);
953 append_flagstr(mfs, sz, "ntponly");
954 }
955
956 if (mflags & RESM_SOURCE) {
957 CLEAR_BIT_IF_DEBUG(RESM_SOURCE, mflags);
958 append_flagstr(mfs, sz, "source");
959 }
960
961 if (mflags & RESM_INTERFACE) {
962 CLEAR_BIT_IF_DEBUG(RESM_INTERFACE, mflags);
963 append_flagstr(mfs, sz, "interface");
964 }
965
966 DEBUG_INVARIANT(!mflags);
967
968 return mfs;
969 }
970 #endif /* DEBUG */
971