#ifndef lint
static char copyright[] =
-"$Id: bpf.c,v 1.15 1997/02/18 14:30:12 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bpf.c,v 1.16 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_BPF_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+#ifdef USE_BPF_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+}
+#endif
+
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
-int if_register_bpf (info, ifp)
+int if_register_bpf (info)
struct interface_info *info;
- struct ifreq *ifp;
{
int sock;
char filename[50];
}
/* Set the BPF device to point at this interface. */
- if (ioctl (sock, BIOCSETIF, ifp) < 0)
+ if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
error ("Can't attach interface %s to bpf device %s: %m",
info -> name, filename);
#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
#ifdef USE_BPF_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the bpf API for sending and receiving,
we don't need to register this interface twice. */
BPF_STMT(BPF_RET+BPF_K, 0),
};
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
int flag = 1;
struct bpf_version v;
u_int32_t bits;
/* Open a BPF device and hang it on this interface... */
- info -> rfdesc = if_register_bpf (info, interface);
+ info -> rfdesc = if_register_bpf (info);
/* Make sure the BPF version is in range... */
if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
#ifndef lint
static char copyright[] =
-"$Id: bpf.c,v 1.15 1997/02/18 14:30:12 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bpf.c,v 1.16 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_BPF_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+#ifdef USE_BPF_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+}
+#endif
+
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
-int if_register_bpf (info, ifp)
+int if_register_bpf (info)
struct interface_info *info;
- struct ifreq *ifp;
{
int sock;
char filename[50];
}
/* Set the BPF device to point at this interface. */
- if (ioctl (sock, BIOCSETIF, ifp) < 0)
+ if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
error ("Can't attach interface %s to bpf device %s: %m",
info -> name, filename);
#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
#ifdef USE_BPF_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the bpf API for sending and receiving,
we don't need to register this interface twice. */
BPF_STMT(BPF_RET+BPF_K, 0),
};
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
int flag = 1;
struct bpf_version v;
u_int32_t bits;
/* Open a BPF device and hang it on this interface... */
- info -> rfdesc = if_register_bpf (info, interface);
+ info -> rfdesc = if_register_bpf (info);
/* Make sure the BPF version is in range... */
if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.29 1997/02/18 14:33:43 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.30 1997/02/19 10:49:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
-struct interface_info *interfaces;
+struct interface_info *interfaces, *dummy_interfaces;
struct timeout *timeouts;
static struct timeout *free_timeouts;
+static int interfaces_invalidated;
static void got_one PROTO ((struct interface_info *));
/* If this is the first real IP address we've
found, keep a pointer to ifreq structure in
which we found it. */
- if (!tmp -> tif)
- tmp -> tif = ifp;
+ if (!tmp -> ifp) {
+ struct ifreq *tif;
+#ifdef HAVE_SA_LEN
+ int len = ((sizeof ifp -> ifr_name) +
+ ifp -> ifr_addr.sa_len);
+#else
+ int len = sizeof *ifp;
+#endif
+ tif = (struct ifreq *)malloc (len);
+ if (!tif)
+ error ("no space to remember ifp.");
+ memcpy (tif, ifp, len);
+ tmp -> ifp = ifp;
+ }
/* Grab the address... */
addr.len = 4;
/* Weed out the interfaces that did not have IP addresses. */
last = (struct interface_info *)0;
for (tmp = interfaces; tmp; tmp = tmp -> next) {
- if (!tmp -> tif || !(tmp -> flags & INTERFACE_REQUESTED)) {
+ if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
error ("%s: not found", tmp -> name);
if (!last)
interfaces = interfaces -> next;
else
last -> next = tmp -> next;
+
+ /* Remember the interface in case we need to know
+ about it later. */
+ tmp -> next = dummy_interfaces;
+ dummy_interfaces = tmp;
continue;
}
last = tmp;
- memcpy (&foo, &tmp -> tif -> ifr_addr,
- sizeof tmp -> tif -> ifr_addr);
+ memcpy (&foo, &tmp -> ifp -> ifr_addr,
+ sizeof tmp -> ifp -> ifr_addr);
/* We must have a subnet declaration for each interface. */
if (!tmp -> shared_network && (state == DISCOVER_SERVER))
}
/* Register the interface... */
- if_register_receive (tmp, tmp -> tif);
- if_register_send (tmp, tmp -> tif);
-
- tmp -> tif = (struct ifreq *)0; /* Can't keep this. */
+ if_register_receive (tmp);
+ if_register_send (tmp);
}
close (sock);
strcpy (fallback_interface.name, "fallback");
fallback_interface.shared_network = &fallback_network;
fallback_network.name = "fallback-net";
- if_register_fallback (&fallback_interface, (struct ifreq *)0);
+ if_register_fallback (&fallback_interface);
+#endif
+}
+
+void reinitialize_interfaces ()
+{
+ struct interface_info *ip;
+
+ for (ip = interfaces; ip; ip = ip -> next) {
+ if_reinitialize_receive (ip);
+ if_reinitialize_send (ip);
+ }
+
+#ifdef USE_FALLBACK
+ if_reinitialize_fallback (&fallback_interface);
#endif
+
+ interfaces_invalidated = 1;
}
#ifdef USE_POLL
if (!fds)
error ("Can't allocate poll structures.");
- i = 0;
- for (l = interfaces; l; l = l -> next) {
- fds [i].fd = l -> rfdesc;
- fds [i].events = POLLIN;
- fds [i].revents = 0;
- ++i;
- }
-
-#ifdef USE_FALLBACK
- fds [i].fd = fallback_interface.wfdesc;
- fds [i].events = POLLIN;
- fds [i].revents = 0;
- ++i;
-#endif
-
do {
-
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
} else
to_msec = -1;
+ /* Set up the descriptors to be polled. */
+ i = 0;
+ for (l = interfaces; l; l = l -> next) {
+ fds [i].fd = l -> rfdesc;
+ fds [i].events = POLLIN;
+ fds [i].revents = 0;
+ ++i;
+ }
+
+#ifdef USE_FALLBACK
+ fds [i].fd = fallback_interface.wfdesc;
+ fds [i].events = POLLIN;
+ fds [i].revents = 0;
+ ++i;
+#endif
+
/* Wait for a packet or a timeout... XXX */
count = poll (fds, nfds, to_msec);
if ((fds [i].revents & POLLIN)) {
fds [i].revents = 0;
got_one (l);
+ if (interfaces_invalidated)
+ break;
}
++i;
}
#ifdef USE_FALLBACK
- if (fds [i].revents & POLLIN)
+ if ((fds [i].revents & POLLIN) && !interfaces_invalidated)
fallback_discard (&fallback_interface);
#endif
+ interfaces_invalidated = 0;
} while (1);
}
#else
int count;
struct timeval tv, *tvp;
- FD_ZERO (&r);
FD_ZERO (&w);
FD_ZERO (&x);
do {
- /* Set up the read mask. */
- for (l = interfaces; l; l = l -> next) {
- FD_SET (l -> rfdesc, &r);
- FD_SET (l -> rfdesc, &x);
- if (l -> rfdesc > max)
- max = l -> rfdesc;
- }
-#ifdef USE_FALLBACK
- FD_SET (fallback_interface.wfdesc, &r);
- if (fallback_interface.wfdesc > max)
- max = fallback_interface.wfdesc;
-#endif
-
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
} else
tvp = (struct timeval *)0;
+ /* Set up the read mask. */
+ FD_ZERO (&r);
+
+ for (l = interfaces; l; l = l -> next) {
+ FD_SET (l -> rfdesc, &r);
+ FD_SET (l -> rfdesc, &x);
+ if (l -> rfdesc > max)
+ max = l -> rfdesc;
+ }
+#ifdef USE_FALLBACK
+ FD_SET (fallback_interface.wfdesc, &r);
+ if (fallback_interface.wfdesc > max)
+ max = fallback_interface.wfdesc;
+#endif
+
/* Wait for a packet or a timeout... XXX */
count = select (max + 1, &r, &w, &x, tvp);
if (!FD_ISSET (l -> rfdesc, &r))
continue;
got_one (l);
+ if (interfaces_invalidated)
+ break;
}
#ifdef USE_FALLBACK
- if (FD_ISSET (fallback_interface.wfdesc, &r))
+ if (FD_ISSET (fallback_interface.wfdesc, &r) &&
+ !interfaces_invalidated)
fallback_discard (&fallback_interface);
#endif
+ interfaces_invalidated = 1;
} while (1);
}
#endif /* USE_POLL */
#ifndef lint
static char copyright[] =
-"$Id: nit.c,v 1.11 1997/02/18 14:30:12 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nit.c,v 1.12 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_NIT_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+#ifdef USE_NIT_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+}
+#endif
+
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
-int if_register_nit (info, ifp)
+int if_register_nit (info)
struct interface_info *info;
- struct ifreq *ifp;
{
int sock;
char filename[50];
/* Set the NIT device to point at this interface. */
sio.ic_cmd = NIOCBIND;
- sio.ic_len = sizeof *ifp;
- sio.ic_dp = (char *)ifp;
+ sio.ic_len = sizeof *(info -> ifp);
+ sio.ic_dp = (char *)(info -> ifp);
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
error ("Can't attach interface %s to nit device: %m",
#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */
#ifdef USE_NIT_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the nit API for sending and receiving,
we don't need to register this interface twice. */
struct packetfilt pf;
struct strioctl sio;
- info -> wfdesc = if_register_nit (info, interface);
+ info -> wfdesc = if_register_nit (info);
pf.Pf_Priority = 0;
pf.Pf_FilterLen = 1;
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the NIT program! XXX */
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
int flag = 1;
u_int32_t x;
struct timeval t;
/* Open a NIT device and hang it on this interface... */
- info -> rfdesc = if_register_nit (info, interface);
+ info -> rfdesc = if_register_nit (info);
/* Set the snap length to 0, which means always take the whole
packet. */
#ifndef lint
static char copyright[] =
-"$Id: raw.c,v 1.9 1997/02/18 14:32:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: raw.c,v 1.10 1997/02/19 10:51:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/uio.h>
/* Generic interface registration routine... */
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
struct sockaddr_in name;
int sock;
#ifndef lint
static char copyright[] =
-"$Id: socket.c,v 1.18 1997/02/18 14:30:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: socket.c,v 1.19 1997/02/19 10:49:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
# define USE_SOCKET_SEND
# define if_register_send if_register_fallback
# define send_packet send_fallback
+# define if_reinitialize_send if_reinitialize_fallback
+#endif
+
+static int once = 0;
+
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_SOCKET_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+#if 0
+#ifndef USE_SOCKET_RECEIVE
+ once = 0;
+ close (info -> wfdesc);
+#endif
+ if_register_send (info);
+#endif
+}
+#endif
+
+#ifdef USE_SOCKET_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+#if 0
+ once = 0;
+ close (info -> rfdesc);
+ if_register_receive (info);
+#endif
+}
#endif
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE)
/* Generic interface registration routine... */
-int if_register_socket (info, interface)
+int if_register_socket (info)
struct interface_info *info;
- struct ifreq *interface;
{
struct sockaddr_in name;
int sock;
int flag;
#ifndef SO_BINDTODEVICE
- static int once = 0;
-
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s%s%s%s%s",
#ifdef SO_BINDTODEVICE
/* Bind this socket to this interface. */
- if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
- (char *)interface, sizeof(*interface)) < 0) {
+ if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
+ (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
}
#endif
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
#ifdef USE_SOCKET_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
-
{
#ifndef USE_SOCKET_RECEIVE
- info -> wfdesc = if_register_socket (info, interface);
+ info -> wfdesc = if_register_socket (info);
#else
info -> wfdesc = info -> rfdesc;
#endif
#endif /* USE_SOCKET_SEND */
#ifdef USE_SOCKET_RECEIVE
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info, interface);
+ info -> rfdesc = if_register_socket (info);
note ("Listening on Socket/%s/%s",
info -> name,
(info -> shared_network ?
#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.29 1997/02/18 14:33:43 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.30 1997/02/19 10:49:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
-struct interface_info *interfaces;
+struct interface_info *interfaces, *dummy_interfaces;
struct timeout *timeouts;
static struct timeout *free_timeouts;
+static int interfaces_invalidated;
static void got_one PROTO ((struct interface_info *));
/* If this is the first real IP address we've
found, keep a pointer to ifreq structure in
which we found it. */
- if (!tmp -> tif)
- tmp -> tif = ifp;
+ if (!tmp -> ifp) {
+ struct ifreq *tif;
+#ifdef HAVE_SA_LEN
+ int len = ((sizeof ifp -> ifr_name) +
+ ifp -> ifr_addr.sa_len);
+#else
+ int len = sizeof *ifp;
+#endif
+ tif = (struct ifreq *)malloc (len);
+ if (!tif)
+ error ("no space to remember ifp.");
+ memcpy (tif, ifp, len);
+ tmp -> ifp = ifp;
+ }
/* Grab the address... */
addr.len = 4;
/* Weed out the interfaces that did not have IP addresses. */
last = (struct interface_info *)0;
for (tmp = interfaces; tmp; tmp = tmp -> next) {
- if (!tmp -> tif || !(tmp -> flags & INTERFACE_REQUESTED)) {
+ if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
error ("%s: not found", tmp -> name);
if (!last)
interfaces = interfaces -> next;
else
last -> next = tmp -> next;
+
+ /* Remember the interface in case we need to know
+ about it later. */
+ tmp -> next = dummy_interfaces;
+ dummy_interfaces = tmp;
continue;
}
last = tmp;
- memcpy (&foo, &tmp -> tif -> ifr_addr,
- sizeof tmp -> tif -> ifr_addr);
+ memcpy (&foo, &tmp -> ifp -> ifr_addr,
+ sizeof tmp -> ifp -> ifr_addr);
/* We must have a subnet declaration for each interface. */
if (!tmp -> shared_network && (state == DISCOVER_SERVER))
}
/* Register the interface... */
- if_register_receive (tmp, tmp -> tif);
- if_register_send (tmp, tmp -> tif);
-
- tmp -> tif = (struct ifreq *)0; /* Can't keep this. */
+ if_register_receive (tmp);
+ if_register_send (tmp);
}
close (sock);
strcpy (fallback_interface.name, "fallback");
fallback_interface.shared_network = &fallback_network;
fallback_network.name = "fallback-net";
- if_register_fallback (&fallback_interface, (struct ifreq *)0);
+ if_register_fallback (&fallback_interface);
+#endif
+}
+
+void reinitialize_interfaces ()
+{
+ struct interface_info *ip;
+
+ for (ip = interfaces; ip; ip = ip -> next) {
+ if_reinitialize_receive (ip);
+ if_reinitialize_send (ip);
+ }
+
+#ifdef USE_FALLBACK
+ if_reinitialize_fallback (&fallback_interface);
#endif
+
+ interfaces_invalidated = 1;
}
#ifdef USE_POLL
if (!fds)
error ("Can't allocate poll structures.");
- i = 0;
- for (l = interfaces; l; l = l -> next) {
- fds [i].fd = l -> rfdesc;
- fds [i].events = POLLIN;
- fds [i].revents = 0;
- ++i;
- }
-
-#ifdef USE_FALLBACK
- fds [i].fd = fallback_interface.wfdesc;
- fds [i].events = POLLIN;
- fds [i].revents = 0;
- ++i;
-#endif
-
do {
-
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
} else
to_msec = -1;
+ /* Set up the descriptors to be polled. */
+ i = 0;
+ for (l = interfaces; l; l = l -> next) {
+ fds [i].fd = l -> rfdesc;
+ fds [i].events = POLLIN;
+ fds [i].revents = 0;
+ ++i;
+ }
+
+#ifdef USE_FALLBACK
+ fds [i].fd = fallback_interface.wfdesc;
+ fds [i].events = POLLIN;
+ fds [i].revents = 0;
+ ++i;
+#endif
+
/* Wait for a packet or a timeout... XXX */
count = poll (fds, nfds, to_msec);
if ((fds [i].revents & POLLIN)) {
fds [i].revents = 0;
got_one (l);
+ if (interfaces_invalidated)
+ break;
}
++i;
}
#ifdef USE_FALLBACK
- if (fds [i].revents & POLLIN)
+ if ((fds [i].revents & POLLIN) && !interfaces_invalidated)
fallback_discard (&fallback_interface);
#endif
+ interfaces_invalidated = 0;
} while (1);
}
#else
int count;
struct timeval tv, *tvp;
- FD_ZERO (&r);
FD_ZERO (&w);
FD_ZERO (&x);
do {
- /* Set up the read mask. */
- for (l = interfaces; l; l = l -> next) {
- FD_SET (l -> rfdesc, &r);
- FD_SET (l -> rfdesc, &x);
- if (l -> rfdesc > max)
- max = l -> rfdesc;
- }
-#ifdef USE_FALLBACK
- FD_SET (fallback_interface.wfdesc, &r);
- if (fallback_interface.wfdesc > max)
- max = fallback_interface.wfdesc;
-#endif
-
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
} else
tvp = (struct timeval *)0;
+ /* Set up the read mask. */
+ FD_ZERO (&r);
+
+ for (l = interfaces; l; l = l -> next) {
+ FD_SET (l -> rfdesc, &r);
+ FD_SET (l -> rfdesc, &x);
+ if (l -> rfdesc > max)
+ max = l -> rfdesc;
+ }
+#ifdef USE_FALLBACK
+ FD_SET (fallback_interface.wfdesc, &r);
+ if (fallback_interface.wfdesc > max)
+ max = fallback_interface.wfdesc;
+#endif
+
/* Wait for a packet or a timeout... XXX */
count = select (max + 1, &r, &w, &x, tvp);
if (!FD_ISSET (l -> rfdesc, &r))
continue;
got_one (l);
+ if (interfaces_invalidated)
+ break;
}
#ifdef USE_FALLBACK
- if (FD_ISSET (fallback_interface.wfdesc, &r))
+ if (FD_ISSET (fallback_interface.wfdesc, &r) &&
+ !interfaces_invalidated)
fallback_discard (&fallback_interface);
#endif
+ interfaces_invalidated = 1;
} while (1);
}
#endif /* USE_POLL */
#ifndef lint
static char copyright[] =
-"$Id: nit.c,v 1.11 1997/02/18 14:30:12 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nit.c,v 1.12 1997/02/19 10:49:20 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_NIT_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+}
+#endif
+
+#ifdef USE_NIT_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+}
+#endif
+
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
-int if_register_nit (info, ifp)
+int if_register_nit (info)
struct interface_info *info;
- struct ifreq *ifp;
{
int sock;
char filename[50];
/* Set the NIT device to point at this interface. */
sio.ic_cmd = NIOCBIND;
- sio.ic_len = sizeof *ifp;
- sio.ic_dp = (char *)ifp;
+ sio.ic_len = sizeof *(info -> ifp);
+ sio.ic_dp = (char *)(info -> ifp);
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
error ("Can't attach interface %s to nit device: %m",
#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */
#ifdef USE_NIT_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the nit API for sending and receiving,
we don't need to register this interface twice. */
struct packetfilt pf;
struct strioctl sio;
- info -> wfdesc = if_register_nit (info, interface);
+ info -> wfdesc = if_register_nit (info);
pf.Pf_Priority = 0;
pf.Pf_FilterLen = 1;
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the NIT program! XXX */
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
int flag = 1;
u_int32_t x;
struct timeval t;
/* Open a NIT device and hang it on this interface... */
- info -> rfdesc = if_register_nit (info, interface);
+ info -> rfdesc = if_register_nit (info);
/* Set the snap length to 0, which means always take the whole
packet. */
#ifndef lint
static char copyright[] =
-"$Id: raw.c,v 1.9 1997/02/18 14:32:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: raw.c,v 1.10 1997/02/19 10:51:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/uio.h>
/* Generic interface registration routine... */
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
{
struct sockaddr_in name;
int sock;
#ifndef lint
static char copyright[] =
-"$Id: socket.c,v 1.18 1997/02/18 14:30:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: socket.c,v 1.19 1997/02/19 10:49:19 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
# define USE_SOCKET_SEND
# define if_register_send if_register_fallback
# define send_packet send_fallback
+# define if_reinitialize_send if_reinitialize_fallback
+#endif
+
+static int once = 0;
+
+/* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+#ifdef USE_SOCKET_SEND
+void if_reinitialize_send (info)
+ struct interface_info *info;
+{
+#if 0
+#ifndef USE_SOCKET_RECEIVE
+ once = 0;
+ close (info -> wfdesc);
+#endif
+ if_register_send (info);
+#endif
+}
+#endif
+
+#ifdef USE_SOCKET_RECEIVE
+void if_reinitialize_receive (info)
+ struct interface_info *info;
+{
+#if 0
+ once = 0;
+ close (info -> rfdesc);
+ if_register_receive (info);
+#endif
+}
#endif
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE)
/* Generic interface registration routine... */
-int if_register_socket (info, interface)
+int if_register_socket (info)
struct interface_info *info;
- struct ifreq *interface;
{
struct sockaddr_in name;
int sock;
int flag;
#ifndef SO_BINDTODEVICE
- static int once = 0;
-
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s%s%s%s%s",
#ifdef SO_BINDTODEVICE
/* Bind this socket to this interface. */
- if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
- (char *)interface, sizeof(*interface)) < 0) {
+ if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
+ (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
}
#endif
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
#ifdef USE_SOCKET_SEND
-void if_register_send (info, interface)
+void if_register_send (info)
struct interface_info *info;
- struct ifreq *interface;
-
{
#ifndef USE_SOCKET_RECEIVE
- info -> wfdesc = if_register_socket (info, interface);
+ info -> wfdesc = if_register_socket (info);
#else
info -> wfdesc = info -> rfdesc;
#endif
#endif /* USE_SOCKET_SEND */
#ifdef USE_SOCKET_RECEIVE
-void if_register_receive (info, interface)
+void if_register_receive (info)
struct interface_info *info;
- struct ifreq *interface;
{
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info, interface);
+ info -> rfdesc = if_register_socket (info);
note ("Listening on Socket/%s/%s",
info -> name,
(info -> shared_network ?