#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.47.2.3 1998/07/11 00:35:20 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.47.2.4 1998/12/20 18:26:22 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
-struct interface_info *interfaces, *dummy_interfaces;
+struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
struct protocol *protocols;
struct timeout *timeouts;
static struct timeout *free_timeouts;
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *));
-static void got_one PROTO ((struct protocol *));
int quiet_interface_discovery;
/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
#ifdef ALIAS_NAMES_PERMUTED
char *s;
#endif
-#ifdef USE_FALLBACK
- static struct shared_network fallback_network;
-#endif
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
close (sock);
-#ifdef USE_FALLBACK
- strcpy (fallback_interface.name, "fallback");
- fallback_interface.shared_network = &fallback_network;
- fallback_network.name = "fallback-net";
- if_register_fallback (&fallback_interface);
- add_protocol ("fallback", fallback_interface.wfdesc,
- fallback_discard, &fallback_interface);
-#endif
+ maybe_setup_fallback ();
+}
+
+struct interface_info *setup_fallback ()
+{
+ fallback_interface =
+ ((struct interface_info *)
+ dmalloc (sizeof *fallback_interface, "discover_interfaces"));
+ if (!fallback_interface)
+ error ("Insufficient memory to record fallback interface.");
+ memset (fallback_interface, 0, sizeof *fallback_interface);
+ strcpy (fallback_interface -> name, "fallback");
+ fallback_interface -> shared_network =
+ new_shared_network ("parse_statement");
+ if (!fallback_interface -> shared_network)
+ error ("No memory for shared subnet");
+ memset (fallback_interface -> shared_network, 0,
+ sizeof (struct shared_network));
+ fallback_interface -> shared_network -> name = "fallback-net";
+ return fallback_interface;
}
void reinitialize_interfaces ()
if_reinitialize_send (ip);
}
-#ifdef USE_FALLBACK
- if_reinitialize_fallback (&fallback_interface);
-#endif
+ if (fallback_interface)
+ if_reinitialize_send (fallback_interface);
interfaces_invalidated = 1;
}
#ifdef USE_POLL
-/* Wait for packets to come in using poll(). Anyway, when a packet
- comes in, call receive_packet to receive the packet and possibly
- strip hardware addressing information from it, and then call
- do_packet to try to do something with it.
-
- As you can see by comparing this with the code that uses select(),
- below, this is gratuitously complex. Quelle surprise, eh? This is
- SysV we're talking about, after all, and even in the 90's, it
- wouldn't do for SysV to make networking *easy*, would it? Rant,
- rant... */
+/* Wait for packets to come in using poll(). When a packet comes in,
+ call receive_packet to receive the packet and possibly strip hardware
+ addressing information from it, and then call through the
+ bootp_packet_handler hook to try to do something with it. */
void dispatch ()
{
#else
/* Wait for packets to come in using select(). When one does, call
receive_packet to receive the packet and possibly strip hardware
- addressing information from it, and then call do_packet to try to
- do something with it. */
+ addressing information from it, and then call through the
+ bootp_packet_handler hook to try to do something with it. */
void dispatch ()
{
}
#endif /* USE_POLL */
-static void got_one (l)
+void got_one (l)
struct protocol *l;
{
struct sockaddr_in from;
int saplen;
int rslt;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
dbuflen = 0;
/* Assemble the headers... */
}
#endif /* !defined (USE_POLL) */
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif /* USE_DLPI */
#ifndef lint
static char copyright[] =
-"$Id: nit.c,v 1.15 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nit.c,v 1.15.2.1 1998/12/20 18:27:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
int hw_end;
struct sockaddr_in foo;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
/* Start with the sockaddr struct... */
junk = (struct sockaddr *)&buf [0];
bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
#ifndef lint
static char copyright[] =
-"$Id: socket.c,v 1.26.2.2 1998/06/25 21:11:32 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: socket.c,v 1.26.2.3 1998/12/20 18:28:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#ifdef SO_BINDTODEVICE
/* Bind this socket to this interface. */
- if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
+ if (info -> ifp &&
+ setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
(char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
}
}
#endif /* USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_FALLBACK
+#ifdef USE_SOCKET_SEND
/* This just reads in a packet and silently discards it. */
void fallback_discard (protocol)
if (status < 0)
warn ("fallback_discard: %m");
}
-#endif /* USE_SOCKET_RECEIVE */
+#endif /* USE_SOCKET_SEND */
+
+#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
+int can_unicast_without_arp ()
+{
+ return 0;
+}
+
+/* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise,
+ do not. */
+
+void maybe_setup_fallback ()
+{
+#if defined (SO_BINDTODEVICE)
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ fbi -> wfdesc = if_register_socket (fbi);
+ add_protocol ("fallback, fbi -> rfdesc, got_one, fbi);
+ }
+#endif
+}
+#endif /* USE_SOCKET_SEND && !USE_SOCKET_FALLBACK */
#ifndef lint
static char copyright[] =
-"$Id: upf.c,v 1.3 1997/10/20 21:47:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: upf.c,v 1.3.2.1 1998/12/20 18:29:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
unsigned char buf [256];
struct iovec iov [2];
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
extern int log_priority;
extern int log_perror;
-#ifdef USE_FALLBACK
-extern struct interface_info fallback_interface;
-#endif
-
extern char *path_dhcpd_conf;
extern char *path_dhcpd_db;
extern char *path_dhcpd_pid;
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
-void fallback_discard PROTO ((struct protocol *));
#endif
#ifdef USE_SOCKET_SEND
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
+void fallback_discard PROTO ((struct protocol *));
#endif
#ifdef USE_SOCKET_RECEIVE
void if_reinitialize_receive PROTO ((struct interface_info *));
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
-void if_enable PROTO ((struct interface_info *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* bpf.c */
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_BPF_SEND)
-void if_enable PROTO ((struct interface_info *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* nit.c */
unsigned char *, size_t,
struct sockaddr_in *, struct hardware *));
#endif
-#if defined (USE_BPF_SEND)
-void if_enable PROTO ((struct interface_info *));
+#if defined (USE_NIT_SEND)
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
+#endif
+
+#ifdef USE_DLPI_SEND
+void if_reinitialize_send PROTO ((struct interface_info *));
+void if_register_send PROTO ((struct interface_info *));
+ssize_t send_packet PROTO ((struct interface_info *,
+ struct packet *, struct dhcp_packet *, size_t,
+ struct in_addr,
+ struct sockaddr_in *, struct hardware *));
+#endif
+#ifdef USE_DLPI_RECEIVE
+void if_reinitialize_receive PROTO ((struct interface_info *));
+void if_register_receive PROTO ((struct interface_info *));
+ssize_t receive_packet PROTO ((struct interface_info *,
+ unsigned char *, size_t,
+ struct sockaddr_in *, struct hardware *));
+#endif
+#if defined (USE_DLPI_SEND)
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* raw.c */
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
+int can_unicast_without_arp PROTO ((void));
+void maybe_setup_fallback PROTO ((void));
#endif
/* dispatch.c */
-extern struct interface_info *interfaces, *dummy_interfaces;
+extern struct interface_info *interfaces,
+ *dummy_interfaces, *fallback_interface;
extern struct protocol *protocols;
extern int quiet_interface_discovery;
extern void (*bootp_packet_handler) PROTO ((struct interface_info *,
struct iaddr, struct hardware *));
extern struct timeout *timeouts;
void discover_interfaces PROTO ((int));
+struct interface_info *setup_fallback PROTO ((void));
void reinitialize_interfaces PROTO ((void));
void dispatch PROTO ((void));
int locate_network PROTO ((struct packet *));
+void got_one PROTO ((struct protocol *));
void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *));
void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
void add_protocol PROTO ((char *, int,
#ifndef lint
static char copyright[] =
-"$Id: dhcrelay.c,v 1.9.2.5 1998/11/24 22:57:56 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcrelay.c,v 1.9.2.6 1998/12/20 18:33:23 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
char *path_dhcrelay_pid = _PATH_DHCRELAY_PID;
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
u_int16_t local_port;
u_int16_t remote_port;
int log_priority;
/* If it's a bootreply, forward it to the client. */
if (packet -> op == BOOTREPLY) {
-#ifdef USE_FALLBACK
- if (!(packet -> flags & htons (BOOTP_BROADCAST))) {
+ if (!(packet -> flags & htons (BOOTP_BROADCAST)) &&
+ can_unicast_without_arp ()) {
to.sin_addr = packet -> yiaddr;
to.sin_port = remote_port;
- } else
-#endif
- {
+ } else {
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = remote_port;
}
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
servers. */
for (sp = servers; sp; sp = sp -> next) {
- if (
-#ifdef USE_FALLBACK
- send_fallback (&fallback_interface,
- (struct packet *)0,
- packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#else
- send_packet (interfaces,
+ if (send_packet ((fallback_interface
+ ? fallback_interface : interfaces),
(struct packet *)0,
packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#endif
- < 0) {
+ &sp -> to, (struct hardware *)0) < 0) {
debug ("send_packet: %m");
} else {
debug ("forwarded BOOTREQUEST for %s to %s",