static	char	*getline __P((char *, size_t, FILE *, int *)); static	char	*ipfname = IPL_NAME; static	void	usage __P((void)); static	void	showversion __P((void)); static	int	get_flags __P((void));   static void usage() { fprintf(stderr, "usage: ipf [-6AdDEInoPrsUvVyzZ] %s %s %s\n", "[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]"); exit(1); }   int main(argc,argv) int argc; char *argv[]; { int c;  while ((c = getopt(argc, argv, "6AdDEf:F:Il:noPrsUvVyzZ")) != -1) { switch (c) { case '?' : usage(); #ifdef	USE_INET6 case '6' : use_inet6 = 1; break; #endif case 'A' : opts &= ~OPT_INACTIVE; break; case 'E' : set_state((u_int)1); break; case 'D' : set_state((u_int)0); break; case 'd' : opts |= OPT_DEBUG; break; case 'f' : procfile(argv[0], optarg); break; case 'F' : flushfilter(optarg); break; case 'I' : opts |= OPT_INACTIVE; break; case 'l' : packetlogon(optarg); break; case 'n' : opts |= OPT_DONOTHING; break; case 'o' : break; case 'P' : ipfname = IPL_AUTH; break; case 'r' : opts |= OPT_REMOVE; break; case 's' : swapactive(); break; #if SOLARIS case 'U' : blockunknown(); break; #endif case 'v' : opts |= OPT_VERBOSE; break; case 'V' : showversion(); break; case 'y' : frsync(); break; case 'z' : opts |= OPT_ZERORULEST; break; case 'Z' : zerostats(); break; } }  if (fd != -1) (void) close(fd);  exit(0);  }   static int opendevice(ipfdev) char *ipfdev; { if (opts & OPT_DONOTHING) return -2;  if (!ipfdev) ipfdev = ipfname;  if (!(opts & OPT_DONOTHING) && fd == -1) if ((fd = open(ipfdev, O_RDWR)) == -1) if ((fd = open(ipfdev, O_RDONLY)) == -1) perror("open device"); return fd; }   static void closedevice() { close(fd); fd = -1; }   static	int	get_flags() { int i;  if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) { perror("SIOCGETFF"); return 0; } return i; }   static	void	set_state(enable) u_int	enable; { if (opendevice(ipfname) != -2) if (ioctl(fd, SIOCFRENB, &enable) == -1) { if (errno == EBUSY) fprintf(stderr, "IP FIlter: already initialized\n"); else perror("SIOCFRENB"); } return; }  static	void	procfile(name, file) char	*name, *file; { FILE	*fp; char	line[513], *s; struct	frentry	*fr; u_int	add, del; int     linenum = 0;  (void) opendevice(ipfname);  if (opts & OPT_INACTIVE) { add = SIOCADIFR; del = SIOCRMIFR; } else { add = SIOCADAFR; del = SIOCRMAFR; } if (opts & OPT_DEBUG) printf("add %x del %x\n", add, del);  initparse();  if (!strcmp(file, "-")) fp = stdin; else if (!(fp = fopen(file, "r"))) { fprintf(stderr, "%s: fopen(%s) failed: %s\n", name, file, STRERROR(errno)); exit(1); }  while (getline(line, sizeof(line), fp, &linenum)) {  if ((s = index(line, '\r'))) *s = '\0';  if ((s = index(line, '#'))) *s = '\0';  if (!*line) continue;  if (opts & OPT_VERBOSE) (void)fprintf(stderr, "[%s]\n", line);  fr = parse(line, linenum); (void)fflush(stdout);  if (fr) { if (opts & OPT_ZERORULEST) add = SIOCZRLST; else if (opts & OPT_INACTIVE) add = (u_int)fr->fr_hits ? SIOCINIFR : SIOCADIFR; else add = (u_int)fr->fr_hits ? SIOCINAFR : SIOCADAFR; if (fr->fr_hits) fr->fr_hits--; if (fr && (opts & OPT_VERBOSE)) printfr(fr); if (fr && (opts & OPT_OUTQUE)) fr->fr_flags |= FR_OUTQUE;  if (opts & OPT_DEBUG) binprint(fr);  if ((opts & OPT_ZERORULEST) && !(opts & OPT_DONOTHING)) { if (ioctl(fd, add, &fr) == -1) { fprintf(stderr, "%d:", linenum); perror("ioctl(SIOCZRLST)"); } else { #ifdef	USE_QUAD_T printf("hits %qd bytes %qd ", (long long)fr->fr_hits, (long long)fr->fr_bytes); #else printf("hits %ld bytes %ld ", fr->fr_hits, fr->fr_bytes); #endif printfr(fr); } } else if ((opts & OPT_REMOVE) && !(opts & OPT_DONOTHING)) { if (ioctl(fd, del, &fr) == -1) { fprintf(stderr, "%d:", linenum); perror("ioctl(delete rule)"); } } else if (!(opts & OPT_DONOTHING)) { if (ioctl(fd, add, &fr) == -1) { fprintf(stderr, "%d:", linenum); perror("ioctl(add/insert rule)"); } } } } if (ferror(fp) || !feof(fp)) { fprintf(stderr, "%s: %s: file error or line too long\n", name, file); exit(1); } (void)fclose(fp); }
static	char	*getline __P((char *, size_t, FILE *, int *));static	char	*ipfname = IPL_NAME;static	void	usage __P((void));static	void	showversion __P((void));static	int	get_flags __P((void));static void usage(){	fprintf(stderr, "usage: ipf [-6AdDEInoPrsUvVyzZ] %s %s %s\n",		"[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");	exit(1);}int main(argc,argv)int argc;char *argv[];{	int c;	while ((c = getopt(argc, argv, "6AdDEf:F:Il:noPrsUvVyzZ")) != -1) {		switch (c)		{		case '?' :			usage();#ifdef	USE_INET6		case '6' :			use_inet6 = 1;			break;#endif		case 'A' :			opts &= ~OPT_INACTIVE;			break;		case 'E' :			set_state((u_int)1);			break;		case 'D' :			set_state((u_int)0);			break;		case 'd' :			opts |= OPT_DEBUG;			break;		case 'f' :			procfile(argv[0], optarg);			break;		case 'F' :			flushfilter(optarg);			break;		case 'I' :			opts |= OPT_INACTIVE;			break;		case 'l' :			packetlogon(optarg);			break;		case 'n' :			opts |= OPT_DONOTHING;			break;		case 'o' :			break;		case 'P' :			ipfname = IPL_AUTH;			break;		case 'r' :			opts |= OPT_REMOVE;			break;		case 's' :			swapactive();			break;#if SOLARIS		case 'U' :			blockunknown();			break;#endif		case 'v' :			opts |= OPT_VERBOSE;			break;		case 'V' :			showversion();			break;		case 'y' :			frsync();			break;		case 'z' :			opts |= OPT_ZERORULEST;			break;		case 'Z' :			zerostats();			break;		}	}	if (fd != -1)		(void) close(fd);	exit(0);	/* NOTREACHED */}static int opendevice(ipfdev)char *ipfdev;{	if (opts & OPT_DONOTHING)		return -2;	if (!ipfdev)		ipfdev = ipfname;	if (!(opts & OPT_DONOTHING) && fd == -1)		if ((fd = open(ipfdev, O_RDWR)) == -1)			if ((fd = open(ipfdev, O_RDONLY)) == -1)				perror("open device");	return fd;}static void closedevice(){	close(fd);	fd = -1;}static	int	get_flags(){	int i;	if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) {		perror("SIOCGETFF");		return 0;	}	return i;}static	void	set_state(enable)u_int	enable;{	if (opendevice(ipfname) != -2)		if (ioctl(fd, SIOCFRENB, &enable) == -1) {			if (errno == EBUSY)				fprintf(stderr,					"IP FIlter: already initialized\n");			else				perror("SIOCFRENB");		}	return;}static	void	procfile(name, file)char	*name, *file;{	FILE	*fp;	char	line[513], *s;	struct	frentry	*fr;	u_int	add, del;	int     linenum = 0;	(void) opendevice(ipfname);	if (opts & OPT_INACTIVE) {		add = SIOCADIFR;		del = SIOCRMIFR;	} else {		add = SIOCADAFR;		del = SIOCRMAFR;	}	if (opts & OPT_DEBUG)		printf("add %x del %x\n", add, del);	initparse();	if (!strcmp(file, "-"))		fp = stdin;	else if (!(fp = fopen(file, "r"))) {		fprintf(stderr, "%s: fopen(%s) failed: %s\n", name, file,			STRERROR(errno));		exit(1);	}	while (getline(line, sizeof(line), fp, &linenum)) {		/*		 * treat CR as EOL.  LF is converted to NUL by getline().		 */		if ((s = index(line, '\r')))			*s = '\0';		/*		 * # is comment marker, everything after is a ignored		 */		if ((s = index(line, '#')))			*s = '\0';		if (!*line)			continue;		if (opts & OPT_VERBOSE)			(void)fprintf(stderr, "[%s]\n", line);		fr = parse(line, linenum);		(void)fflush(stdout);		if (fr) {			if (opts & OPT_ZERORULEST)				add = SIOCZRLST;			else if (opts & OPT_INACTIVE)				add = (u_int)fr->fr_hits ? SIOCINIFR :							   SIOCADIFR;			else				add = (u_int)fr->fr_hits ? SIOCINAFR :							   SIOCADAFR;			if (fr->fr_hits)				fr->fr_hits--;			if (fr && (opts & OPT_VERBOSE))				printfr(fr);			if (fr && (opts & OPT_OUTQUE))				fr->fr_flags |= FR_OUTQUE;			if (opts & OPT_DEBUG)				binprint(fr);			if ((opts & OPT_ZERORULEST) &&			    !(opts & OPT_DONOTHING)) {				if (ioctl(fd, add, &fr) == -1) {					fprintf(stderr, "%d:", linenum);					perror("ioctl(SIOCZRLST)");				} else {#ifdef	USE_QUAD_T					printf("hits %qd bytes %qd ",						(long long)fr->fr_hits,						(long long)fr->fr_bytes);#else					printf("hits %ld bytes %ld ",						fr->fr_hits, fr->fr_bytes);#endif					printfr(fr);				}			} else if ((opts & OPT_REMOVE) &&				   !(opts & OPT_DONOTHING)) {				if (ioctl(fd, del, &fr) == -1) {					fprintf(stderr, "%d:", linenum);					perror("ioctl(delete rule)");				}			} else if (!(opts & OPT_DONOTHING)) {				if (ioctl(fd, add, &fr) == -1) {					fprintf(stderr, "%d:", linenum);					perror("ioctl(add/insert rule)");				}			}		}	}	if (ferror(fp) || !feof(fp)) {		fprintf(stderr, "%s: %s: file error or line too long\n",		    name, file);		exit(1);	}	(void)fclose(fp);}/* * Similar to fgets(3) but can handle '\\' and NL is converted to NUL. * Returns NULL if error occured, EOF encounterd or input line is too long. */static char *getline(str, size, file, linenum)register char	*str;size_t	size;FILE	*file;int	*linenum;{	char *p;	int s, len;	do {		for (p = str, s = size;; p += (len - 1), s -= (len - 1)) {			/*			 * if an error occured, EOF was encounterd, or there			 * was no room to put NUL, return NULL.			 */			if (fgets(p, s, file) == NULL)				return (NULL);			len = strlen(p);			if (p[len - 1] != '\n') {				p[len] = '\0';				break;			}			(*linenum)++;			p[len - 1] = '\0';			if (len < 2 || p[len - 2] != '\\')				break;			else				/*				 * Convert '\\' to a space so words don't				 * run together				 */				p[len - 2] = ' ';		}	} while (*str == '\0');	return (str);}