コード例 #1
0
int main(int argc_, char *argv_[])
{
	char *argv[EBTD_ARGC_MAX], cmdline[EBTD_CMDLINE_MAXLN];
	int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace, c, flush = 1;
	char ebtables_str[] = "ebtables";

	while ((c = getopt_long(argc_, argv_, "n", options, NULL)) != -1) {
		switch(c) {
			case 'n':
				flush = 0;
				break;
			default:
				print_usage();
				break;
		}
	}

	ebt_silent = 0;
	copy_table_names();
	ebt_early_init_once();
	argv[0] = ebtables_str;

	while (fgets(cmdline, EBTD_CMDLINE_MAXLN, stdin)) {
		line++;
		if (*cmdline == '#' || *cmdline == '\n')
			continue;
		*strchr(cmdline, '\n') = '\0';
		if (*cmdline == '*') {
			if (table_nr != -1) {
				ebt_deliver_table(&replace[table_nr]);
				ebt_deliver_counters(&replace[table_nr]);
			}
			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, cmdline+1))
					break;
			if (i == 3)
				ebtrest_print_error("table '%s' was not recognized", cmdline+1);
			table_nr = i;
			replace[table_nr].command = 11;
			ebt_get_kernel_table(&replace[table_nr], flush);
			replace[table_nr].command = 0;
			replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */
			continue;
		} else if (table_nr == -1)
			ebtrest_print_error("no table specified");
		if (*cmdline == ':') {
			int policy, chain_nr;
			char *ch;

			if (!(ch = strchr(cmdline, ' ')))
				ebtrest_print_error("no policy specified");
			*ch = '\0';
			for (i = 0; i < NUM_STANDARD_TARGETS; i++)
				if (!strcmp(ch+1, ebt_standard_targets[i])) {
					policy = -i -1;
					if (policy == EBT_CONTINUE)
						i = NUM_STANDARD_TARGETS;
					break;
				}
			if (i == NUM_STANDARD_TARGETS)
				ebtrest_print_error("invalid policy specified");
			/* No need to check chain name for consistency, since
			 * we're supposed to be reading an automatically generated
			 * file. */
			if ((chain_nr = ebt_get_chainnr(&replace[table_nr], cmdline+1)) == -1)
				ebt_new_chain(&replace[table_nr], cmdline+1, policy);
			else
				replace[table_nr].chains[chain_nr]->policy = policy;
			continue;
		}
		argv[1] = cmdline;
		offset = whitespace = 0;
		argc = 2;
		while (cmdline[offset] != '\0') {
			if (cmdline[offset] == '\"') {
				whitespace = 0;
				quotemode ^= 1;
				if (quotemode)
					argv[argc++] = &cmdline[offset+1];
				else if (cmdline[offset+1] != ' ' && cmdline[offset+1] != '\0')
					ebtrest_print_error("syntax error at \"");
				cmdline[offset] = '\0';
			} else if (!quotemode && cmdline[offset] == ' ') {
				whitespace = 1;
				cmdline[offset] = '\0';
			} else if (whitespace == 1) {
				argv[argc++] = &cmdline[offset];
				whitespace = 0;
			}
			offset++;
		}
		if (quotemode)
			ebtrest_print_error("wrong use of '\"'");
		optind = 0; /* Setting optind = 1 causes serious annoyances */
		do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]);
		ebt_reinit_extensions();
	}

	if (table_nr != -1) {
		ebt_deliver_table(&replace[table_nr]);
		ebt_deliver_counters(&replace[table_nr]);
	}
	return 0;
}
コード例 #2
0
int main(int argc_, char *argv_[])
{
	char *argv[EBTD_ARGC_MAX], *args[4], name[] = "mkdir",
	     mkdir_option[] = "-p", mkdir_dir[] = EBTD_PIPE_DIR,
	     cmdline[EBTD_CMDLINE_MAXLN];
	int readfd, base = 0, offset = 0, n = 0, ret = 0, quotemode = 0;

	
	args[0] = name;
	args[1] = mkdir_option;
	args[2] = mkdir_dir;
	args[3] = NULL;
	switch (fork()) {
	case 0:
		execvp(args[0], args);

		
		exit(0);
	case -1:
		return -1;

	default: 
		wait(NULL);
	}

	if (mkfifo(EBTD_PIPE, 0600) < 0 && errno != EEXIST) {
		printf("Error creating FIFO " EBTD_PIPE "\n");
		ret = -1;
		goto do_exit;
	}

	if ((readfd = open(EBTD_PIPE, O_RDONLY | O_NONBLOCK, 0)) == -1) {
		perror("open");
		ret = -1;
		goto do_exit;
	}

	if (signal(SIGPIPE, sigpipe_handler) == SIG_ERR) {
		perror("signal");
		ret = -1;
		goto do_exit;
	}

	ebt_silent = 1;

	copy_table_names();
	ebt_early_init_once();

	while (1) {
		int n2, i, argc, table_nr, ntot;

		
		ntot = read(readfd, cmdline+offset, EBTD_CMDLINE_MAXLN-offset-1);
		if (ntot <= 0)
			continue;
		ntot += offset;
continue_read:
		
		for (; offset < ntot; n++, offset++) {
			if (cmdline[offset] == '\"') {
				quotemode ^= 1;
				cmdline[offset] = '\0';
			} else if (!quotemode && cmdline[offset] == ' ') {
				cmdline[offset] = '\0';
			} else if (cmdline[offset] == '\n') {
				if (quotemode)
					ebt_print_error("ebtablesd: wrong number of \" delimiters");
				cmdline[offset] = '\0';
				break;
			}
		}
		if (n == 0) {
			if (offset == ntot) {
				
				base = 0;
				offset = 0;
				continue;
			}
			offset++;
			base = offset;
			n = 0;
			goto continue_read;
		}
		if (offset == ntot) { 
			if (base == 0) {
				ebt_print_error("ebtablesd: the maximum command line length is %d", EBTD_CMDLINE_MAXLN-1);
				goto write_msg;
			}
			memmove(cmdline, cmdline+base+offset, ntot-offset);
			offset -= base;
			offset++;
			base = 0;
			continue;
		}

		table_nr = 0;
		n2 = 0;
		argc = 0;
		while (n2 < n && argc < EBTD_ARGC_MAX) {
			if (*(cmdline + base + n2) == '\0') {
				n2++;
				continue;
			}
			argv[argc++] = cmdline + base + n2;
			n2 += strlen(cmdline + base + n2) + 1;
		}
		offset++; 
		base = offset;

		if (argc > EBTD_ARGC_MAX) {
			ebt_print_error("ebtablesd: maximum %d arguments "
			                "allowed", EBTD_ARGC_MAX - 1);
			goto write_msg;
		}
		if (argc == 1) {
			ebt_print_error("ebtablesd: no arguments");
			goto write_msg;
		}

		
		if (!strcmp(argv[1], "-t")) {
			if (argc < 3) {
				ebt_print_error("ebtablesd: -t but no table");
				goto write_msg;
			}
			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			table_nr = i;
		} else if (!strcmp(argv[1], "free")) {
			if (argc != 3) {
				ebt_print_error("ebtablesd: command free "
				                "needs exactly one argument");
				goto write_msg;
			}
			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			if (!(replace[i].flags & OPT_KERNELDATA)) {
				ebt_print_error("ebtablesd: table %s has not "
				                "been opened");
				goto write_msg;
			}
			ebt_cleanup_replace(&replace[i]);
			copy_table_names();
			replace[i].flags &= ~OPT_KERNELDATA;
			goto write_msg;
		} else if (!strcmp(argv[1], "open")) {
			if (argc != 3) {
				ebt_print_error("ebtablesd: command open "
				                "needs exactly one argument");
				goto write_msg;
			}

			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			if (replace[i].flags & OPT_KERNELDATA) {
				ebt_print_error("ebtablesd: table %s needs to "
				                "be freed before it can be "
				                "opened");
				goto write_msg;
			}
			if (!ebt_get_kernel_table(&replace[i], 0)) {
				replace[i].flags |= OPT_KERNELDATA;
				open_method[i] = OPEN_METHOD_KERNEL;
			}
			goto write_msg;
		} else if (!strcmp(argv[1], "fopen")) {
			struct ebt_u_replace tmp;

			memset(&tmp, 0, sizeof(tmp));
			if (argc != 4) {
				ebt_print_error("ebtablesd: command fopen "
				                "needs exactly two arguments");
				goto write_msg;
			}

			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			if (replace[i].flags & OPT_KERNELDATA) {
				ebt_print_error("ebtablesd: table %s needs to "
				                "be freed before it can be "
				                "opened");
				goto write_msg;
			}
			tmp.filename = (char *)malloc(strlen(argv[3]) + 1);
			if (!tmp.filename) {
				ebt_print_error("Out of memory");
				goto write_msg;
			}
			strcpy(tmp.filename, argv[3]);
			strcpy(tmp.name, "filter");
			tmp.command = 'L'; 

			ebt_get_kernel_table(&tmp, 0);
			free(tmp.filename);
			tmp.filename = NULL;
			if (ebt_errormsg[0] != '\0')
				goto write_msg;

			if (strcmp(tmp.name, argv[2])) {
				ebt_print_error("ebtablesd: opened file with "
				                "wrong table name '%s'", tmp.name);
				ebt_cleanup_replace(&tmp);
				goto write_msg;
			}
			replace[i] = tmp;
			replace[i].command = '\0';
			replace[i].flags |= OPT_KERNELDATA;
			open_method[i] = OPEN_METHOD_FILE;
			goto write_msg;
		} else if (!strcmp(argv[1], "commit")) {
			if (argc != 3) {
				ebt_print_error("ebtablesd: command commit "
				                "needs exactly one argument");
				goto write_msg;
			}

			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			if (!(replace[i].flags & OPT_KERNELDATA)) {
				ebt_print_error("ebtablesd: table %s has not "
				                "been opened");
				goto write_msg;
			}
			if (open_method[i] == OPEN_METHOD_FILE)
				replace[i].num_counters = 0;
			ebt_deliver_table(&replace[i]);
			if (ebt_errormsg[0] == '\0' && open_method[i] == OPEN_METHOD_KERNEL)
				ebt_deliver_counters(&replace[i]);
			goto write_msg;
		} else if (!strcmp(argv[1], "fcommit")) {
			if (argc != 4) {
				ebt_print_error("ebtablesd: command commit "
				                "needs exactly two argument");
				goto write_msg;
			}

			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, argv[2]))
					break;
			if (i == 3) {
				ebt_print_error("ebtablesd: table '%s' was "
				                "not recognized", argv[2]);
				goto write_msg;
			}
			if (!(replace[i].flags & OPT_KERNELDATA)) {
				ebt_print_error("ebtablesd: table %s has not "
				                "been opened");
				goto write_msg;
			}
			replace[i].filename = (char *)malloc(strlen(argv[3]) + 1);
			if (!replace[i].filename) {
				ebt_print_error("Out of memory");
				goto write_msg;
			}
			strcpy(replace[i].filename, argv[3]);
			ebt_deliver_table(&replace[i]);
			if (ebt_errormsg[0] == '\0' && open_method[i] == OPEN_METHOD_KERNEL)
				ebt_deliver_counters(&replace[i]);
			free(replace[i].filename);
			replace[i].filename = NULL;
			goto write_msg;
		}else if (!strcmp(argv[1], "quit")) {
			if (argc != 2) {
				ebt_print_error("ebtablesd: command quit does "
				                "not take any arguments");
				goto write_msg;
			}
			break;
		}
		if (!(replace[table_nr].flags & OPT_KERNELDATA)) {
			ebt_print_error("ebtablesd: table %s has not been "
			                "opened", replace[table_nr].name);
			goto write_msg;
		}
		optind = 0; 
		do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]);
		ebt_reinit_extensions();
write_msg:
#ifndef SILENT_DAEMON
		if (ebt_errormsg[0] != '\0')
			printf("%s.\n", ebt_errormsg);
#endif
		ebt_errormsg[0]= '\0';
		n = 0;
		goto continue_read;
	}
do_exit:
	unlink(EBTD_PIPE);
	
	return 0;
}