diff options
-rw-r--r-- | usr.sbin/dhcpd/dhcpd.c | 18 | ||||
-rw-r--r-- | usr.sbin/dhcpd/dhcpd.h | 4 | ||||
-rw-r--r-- | usr.sbin/dhcpd/dispatch.c | 37 |
3 files changed, 47 insertions, 12 deletions
diff --git a/usr.sbin/dhcpd/dhcpd.c b/usr.sbin/dhcpd/dhcpd.c index da47b598910..dc2fa85a51c 100644 --- a/usr.sbin/dhcpd/dhcpd.c +++ b/usr.sbin/dhcpd/dhcpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.c,v 1.38 2008/05/29 19:02:47 deraadt Exp $ */ +/* $OpenBSD: dhcpd.c,v 1.39 2010/04/19 12:22:09 claudio Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@cvs.openbsd.org> @@ -71,7 +71,7 @@ struct syslog_data sdata = SYSLOG_DATA_INIT; int main(int argc, char *argv[]) { - int ch, cftest = 0, daemonize = 1; + int ch, cftest = 0, daemonize = 1, rdomain = -1; extern char *__progname; char *sync_iface = NULL; char *sync_baddr = NULL; @@ -168,17 +168,21 @@ main(int argc, char *argv[]) if (cftest) exit(0); + db_startup(); + discover_interfaces(&rdomain); + + if (rdomain != -1) + if (setrdomain(rdomain) == -1) + error("setrdomain (%m)"); + + icmp_startup(1, lease_pinged); + if (syncsend || syncrecv) { syncfd = sync_init(sync_iface, sync_baddr, sync_port); if (syncfd == -1) err(1, "sync init"); } - db_startup(); - discover_interfaces(); - icmp_startup(1, lease_pinged); - - if ((pw = getpwnam("_dhcp")) == NULL) error("user \"_dhcp\" not found"); diff --git a/usr.sbin/dhcpd/dhcpd.h b/usr.sbin/dhcpd/dhcpd.h index 2614f73e245..075d8222ad0 100644 --- a/usr.sbin/dhcpd/dhcpd.h +++ b/usr.sbin/dhcpd/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.44 2010/01/02 04:21:16 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.45 2010/04/19 12:22:09 claudio Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998, 1999 @@ -625,7 +625,7 @@ extern struct protocol *protocols; extern void (*bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *); extern struct dhcpd_timeout *timeouts; -void discover_interfaces(void); +void discover_interfaces(int *); void dispatch(void); int locate_network(struct packet *); void got_one(struct protocol *); diff --git a/usr.sbin/dhcpd/dispatch.c b/usr.sbin/dhcpd/dispatch.c index dae45e2713e..ff431c85fcb 100644 --- a/usr.sbin/dhcpd/dispatch.c +++ b/usr.sbin/dhcpd/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.25 2010/01/02 04:21:16 krw Exp $ */ +/* $OpenBSD: dispatch.c,v 1.26 2010/04/19 12:22:09 claudio Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998, 1999 @@ -56,6 +56,7 @@ void (*bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *); static int interface_status(struct interface_info *ifinfo); +int get_rdomain(char *); /* Use getifaddrs() to get a list of all the attached interfaces. For each interface that's of type INET and not the loopback interface, @@ -63,14 +64,14 @@ static int interface_status(struct interface_info *ifinfo); subnet it's on, and add it to the list of interfaces. */ void -discover_interfaces(void) +discover_interfaces(int *rdomain) { struct interface_info *tmp; struct interface_info *last, *next; struct subnet *subnet; struct shared_network *share; struct sockaddr_in foo; - int ir = 0; + int ir = 0, ird; struct ifreq *tif; struct ifaddrs *ifap, *ifa; @@ -83,6 +84,9 @@ discover_interfaces(void) */ if (interfaces != NULL) ir = 1; + else + /* must specify an interface when rdomains are used */ + *rdomain = 0; /* Cycle through the list of interfaces looking for IP addresses. */ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { @@ -106,6 +110,15 @@ discover_interfaces(void) if (tmp == NULL && ir) continue; + ird = get_rdomain(ifa->ifa_name); + if (*rdomain == -1) + *rdomain = ird; + else if (*rdomain != ird && ir) + error("Interface %s is not in rdomain %d", + tmp->name, *rdomain); + else if (*rdomain != ird && !ir) + continue; + /* If there isn't already an interface by this name, allocate one. */ if (tmp == NULL) { @@ -608,3 +621,21 @@ remove_protocol(struct protocol *proto) } } } + +int +get_rdomain(char *name) +{ + int rv = 0, s; + struct ifreq ifr; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + error("get_rdomain socket: %m"); + + bzero(&ifr, sizeof(ifr)); + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFRTABLEID, (caddr_t)&ifr) != -1) + rv = ifr.ifr_rdomainid; + + close(s); + return rv; +} |