2 * ntp_restrict.c - determine host restrictions
13 #include "ntp_lists.h"
14 #include "ntp_stdlib.h"
15 #include "ntp_assert.h"
18 * This code keeps a simple address-and-mask list of hosts we want
19 * to place restrictions on (or remove them from). The restrictions
20 * are implemented as a set of flags which tell you what the host
21 * can't do. There is a subroutine entry to return the flags. The
22 * list is kept sorted to reduce the average number of comparisons
23 * and make sure you get the set of restrictions most specific to
26 * The algorithm is that, when looking up a host, it is first assumed
27 * that the default set of restrictions will apply. It then searches
28 * down through the list. Whenever it finds a match it adopts the
29 * match's flags instead. When you hit the point where the sorted
30 * address is greater than the target, you return with the last set of
31 * flags you found. Because of the ordering of the list, the most
32 * specific match will provide the final set of flags.
34 * This was originally intended to restrict you from sync'ing to your
35 * own broadcasts when you are doing that, by restricting yourself from
36 * your own interfaces. It was also thought it would sometimes be useful
37 * to keep a misbehaving host or two from abusing your primary clock. It
38 * has been expanded, however, to suit the needs of those with more
39 * restrictive access policies.
42 * We will use two lists, one for IPv4 addresses and one for IPv6
43 * addresses. This is not protocol-independant but for now I can't
44 * find a way to respect this. We'll check this later... JFB 07/2001
46 #define MASK_IPV6_ADDR(dst, src, msk) \
49 for (idx = 0; idx < (int)COUNTOF((dst)->s6_addr); idx++) { \
50 (dst)->s6_addr[idx] = (src)->s6_addr[idx] \
51 & (msk)->s6_addr[idx]; \
56 * We allocate INC_RESLIST{4|6} entries to the free list whenever empty.
57 * Auto-tune these to be just less than 1KB (leaving at least 16 bytes
58 * for allocator overhead).
60 #define INC_RESLIST4 ((1024 - 16) / V4_SIZEOF_RESTRICT_U)
61 #define INC_RESLIST6 ((1024 - 16) / V6_SIZEOF_RESTRICT_U)
64 * The restriction list
66 restrict_u *restrictlist4;
67 restrict_u *restrictlist6;
68 static int restrictcount; /* count in the restrict lists */
71 * The free list and associated counters. Also some uninteresting
74 static restrict_u *resfree4; /* available entries (free list) */
75 static restrict_u *resfree6;
77 static u_long res_calls;
78 static u_long res_found;
79 static u_long res_not_found;
82 * Count number of restriction entries referring to RES_LIMITED, to
83 * control implicit activation/deactivation of the MRU monlist.
85 static u_long res_limited_refcnt;
88 * Our default entries.
90 * We can make this cleaner with c99 support: see init_restrict().
92 static restrict_u restrict_def4;
93 static restrict_u restrict_def6;
96 * "restrict source ..." enabled knob and restriction bits.
98 static int restrict_source_enabled;
99 static u_short restrict_source_rflags;
100 static u_short restrict_source_mflags;
101 static short restrict_source_ippeerlimit;
106 static restrict_u * alloc_res4(void);
107 static restrict_u * alloc_res6(void);
108 static void free_res(restrict_u *, int);
109 static void inc_res_limited(void);
110 static void dec_res_limited(void);
111 static restrict_u * match_restrict4_addr(u_int32, u_short);
112 static restrict_u * match_restrict6_addr(const struct in6_addr *,
114 static restrict_u * match_restrict_entry(const restrict_u *, int);
115 static int res_sorts_before4(restrict_u *, restrict_u *);
116 static int res_sorts_before6(restrict_u *, restrict_u *);
117 static char * roptoa(restrict_op op);
120 void dump_restricts(void);
123 * dump_restrict - spit out a restrict_u
131 char as[INET6_ADDRSTRLEN];
132 char ms[INET6_ADDRSTRLEN];
135 inet_ntop(AF_INET6, &res->u.v6.addr, as, sizeof as);
136 inet_ntop(AF_INET6, &res->u.v6.mask, ms, sizeof ms);
138 struct in_addr sia = { htonl(res->u.v4.addr) };
139 struct in_addr sim = { htonl(res->u.v4.mask) };
141 inet_ntop(AF_INET, &sia, as, sizeof as);
142 inet_ntop(AF_INET, &sim, ms, sizeof ms);
144 mprintf("restrict node at %p: %s/%s count %d, rflags %05x, mflags %05x, ippeerlimit %d, expire %lu, next %p\n",
145 res, as, ms, res->count, res->rflags, res->mflags,
146 res->ippeerlimit, res->expire, res->link);
152 * dump_restricts - spit out the 'restrict' lines
157 int defaultv4_done = 0;
158 int defaultv6_done = 0;
162 mprintf("dump_restrict: restrict_def4: %p\n", &restrict_def4);
163 /* Spit out 'restrict {,-4,-6} default ...' lines, if needed */
164 for (res = &restrict_def4; res != NULL; res = next) {
165 dump_restrict(res, 0);
169 mprintf("dump_restrict: restrict_def6: %p\n", &restrict_def6);
170 for (res = &restrict_def6; res != NULL; res = next) {
171 dump_restrict(res, 1);
175 /* Spit out the IPv4 list */
176 mprintf("dump_restrict: restrictlist4: %p\n", &restrictlist4);
177 for (res = restrictlist4; res != NULL; res = next) {
178 dump_restrict(res, 0);
182 /* Spit out the IPv6 list */
183 mprintf("dump_restrict: restrictlist6: %p\n", &restrictlist6);
184 for (res = restrictlist6; res != NULL; res = next) {
185 dump_restrict(res, 1);
193 * init_restrict - initialize the restriction data structures
199 * The restriction lists begin with a default entry with address
200 * and mask 0, which will match any entry. The lists are kept
201 * sorted by descending address followed by descending mask:
204 * 192.168.0.0 255.255.255.0 kod limited noquery nopeer
205 * 192.168.0.0 255.255.0.0 kod limited
206 * 0.0.0.0 0.0.0.0 kod limited noquery
208 * The first entry which matches an address is used. With the
209 * example restrictions above, 192.168.0.0/24 matches the first
210 * entry, the rest of 192.168.0.0/16 matches the second, and
211 * everything else matches the third (default).
213 * Note this achieves the same result a little more efficiently
214 * than the documented behavior, which is to keep the lists
215 * sorted by ascending address followed by ascending mask, with
216 * the _last_ matching entry used.
218 * An additional wrinkle is we may have multiple entries with
219 * the same address and mask but differing match flags (mflags).
220 * At present there is only one, RESM_NTPONLY. Entries with
221 * RESM_NTPONLY are sorted earlier so they take precedence over
222 * any otherwise similar entry without. Again, this is the same
223 * behavior as but reversed implementation compared to the docs.
227 restrict_def4.ippeerlimit = -1; /* Cleaner if we have C99 */
228 restrict_def6.ippeerlimit = -1; /* Cleaner if we have C99 */
230 LINK_SLIST(restrictlist4, &restrict_def4, link);
231 LINK_SLIST(restrictlist6, &restrict_def6, link);
239 const size_t cb = V4_SIZEOF_RESTRICT_U;
240 const size_t count = INC_RESLIST4;
245 UNLINK_HEAD_SLIST(res, resfree4, link);
249 rl = eallocarray(count, cb);
250 /* link all but the first onto free list */
251 res = (void *)((char *)rl + (count - 1) * cb);
252 for (i = count - 1; i > 0; i--) {
253 LINK_SLIST(resfree4, res, link);
254 res = (void *)((char *)res - cb);
257 /* allocate the first */
265 const size_t cb = V6_SIZEOF_RESTRICT_U;
266 const size_t count = INC_RESLIST6;
271 UNLINK_HEAD_SLIST(res, resfree6, link);
275 rl = eallocarray(count, cb);
276 /* link all but the first onto free list */
277 res = (void *)((char *)rl + (count - 1) * cb);
278 for (i = count - 1; i > 0; i--) {
279 LINK_SLIST(resfree6, res, link);
280 res = (void *)((char *)res - cb);
283 /* allocate the first */
294 restrict_u ** plisthead;
295 restrict_u * unlinked;
298 if (RES_LIMITED & res->rflags)
302 plisthead = &restrictlist6;
304 plisthead = &restrictlist4;
305 UNLINK_SLIST(unlinked, *plisthead, res, link, restrict_u);
306 INSIST(unlinked == res);
309 zero_mem(res, V6_SIZEOF_RESTRICT_U);
310 plisthead = &resfree6;
312 zero_mem(res, V4_SIZEOF_RESTRICT_U);
313 plisthead = &resfree4;
315 LINK_SLIST(*plisthead, res, link);
320 inc_res_limited(void)
322 if (!res_limited_refcnt)
324 res_limited_refcnt++;
329 dec_res_limited(void)
331 res_limited_refcnt--;
332 if (!res_limited_refcnt)
338 match_restrict4_addr(
347 for (res = restrictlist4; res != NULL; res = next) {
348 struct in_addr sia = { htonl(res->u.v4.addr) };
351 DPRINTF(2, ("match_restrict4_addr: Checking %s, port %d ... ",
352 inet_ntoa(sia), port));
354 && res->expire <= current_time)
355 free_res(res, v6); /* zeroes the contents */
356 if ( res->u.v4.addr == (addr & res->u.v4.mask)
357 && ( !(RESM_NTPONLY & res->mflags)
358 || NTP_PORT == port)) {
359 DPRINTF(2, ("MATCH: ippeerlimit %d\n", res->ippeerlimit));
362 DPRINTF(2, ("doesn't match: ippeerlimit %d\n", res->ippeerlimit));
369 match_restrict6_addr(
370 const struct in6_addr * addr,
377 struct in6_addr masked;
379 for (res = restrictlist6; res != NULL; res = next) {
383 res->expire <= current_time)
385 MASK_IPV6_ADDR(&masked, addr, &res->u.v6.mask);
386 if (ADDR6_EQ(&masked, &res->u.v6.addr)
387 && (!(RESM_NTPONLY & res->mflags)
388 || NTP_PORT == (int)port))
396 * match_restrict_entry - find an exact match on a restrict list.
398 * Exact match is addr, mask, and mflags all equal.
399 * In order to use more common code for IPv4 and IPv6, this routine
400 * requires the caller to populate a restrict_u with mflags and either
401 * the v4 or v6 address and mask as appropriate. Other fields in the
402 * input restrict_u are ignored.
405 match_restrict_entry(
406 const restrict_u * pmatch,
415 rlist = restrictlist6;
416 cb = sizeof(pmatch->u.v6);
418 rlist = restrictlist4;
419 cb = sizeof(pmatch->u.v4);
422 for (res = rlist; res != NULL; res = res->link)
423 if (res->mflags == pmatch->mflags &&
424 !memcmp(&res->u, &pmatch->u, cb))
431 * res_sorts_before4 - compare two restrict4 entries
433 * Returns nonzero if r1 sorts before r2. We sort by descending
434 * address, then descending mask, then descending mflags, so sorting
435 * before means having a higher value.
445 if (r1->u.v4.addr > r2->u.v4.addr)
447 else if (r1->u.v4.addr < r2->u.v4.addr)
449 else if (r1->u.v4.mask > r2->u.v4.mask)
451 else if (r1->u.v4.mask < r2->u.v4.mask)
453 else if (r1->mflags > r2->mflags)
463 * res_sorts_before6 - compare two restrict6 entries
465 * Returns nonzero if r1 sorts before r2. We sort by descending
466 * address, then descending mask, then descending mflags, so sorting
467 * before means having a higher value.
478 cmp = ADDR6_CMP(&r1->u.v6.addr, &r2->u.v6.addr);
479 if (cmp > 0) /* r1->addr > r2->addr */
481 else if (cmp < 0) /* r2->addr > r1->addr */
484 cmp = ADDR6_CMP(&r1->u.v6.mask, &r2->u.v6.mask);
485 if (cmp > 0) /* r1->mask > r2->mask*/
487 else if (cmp < 0) /* r2->mask > r1->mask */
489 else if (r1->mflags > r2->mflags)
500 * restrictions - return restrictions for this host in *r4a
509 struct in6_addr *pin6;
511 REQUIRE(NULL != r4a);
514 r4a->rflags = RES_IGNORE;
515 r4a->ippeerlimit = 0;
517 DPRINTF(1, ("restrictions: looking up %s\n", stoa(srcadr)));
519 /* IPv4 source address */
520 if (IS_IPV4(srcadr)) {
522 * Ignore any packets with a multicast source address
523 * (this should be done early in the receive process,
526 if (IN_CLASSD(SRCADR(srcadr))) {
527 DPRINTF(1, ("restrictions: srcadr %s is multicast\n", stoa(srcadr)));
528 r4a->ippeerlimit = 2; /* XXX: we should use a better value */
532 match = match_restrict4_addr(SRCADR(srcadr),
535 INSIST(match != NULL);
539 * res_not_found counts only use of the final default
540 * entry, not any "restrict default ntpport ...", which
541 * would be just before the final default.
543 if (&restrict_def4 == match)
547 r4a->rflags = match->rflags;
548 r4a->ippeerlimit = match->ippeerlimit;
551 /* IPv6 source address */
552 if (IS_IPV6(srcadr)) {
553 pin6 = PSOCK_ADDR6(srcadr);
556 * Ignore any packets with a multicast source address
557 * (this should be done early in the receive process,
560 if (IN6_IS_ADDR_MULTICAST(pin6))
563 match = match_restrict6_addr(pin6, SRCPORT(srcadr));
564 INSIST(match != NULL);
566 if (&restrict_def6 == match)
570 r4a->rflags = match->rflags;
571 r4a->ippeerlimit = match->ippeerlimit;
578 * roptoa - convert a restrict_op to a string
581 roptoa(restrict_op op) {
585 case RESTRICT_FLAGS: return "RESTRICT_FLAGS";
586 case RESTRICT_UNFLAG: return "RESTRICT_UNFLAGS";
587 case RESTRICT_REMOVE: return "RESTRICT_REMOVE";
588 case RESTRICT_REMOVEIF: return "RESTRICT_REMOVEIF";
590 snprintf(sb, sizeof sb, "**RESTRICT_#%d**", op);
597 * hack_restrict - add/subtract/manipulate entries on the restrict list
602 sockaddr_u * resaddr,
603 sockaddr_u * resmask,
613 restrict_u ** plisthead;
615 DPRINTF(1, ("hack_restrict: op %s addr %s mask %s ippeerlimit %d mflags %08x rflags %08x\n",
616 roptoa(op), stoa(resaddr), stoa(resmask), ippeerlimit, mflags, rflags));
618 if (NULL == resaddr) {
619 REQUIRE(NULL == resmask);
620 REQUIRE(RESTRICT_FLAGS == op);
621 restrict_source_rflags = rflags;
622 restrict_source_mflags = mflags;
623 restrict_source_ippeerlimit = ippeerlimit;
624 restrict_source_enabled = 1;
631 /* silence VC9 potentially uninit warnings */
632 // HMS: let's use a compiler-specific "enable" for this.
637 if (IS_IPV4(resaddr)) {
640 * Get address and mask in host byte order for easy
641 * comparison as u_int32
643 match.u.v4.addr = SRCADR(resaddr);
644 match.u.v4.mask = SRCADR(resmask);
645 match.u.v4.addr &= match.u.v4.mask;
647 } else if (IS_IPV6(resaddr)) {
650 * Get address and mask in network byte order for easy
651 * comparison as byte sequences (e.g. memcmp())
653 match.u.v6.mask = SOCK_ADDR6(resmask);
654 MASK_IPV6_ADDR(&match.u.v6.addr, PSOCK_ADDR6(resaddr),
657 } else /* not IPv4 nor IPv6 */
660 match.rflags = rflags;
661 match.mflags = mflags;
662 match.ippeerlimit = ippeerlimit;
663 match.expire = expire;
664 res = match_restrict_entry(&match, v6);
670 * Here we add bits to the rflags. If this is a
671 * new restriction add it.
677 V6_SIZEOF_RESTRICT_U);
678 plisthead = &restrictlist6;
682 V4_SIZEOF_RESTRICT_U);
683 plisthead = &restrictlist4;
688 ? res_sorts_before6(res, L_S_S_CUR())
689 : res_sorts_before4(res, L_S_S_CUR()),
692 if (RES_LIMITED & rflags)
695 if ( (RES_LIMITED & rflags)
696 && !(RES_LIMITED & res->rflags))
698 res->rflags |= rflags;
701 res->ippeerlimit = match.ippeerlimit;
705 case RESTRICT_UNFLAG:
707 * Remove some bits from the rflags. If we didn't
708 * find this one, just return.
711 if ( (RES_LIMITED & res->rflags)
712 && (RES_LIMITED & rflags))
714 res->rflags &= ~rflags;
718 case RESTRICT_REMOVE:
719 case RESTRICT_REMOVEIF:
721 * Remove an entry from the table entirely if we
722 * found one. Don't remove the default entry and
723 * don't remove an interface entry.
726 && (RESTRICT_REMOVEIF == op
727 || !(RESM_INTERFACE & res->mflags))
728 && res != &restrict_def4
729 && res != &restrict_def6)
733 default: /* unknown op */
742 * restrict_source - maintains dynamic "restrict source ..." entries as
748 int farewell, /* 0 to add, 1 to remove */
749 u_long expire /* 0 is infinite, valid until */
756 if (!restrict_source_enabled || SOCK_UNSPEC(addr) ||
757 IS_MCAST(addr) || ISREFCLOCKADR(addr))
760 REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr));
762 SET_HOSTMASK(&onesmask, AF(addr));
764 hack_restrict(RESTRICT_REMOVE, addr, &onesmask,
766 DPRINTF(1, ("restrict_source: %s removed", stoa(addr)));
771 * If there is a specific entry for this address, hands
772 * off, as it is condidered more specific than "restrict
774 * However, if the specific entry found is a fleeting one
775 * added by pool_xmit() before soliciting, replace it
776 * immediately regardless of the expire value to make way
777 * for the more persistent entry.
780 res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr));
782 found_specific = (SRCADR(&onesmask) == res->u.v4.mask);
784 res = match_restrict6_addr(&SOCK_ADDR6(addr),
787 found_specific = ADDR6_EQ(&res->u.v6.mask,
788 &SOCK_ADDR6(&onesmask));
790 if (!expire && found_specific && res->expire) {
792 free_res(res, IS_IPV6(addr));
797 hack_restrict(RESTRICT_FLAGS, addr, &onesmask,
798 restrict_source_ippeerlimit, restrict_source_mflags,
799 restrict_source_rflags, expire);
800 DPRINTF(1, ("restrict_source: %s host restriction added\n",