📄 nslint.c
字号:
++cp; ch = *cp; if (isupper(ch)) ch = tolower(ch); if (strchr("wdhms", ch) != NULL) ++cp; while (isspace(*cp)) ++cp; if (*cp != '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d bad $ttl \"%s\"\n", prog, cwd, file, n, cp2); } (void)strcpy(name, lastname); continue; } /* Parse ttl or use default */ if (isdigit(*cp)) { ttl = atoi(cp); do { ++cp; } while (isdigit(*cp)); ch = *cp; if (isupper(ch)) ch = tolower(ch); switch (ch) { case 'w': ttl *= 7; /* fall through */ case 'd': ttl *= 24; /* fall through */ case 'h': ttl *= 60; /* fall through */ case 'm': ttl *= 60; /* fall through */ case 's': ++cp; break; default: ; /* none */ } if (!isspace(*cp)) { ++errors; fprintf(stderr, "%s: %s/%s:%d bad ttl\n", prog, cwd, file, n); continue; } /* Find next token */ ++cp; while (isspace(*cp)) ++cp; } else ttl = soaval[SOA_MINIMUM]; /* Eat optional "in" */ if ((cp[0] == 'i' || cp[0] == 'I') && (cp[1] == 'n' || cp[1] == 'N') && isspace(cp[2])) { /* Find next token */ cp += 3; while (isspace(*cp)) ++cp; } else if ((cp[0] == 'c' || cp[0] == 'C') && isspace(cp[5]) && strncasecmp(cp, "chaos", 5) == 0) { /* Find next token */ cp += 5; while (isspace(*cp)) ++cp; } /* Find end of record type, converting to lowercase */ rtype = cp; for (rtype = cp; !isspace(*cp) && *cp != '\0'; ++cp) if (isupper(*cp)) *cp = tolower(*cp); *cp++ = '\0'; /* Find "the rest" */ while (isspace(*cp)) ++cp; /* Check for non-ptr names with dots but no trailing dot */ if (!isdigit(*name) && checkdots(name) && strcmp(domain, ".") != 0) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"%s\" name missing trailing dot: %s\n", prog, cwd, file, n, rtype, name); } /* Check for FQDNs outside the zone */ cp2 = name + strlen(name) - 1; if (cp2 >= name && *cp2 == '.' && strchr(name, '.') != NULL) { cp2 = name + strlen(name) - strlen(zone); if (cp2 >= name && strcasecmp(cp2, zone) != 0) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"%s\" outside zone %s\n", prog, cwd, file, n, name, zone); } }#define CHECK4(p, a, b, c, d) \ (p[0] == (a) && p[1] == (b) && p[2] == (c) && p[3] == (d) && p[4] == '\0')#define CHECK3(p, a, b, c) \ (p[0] == (a) && p[1] == (b) && p[2] == (c) && p[3] == '\0')#define CHECK2(p, a, b) \ (p[0] == (a) && p[1] == (b) && p[2] == '\0')#define CHECKDOT(p) \ (p[0] == '.' && p[1] == '\0') if (rtype[0] == 'a' && rtype[1] == '\0') { /* Handle "a" record */ add_domain(name, domain); addr = htonl(inet_addr(cp)); if ((int)addr == -1) { ++errors; cp2 = cp + strlen(cp) - 1; if (cp2 >= cp && *cp2 == '\n') *cp2 = '\0'; fprintf(stderr, "%s: %s/%s:%d bad \"a\" record ip addr \"%s\"\n", prog, cwd, file, n, cp); continue; } errors += updateitem(name, addr, REC_A, ttl, 0); } else if (CHECK4(rtype, 'a', 'a', 'a', 'a')) { /* Just eat for now */ continue; } else if (CHECK3(rtype, 'p', 't', 'r')) { /* Handle "ptr" record */ add_domain(name, domain); if (strcmp(cp, "@") == 0) (void)strcpy(cp, zone); if (checkdots(cp)) { ++errors; fprintf(stderr, dotfmt, prog, cwd, file, n, rtype, cp); } add_domain(cp, domain); errstr = NULL; addr = parseptr(name, net, mask, &errstr); if (errstr != NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d bad \"ptr\" record (%s) ip addr \"%s\"\n", prog, cwd, file, n, errstr, name); continue; } errors += updateitem(cp, addr, REC_PTR, 0, 0); } else if (CHECK3(rtype, 's', 'o', 'a')) { /* Handle "soa" record */ if (!CHECKDOT(name)) { add_domain(name, domain); errors += updateitem(name, 0, REC_SOA, 0, 0); } errstr = NULL; if (!parsesoa(cp, &errstr)) ++sawsoa; if (errstr != NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d bad \"soa\" record (%s)\n", prog, cwd, file, n, errstr); continue; } } else if (CHECK3(rtype, 'w', 'k', 's')) { /* Handle "wks" record */ addr = htonl(inet_addr(cp)); if ((int)addr == -1) { ++errors; cp2 = cp; while (!isspace(*cp2) && *cp2 != '\0') ++cp2; *cp2 = '\0'; fprintf(stderr, "%s: %s/%s:%d bad \"wks\" record ip addr \"%s\"\n", prog, cwd, file, n, cp); continue; } /* Step over ip address */ while (*cp == '.' || isdigit(*cp)) ++cp; while (isspace(*cp)) *cp++ = '\0'; /* Make sure services are legit */ errstr = NULL; n += checkwks(f, cp, &smtp, &errstr); if (errstr != NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d bad \"wks\" record (%s)\n", prog, cwd, file, n, errstr); continue; } add_domain(name, domain); errors += updateitem(name, addr, REC_WKS, 0, smtp ? FLG_SMTPWKS : 0); /* XXX check to see if ip address records exists? */ } else if (rtype[0] == 'h' && strcmp(rtype, "hinfo") == 0) { /* Handle "hinfo" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_HINFO, 0, 0); cp2 = cp; cp = parsequoted(cp); if (cp == NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"hinfo\" missing quote: %s\n", prog, cwd, file, n, cp2); continue; } if (!isspace(*cp)) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"hinfo\" missing white space: %s\n", prog, cwd, file, n, cp2); continue; } ++cp; while (isspace(*cp)) ++cp; if (*cp == '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d \"hinfo\" missing keyword: %s\n", prog, cwd, file, n, cp2); continue; } cp = parsequoted(cp); if (cp == NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"hinfo\" missing quote: %s\n", prog, cwd, file, n, cp2); continue; } if (*cp != '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d \"hinfo\" garbage after keywords: %s\n", prog, cwd, file, n, cp2); continue; } } else if (CHECK2(rtype, 'm', 'x')) { /* Handle "mx" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_MX, ttl, 0); /* Look for priority */ if (!isdigit(*cp)) { ++errors; fprintf(stderr, "%s: %s/%s:%d bad \"mx\" priority: %s\n", prog, cwd, file, n, cp); } /* Skip over priority */ ++cp; while (isdigit(*cp)) ++cp; while (isspace(*cp)) ++cp; if (*cp == '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d missing \"mx\" hostname\n", prog, cwd, file, n); } if (strcmp(cp, "@") == 0) (void)strcpy(cp, zone); if (checkdots(cp)) { ++errors; fprintf(stderr, dotfmt, prog, cwd, file, n, rtype, cp); } /* Check to see if mx host exists */ add_domain(cp, domain); flags = FLG_MXREF; if (*name == *cp && strcmp(name, cp) == 0) flags |= FLG_SELFMX; errors += updateitem(cp, 0, REC_REF, 0, flags); } else if (rtype[0] == 'c' && strcmp(rtype, "cname") == 0) { /* Handle "cname" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_CNAME, 0, 0); if (checkdots(cp)) { ++errors; fprintf(stderr, dotfmt, prog, cwd, file, n, rtype, cp); } /* Make sure cname points somewhere */ if (strcmp(cp, "@") == 0) (void)strcpy(cp, zone); add_domain(cp, domain); errors += updateitem(cp, 0, REC_REF, 0, 0); } else if (CHECK3(rtype, 's', 'r', 'v')) { /* Handle "srv" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_SRV, 0, 0); cp2 = cp; /* Skip over three values */ for (i = 0; i < 3; ++i) { if (!isdigit(*cp)) { ++errors; fprintf(stderr, "%s: %s/%s:%d" " bad \"srv\" value: %s\n", prog, cwd, file, n, cp); } /* Skip over value */ ++cp; while (isdigit(*cp)) ++cp; while (isspace(*cp)) ++cp; } /* Check to see if mx host exists */ add_domain(cp, domain); errors += updateitem(cp, 0, REC_REF, 0, 0); } else if (CHECK3(rtype, 't', 'x', 't')) { /* Handle "txt" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_TXT, 0, 0); cp2 = cp; cp = parsequoted(cp); if (cp == NULL) { ++errors; fprintf(stderr, "%s: %s/%s:%d \"txt\" missing quote: %s\n", prog, cwd, file, n, cp2); continue; } while (isspace(*cp)) ++cp; if (*cp != '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d \"txt\" garbage after text: %s\n", prog, cwd, file, n, cp2); continue; } } else if (CHECK2(rtype, 'n', 's')) { /* Handle "ns" record */ errors += updateitem(zone, 0, REC_NS, 0, 0); if (strcmp(cp, "@") == 0) (void)strcpy(cp, zone); if (checkdots(cp)) { ++errors; fprintf(stderr, dotfmt, prog, cwd, file, n, rtype, cp); } add_domain(cp, domain); errors += updateitem(cp, 0, REC_REF, 0, 0); } else if (CHECK2(rtype, 'r', 'p')) { /* Handle "rp" record */ add_domain(name, domain); errors += updateitem(name, 0, REC_RP, 0, 0); cp2 = cp; /* Step over mailbox name */ /* XXX could add_domain() and check further */ while (!isspace(*cp) && *cp != '\0') ++cp; if (*cp == '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d \"rp\" missing text name: %s\n", prog, cwd, file, n, cp2); continue; } ++cp; cp3 = cp; /* Step over text name */ while (!isspace(*cp) && *cp != '\0') ++cp; if (*cp != '\0') { ++errors; fprintf(stderr, "%s: %s/%s:%d \"rp\" garbage after text name: %s\n", prog, cwd, file, n, cp2); continue; } /* Make sure text name points somewhere (if not ".") */ if (!CHECKDOT(cp3)) { add_domain(cp3, domain); errors += updateitem(cp3, 0, REC_REF, 0, 0); } } else if (rtype[0] == 'a' && strcmp(rtype, "allowdupa") == 0) { /* Handle "allow duplicate a" record */ add_domain(name, domain); addr = htonl(inet_addr(cp)); if ((int)addr == -1) { ++errors; cp2 = cp + strlen(cp) - 1; if (cp2 >= cp && *cp2 == '\n') *cp2 = '\0'; fprintf(stderr, "%s: %s/%s:%d bad \"allowdupa\" record ip addr \"%s\"\n", prog, cwd, file, n, cp); continue; } errors += updateitem(name, addr, 0, 0, FLG_ALLOWDUPA); } else { /* Unknown record type */ ++errors; fprintf(stderr, "%s: %s/%s:%d unknown record type \"%s\"\n", prog, cwd, file, n, rtype); add_domain(name, domain); errors += updateitem(name, 0, REC_UNKNOWN, 0, 0); } (void)strcpy(lastname, name); } (void)fclose(f); return;}/* Records we use to detect duplicates */static struct duprec { int record; char *name;} duprec[] = { { REC_A, "a" }, { REC_HINFO, "hinfo" }, { 0, NULL },};voidcheckdups(register struct item *ip, register int records){ register struct duprec *dp; records &= (ip->records & MASK_TEST_DUP); if (records == 0) return; for (dp = duprec; dp->name != NULL; ++dp) if ((records & dp->record) != 0) { ++errors; fprintf(stderr, "%s: multiple \"%s\" records for %s\n", prog, dp->name, ip->host); records &= ~dp->record; } if (records != 0) fprintf(stderr, "%s: checkdups: records not zero (%d)\n", prog, records);}intupdateitem(register const char *host, register u_int32_t addr, register int records, register u_int ttl, register int flags){ register const char *ccp; register int n, errs; register u_int i; register struct item *ip; int foundsome; n = 0; foundsome = 0; errs = 0; ITEMHASH(host, i, ccp); ip = &items[i & (ITEMSIZE - 1)]; while (n < ITEMSIZE && ip->host) { if ((addr == 0 || addr == ip->addr || ip->addr == 0) && *host == *ip->host && strcmp(host, ip->host) == 0) { ++foundsome; if (ip->addr == 0) ip->addr = addr; if ((records & MASK_TEST_DUP) != 0) checkdups(ip, records); ip->records |= records; /* Only check differing ttl's for A and MX records */ if (ip->ttl == 0) ip->ttl = ttl; else if (ttl != 0 && ip->ttl != ttl) { fprintf(stderr, "%s: differing ttls for %s (%u != %u)\n", prog, ip->host, ttl, ip->ttl); ++errs; } ip->flags |= flags; /* Not done if we wildcard matched the name */ if (addr) return (errs); } ++n; ++ip; if (ip >= &items[ITEMSIZE]) ip = items; } if (n >= ITEMSIZE) { fprintf(stderr, "%s: out of item slots (max %d)\n", prog, ITEMSIZE); exit(1); } /* Done if we were wildcarding the name (and found entries for it) */ if (addr == 0 && foundsome) return (errs); /* Didn't find it, make new entry */ ++itemcnt; if (ip->host) { fprintf(stderr, "%s: reusing bucket!\n", prog); exit(1); } ip->addr = addr; ip->host = savestr(host); if ((records & MASK_TEST_DUP) != 0) checkdups(ip, records); ip->records |= records; if (ttl != 0) ip->ttl = ttl; ip->flags |= flags; return (errs);}static const char *microlist[] = { "_tcp", "_udp", "_msdcs", "_sites", NULL};intrfc1034host(register const char *host, register int recs){ register const char *cp, **p; register int underok; underok = 0; for (p = microlist; *p != NULL ;++p) if ((cp = strstr(host, *p)) != NULL && cp > host && cp[-1] == '.' && cp[strlen(*p)] == '.') { ++underok; break; } cp = host; if (!(isalpha(*cp) || isdigit(*cp) || (*cp == '_' && underok))) { fprintf(stderr, "%s: illegal hostname \"%s\" (starts with non-alpha/numeric)\n", prog, host); return (1); } for (++cp; *cp != '.' && *cp != '\0'; ++cp) if (!(isalpha(*cp) || isdigit(*cp) || *cp == '-' || (*cp == '/' && (recs & REC_SOA) != 0))) { fprintf(stderr, "%s: illegal hostname \"%s\" ('%c' illegal character)\n", prog, host, *cp); return (1); } if (--cp >= host && *cp == '-') { fprintf(stderr, "%s: illegal hostname \"%s\" (ends with '-')\n", prog, host); return (1); } return (0);}intnslint(void){ register int n, records, flags; register struct item *ip, *lastaip, **ipp, **itemlist; register u_int32_t addr, lastaddr, mask; itemlist = (struct item **)calloc(itemcnt, sizeof(*ipp)); if (itemlist == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -