Example #1
0
int
main(int argc, char *argv[])
{
	long fib = 0;
	int ch;
	char *ep;
	int	numfibs;
	size_t intsize = sizeof(int);

        if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
		errx(1, "Multiple FIBS not supported");
	if (argc < 2)
		usage();
	ep = argv[1];
	/*
	 * convert -N or N to -FN. (N is a number)
	 */
	if (ep[0]== '-' && isdigit((unsigned char)ep[1]))
		ep++;
	if (isdigit((unsigned char)*ep))
               if (asprintf(&argv[1], "-F%s", ep) < 0)
                        err(1, "asprintf");

	while ((ch = getopt(argc, argv, "F:")) != -1) {
		switch (ch) {
		case 'F':
			errno = 0;
			fib = strtol(optarg, &ep, 10);
			if (ep == optarg || *ep != '\0' || errno ||
			    fib < 0 || fib >= numfibs)
				errx(1, "%s: invalid FIB (max %d)",
				    optarg, numfibs - 1);
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		usage();

	errno = 0;
	if (setfib((int)fib))
		warn("setfib");
	execvp(*argv, argv);
	err(errno == ENOENT ? 127 : 126, "%s", *argv);
}
Example #2
0
int
main(int argc, char *argv[])
{
	int ch, cftest = 0, daemonize = 1, rdomain = -1, udpsockmode = 0;
	char *sync_iface = NULL;
	char *sync_baddr = NULL;
	u_short sync_port = 0;
	struct servent *ent;
	struct in_addr udpaddr;

	/* Initially, log errors to stderr as well as to syslogd. */

	progname = argv[0]; /* XXX: yeah, ugly. */
	opterr = 0;
	while ((ch = getopt(argc, argv, "A:C:L:c:dfl:nu::Y:y:")) != -1)
		switch (ch) {
		case 'Y':
			syncsend = 1;
			break;
		case 'y':
			syncrecv = 1;
			break;
		}
	if (syncsend || syncrecv) {
		if ((ent = getservbyname("dhcpd-sync", "udp")) == NULL)
			errx(1, "Can't find service \"dhcpd-sync\" in "
			    "/etc/services");
		sync_port = ntohs(ent->s_port);
	}
	udpaddr.s_addr = htonl(INADDR_BROADCAST);

	optreset = optind = opterr = 1;
	while ((ch = getopt(argc, argv, "A:C:L:c:dfl:nu::Y:y:")) != -1)
		switch (ch) {
		case 'A':
			abandoned_tab = optarg;
			break;
		case 'C':
			changedmac_tab = optarg;
			break;
		case 'L':
			leased_tab = optarg;
			break;
		case 'c':
			path_dhcpd_conf = optarg;
			break;
		case 'd':
			daemonize = 0;
			log_perror = 1;
			break;
		case 'f':
			daemonize = 0;
			break;
		case 'l':
			path_dhcpd_db = optarg;
			break;
		case 'n':
			daemonize = 0;
			cftest = 1;
			log_perror = 1;
			break;
		case 'u':
			udpsockmode = 1;
			if (optarg != NULL) {
				if (inet_aton(optarg, &udpaddr) != 1)
					errx(1, "Cannot parse binding IP "
					    "address: %s", optarg);
			}
			break;
		case 'Y':
			if (sync_addhost(optarg, sync_port) != 0)
				sync_iface = optarg;
			syncsend = 1;
			break;
		case 'y':
			sync_baddr = optarg;
			syncrecv = 1;
			break;
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	while (argc > 0) {
		struct interface_info *tmp = calloc(1, sizeof(*tmp));
		if (!tmp)
			error("calloc");
		(void)strlcpy(tmp->name, argv[0], sizeof(tmp->name));
		tmp->next = interfaces;
		interfaces = tmp;
		argc--;
		argv++;
	}

	/* Default DHCP/BOOTP ports. */
	server_port = htons(SERVER_PORT);
	client_port = htons(CLIENT_PORT);

	tzset();

	(void)time(&cur_time);
	if (!readconf())
		error("Configuration file errors encountered");

	if (cftest)
		exit(0);

	db_startup();
	if (!udpsockmode || argc > 0)
		discover_interfaces(&rdomain);
	if (rdomain != -1) {
		if (setfib(rdomain) == -1)
			error("setfib (%m)");
	}
	if (udpsockmode)
		udpsock_startup(udpaddr);
	icmp_startup(1, lease_pinged);

	if (syncsend || syncrecv) {
		syncfd = sync_init(sync_iface, sync_baddr, sync_port);
		if (syncfd == -1)
			err(1, "sync init");
	}

	if ((pw = getpwnam("_dhcp")) == NULL)
		error("user \"_dhcp\" not found");

	if (daemonize)
		(void)daemon(0, 0);

	/* don't go near /dev/pf unless we actually intend to use it */
	if ((abandoned_tab != NULL) ||
	    (changedmac_tab != NULL) ||
	    (leased_tab != NULL)) {
		if (pipe(pfpipe) == -1)
			error("pipe (%m)");
		switch (pfproc_pid = fork()) {
		case -1:
			error("fork (%m)");
			/* NOTREACHED */
			exit(1);
		case 0:
			/* child process. start up table engine */
			(void)close(pfpipe[1]);
			pftable_handler();
			/* NOTREACHED */
			exit(1);
		default:
			(void)close(pfpipe[0]);
			gotpipe = 1;
			break;
		}
	}

	if (chroot("/var/empty") == -1)
		error("chroot %s: %m", "/var/empty");

	if (chdir("/") == -1)
		error("chdir(\"/\"): %m");
	if (setgroups(1, &pw->pw_gid) ||
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
		error("can't drop privileges: %m");

	add_timeout(cur_time + 5, periodic_scan, NULL);
	dispatch();

	/* not reached */
	exit(0);
}