/*------------------------------------------------------------------------ * rtget - get the route for a given IP destination *------------------------------------------------------------------------ */ struct route * rtget(IPaddr dest, Bool local) { struct route *prt; int hv; if (!Route.ri_valid) rtinit(); wait(Route.ri_mutex); hv = rthash(dest); for (prt=rttable[hv]; prt; prt=prt->rt_next) { if (prt->rt_ttl <= 0) continue; /* route has expired */ if (netmatch(dest, prt->rt_net, prt->rt_mask, local)) if (prt->rt_metric < RTM_INF) break; } if (prt == 0) prt = Route.ri_default; /* may be NULL too... */ if (prt != 0 && prt->rt_metric >= RTM_INF) prt = 0; if (prt) { prt->rt_refcnt++; prt->rt_usecnt++; } signal(Route.ri_mutex); return prt; }
/* * Determine whether an access list grants rights to a particular host. * We match on aliases of the hostname as well as on the canonical name. * Names in the access list may be either hosts or netgroups; they're * not distinguished syntactically. We check for hosts first because * it's cheaper (just M*N strcmp()s), then try netgroups. */ int in_access_list(struct netbuf *nb, struct nd_hostservlist *clnames, char *access_list) /* N.B. we clobber this "input" parameter */ { int nentries; char *gr; char *lasts; char *host; int off; int i; int netgroup_match; int response; /* * If no access list - then it's unrestricted */ if (access_list == NULL || *access_list == '\0') return (1); nentries = 0; for (gr = strtok_r(access_list, ":", &lasts); gr != NULL; gr = strtok_r(NULL, ":", &lasts)) { /* * If the list name has a '-' prepended * then a match of the following name * implies failure instead of success. */ if (*gr == '-') { response = 0; gr++; } else response = 1; /* * The following loops through all the * client's aliases. Usually it's just one name. */ for (i = 0; i < clnames->h_cnt; i++) { host = clnames->h_hostservs[i].h_host; /* * If the list name begins with a dot then * do a domain name suffix comparison. * A single dot matches any name with no * suffix. */ if (*gr == '.') { if (*(gr + 1) == '\0') { /* single dot */ if (strchr(host, '.') == NULL) return (response); } else { off = strlen(host) - strlen(gr); if (off > 0 && strcasecmp(host + off, gr) == 0) { return (response); } } } else /* * If the list name begins with an at * sign then do a network comparison. */ if (*gr == '@') { if (netmatch(nb, gr + 1)) return (response); } else /* * Just do a hostname match */ if (strcasecmp(gr, host) == 0) { return (response); /* Matched a hostname */ } } nentries++; } netgroup_match = netgroup_check(clnames, access_list, nentries); return (netgroup_match); }