예제 #1
0
static void mplex_parse(struct line line) {
	switch (*line.data) {
	case '0' ... '9':
		sqfill(line);
		break;
	case 'I':
		addnet(line);
		break;
	case 'L':
		line_accept(line);
		break;
	case 'F':
		freeze_net(line);
		break;
	case 'D':
		delnet(line);
		break;
	case 'S':
		start_ssl(line);
		break;
	case 'X':
		io_stop = 1;
		break;
	case 'R':
		io_stop = 0;
		reboot(line);
		break;
	default:
		die("Protocol violation: %s", line.data);
	}
}
예제 #2
0
파일: arpwatch.c 프로젝트: einyx/arpwatch
int
main(int argc, char **argv)
{
	register char *cp;
	register int op, pid, snaplen, timeout, linktype, status;
#ifdef TIOCNOTTY
	register int fd;
#endif
	register pcap_t *pd;
	register char *interface, *rfilename;
	struct bpf_program code;
	char errbuf[PCAP_ERRBUF_SIZE];

	if (argv[0] == NULL)
		prog = "arpwatch";
	else if ((cp = strrchr(argv[0], '/')) != NULL)
		prog = cp + 1;
	else
		prog = argv[0];

	if (abort_on_misalignment(errbuf) < 0) {
		(void)fprintf(stderr, "%s: %s\n", prog, errbuf);
		exit(1);
	}

	opterr = 0;
	interface = NULL;
	rfilename = NULL;
	pd = NULL;
	while ((op = getopt(argc, argv, "df:i:n:Nr:")) != EOF)
		switch (op) {

		case 'd':
			++debug;
#ifndef DEBUG
			(void)fprintf(stderr,
			    "%s: Warning: Not compiled with -DDEBUG\n", prog);
#endif
			break;

		case 'f':
			arpfile = optarg;
			break;

		case 'i':
			interface = optarg;
			break;

		case 'n':
			if (!addnet(optarg))
				usage();
			break;

		case 'N':
			++nobogons;
			break;

		case 'r':
			rfilename = optarg;
			break;

		default:
			usage();
		}

	if (optind != argc)
		usage();

	if (rfilename != NULL) {
		net = 0;
		netmask = 0;
	} else {
		/* Determine interface if not specified */
		if (interface == NULL &&
		    (interface = pcap_lookupdev(errbuf)) == NULL) {
			(void)fprintf(stderr, "%s: lookup_device: %s\n",
			    prog, errbuf);
			exit(1);
		}

		/* Determine network and netmask */
		if (pcap_lookupnet(interface, &net, &netmask, errbuf) < 0) {
			(void)fprintf(stderr, "%s: bad interface %s: %s\n",
			    prog, interface, errbuf);
			exit(1);
		}

		/* Drop into the background if not debugging */
		if (!debug) {
			pid = fork();
			if (pid < 0) {
				syslog(LOG_ERR, "main fork(): %m");
				exit(1);
			} else if (pid != 0)
				exit(0);
			(void)close(fileno(stdin));
			(void)close(fileno(stdout));
			(void)close(fileno(stderr));
#ifdef TIOCNOTTY
			fd = open("/dev/tty", O_RDWR);
			if (fd >= 0) {
				(void)ioctl(fd, TIOCNOTTY, 0);
				(void)close(fd);
			}
#else
			(void) setsid();
#endif
		}
	}

	openlog(prog, 0, LOG_DAEMON);

	if (chdir(arpdir) < 0) {
		syslog(LOG_ERR, "chdir(%s): %m", arpdir);
		syslog(LOG_ERR, "(using current working directory)");
	}

	if (rfilename != NULL) {
		pd = pcap_open_offline(rfilename, errbuf);
		if (pd == NULL) {
			syslog(LOG_ERR, "pcap open %s: %s", rfilename,  errbuf);
			exit(1);
		}
		swapped = pcap_is_swapped(pd);
	} else {
		snaplen = max(sizeof(struct ether_header),
		    sizeof(struct fddi_header)) + sizeof(struct ether_arp);
		timeout = 1000;
		pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf);
		if (pd == NULL) {
			syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf);
			exit(1);
		}
#ifdef WORDS_BIGENDIAN
		swapped = 1;
#endif
	}

	/*
	 * Revert to non-privileged user after opening sockets
	 * (not needed on most systems).
	 */
	setgid(getgid());
	setuid(getuid());

	/* Must be ethernet or fddi */
	linktype = pcap_datalink(pd);
	if (linktype != DLT_EN10MB && linktype != DLT_FDDI) {
		syslog(LOG_ERR, "Link layer type %d not ethernet or fddi",
		    linktype);
		exit(1);
	}

	/* Compile and install filter */
	if (pcap_compile(pd, &code, "arp or rarp", 1, netmask) < 0) {
		syslog(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
		exit(1);
	}
	if (pcap_setfilter(pd, &code) < 0) {
		syslog(LOG_ERR, "pcap_setfilter: %s", pcap_geterr(pd));
		exit(1);
	}
	if (rfilename == NULL)
		syslog(LOG_INFO, "listening on %s", interface);

	/* Read in database */
	initializing = 1;
	if (!readdata())
		exit(1);
	sorteinfo();
#ifdef DEBUG
	if (debug > 2) {
		debugdump();
		exit(0);
	}
#endif
	initializing = 0;

	(void)setsignal(SIGINT, die);
	(void)setsignal(SIGTERM, die);
	(void)setsignal(SIGHUP, die);
	if (rfilename == NULL) {
		(void)setsignal(SIGQUIT, checkpoint);
		(void)setsignal(SIGALRM, checkpoint);
		(void)alarm(CHECKPOINT);
	}

	switch (linktype) {

	case DLT_EN10MB:
		status = pcap_loop(pd, 0, process_ether, NULL);
		break;

	case DLT_FDDI:
		status = pcap_loop(pd, 0, process_fddi, NULL);
		break;

	default:
		syslog(LOG_ERR, "bad linktype %d (can't happen)", linktype);
		exit(1);
	}
	if (status < 0) {
		syslog(LOG_ERR, "pcap_loop: %s", pcap_geterr(pd));
		exit(1);
	}
	pcap_close(pd);
	if (!dump())
		exit(1);
	exit(0);
}