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); }
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); }