177618c32SAntonio Huete Jimenez /* $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.59 2012/10/11 08:05:05 sthen Exp $ */
2846204b6SHasso Tepper
3846204b6SHasso Tepper /*
4846204b6SHasso Tepper * Copyright 2004 Henning Brauer <henning@openbsd.org>
5846204b6SHasso Tepper * Copyright (c) 1995, 1996, 1997, 1998, 1999
6846204b6SHasso Tepper * The Internet Software Consortium. All rights reserved.
7846204b6SHasso Tepper *
8846204b6SHasso Tepper * Redistribution and use in source and binary forms, with or without
9846204b6SHasso Tepper * modification, are permitted provided that the following conditions
10846204b6SHasso Tepper * are met:
11846204b6SHasso Tepper *
12846204b6SHasso Tepper * 1. Redistributions of source code must retain the above copyright
13846204b6SHasso Tepper * notice, this list of conditions and the following disclaimer.
14846204b6SHasso Tepper * 2. Redistributions in binary form must reproduce the above copyright
15846204b6SHasso Tepper * notice, this list of conditions and the following disclaimer in the
16846204b6SHasso Tepper * documentation and/or other materials provided with the distribution.
17846204b6SHasso Tepper * 3. Neither the name of The Internet Software Consortium nor the names
18846204b6SHasso Tepper * of its contributors may be used to endorse or promote products derived
19846204b6SHasso Tepper * from this software without specific prior written permission.
20846204b6SHasso Tepper *
21846204b6SHasso Tepper * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22846204b6SHasso Tepper * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23846204b6SHasso Tepper * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24846204b6SHasso Tepper * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25846204b6SHasso Tepper * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26846204b6SHasso Tepper * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27846204b6SHasso Tepper * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28846204b6SHasso Tepper * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29846204b6SHasso Tepper * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30846204b6SHasso Tepper * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31846204b6SHasso Tepper * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32846204b6SHasso Tepper * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33846204b6SHasso Tepper * SUCH DAMAGE.
34846204b6SHasso Tepper *
35846204b6SHasso Tepper * This software has been written for the Internet Software Consortium
36846204b6SHasso Tepper * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37846204b6SHasso Tepper * Enterprises. To learn more about the Internet Software Consortium,
38846204b6SHasso Tepper * see ``http://www.vix.com/isc''. To learn more about Vixie
39846204b6SHasso Tepper * Enterprises, see ``http://www.vix.com''.
40846204b6SHasso Tepper */
41846204b6SHasso Tepper
42846204b6SHasso Tepper #include <sys/ioctl.h>
43846204b6SHasso Tepper
44846204b6SHasso Tepper #include <net/if_media.h>
45846204b6SHasso Tepper
46846204b6SHasso Tepper #include <ifaddrs.h>
47846204b6SHasso Tepper #include <poll.h>
48846204b6SHasso Tepper
49846204b6SHasso Tepper #include "dhcpd.h"
50846204b6SHasso Tepper
518d05e1a0SAntonio Huete Jimenez struct timeout timeout;
52846204b6SHasso Tepper
53846204b6SHasso Tepper /*
543281ce24SAntonio Huete Jimenez * Use getifaddrs() to get a list of all the attached interfaces. Find
553281ce24SAntonio Huete Jimenez * our interface on the list and store the interesting information about it.
56846204b6SHasso Tepper */
57846204b6SHasso Tepper void
discover_interface(void)58846204b6SHasso Tepper discover_interface(void)
59846204b6SHasso Tepper {
60846204b6SHasso Tepper struct ifaddrs *ifap, *ifa;
61846204b6SHasso Tepper struct ifreq *tif;
62846204b6SHasso Tepper int len = IFNAMSIZ + sizeof(struct sockaddr_storage);
63846204b6SHasso Tepper
64846204b6SHasso Tepper if (getifaddrs(&ifap) != 0)
65846204b6SHasso Tepper error("getifaddrs failed");
66846204b6SHasso Tepper
67846204b6SHasso Tepper for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
68846204b6SHasso Tepper if ((ifa->ifa_flags & IFF_LOOPBACK) ||
69846204b6SHasso Tepper (ifa->ifa_flags & IFF_POINTOPOINT) ||
70846204b6SHasso Tepper (!(ifa->ifa_flags & IFF_UP)))
71846204b6SHasso Tepper continue;
72846204b6SHasso Tepper
73846204b6SHasso Tepper if (strcmp(ifi->name, ifa->ifa_name))
74846204b6SHasso Tepper continue;
75846204b6SHasso Tepper
76846204b6SHasso Tepper /*
773281ce24SAntonio Huete Jimenez * If we have the capability, extract & save link information.
78846204b6SHasso Tepper */
79846204b6SHasso Tepper if (ifa->ifa_addr->sa_family == AF_LINK) {
80846204b6SHasso Tepper struct sockaddr_dl *foo =
81846204b6SHasso Tepper (struct sockaddr_dl *)ifa->ifa_addr;
82846204b6SHasso Tepper
83846204b6SHasso Tepper ifi->index = foo->sdl_index;
84846204b6SHasso Tepper ifi->hw_address.hlen = foo->sdl_alen;
85846204b6SHasso Tepper ifi->hw_address.htype = HTYPE_ETHER; /* XXX */
86846204b6SHasso Tepper memcpy(ifi->hw_address.haddr,
87846204b6SHasso Tepper LLADDR(foo), foo->sdl_alen);
88846204b6SHasso Tepper }
89846204b6SHasso Tepper if (!ifi->ifp) {
90846204b6SHasso Tepper if ((tif = malloc(len)) == NULL)
91846204b6SHasso Tepper error("no space to remember ifp");
92846204b6SHasso Tepper strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
93846204b6SHasso Tepper ifi->ifp = tif;
94846204b6SHasso Tepper }
95846204b6SHasso Tepper }
96846204b6SHasso Tepper
97846204b6SHasso Tepper if (!ifi->ifp)
98846204b6SHasso Tepper error("%s: not found", ifi->name);
99846204b6SHasso Tepper
100846204b6SHasso Tepper /* Register the interface... */
101846204b6SHasso Tepper if_register_receive();
102846204b6SHasso Tepper if_register_send();
103846204b6SHasso Tepper freeifaddrs(ifap);
104846204b6SHasso Tepper }
105846204b6SHasso Tepper
106846204b6SHasso Tepper /*
1073281ce24SAntonio Huete Jimenez * Loop waiting for packets, timeouts or routing messages.
108846204b6SHasso Tepper */
109846204b6SHasso Tepper void
dispatch(void)110846204b6SHasso Tepper dispatch(void)
111846204b6SHasso Tepper {
112846204b6SHasso Tepper int count, to_msec;
113846204b6SHasso Tepper struct pollfd fds[2];
1143c279f6eSAntonio Huete Jimenez time_t cur_time, howlong;
1158d05e1a0SAntonio Huete Jimenez void (*func)(void);
116846204b6SHasso Tepper
117846204b6SHasso Tepper do {
118846204b6SHasso Tepper /*
1198d05e1a0SAntonio Huete Jimenez * Call expired timeout, and then if there's still
120846204b6SHasso Tepper * a timeout registered, time out the select call then.
121846204b6SHasso Tepper */
122846204b6SHasso Tepper another:
123d19bab2eSAntonio Huete Jimenez if (!ifi)
124d19bab2eSAntonio Huete Jimenez error("No interfaces available");
125d19bab2eSAntonio Huete Jimenez
1268d05e1a0SAntonio Huete Jimenez if (timeout.func) {
1278d05e1a0SAntonio Huete Jimenez time(&cur_time);
1288d05e1a0SAntonio Huete Jimenez if (timeout.when <= cur_time) {
1298d05e1a0SAntonio Huete Jimenez func = timeout.func;
1308d05e1a0SAntonio Huete Jimenez cancel_timeout();
1318d05e1a0SAntonio Huete Jimenez (*(func))();
132846204b6SHasso Tepper goto another;
133846204b6SHasso Tepper }
134846204b6SHasso Tepper /*
135846204b6SHasso Tepper * Figure timeout in milliseconds, and check for
136846204b6SHasso Tepper * potential overflow, so we can cram into an
137846204b6SHasso Tepper * int for poll, while not polling with a
138846204b6SHasso Tepper * negative timeout and blocking indefinitely.
139846204b6SHasso Tepper */
1408d05e1a0SAntonio Huete Jimenez howlong = timeout.when - cur_time;
141846204b6SHasso Tepper if (howlong > INT_MAX / 1000)
142846204b6SHasso Tepper howlong = INT_MAX / 1000;
143846204b6SHasso Tepper to_msec = howlong * 1000;
144846204b6SHasso Tepper } else
145846204b6SHasso Tepper to_msec = -1;
146846204b6SHasso Tepper
147846204b6SHasso Tepper /* Set up the descriptors to be polled. */
148846204b6SHasso Tepper if (!ifi || ifi->rfdesc == -1)
149846204b6SHasso Tepper error("No live interface to poll on");
150846204b6SHasso Tepper
151846204b6SHasso Tepper fds[0].fd = ifi->rfdesc;
152846204b6SHasso Tepper fds[1].fd = routefd; /* Could be -1, which will be ignored. */
153846204b6SHasso Tepper fds[0].events = fds[1].events = POLLIN;
154846204b6SHasso Tepper
155846204b6SHasso Tepper /* Wait for a packet or a timeout... XXX */
156846204b6SHasso Tepper count = poll(fds, 2, to_msec);
157846204b6SHasso Tepper
158846204b6SHasso Tepper /* Not likely to be transitory... */
159846204b6SHasso Tepper if (count == -1) {
160846204b6SHasso Tepper if (errno == EAGAIN || errno == EINTR) {
161846204b6SHasso Tepper continue;
162846204b6SHasso Tepper } else
163846204b6SHasso Tepper error("poll: %m");
164846204b6SHasso Tepper }
165846204b6SHasso Tepper
166846204b6SHasso Tepper if ((fds[0].revents & (POLLIN | POLLHUP))) {
167*d99acfb3SMarkus Pfeiffer /* XXX profmakx: I am not sure whether updating the linkstate
168*d99acfb3SMarkus Pfeiffer here is the best idea, but it being not up to date leads
169*d99acfb3SMarkus Pfeiffer to a busy loop.
170*d99acfb3SMarkus Pfeiffer Alternatively we can just remove the link state check since
171*d99acfb3SMarkus Pfeiffer the link state is checked in got_one() later on
172*d99acfb3SMarkus Pfeiffer */
173*d99acfb3SMarkus Pfeiffer ifi->linkstat = interface_status(ifi->name);
174*d99acfb3SMarkus Pfeiffer
175bdf60627SAntonio Huete Jimenez if (ifi && ifi->linkstat && ifi->rfdesc != -1)
176846204b6SHasso Tepper got_one();
177846204b6SHasso Tepper }
178846204b6SHasso Tepper if ((fds[1].revents & (POLLIN | POLLHUP))) {
179f57dac5bSAntonio Huete Jimenez if (ifi)
180846204b6SHasso Tepper routehandler();
181846204b6SHasso Tepper }
182846204b6SHasso Tepper } while (1);
183846204b6SHasso Tepper }
184846204b6SHasso Tepper
185846204b6SHasso Tepper void
got_one(void)186846204b6SHasso Tepper got_one(void)
187846204b6SHasso Tepper {
188846204b6SHasso Tepper struct sockaddr_in from;
189846204b6SHasso Tepper struct hardware hfrom;
190846204b6SHasso Tepper struct iaddr ifrom;
191846204b6SHasso Tepper ssize_t result;
192846204b6SHasso Tepper
193846204b6SHasso Tepper if ((result = receive_packet(&from, &hfrom)) == -1) {
194846204b6SHasso Tepper warning("receive_packet failed on %s: %s", ifi->name,
195846204b6SHasso Tepper strerror(errno));
196846204b6SHasso Tepper ifi->errors++;
197846204b6SHasso Tepper if ((!interface_status(ifi->name)) ||
198846204b6SHasso Tepper (ifi->noifmedia && ifi->errors > 20)) {
199846204b6SHasso Tepper /* our interface has gone away. */
2009930e9a8SAntonio Huete Jimenez error("Interface %s no longer appears valid.",
201846204b6SHasso Tepper ifi->name);
202846204b6SHasso Tepper }
203846204b6SHasso Tepper return;
204846204b6SHasso Tepper }
205846204b6SHasso Tepper if (result == 0)
206846204b6SHasso Tepper return;
207846204b6SHasso Tepper
208846204b6SHasso Tepper ifrom.len = 4;
209846204b6SHasso Tepper memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
210846204b6SHasso Tepper
211846204b6SHasso Tepper do_packet(result, from.sin_port, ifrom, &hfrom);
212846204b6SHasso Tepper }
213846204b6SHasso Tepper
214852231a5SMatthew Dillon /*
215852231a5SMatthew Dillon * Normally its ok to force the interface link up, but don't do it
216852231a5SMatthew Dillon * if it is an 80211 interface.
217852231a5SMatthew Dillon */
218846204b6SHasso Tepper int
interface_link_forceup(char * ifname)219846204b6SHasso Tepper interface_link_forceup(char *ifname)
220846204b6SHasso Tepper {
221846204b6SHasso Tepper struct ifreq ifr;
222852231a5SMatthew Dillon struct ifmediareq ifmr;
223846204b6SHasso Tepper int sock;
224846204b6SHasso Tepper
225846204b6SHasso Tepper if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
226846204b6SHasso Tepper error("Can't create socket");
227846204b6SHasso Tepper
228846204b6SHasso Tepper memset(&ifr, 0, sizeof(ifr));
229846204b6SHasso Tepper strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
230846204b6SHasso Tepper if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
231846204b6SHasso Tepper close(sock);
232846204b6SHasso Tepper return (-1);
233846204b6SHasso Tepper }
234852231a5SMatthew Dillon memset(&ifmr, 0, sizeof(ifmr));
235852231a5SMatthew Dillon strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
236852231a5SMatthew Dillon if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) != -1) {
237852231a5SMatthew Dillon if (IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) {
238852231a5SMatthew Dillon return 0;
239852231a5SMatthew Dillon }
240852231a5SMatthew Dillon }
241846204b6SHasso Tepper
242846204b6SHasso Tepper if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
243846204b6SHasso Tepper ifr.ifr_flags |= IFF_UP;
244846204b6SHasso Tepper if (ioctl(sock, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
245846204b6SHasso Tepper close(sock);
246846204b6SHasso Tepper return (-1);
247846204b6SHasso Tepper }
248846204b6SHasso Tepper close(sock);
249846204b6SHasso Tepper return (0);
250846204b6SHasso Tepper }
251846204b6SHasso Tepper close(sock);
252846204b6SHasso Tepper return (1);
253846204b6SHasso Tepper }
254846204b6SHasso Tepper
255846204b6SHasso Tepper int
interface_status(char * ifname)256846204b6SHasso Tepper interface_status(char *ifname)
257846204b6SHasso Tepper {
258846204b6SHasso Tepper struct ifreq ifr;
259846204b6SHasso Tepper struct ifmediareq ifmr;
260846204b6SHasso Tepper int sock;
261846204b6SHasso Tepper
262846204b6SHasso Tepper if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
263846204b6SHasso Tepper error("Can't create socket");
264846204b6SHasso Tepper
265846204b6SHasso Tepper /* get interface flags */
266846204b6SHasso Tepper memset(&ifr, 0, sizeof(ifr));
267846204b6SHasso Tepper strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
268f6c633e7SAntonio Huete Jimenez if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
2699930e9a8SAntonio Huete Jimenez error("ioctl(SIOCGIFFLAGS) on %s: %m", ifname);
270846204b6SHasso Tepper }
271846204b6SHasso Tepper
272846204b6SHasso Tepper /*
273846204b6SHasso Tepper * if one of UP and RUNNING flags is dropped,
274846204b6SHasso Tepper * the interface is not active.
275846204b6SHasso Tepper */
276846204b6SHasso Tepper if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
277846204b6SHasso Tepper goto inactive;
278846204b6SHasso Tepper
279846204b6SHasso Tepper /* Next, check carrier on the interface, if possible */
280846204b6SHasso Tepper if (ifi->noifmedia)
281846204b6SHasso Tepper goto active;
282846204b6SHasso Tepper memset(&ifmr, 0, sizeof(ifmr));
283846204b6SHasso Tepper strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
284f6c633e7SAntonio Huete Jimenez if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
285846204b6SHasso Tepper /*
286846204b6SHasso Tepper * EINVAL or ENOTTY simply means that the interface
287846204b6SHasso Tepper * does not support the SIOCGIFMEDIA ioctl. We regard it alive.
288846204b6SHasso Tepper */
2894cada237SAntonio Huete Jimenez #ifdef DEBUG
290846204b6SHasso Tepper if (errno != EINVAL && errno != ENOTTY)
291846204b6SHasso Tepper debug("ioctl(SIOCGIFMEDIA) on %s: %m", ifname);
2924cada237SAntonio Huete Jimenez #endif
293846204b6SHasso Tepper ifi->noifmedia = 1;
294846204b6SHasso Tepper goto active;
295846204b6SHasso Tepper }
296846204b6SHasso Tepper if (ifmr.ifm_status & IFM_AVALID) {
297846204b6SHasso Tepper if (ifmr.ifm_status & IFM_ACTIVE)
298846204b6SHasso Tepper goto active;
299846204b6SHasso Tepper else
300846204b6SHasso Tepper goto inactive;
301846204b6SHasso Tepper }
3022de2b2feSAntonio Huete Jimenez
3032de2b2feSAntonio Huete Jimenez /* Assume 'active' if IFM_AVALID is not set. */
3042de2b2feSAntonio Huete Jimenez
305846204b6SHasso Tepper active:
306846204b6SHasso Tepper close(sock);
307846204b6SHasso Tepper return (1);
3082de2b2feSAntonio Huete Jimenez inactive:
3092de2b2feSAntonio Huete Jimenez close(sock);
3102de2b2feSAntonio Huete Jimenez return (0);
311846204b6SHasso Tepper }
312846204b6SHasso Tepper
313846204b6SHasso Tepper void
set_timeout(time_t when,void (* where)(void))3148d05e1a0SAntonio Huete Jimenez set_timeout(time_t when, void (*where)(void))
315846204b6SHasso Tepper {
3168d05e1a0SAntonio Huete Jimenez timeout.when = when;
3178d05e1a0SAntonio Huete Jimenez timeout.func = where;
318846204b6SHasso Tepper }
319846204b6SHasso Tepper
320846204b6SHasso Tepper void
set_timeout_interval(time_t secs,void (* where)(void))3213c279f6eSAntonio Huete Jimenez set_timeout_interval(time_t secs, void (*where)(void))
3223c279f6eSAntonio Huete Jimenez {
3233c279f6eSAntonio Huete Jimenez timeout.when = time(NULL) + secs;
3243c279f6eSAntonio Huete Jimenez timeout.func = where;
3253c279f6eSAntonio Huete Jimenez }
3263c279f6eSAntonio Huete Jimenez
3273c279f6eSAntonio Huete Jimenez void
cancel_timeout(void)3288d05e1a0SAntonio Huete Jimenez cancel_timeout(void)
329846204b6SHasso Tepper {
3308d05e1a0SAntonio Huete Jimenez timeout.when = 0;
3318d05e1a0SAntonio Huete Jimenez timeout.func = NULL;
332846204b6SHasso Tepper }
333107428a4SAntonio Huete Jimenez
334107428a4SAntonio Huete Jimenez int
subnet_exists(struct client_lease * l)335107428a4SAntonio Huete Jimenez subnet_exists(struct client_lease *l)
336107428a4SAntonio Huete Jimenez {
337107428a4SAntonio Huete Jimenez struct ifaddrs *ifap, *ifa;
338107428a4SAntonio Huete Jimenez in_addr_t mymask, myaddr, mynet, hismask, hisaddr, hisnet;
339107428a4SAntonio Huete Jimenez
340107428a4SAntonio Huete Jimenez bcopy(l->options[DHO_SUBNET_MASK].data, &mymask, 4);
341107428a4SAntonio Huete Jimenez bcopy(l->address.iabuf, &myaddr, 4);
342107428a4SAntonio Huete Jimenez mynet = mymask & myaddr;
343107428a4SAntonio Huete Jimenez
344107428a4SAntonio Huete Jimenez if (getifaddrs(&ifap) != 0)
345107428a4SAntonio Huete Jimenez error("getifaddrs failed");
346107428a4SAntonio Huete Jimenez
347107428a4SAntonio Huete Jimenez for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
348107428a4SAntonio Huete Jimenez if (strcmp(ifi->name, ifa->ifa_name) == 0)
349107428a4SAntonio Huete Jimenez continue;
350107428a4SAntonio Huete Jimenez
351107428a4SAntonio Huete Jimenez if (ifa->ifa_addr->sa_family != AF_INET)
352107428a4SAntonio Huete Jimenez continue;
353107428a4SAntonio Huete Jimenez
354107428a4SAntonio Huete Jimenez hismask = ((struct sockaddr_in *)ifa->ifa_netmask)->
355107428a4SAntonio Huete Jimenez sin_addr.s_addr;
356107428a4SAntonio Huete Jimenez hisaddr = ((struct sockaddr_in *)ifa->ifa_addr)->
357107428a4SAntonio Huete Jimenez sin_addr.s_addr;
358107428a4SAntonio Huete Jimenez hisnet = hisaddr & hismask;
359107428a4SAntonio Huete Jimenez
360107428a4SAntonio Huete Jimenez if (hisnet == 0)
361107428a4SAntonio Huete Jimenez continue;
362107428a4SAntonio Huete Jimenez
363107428a4SAntonio Huete Jimenez /* Would his packets go out *my* interface? */
364107428a4SAntonio Huete Jimenez if (mynet == (hisaddr & mymask)) {
365107428a4SAntonio Huete Jimenez note("interface %s already has the offered subnet!",
366107428a4SAntonio Huete Jimenez ifa->ifa_name);
367107428a4SAntonio Huete Jimenez return (1);
368107428a4SAntonio Huete Jimenez }
369107428a4SAntonio Huete Jimenez
370107428a4SAntonio Huete Jimenez /* Would my packets go out *his* interface? */
371107428a4SAntonio Huete Jimenez if (hisnet == (myaddr & hismask)) {
372107428a4SAntonio Huete Jimenez note("interface %s already has the offered subnet!",
373107428a4SAntonio Huete Jimenez ifa->ifa_name);
374107428a4SAntonio Huete Jimenez return (1);
375107428a4SAntonio Huete Jimenez }
376107428a4SAntonio Huete Jimenez }
377107428a4SAntonio Huete Jimenez
378107428a4SAntonio Huete Jimenez freeifaddrs(ifap);
379107428a4SAntonio Huete Jimenez
380107428a4SAntonio Huete Jimenez return (0);
381107428a4SAntonio Huete Jimenez }
382