]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Generalize fallback support.
authorTed Lemon <source@isc.org>
Sun, 20 Dec 1998 18:33:23 +0000 (18:33 +0000)
committerTed Lemon <source@isc.org>
Sun, 20 Dec 1998 18:33:23 +0000 (18:33 +0000)
common/dispatch.c
common/dlpi.c
common/nit.c
common/socket.c
common/upf.c
includes/dhcpd.h
relay/dhcrelay.c

index a5e79cdade1ff8443dd6e81106cc9fec71c1a868..4707c484e6a7285f506cd39fea7c8ed2180d94b5 100644 (file)
 
 #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;
@@ -57,7 +57,6 @@ void (*bootp_packet_handler) PROTO ((struct interface_info *,
                                     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.
@@ -83,9 +82,6 @@ void discover_interfaces (state)
 #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)
@@ -385,14 +381,26 @@ void discover_interfaces (state)
 
        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 ()
@@ -404,24 +412,17 @@ 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 ()
 {
@@ -509,8 +510,8 @@ 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 ()
 {
@@ -576,7 +577,7 @@ void dispatch ()
 }
 #endif /* USE_POLL */
 
-static void got_one (l)
+void got_one (l)
        struct protocol *l;
 {
        struct sockaddr_in from;
index 7d02ec0b6f46e33b181e4e16920e71bc6c9ed747..1158d1f574ce726916ea30d649731bc343d959c5 100644 (file)
@@ -460,6 +460,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
        int saplen;
        int rslt;
 
+       if (!strcmp (interface -> name, "fallback"))
+               return send_fallback (interface, packet, raw,
+                                     len, from, to, hto);
+
        dbuflen = 0;
 
        /* Assemble the headers... */
@@ -1226,4 +1230,19 @@ static void sigalrm (sig)
 }
 #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 */
index 0633f1d393b014836bf6c296b53048298b552ea0..1801bb9f35799b1781428fbcc24b31073572f273 100644 (file)
@@ -42,7 +42,7 @@
 
 #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"
@@ -264,6 +264,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
        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];
@@ -344,4 +348,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
        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
index b317ff2ba255d50132c9d9c7225b8234e29b4aa6..d1e7f741f1fc27451b8ffa48c14d24eb35fc916d 100644 (file)
@@ -50,7 +50,7 @@
 
 #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"
@@ -138,7 +138,8 @@ int if_register_socket (info)
 
 #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");
        }
@@ -236,7 +237,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
 }
 #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)
@@ -253,4 +254,26 @@ 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 */
index 498b6e6cde1bd55d184f83457fefa8199c4b58c8..7da9aff62ee857aa61b8aab5b6c36c635e8ef63f 100644 (file)
@@ -42,7 +42,7 @@
 
 #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"
@@ -232,6 +232,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
        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,
@@ -295,4 +299,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
        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
index 22de3c85c61c457b507d46fc74a1a12728502636..e4513ea3708c99484cd3ba56097dc3ea0c0d96ad 100644 (file)
@@ -482,10 +482,6 @@ extern u_int16_t remote_port;
 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;
@@ -654,7 +650,6 @@ ssize_t send_fallback PROTO ((struct interface_info *,
                              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
@@ -664,6 +659,7 @@ ssize_t send_packet PROTO ((struct interface_info *,
                            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 *));
@@ -673,7 +669,8 @@ ssize_t receive_packet 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 */
@@ -696,7 +693,8 @@ ssize_t receive_packet PROTO ((struct interface_info *,
                               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 */
@@ -719,8 +717,29 @@ ssize_t receive_packet PROTO ((struct interface_info *,
                               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 */
@@ -731,10 +750,13 @@ ssize_t send_packet PROTO ((struct interface_info *,
                            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 *,
@@ -743,9 +765,11 @@ 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,
index e4bc8ecdbf15f709fa92e024206afd69e860f45f..ff1315590240f33508784d989c44c1d9073b8f48 100644 (file)
@@ -42,7 +42,7 @@
 
 #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"
@@ -64,10 +64,6 @@ char *tlname;
 
 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;
@@ -249,13 +245,11 @@ void relay (ip, packet, length, from_port, from, hfrom)
 
        /* 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;
                }
@@ -314,19 +308,11 @@ void relay (ip, packet, length, from_port, from, hfrom)
        /* 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",