From: Ted Lemon Date: Sun, 20 Dec 1998 18:33:23 +0000 (+0000) Subject: Generalize fallback support. X-Git-Tag: V2-BETA-1-PATCH-7~24 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c267e01ba57ed0f7482552ff7e2d034fd37b2e35;p=thirdparty%2Fdhcp.git Generalize fallback support. --- diff --git a/common/dispatch.c b/common/dispatch.c index a5e79cdad..4707c484e 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -42,13 +42,13 @@ #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 -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; diff --git a/common/dlpi.c b/common/dlpi.c index 7d02ec0b6..1158d1f57 100644 --- a/common/dlpi.c +++ b/common/dlpi.c @@ -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 */ diff --git a/common/nit.c b/common/nit.c index 0633f1d39..1801bb9f3 100644 --- a/common/nit.c +++ b/common/nit.c @@ -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 diff --git a/common/socket.c b/common/socket.c index b317ff2ba..d1e7f741f 100644 --- a/common/socket.c +++ b/common/socket.c @@ -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 */ diff --git a/common/upf.c b/common/upf.c index 498b6e6cd..7da9aff62 100644 --- a/common/upf.c +++ b/common/upf.c @@ -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 diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 22de3c85c..e4513ea37 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -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, diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index e4bc8ecdb..ff1315590 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -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",