/* * restrictions - return restrictions for this host */ u_short restrictions( sockaddr_u *srcadr ) { restrict_u *match; struct in6_addr *pin6; u_short flags; res_calls++; flags = 0; /* IPv4 source address */ if (IS_IPV4(srcadr)) { /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN_CLASSD(SRCADR(srcadr))) return (int)RES_IGNORE; match = match_restrict4_addr(SRCADR(srcadr), SRCPORT(srcadr)); match->count++; /* * res_not_found counts only use of the final default * entry, not any "restrict default ntpport ...", which * would be just before the final default. */ if (&restrict_def4 == match) res_not_found++; else res_found++; flags = match->flags; } /* IPv6 source address */ if (IS_IPV6(srcadr)) { pin6 = PSOCK_ADDR6(srcadr); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN6_IS_ADDR_MULTICAST(pin6)) return (int)RES_IGNORE; match = match_restrict6_addr(pin6, SRCPORT(srcadr)); match->count++; if (&restrict_def6 == match) res_not_found++; else res_found++; flags = match->flags; } return (flags); }
/* * restrict_source - maintains dynamic "restrict source ..." entries as * peers come and go. */ void restrict_source( sockaddr_u * addr, int farewell, /* 0 to add, 1 to remove */ u_long expire /* 0 is infinite, valid until */ ) { sockaddr_u onesmask; restrict_u * res; int found_specific; if (!restrict_source_enabled || SOCK_UNSPEC(addr) || IS_MCAST(addr) || ISREFCLOCKADR(addr)) return; REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr)); SET_HOSTMASK(&onesmask, AF(addr)); if (farewell) { hack_restrict(RESTRICT_REMOVE, addr, &onesmask, 0, 0, 0); DPRINTF(1, ("restrict_source: %s removed", stoa(addr))); return; } /* * If there is a specific entry for this address, hands * off, as it is condidered more specific than "restrict * server ...". * However, if the specific entry found is a fleeting one * added by pool_xmit() before soliciting, replace it * immediately regardless of the expire value to make way * for the more persistent entry. */ if (IS_IPV4(addr)) { res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr)); INSIST(res != NULL); found_specific = (SRCADR(&onesmask) == res->u.v4.mask); } else { res = match_restrict6_addr(&SOCK_ADDR6(addr), SRCPORT(addr)); INSIST(res != NULL); found_specific = ADDR6_EQ(&res->u.v6.mask, &SOCK_ADDR6(&onesmask)); } if (!expire && found_specific && res->expire) { found_specific = 0; free_res(res, IS_IPV6(addr)); } if (found_specific) return; hack_restrict(RESTRICT_FLAGS, addr, &onesmask, restrict_source_mflags, restrict_source_flags, expire); DPRINTF(1, ("restrict_source: %s host restriction added\n", stoa(addr))); }
static char decodeaddrtype( sockaddr_u *sock ) { char ch = '-'; u_int32 dummy; switch(AF(sock)) { case AF_INET: dummy = SRCADR(sock); ch = (char)(((dummy&0xf0000000)==0xe0000000) ? 'm' : ((dummy&0x000000ff)==0x000000ff) ? 'b' : ((dummy&0xffffffff)==0x7f000001) ? 'l' : ((dummy&0xffffffe0)==0x00000000) ? '-' : 'u'); break; case AF_INET6: if (IN6_IS_ADDR_MULTICAST(PSOCK_ADDR6(sock))) ch = 'm'; else ch = 'u'; break; default: ch = '-'; break; } return ch; }
const char * refnumtoa( sockaddr_u *num ) { u_int32 netnum; char *buf; const char *rclock; if (!ISREFCLOCKADR(num)) return socktoa(num); LIB_GETBUF(buf); netnum = SRCADR(num); rclock = clockname((int)((u_long)netnum >> 8) & 0xff); if (rclock != NULL) snprintf(buf, LIB_BUFLENGTH, "%s(%lu)", rclock, (u_long)netnum & 0xff); else snprintf(buf, LIB_BUFLENGTH, "REFCLK(%lu,%lu)", ((u_long)netnum >> 8) & 0xff, (u_long)netnum & 0xff); return buf; }
sockaddr_u * netof( sockaddr_u *hostaddr ) { static sockaddr_u netofbuf[8]; static int next_netofbuf; u_int32 netnum; sockaddr_u * netaddr; netaddr = &netofbuf[next_netofbuf]; next_netofbuf = (next_netofbuf + 1) % COUNTOF(netofbuf); memcpy(netaddr, hostaddr, sizeof(*netaddr)); if (IS_IPV4(netaddr)) { netnum = SRCADR(netaddr); /* * We live in a modern CIDR world where the basement nets, which * used to be class A, are now probably associated with each * host address. So, for class-A nets, all bits are significant. */ if (IN_CLASSC(netnum)) netnum &= IN_CLASSC_NET; else if (IN_CLASSB(netnum)) netnum &= IN_CLASSB_NET; SET_ADDR4(netaddr, netnum); } else if (IS_IPV6(netaddr)) /* assume the typical /64 subnet size */ zero_mem(&NSRCADR6(netaddr)[8], 8); #ifdef DEBUG else { msyslog(LOG_ERR, "netof unknown AF %d", AF(netaddr)); exit(1); } #endif return netaddr; }
/* * hack_restrict - add/subtract/manipulate entries on the restrict list */ void hack_restrict( int op, struct sockaddr_storage *resaddr, struct sockaddr_storage *resmask, int mflags, int flags ) { register u_int32 addr = 0; register u_int32 mask = 0; struct in6_addr addr6; struct in6_addr mask6; register struct restrictlist *rl = NULL; register struct restrictlist *rlprev = NULL; register struct restrictlist6 *rl6 = NULL; register struct restrictlist6 *rlprev6 = NULL; int i, addr_cmp, mask_cmp; memset(&addr6, 0, sizeof(struct in6_addr)); memset(&mask6, 0, sizeof(struct in6_addr)); if (resaddr->ss_family == AF_INET) { /* * Get address and mask in host byte order */ addr = SRCADR(resaddr); mask = SRCADR(resmask); addr &= mask; /* make sure low bits zero */ /* * If this is the default address, point at first on * list. Else go searching for it. */ if (addr == 0) { rlprev = NULL; rl = restrictlist; } else { rlprev = restrictlist; rl = rlprev->next; while (rl != NULL) { if (rl->addr > addr) { rl = NULL; break; } else if (rl->addr == addr) { if (rl->mask == mask) { if ((mflags & RESM_NTPONLY) == (rl->mflags & RESM_NTPONLY)) break; if (!(mflags & RESM_NTPONLY)) { rl = NULL; break; } } else if (rl->mask > mask) { rl = NULL; break; } } rlprev = rl; rl = rl->next; } } } if (resaddr->ss_family == AF_INET6) { mask6 = GET_INADDR6(*resmask); SET_IPV6_ADDR_MASK(&addr6, &GET_INADDR6(*resaddr), &mask6); if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { rlprev6 = NULL; rl6 = restrictlist6; } else { rlprev6 = restrictlist6; rl6 = rlprev6->next; while (rl6 != NULL) { addr_cmp = memcmp(&rl6->addr6, &addr6, sizeof(addr6)); if (addr_cmp > 0) { rl6 = NULL; break; } else if (addr_cmp == 0) { mask_cmp = memcmp(&rl6->mask6, &mask6, sizeof(mask6)); if (mask_cmp == 0) { if ((mflags & RESM_NTPONLY) == (rl6->mflags & RESM_NTPONLY)) break; if (!(mflags & RESM_NTPONLY)) { rl6 = NULL; break; } } else if (mask_cmp > 0) { rl6 = NULL; break; } } rlprev6 = rl6; rl6 = rl6->next; } } } /* * In case the above wasn't clear :-), either rl now points * at the entry this call refers to, or rl is zero and rlprev * points to the entry prior to where this one should go in * the sort. */ /* * Switch based on operation */ if (resaddr->ss_family == AF_INET) { switch (op) { case RESTRICT_FLAGS: /* * Here we add bits to the flags. If this is a * new restriction add it. */ if (rl == NULL) { if (resfree == NULL) { rl = (struct restrictlist *) emalloc(INCRESLIST * sizeof(struct restrictlist)); memset((char *)rl, 0, INCRESLIST * sizeof(struct restrictlist)); for (i = 0; i < INCRESLIST; i++) { rl->next = resfree; resfree = rl; rl++; } numresfree = INCRESLIST; } rl = resfree; resfree = rl->next; numresfree--; rl->addr = addr; rl->mask = mask; rl->mflags = (u_short)mflags; if (rlprev == NULL) { rl->next = restrictlist; restrictlist = rl; } else { rl->next = rlprev->next; rlprev->next = rl; } restrictcount++; } if ((rl->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt++; mon_start(MON_RES); } rl->flags |= (u_short)flags; break; case RESTRICT_UNFLAG: /* * Remove some bits from the flags. If we didn't * find this one, just return. */ if (rl != NULL) { if ((rl->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt--; if (res_limited_refcnt == 0) mon_stop(MON_RES); } rl->flags &= (u_short)~flags; } break; case RESTRICT_REMOVE: case RESTRICT_REMOVEIF: /* * Remove an entry from the table entirely if we * found one. Don't remove the default entry and * don't remove an interface entry. */ if (rl != NULL && rl->addr != htonl(INADDR_ANY) && !(rl->mflags & RESM_INTERFACE && op != RESTRICT_REMOVEIF)) { if (rlprev != NULL) { rlprev->next = rl->next; } else { restrictlist = rl->next; } restrictcount--; if (rl->flags & RES_LIMITED) { res_limited_refcnt--; if (res_limited_refcnt == 0) mon_stop(MON_RES); } memset((char *)rl, 0, sizeof(struct restrictlist)); rl->next = resfree; resfree = rl; numresfree++; } break; default: break; } } else if (resaddr->ss_family == AF_INET6) { switch (op) { case RESTRICT_FLAGS: /* * Here we add bits to the flags. If this is a * new restriction add it. */ if (rl6 == NULL) { if (resfree6 == NULL) { rl6 = (struct restrictlist6 *)emalloc( INCRESLIST * sizeof(struct restrictlist6)); memset((char *)rl6, 0, INCRESLIST * sizeof(struct restrictlist6)); for (i = 0; i < INCRESLIST; i++) { rl6->next = resfree6; resfree6 = rl6; rl6++; } numresfree6 = INCRESLIST; } rl6 = resfree6; resfree6 = rl6->next; numresfree6--; rl6->addr6 = addr6; rl6->mask6 = mask6; rl6->mflags = (u_short)mflags; if (rlprev6 != NULL) { rl6->next = rlprev6->next; rlprev6->next = rl6; } else { rl6->next = restrictlist6; restrictlist6 = rl6; } restrictcount6++; } if ((rl6->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt6++; mon_start(MON_RES); } rl6->flags |= (u_short)flags; break; case RESTRICT_UNFLAG: /* * Remove some bits from the flags. If we didn't * find this one, just return. */ if (rl6 != NULL) { if ((rl6->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt6--; if (res_limited_refcnt6 == 0) mon_stop(MON_RES); } rl6->flags &= (u_short)~flags; } break; case RESTRICT_REMOVE: case RESTRICT_REMOVEIF: /* * Remove an entry from the table entirely if we * found one. Don't remove the default entry and * don't remove an interface entry. */ if (rl6 != NULL && !IN6_IS_ADDR_UNSPECIFIED(&rl6->addr6) && !(rl6->mflags & RESM_INTERFACE && op != RESTRICT_REMOVEIF)) { if (rlprev6 != NULL) { rlprev6->next = rl6->next; } else { restrictlist6 = rl6->next; } restrictcount6--; if (rl6->flags & RES_LIMITED) { res_limited_refcnt6--; if (res_limited_refcnt6 == 0) mon_stop(MON_RES); } memset((char *)rl6, 0, sizeof(struct restrictlist6)); rl6->next = resfree6; resfree6 = rl6; numresfree6++; } break; default: break; } } }
/* * restrictions - return restrictions for this host */ int restrictions( struct sockaddr_storage *srcadr, int at_listhead ) { struct restrictlist *rl; struct restrictlist *match = NULL; struct restrictlist6 *rl6; struct restrictlist6 *match6 = NULL; struct in6_addr hostaddr6; struct in6_addr hostservaddr6; u_int32 hostaddr; int flags = 0; int isntpport; res_calls++; if (srcadr->ss_family == AF_INET) { /* * We need the host address in host order. Also need to * know whether this is from the ntp port or not. */ hostaddr = SRCADR(srcadr); isntpport = (SRCPORT(srcadr) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * later!) */ if (IN_CLASSD(SRCADR(srcadr))) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. * Work our way down from there. */ match = restrictlist; for (rl = match->next; rl != NULL && rl->addr <= hostaddr; rl = rl->next) if ((hostaddr & rl->mask) == rl->addr) { if ((rl->mflags & RESM_NTPONLY) && !isntpport) continue; match = rl; } match->count++; if (match == restrictlist) res_not_found++; else res_found++; flags = match->flags; } /* IPv6 source address */ if (srcadr->ss_family == AF_INET6) { /* * Need to know whether this is from the ntp port or * not. */ hostaddr6 = GET_INADDR6(*srcadr); isntpport = (ntohs(( (struct sockaddr_in6 *)srcadr)->sin6_port) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * later!) */ if (IN6_IS_ADDR_MULTICAST(&hostaddr6)) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. * Work our way down from there. */ match6 = restrictlist6; for (rl6 = match6->next; rl6 != NULL && (memcmp(&(rl6->addr6), &hostaddr6, sizeof(hostaddr6)) <= 0); rl6 = rl6->next) { SET_IPV6_ADDR_MASK(&hostservaddr6, &hostaddr6, &rl6->mask6); if (memcmp(&hostservaddr6, &(rl6->addr6), sizeof(hostservaddr6)) == 0) { if ((rl6->mflags & RESM_NTPONLY) && !isntpport) continue; match6 = rl6; } } match6->count++; if (match6 == restrictlist6) res_not_found++; else res_found++; flags = match6->flags; } /* * The following implements a generalized call gap facility. * Douse the RES_LIMITED bit only if the interval since the last * packet is greater than res_min_interval and the average is * greater thatn res_avg_interval. */ if (!at_listhead || mon_enabled == MON_OFF) { flags &= ~RES_LIMITED; } else { struct mon_data *md; /* * At this poin the most recent arrival is first in the * MRU list. Let the first 10 packets in for free until * the average stabilizes. */ md = mon_mru_list.mru_next; if (md->avg_interval == 0) md->avg_interval = md->drop_count; else md->avg_interval += (md->drop_count - md->avg_interval) / RES_AVG; if (md->count < 10 || (md->drop_count > res_min_interval && md->avg_interval > res_avg_interval)) flags &= ~RES_LIMITED; md->drop_count = flags; } return (flags); }
/* * hack_restrict - add/subtract/manipulate entries on the restrict list */ void hack_restrict( int op, sockaddr_u * resaddr, sockaddr_u * resmask, u_short mflags, u_short flags, u_long expire ) { int v6; restrict_u match; restrict_u * res; restrict_u ** plisthead; DPRINTF(1, ("restrict: op %d addr %s mask %s mflags %08x flags %08x\n", op, stoa(resaddr), stoa(resmask), mflags, flags)); if (NULL == resaddr) { REQUIRE(NULL == resmask); REQUIRE(RESTRICT_FLAGS == op); restrict_source_flags = flags; restrict_source_mflags = mflags; restrict_source_enabled = 1; return; } ZERO(match); #if 0 /* silence VC9 potentially uninit warnings */ // HMS: let's use a compiler-specific "enable" for this. res = NULL; v6 = 0; #endif if (IS_IPV4(resaddr)) { v6 = 0; /* * Get address and mask in host byte order for easy * comparison as u_int32 */ match.u.v4.addr = SRCADR(resaddr); match.u.v4.mask = SRCADR(resmask); match.u.v4.addr &= match.u.v4.mask; } else if (IS_IPV6(resaddr)) { v6 = 1; /* * Get address and mask in network byte order for easy * comparison as byte sequences (e.g. memcmp()) */ match.u.v6.mask = SOCK_ADDR6(resmask); MASK_IPV6_ADDR(&match.u.v6.addr, PSOCK_ADDR6(resaddr), &match.u.v6.mask); } else /* not IPv4 nor IPv6 */ REQUIRE(0); match.flags = flags; match.mflags = mflags; match.expire = expire; res = match_restrict_entry(&match, v6); switch (op) { case RESTRICT_FLAGS: /* * Here we add bits to the flags. If this is a * new restriction add it. */ if (NULL == res) { if (v6) { res = alloc_res6(); memcpy(res, &match, V6_SIZEOF_RESTRICT_U); plisthead = &restrictlist6; } else { res = alloc_res4(); memcpy(res, &match, V4_SIZEOF_RESTRICT_U); plisthead = &restrictlist4; } LINK_SORT_SLIST( *plisthead, res, (v6) ? res_sorts_before6(res, L_S_S_CUR()) : res_sorts_before4(res, L_S_S_CUR()), link, restrict_u); restrictcount++; if (RES_LIMITED & flags) inc_res_limited(); } else { if ((RES_LIMITED & flags) && !(RES_LIMITED & res->flags)) inc_res_limited(); res->flags |= flags; } break; case RESTRICT_UNFLAG: /* * Remove some bits from the flags. If we didn't * find this one, just return. */ if (res != NULL) { if ((RES_LIMITED & res->flags) && (RES_LIMITED & flags)) dec_res_limited(); res->flags &= ~flags; } break; case RESTRICT_REMOVE: case RESTRICT_REMOVEIF: /* * Remove an entry from the table entirely if we * found one. Don't remove the default entry and * don't remove an interface entry. */ if (res != NULL && (RESTRICT_REMOVEIF == op || !(RESM_INTERFACE & res->mflags)) && res != &restrict_def4 && res != &restrict_def6) free_res(res, v6); break; default: /* unknown op */ INSIST(0); break; } }
/* * hack_restrict - add/subtract/manipulate entries on the restrict list */ void hack_restrict( int op, struct sockaddr_in *resaddr, struct sockaddr_in *resmask, int mflags, int flags ) { register u_int32 addr; register u_int32 mask; register struct restrictlist *rl; register struct restrictlist *rlprev; int i; /* * Get address and mask in host byte order */ addr = SRCADR(resaddr); mask = SRCADR(resmask); addr &= mask; /* make sure low bits are zero */ /* * If this is the default address, point at first on list. Else * go searching for it. */ if (addr == htonl(INADDR_ANY)) { rlprev = 0; rl = restrictlist; } else { rlprev = restrictlist; rl = rlprev->next; while (rl != 0) { if (rl->addr > addr) { rl = 0; break; } else if (rl->addr == addr) { if (rl->mask == mask) { if ((mflags & RESM_NTPONLY) == (rl->mflags & RESM_NTPONLY)) break; /* exact match */ if (!(mflags & RESM_NTPONLY)) { /* * No flag fits before flag */ rl = 0; break; } /* continue on */ } else if (rl->mask > mask) { rl = 0; break; } } rlprev = rl; rl = rl->next; } } /* * In case the above wasn't clear :-), either rl now points * at the entry this call refers to, or rl is zero and rlprev * points to the entry prior to where this one should go in * the sort. */ /* * Switch based on operation */ switch (op) { case RESTRICT_FLAGS: /* * Here we add bits to the flags. If this is a new * restriction add it. */ if (rl == 0) { if (numresfree == 0) { rl = (struct restrictlist *) emalloc( INCRESLIST*sizeof(struct restrictlist)); memset((char *)rl, 0, INCRESLIST*sizeof(struct restrictlist)); for (i = 0; i < INCRESLIST; i++) { rl->next = resfree; resfree = rl; rl++; } numresfree = INCRESLIST; } rl = resfree; resfree = rl->next; numresfree--; rl->addr = addr; rl->mask = mask; rl->mflags = (u_short)mflags; rl->next = rlprev->next; rlprev->next = rl; restrictcount++; } if ((rl->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt++; mon_start(MON_RES); /* ensure data gets collected */ } rl->flags |= (u_short)flags; break; case RESTRICT_UNFLAG: /* * Remove some bits from the flags. If we didn't * find this one, just return. */ if (rl != 0) { if ((rl->flags ^ (u_short)flags) & RES_LIMITED) { res_limited_refcnt--; if (res_limited_refcnt == 0) mon_stop(MON_RES); } rl->flags &= (u_short)~flags; } break; case RESTRICT_REMOVE: /* * Remove an entry from the table entirely if we found one. * Don't remove the default entry and don't remove an * interface entry. */ if (rl != 0 && rl->addr != htonl(INADDR_ANY) && !(rl->mflags & RESM_INTERFACE)) { rlprev->next = rl->next; restrictcount--; if (rl->flags & RES_LIMITED) { res_limited_refcnt--; if (res_limited_refcnt == 0) mon_stop(MON_RES); } memset((char *)rl, 0, sizeof(struct restrictlist)); rl->next = resfree; resfree = rl; numresfree++; } break; default: /* Oh, well */ break; } /* done! */ }
/* * restrictions - return restrictions for this host */ int restrictions( struct sockaddr_in *srcadr ) { register struct restrictlist *rl; register struct restrictlist *match; register u_int32 hostaddr; register int isntpport; res_calls++; /* * We need the host address in host order. Also need to know * whether this is from the ntp port or not. */ hostaddr = SRCADR(srcadr); isntpport = (SRCPORT(srcadr) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, later!) */ if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr))) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. Work our * way down from there. */ match = restrictlist; for (rl = match->next; rl != 0 && rl->addr <= hostaddr; rl = rl->next) if ((hostaddr & rl->mask) == rl->addr) { if ((rl->mflags & RESM_NTPONLY) && !isntpport) continue; match = rl; } match->count++; if (match == restrictlist) res_not_found++; else res_found++; /* * The following implements limiting the number of clients * accepted from a given network. The notion of "same network" * is determined by the mask and addr fields of the restrict * list entry. The monitor mechanism has to be enabled for * collecting info on current clients. * * The policy is as follows: * - take the list of clients recorded * from the given "network" seen within the last * client_limit_period seconds * - if there are at most client_limit entries: * --> access allowed * - otherwise sort by time first seen * - current client among the first client_limit seen * hosts? * if yes: access allowed * else: eccess denied */ if (match->flags & RES_LIMITED) { int lcnt; struct mon_data *md, *this_client; #ifdef DEBUG if (debug > 2) printf("limited clients check: %ld clients, period %ld seconds, net is 0x%lX\n", client_limit, client_limit_period, (u_long)netof(hostaddr)); #endif /*DEBUG*/ if (mon_enabled == MON_OFF) { #ifdef DEBUG if (debug > 4) printf("no limit - monitoring is off\n"); #endif return (int)(match->flags & ~RES_LIMITED); } /* * How nice, MRU list provides our current client as the * first entry in the list. * Monitoring was verified to be active above, thus we * know an entry for our client must exist, or some * brain dead set the memory limit for mon entries to ZERO!!! */ this_client = mon_mru_list.mru_next; for (md = mon_fifo_list.fifo_next,lcnt = 0; md != &mon_fifo_list; md = md->fifo_next) { if ((current_time - md->lasttime) > client_limit_period) { #ifdef DEBUG if (debug > 5) printf("checking: %s: ignore: too old: %ld\n", numtoa(md->rmtadr), current_time - md->lasttime); #endif continue; } if (md->mode == MODE_BROADCAST || md->mode == MODE_CONTROL || md->mode == MODE_PRIVATE) { #ifdef DEBUG if (debug > 5) printf("checking: %s: ignore mode %d\n", numtoa(md->rmtadr), md->mode); #endif continue; } if (netof(md->rmtadr) != netof(hostaddr)) { #ifdef DEBUG if (debug > 5) printf("checking: %s: different net 0x%lX\n", numtoa(md->rmtadr), (u_long)netof(md->rmtadr)); #endif continue; } lcnt++; if (lcnt > (int) client_limit || md->rmtadr == hostaddr) { #ifdef DEBUG if (debug > 5) printf("considering %s: found host\n", numtoa(md->rmtadr)); #endif break; } #ifdef DEBUG else { if (debug > 5) printf("considering %s: same net\n", numtoa(md->rmtadr)); } #endif } #ifdef DEBUG if (debug > 4) printf("this one is rank %d in list, limit is %lu: %s\n", lcnt, client_limit, (lcnt <= (int) client_limit) ? "ALLOW" : "REJECT"); #endif if (lcnt <= (int) client_limit) { this_client->lastdrop = 0; return (int)(match->flags & ~RES_LIMITED); } else { this_client->lastdrop = current_time; } } return (int)match->flags; }
/* * restrictions - return restrictions for this host in *r4a */ void restrictions( sockaddr_u *srcadr, r4addr *r4a ) { restrict_u *match; struct in6_addr *pin6; REQUIRE(NULL != r4a); res_calls++; r4a->rflags = RES_IGNORE; r4a->ippeerlimit = 0; DPRINTF(1, ("restrictions: looking up %s\n", stoa(srcadr))); /* IPv4 source address */ if (IS_IPV4(srcadr)) { /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN_CLASSD(SRCADR(srcadr))) { DPRINTF(1, ("restrictions: srcadr %s is multicast\n", stoa(srcadr))); r4a->ippeerlimit = 2; /* XXX: we should use a better value */ return; } match = match_restrict4_addr(SRCADR(srcadr), SRCPORT(srcadr)); INSIST(match != NULL); match->count++; /* * res_not_found counts only use of the final default * entry, not any "restrict default ntpport ...", which * would be just before the final default. */ if (&restrict_def4 == match) res_not_found++; else res_found++; r4a->rflags = match->rflags; r4a->ippeerlimit = match->ippeerlimit; } /* IPv6 source address */ if (IS_IPV6(srcadr)) { pin6 = PSOCK_ADDR6(srcadr); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN6_IS_ADDR_MULTICAST(pin6)) return; match = match_restrict6_addr(pin6, SRCPORT(srcadr)); INSIST(match != NULL); match->count++; if (&restrict_def6 == match) res_not_found++; else res_found++; r4a->rflags = match->rflags; r4a->ippeerlimit = match->ippeerlimit; } return; }