summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/dhcpd/dhcpd.c18
-rw-r--r--usr.sbin/dhcpd/dhcpd.h4
-rw-r--r--usr.sbin/dhcpd/dispatch.c37
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;
+}