From: Antonio Huete Jimenez Date: Thu, 7 Aug 2014 07:47:01 +0000 (+0200) Subject: dhclient - Refuse leases for already configured subnets. X-Git-Url: https://gitweb.dragonflybsd.org/~nant/dragonfly.git/commitdiff_plain/107428a4d66c180d28fe25176b90c1da4d9dabc7 dhclient - Refuse leases for already configured subnets. Taken-from: OpenBSD --- diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 12a7677b4e..9db5f4bdc6 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $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 @@ -743,6 +743,13 @@ dhcpoffer(struct iaddr client_addr, struct option_data *options) 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) diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 4c65a11291..5a77e8dd69 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $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 @@ -253,6 +253,7 @@ void set_timeout_interval(time_t, void (*)(void)); 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]; diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index a5e7622909..27869ebf9e 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -1,4 +1,4 @@ -/* $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 @@ -312,3 +312,52 @@ cancel_timeout(void) 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); +}