-/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.155 2012/09/17 20:30:17 krw Exp $ */
+/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.156 2012/09/18 09:34:09 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
return;
}
+ /*
+ * Reject offers whose subnet is already configured on another
+ * interface.
+ */
+ if (subnet_exists(lease))
+ return;
+
/* If this lease was acquired through a BOOTREPLY, record that
fact. */
if (!options[DHO_DHCP_MESSAGE_TYPE].len)
-/* $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.80 2012/09/01 19:08:42 krw Exp $ */
+/* $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.81 2012/09/18 09:34:09 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
void cancel_timeout(void);
int interface_status(char *);
int interface_link_forceup(char *);
+int subnet_exists(struct client_lease *);
/* tables.c */
extern const struct option dhcp_options[256];
-/* $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.57 2012/09/17 12:10:46 krw Exp $ */
+/* $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.58 2012/09/18 09:34:09 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
timeout.when = 0;
timeout.func = NULL;
}
+
+int
+subnet_exists(struct client_lease *l)
+{
+ struct ifaddrs *ifap, *ifa;
+ in_addr_t mymask, myaddr, mynet, hismask, hisaddr, hisnet;
+
+ bcopy(l->options[DHO_SUBNET_MASK].data, &mymask, 4);
+ bcopy(l->address.iabuf, &myaddr, 4);
+ mynet = mymask & myaddr;
+
+ if (getifaddrs(&ifap) != 0)
+ error("getifaddrs failed");
+
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ if (strcmp(ifi->name, ifa->ifa_name) == 0)
+ continue;
+
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ hismask = ((struct sockaddr_in *)ifa->ifa_netmask)->
+ sin_addr.s_addr;
+ hisaddr = ((struct sockaddr_in *)ifa->ifa_addr)->
+ sin_addr.s_addr;
+ hisnet = hisaddr & hismask;
+
+ if (hisnet == 0)
+ continue;
+
+ /* Would his packets go out *my* interface? */
+ if (mynet == (hisaddr & mymask)) {
+ note("interface %s already has the offered subnet!",
+ ifa->ifa_name);
+ return (1);
+ }
+
+ /* Would my packets go out *his* interface? */
+ if (hisnet == (myaddr & hismask)) {
+ note("interface %s already has the offered subnet!",
+ ifa->ifa_name);
+ return (1);
+ }
+ }
+
+ freeifaddrs(ifap);
+
+ return (0);
+}