/** Start lookups of all addresses in the conf line. The origin must * be a numeric IP address. If the remote host field is not an IP * address, start a DNS lookup for it. * @param aconf Connection to do lookups for. */ void lookup_confhost(struct ConfItem *aconf) { if (EmptyString(aconf->host) || EmptyString(aconf->name)) { Debug((DEBUG_ERROR, "Host/server name error: (%s) (%s)", aconf->host, aconf->name)); return; } if (aconf->origin_name && !ircd_aton(&aconf->origin.addr, aconf->origin_name)) { Debug((DEBUG_ERROR, "Origin name error: (%s) (%s)", aconf->origin_name, aconf->name)); } /* * Do name lookup now on hostnames given and store the * ip numbers in conf structure. */ if (IsIP6Char(*aconf->host)) { if (!ircd_aton(&aconf->address.addr, aconf->host)) { Debug((DEBUG_ERROR, "Host/server name error: (%s) (%s)", aconf->host, aconf->name)); } } else conf_dns_lookup(aconf); }
/** * Implements the mask checking applied to local Z-lines. * Basically, host masks must have a minimum of two non-wild domain * fields, and IP masks must have a minimum of 16 bits. If the mask * has even one wild-card, OVERRIDABLE is returned, assuming the other * check doesn't fail. * @param[in] mask Z-line mask to check. * @return One of CHECK_REJECTED, CHECK_OVERRIDABLE, or CHECK_APPROVED. */ static int zline_checkmask(char *mask) { unsigned int flags = MASK_IP; unsigned int dots = 0; unsigned int ipmask = 0; for (; *mask; mask++) { /* go through given mask */ if (*mask == '.') { /* it's a separator; advance positional wilds */ flags = (flags & ~MASK_WILD_MASK) | ((flags << 1) & MASK_WILD_MASK); dots++; if ((flags & (MASK_IP | MASK_WILDS)) == MASK_IP) ipmask += 8; /* It's an IP with no wilds, count bits */ } else if (*mask == '*' || *mask == '?') flags |= MASK_WILD_0 | MASK_WILDS; /* found a wildcard */ else if (*mask == '/') { /* n.n.n.n/n notation; parse bit specifier */ ++mask; ipmask = strtoul(mask, &mask, 10); /* sanity-check to date */ if (*mask || (flags & (MASK_WILDS | MASK_IP)) != MASK_IP) return CHECK_REJECTED; if (!dots) { if (ipmask > 128) return CHECK_REJECTED; if (ipmask < 128) flags |= MASK_WILDS; } else { if (dots != 3 || ipmask > 32) return CHECK_REJECTED; if (ipmask < 32) flags |= MASK_WILDS; } flags |= MASK_HALT; /* Halt the ipmask calculation */ break; /* get out of the loop */ } else if (!IsIP6Char(*mask)) { flags &= ~MASK_IP; /* not an IP anymore! */ ipmask = 0; } } /* Sanity-check quads */ if (dots > 3 || (!(flags & MASK_WILDS) && dots < 3)) { flags &= ~MASK_IP; ipmask = 0; } /* update bit count if necessary */ if ((flags & (MASK_IP | MASK_WILDS | MASK_HALT)) == MASK_IP) ipmask += 8; /* Check to see that it's not too wide of a mask */ if (flags & MASK_WILDS && ((!(flags & MASK_IP) && (dots < 2 || flags & MASK_WILD_MASK)) || (flags & MASK_IP && ipmask < 16))) return CHECK_REJECTED; /* to wide, reject */ /* Ok, it's approved; require override if it has wildcards, though */ return flags & MASK_WILDS ? CHECK_OVERRIDABLE : CHECK_APPROVED; }