⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nslint.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char copyright[] =    "@(#) Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001\n\The Regents of the University of California.  All rights reserved.\n";static const char rcsid[] =    "@(#) $Id: nslint.c,v 1.1 2001/12/21 04:12:04 marka Exp $ (LBL)";#endif/* * nslint - perform consistency checks on dns files */#include <sys/types.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#include <errno.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_MALLOC_H#include <malloc.h>#endif#ifdef HAVE_MEMORY_H#include <memory.h>#endif#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include "savestr.h"#include "gnuc.h"#ifdef HAVE_OS_PROTO_H#include "os-proto.h"#endif#define NSLINTBOOT "nslint.boot"	/* default nslint.boot file */#define NSLINTCONF "nslint.conf"	/* default nslint.conf file *//* item struct */struct item {	char *host;		/* pointer to hostname */	u_int32_t addr;		/* ip address */	u_int ttl;		/* ttl of A records */	int records;		/* resource records seen */	int flags;		/* flags word */};/* Resource records seen */#define REC_A		0x0001#define REC_PTR		0x0002#define REC_WKS		0x0004#define REC_HINFO	0x0008#define REC_MX		0x0010#define REC_CNAME	0x0020#define REC_NS		0x0040#define REC_SOA		0x0080#define REC_RP		0x0100#define REC_TXT		0x0200#define REC_SRV		0x0400/* These aren't real records */#define REC_OTHER	0x0800#define REC_REF		0x1000#define REC_UNKNOWN	0x2000/* Test for records we want to map to REC_OTHER */#define MASK_TEST_REC (REC_WKS | REC_HINFO | \    REC_MX | REC_SOA | REC_RP | REC_TXT | REC_SRV | REC_UNKNOWN)/* Mask away records we don't care about in the final processing to REC_OTHER */#define MASK_CHECK_REC \    (REC_A | REC_PTR | REC_CNAME | REC_REF | REC_OTHER)/* Test for records we want to check for duplicate name detection */#define MASK_TEST_DUP \    (REC_A | REC_HINFO)/* Flags */#define FLG_SELFMX	0x001	/* mx record refers to self */#define FLG_MXREF	0x002	/* this record referred to by a mx record */#define FLG_SMTPWKS	0x004	/* saw wks with smtp/tcp */#define FLG_ALLOWDUPA	0x008	/* allow duplicate a records *//* Test for smtp problems */#define MASK_TEST_SMTP \    (FLG_SELFMX | FLG_SMTPWKS)#define ITEMSIZE (1 << 17)	/* power of two */#define ITEMHASH(str, h, p) \    for (p = str, h = 0; *p != '.' && *p != '\0';) h = (h << 5) - h + *p++struct	item items[ITEMSIZE];int	itemcnt;		/* count of items *//* Hostname string storage */#define STRSIZE 8192;		/* size to malloc when more space is needed */char	*strptr;		/* pointer to string pool */int	strsize;		/* size of space left in pool */int	debug;int	errors;char	*bootfile = "/etc/named.boot";char	*conffile = "/etc/named.conf";char	*nslintboot;char	*nslintconf;char	*prog;char	*cwd = ".";char **protoserv;		/* valid protocol/service names */int protoserv_init;int protoserv_last;int protoserv_len;static char inaddr[] = ".in-addr.arpa.";/* SOA record */#define SOA_SERIAL	0#define SOA_REFRESH	1#define SOA_RETRY	2#define SOA_EXPIRE	3#define SOA_MINIMUM	4static u_int soaval[5];static int nsoaval;#define NSOAVAL (sizeof(soaval) / sizeof(soaval[0]))/* Forwards */static	inline void add_domain(char *, const char *);int	checkdots(const char *);void	checkdups(struct item *, int);int	checkserv(const char *, char **p);int	checkwks(FILE *, char *, int *, char **);int	cmpaddr(const void *, const void *);int	cmphost(const void *, const void *);int	doboot(const char *, int);int	doconf(const char *, int);void	initprotoserv(void);char	*intoa(u_int32_t);int	main(int, char **);int	nslint(void);int	parseinaddr(const char *, u_int32_t *, u_int32_t *);int	parsenetwork(const char *, char **);u_int32_t parseptr(const char *, u_int32_t, u_int32_t, char **);char	*parsequoted(char *);int	parsesoa(const char *, char **);void	process(const char *, const char *, const char *);int	rfc1034host(const char *, int);int	updateitem(const char *, u_int32_t, int, u_int, int);__dead	void usage(void) __attribute__((volatile));extern	char *optarg;extern	int optind, opterr;/* add domain if necessary */static inline voidadd_domain(register char *name, register const char *domain){	register char *cp;	/* Kill trailing white space and convert to lowercase */	for (cp = name; *cp != '\0' && !isspace(*cp); ++cp)		if (isupper(*cp))			*cp = tolower(*cp);	*cp-- = '\0';	/* If necessary, append domain */	if (cp >= name && *cp++ != '.') {		if (*domain != '.')			*cp++ = '.';		(void)strcpy(cp, domain);	}	/* XXX should we insure a trailing dot? */}intmain(int argc, char **argv){	register char *cp;	register int op, status, i, donamedboot, donamedconf;	if ((cp = strrchr(argv[0], '/')) != NULL)		prog = cp + 1;	else		prog = argv[0];	donamedboot = 0;	donamedconf = 0;	while ((op = getopt(argc, argv, "b:c:B:C:d")) != -1)		switch (op) {		case 'b':			bootfile = optarg;			++donamedboot;			break;		case 'c':			conffile = optarg;			++donamedconf;			break;		case 'B':			nslintboot = optarg;			++donamedboot;			break;		case 'C':			nslintconf = optarg;			++donamedconf;			break;		case 'd':			++debug;			break;		default:			usage();		}	if (optind != argc || (donamedboot && donamedconf))		usage();	if (donamedboot)		status = doboot(bootfile, 1);	else if (donamedconf)		status = doconf(conffile, 1);	else {		status = doconf(conffile, 0);		if (status < 0) {			status = doboot(bootfile, 1);			++donamedboot;		} else			++donamedconf;	}	if (donamedboot) {		if (nslintboot != NULL)			status |= doboot(nslintboot, 1);		else if ((i = doboot(NSLINTBOOT, 0)) > 0)			status |= i;	} else {		if (nslintconf != NULL)			status |= doconf(nslintconf, 1);		else if ((i = doconf(NSLINTCONF, 0)) > 0)			status |= i;	}	status |= nslint();	exit (status);}struct netlist {	u_int32_t net;	u_int32_t mask;};static struct netlist *netlist;static u_int netlistsize;	/* size of array */static u_int netlistcnt;	/* next free element */static u_int32_tfindmask(u_int32_t addr){	register int i;	for (i = 0; i < netlistcnt; ++i)		if ((addr & netlist[i].mask) == netlist[i].net)			return (netlist[i].mask);	return (0);}intparsenetwork(register const char *cp, register char **errstrp){	register int i, w;	register u_int32_t net, mask;	register u_int32_t o;	register int shift;	static char errstr[132];	while (isspace(*cp))		++cp;	net = 0;	mask = 0;	shift = 24;	while (isdigit(*cp) && shift >= 0) {		o = 0;		do {			o = o * 10 + (*cp++ - '0');		} while (isdigit(*cp));		net |= o << shift;		shift -= 8;		if (*cp != '.')			break;		++cp;	}	if (isspace(*cp)) {		++cp;		while (isspace(*cp))			++cp;		mask = htonl(inet_addr(cp));		if ((int)mask == -1) {			*errstrp = errstr;			(void)sprintf(errstr, "bad mask \"%s\"", cp);			return (0);		}		i = 0;		while (isdigit(*cp))			++cp;		for (i = 0; i < 3 && *cp == '.'; ++i) {			++cp;			while (isdigit(*cp))				++cp;		}		if (i != 3) {			*errstrp = "wrong number of dots in mask";			return (0);		}	} else if (*cp == '/') {		++cp;		w = atoi(cp);		do {			++cp;		} while (isdigit(*cp));		if (w < 1 || w > 32) {			*errstrp = "bad mask width";			return (0);		}		mask = 0xffffffff << (32 - w);	} else {		*errstrp = "garbage after net";		return (0);	}	while (isspace(*cp))		++cp;	if (*cp != '\0') {		*errstrp = "trailing garbage";		return (0);	}	/* Finaly sanity checks */	if ((net & ~ mask) != 0) {		*errstrp = errstr;		(void)sprintf(errstr, "host bits set in net \"%s\"",		    intoa(net));		return (0);	}	/* Make sure there's room */	if (netlistsize <= netlistcnt) {		if (netlistsize == 0) {			netlistsize = 32;			netlist = (struct netlist *)			    malloc(netlistsize * sizeof(*netlist));		} else {			netlistsize <<= 1;			netlist = (struct netlist *)			    realloc(netlist, netlistsize * sizeof(*netlist));		}		if (netlist == NULL) {			fprintf(stderr, "%s: nslint: malloc/realloc: %s\n",			    prog, strerror(errno));			exit(1);		}	}	/* Add to list */	netlist[netlistcnt].net = net;	netlist[netlistcnt].mask = mask;	++netlistcnt;	return (1);}intdoboot(register const char *file, register int mustexist){	register int n;	register char *cp, *cp2;	register FILE *f;	char *errstr;	char buf[1024], name[128];	errno = 0;	f = fopen(file, "r");	if (f == NULL) {		/* Not an error if it doesn't exist */		if (!mustexist && errno == ENOENT) {			if (debug > 1)				printf(				    "%s: doit: %s doesn't exist (ignoring)\n",				    prog, file);			return (-1);		}		fprintf(stderr, "%s: %s: %s\n", prog, file, strerror(errno));		exit(1);	}	if (debug > 1)		printf("%s: doit: opened %s\n", prog, file);	n = 0;	while (fgets(buf, sizeof(buf), f) != NULL) {		++n;		/* Skip comments */		if (buf[0] == ';')			continue;		cp = strchr(buf, ';');		if (cp)			*cp = '\0';		cp = buf + strlen(buf) - 1;		if (cp >= buf && *cp == '\n')			*cp = '\0';		cp = buf;		/* Eat leading whitespace */		while (isspace(*cp))			++cp;		/* Skip blank lines */		if (*cp == '\n' || *cp == '\0')			continue;		/* Get name */		cp2 = cp;		while (!isspace(*cp) && *cp != '\0')			++cp;		*cp++ = '\0';		/* Find next keyword */		while (isspace(*cp))			++cp;		if (strcasecmp(cp2, "directory") == 0) {			/* Terminate directory */			cp2 = cp;			while (!isspace(*cp) && *cp != '\0')				++cp;			*cp = '\0';			if (chdir(cp2) < 0) {				++errors;				fprintf(stderr, "%s: can't chdir %s: %s\n",				    prog, cp2, strerror(errno));				exit(1);			}			cwd = savestr(cp2);			continue;		}		if (strcasecmp(cp2, "primary") == 0) {			/* Extract domain, converting to lowercase */			for (cp2 = name; !isspace(*cp) && *cp != '\0'; ++cp)				if (isupper(*cp))					*cp2++ = tolower(*cp);				else					*cp2++ = *cp;			/* Insure trailing dot */			if (cp2 > name && cp2[-1] != '.')				*cp2++ = '.';			*cp2 = '\0';			/* Find file */			while (isspace(*cp))				++cp;			/* Terminate directory */			cp2 = cp;			while (!isspace(*cp) && *cp != '\0')				++cp;			*cp = '\0';			/* Process it! (zone is the same as the domain) */			nsoaval = -1;			memset(soaval, 0, sizeof(soaval));			process(cp2, name, name);			continue;		}		if (strcasecmp(cp2, "network") == 0) {			if (!parsenetwork(cp, &errstr)) {				++errors;				fprintf(stderr,				    "%s: %s:%d: bad network: %s\n",				    prog, file, n, errstr);			}			continue;		}		if (strcasecmp(cp2, "include") == 0) {			/* Terminate include file */			cp2 = cp;			while (!isspace(*cp) && *cp != '\0')				++cp;			*cp = '\0';			errors += doboot(cp2, 1);			continue;		}		/* Eat any other options */	}	(void)fclose(f);	return (errors != 0);}intdoconf(register const char *file, register int mustexist){	register int n, fd, cc, i, depth;	register char *cp, *cp2, *buf;	register char *name, *zonename, *filename, *typename;	register int namelen, zonenamelen, filenamelen, typenamelen;	char *errstr;	struct stat sbuf;	char zone[128], includefile[256];	errno = 0;	fd = open(file, O_RDONLY, 0);	if (fd < 0) {		/* Not an error if it doesn't exist */		if (!mustexist && errno == ENOENT) {			if (debug > 1)				printf(				    "%s: doconf: %s doesn't exist (ignoring)\n",				    prog, file);			return (-1);		}		fprintf(stderr, "%s: %s: %s\n", prog, file, strerror(errno));		exit(1);	}	if (debug > 1)		printf("%s: doconf: opened %s\n", prog, file);	if (fstat(fd, &sbuf) < 0) {		fprintf(stderr, "%s: fstat(%s) %s\n",		    prog, file, strerror(errno));		exit(1);	}	buf = (char *)malloc(sbuf.st_size + 1);	if (buf == NULL) {		fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));		exit(1);	}	/* Slurp entire config file */	n = sbuf.st_size;	cp = buf;	do {		cc = read(fd, cp, n);		if (cc < 0) {			fprintf(stderr, "%s: read(%s) %s\n",			    prog, file, strerror(errno));			exit(1);		}		cp += cc;		n -= cc;	} while (cc != 0 && cc < n);	buf[cc] = '\0';#define EATWHITESPACE \	while (isspace(*cp)) { \		if (*cp == '\n') \			++n; \		++cp; \	}/* Handle both to-end-of-line and C style comments */#define EATCOMMENTS \	{ \	int sawcomment; \	do { \		EATWHITESPACE \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -