mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 14:25:41 +00:00
Initial merge of Poger dhclient and linux hacks
This commit is contained in:
@@ -185,10 +185,10 @@ VARDB = /var/db
|
||||
|
||||
CSRC = options.c errwarn.c convert.c \
|
||||
tree.c memory.c alloc.c print.c hash.c tables.c inet.c \
|
||||
dispatch.c bpf.c packet.c raw.c nit.c socket.c
|
||||
dispatch.c bpf.c packet.c raw.c nit.c socket.c route.c
|
||||
COBJ = options.o errwarn.o convert.o \
|
||||
tree.o memory.o alloc.o print.o hash.o tables.o inet.o \
|
||||
dispatch.o bpf.o packet.o raw.o nit.o socket.o
|
||||
dispatch.o bpf.o packet.o raw.o nit.o socket.o route.o
|
||||
XOBJ = dhcpxlt.o xconflex.o
|
||||
SRCS = dhcpd.c dhcp.c bootp.c conflex.c confpars.c db.c
|
||||
OBJS = dhcpd.o dhcp.o bootp.o conflex.o confpars.o db.o
|
||||
|
24
bpf.c
24
bpf.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: bpf.c,v 1.13 1996/09/02 21:14:58 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: bpf.c,v 1.14 1997/01/02 12:00:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -368,3 +368,25 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (USE_BPF_SEND)
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int sock;
|
||||
|
||||
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
||||
error ("Can't create addrlist socket");
|
||||
|
||||
/* Bring the interface down and then up again to clear
|
||||
* all its routes. */
|
||||
strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
|
||||
if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
|
||||
error ("SIOCGIFFLAGS %s: %m", interface -> name);
|
||||
|
||||
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error ("SIOCSIFFLAGS %s: %m", interface -> name);
|
||||
}
|
||||
#endif
|
||||
|
@@ -60,6 +60,9 @@ typedef unsigned long u_int32_t;
|
||||
extern int h_errno;
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include <sys/time.h> /* gettimeofday()*/
|
||||
#include <linux/time.h> /* also necessary */
|
||||
|
@@ -52,6 +52,10 @@ extern int h_errno;
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#define ifr_netmask ifr_addr
|
||||
|
||||
/* Varargs stuff... */
|
||||
#include <stdarg.h>
|
||||
|
File diff suppressed because it is too large
Load Diff
24
common/bpf.c
24
common/bpf.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: bpf.c,v 1.13 1996/09/02 21:14:58 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: bpf.c,v 1.14 1997/01/02 12:00:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -368,3 +368,25 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (USE_BPF_SEND)
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int sock;
|
||||
|
||||
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
||||
error ("Can't create addrlist socket");
|
||||
|
||||
/* Bring the interface down and then up again to clear
|
||||
* all its routes. */
|
||||
strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
|
||||
if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
|
||||
error ("SIOCGIFFLAGS %s: %m", interface -> name);
|
||||
|
||||
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error ("SIOCSIFFLAGS %s: %m", interface -> name);
|
||||
}
|
||||
#endif
|
||||
|
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: dispatch.c,v 1.27 1996/11/08 20:06:29 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: dispatch.c,v 1.28 1997/01/02 12:00:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -162,6 +162,44 @@ void discover_interfaces (serverP)
|
||||
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
||||
struct iaddr addr;
|
||||
|
||||
#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
|
||||
struct ifreq ifr;
|
||||
struct sockaddr sa;
|
||||
int b, sk;
|
||||
|
||||
/* Read the hardware address from this interface. */
|
||||
ifr = *ifp;
|
||||
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
|
||||
error ("Can't get hardware address for %s: %m",
|
||||
ifr.ifr_name);
|
||||
|
||||
sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
|
||||
|
||||
switch (sa.sa_family) {
|
||||
case ARPHRD_LOOPBACK:
|
||||
/* ignore loopback interface */
|
||||
break;
|
||||
|
||||
case ARPHRD_ETHER:
|
||||
tmp -> hw_address.hlen = 6;
|
||||
tmp -> hw_address.htype = ARPHRD_ETHER;
|
||||
memcpy (tmp -> hw_address.haddr,
|
||||
sa.sa_data, 6);
|
||||
break;
|
||||
|
||||
case ARPHRD_METRICOM:
|
||||
tmp -> hw_address.hlen = 6;
|
||||
tmp -> hw_address.htype = ARPHRD_METRICOM;
|
||||
memcpy (tmp -> hw_address.haddr,
|
||||
sa.sa_data, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
error ("%s: unknown hardware address type %d",
|
||||
ifr.ifr_name, sa.sa_family);
|
||||
}
|
||||
#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
|
||||
|
||||
/* Get a pointer to the address... */
|
||||
memcpy (&foo, &ifp -> ifr_addr,
|
||||
sizeof ifp -> ifr_addr);
|
||||
|
20
common/nit.c
20
common/nit.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: nit.c,v 1.9 1996/09/05 23:56:52 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: nit.c,v 1.10 1997/01/02 12:00:17 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -329,3 +329,21 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (USE_NIT_SEND)
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
/* Bring the interface down and then up again to clear
|
||||
* all its routes. */
|
||||
strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
|
||||
if (ioctl(interface -> rfdesc, SIOCGIFFLAGS, &ifr) < 0)
|
||||
error ("SIOCGIFFLAGS %s: %m", interface -> name);
|
||||
|
||||
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(interface -> rfdesc, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error ("SIOCSIFFLAGS %s: %m", interface -> name);
|
||||
}
|
||||
#endif
|
||||
|
@@ -40,9 +40,17 @@
|
||||
* Enterprises, see ``http://www.vix.com''.
|
||||
*/
|
||||
|
||||
/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu).
|
||||
* This sockopt allows a socket to be bound to a particular interface,
|
||||
* thus enabling the use of DHCPD on a multihomed host.
|
||||
* If SO_BINDTODEVICE is defined in your system header files, the use of
|
||||
* this sockopt will be automatically enabled.
|
||||
* I have implemented it under Linux; other systems should be doable also.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: socket.c,v 1.16 1996/08/27 09:54:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: socket.c,v 1.17 1997/01/02 12:00:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -62,6 +70,8 @@ int if_register_socket (info, interface)
|
||||
struct sockaddr_in name;
|
||||
int sock;
|
||||
int flag;
|
||||
|
||||
#ifndef SO_BINDTODEVICE
|
||||
static int once = 0;
|
||||
|
||||
/* Make sure only one interface is registered. */
|
||||
@@ -72,22 +82,8 @@ int if_register_socket (info, interface)
|
||||
"you must compile in BPF or NIT support. If neither ",
|
||||
"option is supported on your system, please let us ",
|
||||
"know.");
|
||||
|
||||
/* Technically, we need to know what interface every packet
|
||||
comes in on, which means that we can only operate on a
|
||||
machine with a single interface configured. However,
|
||||
we generally don't expect to get broadcast packets on
|
||||
point-to-point interfaces, so we can bend the rules a bit
|
||||
and not count them. This won't allow DHCP-over-PPP,
|
||||
but it's probably right in a lot of cases, and the issue
|
||||
will have to be revisited when DHCP-over-PPP support is
|
||||
done. Currently we determine whether an interface is
|
||||
point-to-point by seeing if it has a link-level address.
|
||||
This only works on 4.4BSD and derivative networking. */
|
||||
#ifdef AF_LINK
|
||||
if (info -> hw_address.hlen) /* XXX */
|
||||
once = 1;
|
||||
#endif
|
||||
once = 1;
|
||||
|
||||
/* Set up the address we're going to bind to. */
|
||||
name.sin_family = AF_INET;
|
||||
@@ -111,10 +107,26 @@ int if_register_socket (info, interface)
|
||||
(char *)&flag, sizeof flag) < 0)
|
||||
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
|
||||
|
||||
#ifndef USE_SOCKET_FALLBACK
|
||||
/* The following will make all-ones broadcasts go out this interface
|
||||
* on those platforms which use the standard sockets API (assuming
|
||||
* the OS-specific routines called by enable_sending() are present
|
||||
* for this platform). */
|
||||
if_enable (info);
|
||||
#endif
|
||||
|
||||
/* Bind the socket to this interface's IP address. */
|
||||
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
||||
error ("Can't bind to dhcp address: %m");
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
/* Bind this socket to this interface. */
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *)interface, sizeof(*interface)) < 0) {
|
||||
error("setting SO_BINDTODEVICE");
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
||||
@@ -197,3 +209,30 @@ size_t fallback_discard (interface)
|
||||
(struct sockaddr *)&from, &flen);
|
||||
}
|
||||
#endif /* USE_SOCKET_RECEIVE */
|
||||
|
||||
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||
/* If we're using the standard socket API without SO_BINDTODEVICE,
|
||||
* we need this kludge to force DHCP broadcasts to go out
|
||||
* this interface, even though it's not available for general
|
||||
* use until we get a lease!
|
||||
* This should work _OK_, but it will cause ALL all-ones
|
||||
* broadcasts on this host to go out this interface--it
|
||||
* could interfere with other interfaces. And God help you
|
||||
* if you run this on multiple interfaces simultaneously.
|
||||
* SO_BINDTODEVICE really is better! */
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
#ifndef SO_BINDTODEVICE
|
||||
struct in_addr broad_addr;
|
||||
broad_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
|
||||
/* Delete old routes for broadcast address. */
|
||||
remove_routes(NULL, &broad_addr);
|
||||
|
||||
/* Add a route for broadcast address to this interface. */
|
||||
/* POTENTIAL PROBLEM: Don't do this to more than one interface! */
|
||||
add_route_direct(interface, &broad_addr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
943
dhclient.c
943
dhclient.c
File diff suppressed because it is too large
Load Diff
1
dhcp.h
1
dhcp.h
@@ -52,6 +52,7 @@
|
||||
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
||||
|
||||
#define BOOTP_MIN_LEN 300
|
||||
#define DHCP_MIN_LEN 548
|
||||
|
||||
struct dhcp_packet {
|
||||
u_int8_t op; /* Message opcode/type */
|
||||
|
43
dhcpd.h
43
dhcpd.h
@@ -451,6 +451,9 @@ size_t receive_packet PROTO ((struct interface_info *,
|
||||
unsigned char *, size_t,
|
||||
struct sockaddr_in *, struct hardware *));
|
||||
#endif
|
||||
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||
void if_enable PROTO ((struct interface_info *));
|
||||
#endif
|
||||
|
||||
/* bpf.c */
|
||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
|
||||
@@ -469,6 +472,9 @@ size_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 *));
|
||||
#endif
|
||||
|
||||
/* nit.c */
|
||||
#ifdef USE_NIT_SEND
|
||||
@@ -484,6 +490,9 @@ size_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 *));
|
||||
#endif
|
||||
|
||||
/* raw.c */
|
||||
#ifdef USE_RAW_SEND
|
||||
@@ -541,6 +550,27 @@ void dhcpack PROTO ((struct packet *));
|
||||
void dhcpnak PROTO ((struct packet *));
|
||||
void send_discover PROTO ((struct interface_info *));
|
||||
void send_request PROTO ((struct packet *));
|
||||
void send_release PROTO ((struct packet *));
|
||||
void dhclient_fail PROTO ((void));
|
||||
void handle_kill PROTO ((int));
|
||||
void disable_interface PROTO ((struct interface_info *));
|
||||
void route_broadcasts PROTO ((struct interface_info *));
|
||||
void apply_parameters PROTO ((struct interface_info *, struct packet *));
|
||||
void dhclient_state_machine PROTO ((void));
|
||||
int state_init PROTO ((void));
|
||||
int state_selecting PROTO ((void));
|
||||
int state_requesting PROTO ((void));
|
||||
int state_bound PROTO ((void));
|
||||
int state_renewing PROTO ((void));
|
||||
int state_rebinding PROTO ((void));
|
||||
TIME abs_time PROTO ((struct packet *, int));
|
||||
void deep_packet_copy PROTO ((struct packet *, struct packet *));
|
||||
void read_packet PROTO ((struct interface_info *, struct packet *));
|
||||
void send_packet_struct PROTO ((struct interface_info *,
|
||||
u_long, struct packet *));
|
||||
void make_discover PROTO ((struct interface_info *, struct packet *));
|
||||
void make_request PROTO ((struct packet *, struct packet *));
|
||||
void make_release PROTO ((struct packet *, struct packet *));
|
||||
|
||||
/* db.c */
|
||||
int write_lease PROTO ((struct lease *));
|
||||
@@ -584,3 +614,16 @@ void convert_address_range PROTO ((FILE *, jrefproto));
|
||||
void convert_date PROTO ((FILE *, jrefproto, char *));
|
||||
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
||||
void indent PROTO ((int));
|
||||
|
||||
/* route.c */
|
||||
void add_route_direct PROTO ((struct interface_info *, struct in_addr));
|
||||
void add_route_net PROTO ((struct interface_info *, struct in_addr,
|
||||
struct in_addr));
|
||||
void add_route_default_gateway PROTO ((struct interface_info *,
|
||||
struct in_addr));
|
||||
void remove_routes PROTO ((struct in_addr));
|
||||
void remove_if_route PROTO ((struct interface_info *, struct in_addr));
|
||||
void remove_all_if_routes PROTO ((struct interface_info *));
|
||||
void set_netmask PROTO ((struct interface_info *, struct in_addr));
|
||||
void set_broadcast_addr PROTO ((struct interface_info *, struct in_addr));
|
||||
void set_ip_address PROTO ((struct interface_info *, struct in_addr));
|
||||
|
40
dispatch.c
40
dispatch.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: dispatch.c,v 1.27 1996/11/08 20:06:29 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: dispatch.c,v 1.28 1997/01/02 12:00:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -162,6 +162,44 @@ void discover_interfaces (serverP)
|
||||
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
||||
struct iaddr addr;
|
||||
|
||||
#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
|
||||
struct ifreq ifr;
|
||||
struct sockaddr sa;
|
||||
int b, sk;
|
||||
|
||||
/* Read the hardware address from this interface. */
|
||||
ifr = *ifp;
|
||||
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
|
||||
error ("Can't get hardware address for %s: %m",
|
||||
ifr.ifr_name);
|
||||
|
||||
sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
|
||||
|
||||
switch (sa.sa_family) {
|
||||
case ARPHRD_LOOPBACK:
|
||||
/* ignore loopback interface */
|
||||
break;
|
||||
|
||||
case ARPHRD_ETHER:
|
||||
tmp -> hw_address.hlen = 6;
|
||||
tmp -> hw_address.htype = ARPHRD_ETHER;
|
||||
memcpy (tmp -> hw_address.haddr,
|
||||
sa.sa_data, 6);
|
||||
break;
|
||||
|
||||
case ARPHRD_METRICOM:
|
||||
tmp -> hw_address.hlen = 6;
|
||||
tmp -> hw_address.htype = ARPHRD_METRICOM;
|
||||
memcpy (tmp -> hw_address.haddr,
|
||||
sa.sa_data, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
error ("%s: unknown hardware address type %d",
|
||||
ifr.ifr_name, sa.sa_family);
|
||||
}
|
||||
#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
|
||||
|
||||
/* Get a pointer to the address... */
|
||||
memcpy (&foo, &ifp -> ifr_addr,
|
||||
sizeof ifp -> ifr_addr);
|
||||
|
@@ -60,6 +60,9 @@ typedef unsigned long u_int32_t;
|
||||
extern int h_errno;
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include <sys/time.h> /* gettimeofday()*/
|
||||
#include <linux/time.h> /* also necessary */
|
||||
|
@@ -52,6 +52,10 @@ extern int h_errno;
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#define ifr_netmask ifr_addr
|
||||
|
||||
/* Varargs stuff... */
|
||||
#include <stdarg.h>
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
||||
|
||||
#define BOOTP_MIN_LEN 300
|
||||
#define DHCP_MIN_LEN 548
|
||||
|
||||
struct dhcp_packet {
|
||||
u_int8_t op; /* Message opcode/type */
|
||||
|
@@ -451,6 +451,9 @@ size_t receive_packet PROTO ((struct interface_info *,
|
||||
unsigned char *, size_t,
|
||||
struct sockaddr_in *, struct hardware *));
|
||||
#endif
|
||||
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||
void if_enable PROTO ((struct interface_info *));
|
||||
#endif
|
||||
|
||||
/* bpf.c */
|
||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
|
||||
@@ -469,6 +472,9 @@ size_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 *));
|
||||
#endif
|
||||
|
||||
/* nit.c */
|
||||
#ifdef USE_NIT_SEND
|
||||
@@ -484,6 +490,9 @@ size_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 *));
|
||||
#endif
|
||||
|
||||
/* raw.c */
|
||||
#ifdef USE_RAW_SEND
|
||||
@@ -541,6 +550,27 @@ void dhcpack PROTO ((struct packet *));
|
||||
void dhcpnak PROTO ((struct packet *));
|
||||
void send_discover PROTO ((struct interface_info *));
|
||||
void send_request PROTO ((struct packet *));
|
||||
void send_release PROTO ((struct packet *));
|
||||
void dhclient_fail PROTO ((void));
|
||||
void handle_kill PROTO ((int));
|
||||
void disable_interface PROTO ((struct interface_info *));
|
||||
void route_broadcasts PROTO ((struct interface_info *));
|
||||
void apply_parameters PROTO ((struct interface_info *, struct packet *));
|
||||
void dhclient_state_machine PROTO ((void));
|
||||
int state_init PROTO ((void));
|
||||
int state_selecting PROTO ((void));
|
||||
int state_requesting PROTO ((void));
|
||||
int state_bound PROTO ((void));
|
||||
int state_renewing PROTO ((void));
|
||||
int state_rebinding PROTO ((void));
|
||||
TIME abs_time PROTO ((struct packet *, int));
|
||||
void deep_packet_copy PROTO ((struct packet *, struct packet *));
|
||||
void read_packet PROTO ((struct interface_info *, struct packet *));
|
||||
void send_packet_struct PROTO ((struct interface_info *,
|
||||
u_long, struct packet *));
|
||||
void make_discover PROTO ((struct interface_info *, struct packet *));
|
||||
void make_request PROTO ((struct packet *, struct packet *));
|
||||
void make_release PROTO ((struct packet *, struct packet *));
|
||||
|
||||
/* db.c */
|
||||
int write_lease PROTO ((struct lease *));
|
||||
@@ -584,3 +614,16 @@ void convert_address_range PROTO ((FILE *, jrefproto));
|
||||
void convert_date PROTO ((FILE *, jrefproto, char *));
|
||||
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
||||
void indent PROTO ((int));
|
||||
|
||||
/* route.c */
|
||||
void add_route_direct PROTO ((struct interface_info *, struct in_addr));
|
||||
void add_route_net PROTO ((struct interface_info *, struct in_addr,
|
||||
struct in_addr));
|
||||
void add_route_default_gateway PROTO ((struct interface_info *,
|
||||
struct in_addr));
|
||||
void remove_routes PROTO ((struct in_addr));
|
||||
void remove_if_route PROTO ((struct interface_info *, struct in_addr));
|
||||
void remove_all_if_routes PROTO ((struct interface_info *));
|
||||
void set_netmask PROTO ((struct interface_info *, struct in_addr));
|
||||
void set_broadcast_addr PROTO ((struct interface_info *, struct in_addr));
|
||||
void set_ip_address PROTO ((struct interface_info *, struct in_addr));
|
||||
|
20
nit.c
20
nit.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: nit.c,v 1.9 1996/09/05 23:56:52 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: nit.c,v 1.10 1997/01/02 12:00:17 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -329,3 +329,21 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (USE_NIT_SEND)
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
/* Bring the interface down and then up again to clear
|
||||
* all its routes. */
|
||||
strncpy(ifr.ifr_name, interface -> name, IFNAMSIZ);
|
||||
if (ioctl(interface -> rfdesc, SIOCGIFFLAGS, &ifr) < 0)
|
||||
error ("SIOCGIFFLAGS %s: %m", interface -> name);
|
||||
|
||||
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(interface -> rfdesc, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error ("SIOCSIFFLAGS %s: %m", interface -> name);
|
||||
}
|
||||
#endif
|
||||
|
276
route.c
276
route.c
@@ -1,62 +1,234 @@
|
||||
/* socket.c
|
||||
|
||||
BSD socket interface code... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
||||
* All rights reserved.
|
||||
/* route.c
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* Routines for updating routing tables and configuring interfaces.
|
||||
*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
* Junior University. All Rights Reserved.
|
||||
* Code originally written by Elliot Poger (poger@leland.stanford.edu).
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of The Internet Software Consortium nor the names
|
||||
* of its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
|
||||
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This software has been written for the Internet Software Consortium
|
||||
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||
* Enterprises. To learn more about the Internet Software Consortium,
|
||||
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||
* Enterprises, see ``http://www.vix.com''.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. Stanford University
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: route.c,v 1.2 1996/08/27 09:53:58 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
|
||||
#if defined (OLD_ROUTE_HACK)
|
||||
#include <net/route.h>
|
||||
|
||||
route_hack (sock)
|
||||
int sock;
|
||||
/* Add a route to this destination through this interface. */
|
||||
void add_route_direct(interface, destination)
|
||||
struct interface_info *interface;
|
||||
struct in_addr destination;
|
||||
{
|
||||
int rsock = socket (PF_ROUTE, SOCK_RAW, AF_INET);
|
||||
struct rt_msghdr
|
||||
note ("add_route_direct %s: %s",
|
||||
interface -> name, inet_ntoa (destination));
|
||||
#if 0
|
||||
struct in_addr directmask;
|
||||
|
||||
if (rsock < 0)
|
||||
error ("Can't make routing socket: %m");
|
||||
directmask.s_addr = htonl (INADDR_BROADCAST); /* this addr only */
|
||||
add_route_net(interface, destination, &directmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add a route to this subnet through this interface. */
|
||||
void add_route_net(interface, destination, netmask)
|
||||
struct interface_info *interface;
|
||||
struct in_addr destination;
|
||||
struct in_addr netmask;
|
||||
{
|
||||
char nbuf [128];
|
||||
|
||||
strncpy (nbuf, inet_ntoa (netmask), sizeof nbuf);
|
||||
nbuf [(sizeof nbuf) - 1] = 0;
|
||||
|
||||
note ("add_route_net %s: %s %s",
|
||||
interface -> name, inet_ntoa (destination), nbuf);
|
||||
#if 0
|
||||
int sock;
|
||||
struct sockaddr_in *sin;
|
||||
struct rtentry rt;
|
||||
|
||||
memset((char *) &rt, 0, sizeof(struct rtentry));
|
||||
sin = (struct sockaddr_in *) &rt.rt_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = destination.s_addr;
|
||||
sin = (struct sockaddr_in *) &rt.rt_genmask;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = netmask.s_addr;
|
||||
rt.rt_flags = RTF_UP;
|
||||
rt.rt_dev = interface->name;
|
||||
if (ioctl(interface -> rfdesc, SIOCADDRT, &rt) < 0)
|
||||
error ("Can't add route to %s through %s: %m",
|
||||
inet_ntoa (destination), interface->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add a route to the default gateway through this interface. */
|
||||
void add_route_default_gateway(interface, gateway)
|
||||
struct interface_info *interface;
|
||||
struct in_addr gateway;
|
||||
{
|
||||
note ("add_route_default_gateway %s: %s",
|
||||
interface -> name, inet_ntoa (gateway));
|
||||
#if 0
|
||||
int sock;
|
||||
struct sockaddr_in *sin;
|
||||
struct rtentry rt;
|
||||
|
||||
/* Route through the gateway. */
|
||||
memset((char *) &rt, 0, sizeof(struct rtentry));
|
||||
sin = (struct sockaddr_in *) &rt.rt_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin = (struct sockaddr_in *) &rt.rt_gateway;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = gateway.s_addr;
|
||||
rt.rt_flags = RTF_UP | RTF_GATEWAY;
|
||||
rt.rt_dev = interface->name;
|
||||
if (ioctl(interface -> rfdesc, SIOCADDRT, &rt) < 0)
|
||||
error ("Can't add route to default gateway");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Remove all routes matching the specified destination. */
|
||||
void remove_routes(destination)
|
||||
struct in_addr destination;
|
||||
{
|
||||
note ("remove_routes: %s", inet_ntoa (destination));
|
||||
#if 0
|
||||
int sock;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in *sin;
|
||||
struct rtentry rt;
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
error("Can't open socket to remove routes");
|
||||
}
|
||||
|
||||
/* Remove all routes to this IP destination. */
|
||||
memset((char *) &rt, 0, sizeof(struct rtentry));
|
||||
sin = (struct sockaddr_in *) &rt.rt_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = destination->s_addr;
|
||||
while (ioctl(sock, SIOCDELRT, &rt) >= 0)
|
||||
;
|
||||
close(sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Remove routes on the specified interface matching the specified
|
||||
destination. */
|
||||
void remove_if_route (interface, destination)
|
||||
struct interface_info *interface;
|
||||
struct in_addr destination;
|
||||
{
|
||||
note ("remove_if_routes %s: %s",
|
||||
interface -> name, inet_ntoa (destination));
|
||||
#if 0
|
||||
int sock;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in *sin;
|
||||
struct rtentry rt;
|
||||
|
||||
/* Remove one specific route. */
|
||||
/* XXX: does this even work? */
|
||||
memset((char *) &rt, 0, sizeof(struct rtentry));
|
||||
sin = (struct sockaddr_in *) &rt.rt_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = destination.s_addr;
|
||||
rt.rt_dev = interface->name;
|
||||
if (ioctl(interface -> rfdesc, SIOCDELRT, &rt) == -1)
|
||||
warn("Error removing route.");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Remove all routes on the specified interface. */
|
||||
|
||||
void remove_all_if_routes(interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
note ("remove_all_if_routes %s", interface -> name);
|
||||
#if 0
|
||||
struct ifreq ifr;
|
||||
|
||||
/* Bring the interface down and then up again to clear
|
||||
* all its routes. */
|
||||
strncpy(ifr.ifr_name, interface->name, IFNAMSIZ);
|
||||
if (ioctl(interface -> rfdesc, SIOCGIFFLAGS, &ifr) == -1)
|
||||
error ("SIOCGIFFLAGS %s: %m", interface -> name);
|
||||
|
||||
ifr.ifr_flags &= ~(IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(interface -> rfdesc, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error ("Can't bring down interface");
|
||||
|
||||
strncpy(ifr.ifr_name,interface->name,IFNAMSIZ);
|
||||
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
|
||||
if (ioctl(interface -> rfdesc, SIOCSIFFLAGS, &ifr) == -1)
|
||||
error("Can't bring interface back up");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the netmask (in network byte order!) of this interface. */
|
||||
void set_netmask(interface, netmask)
|
||||
struct interface_info *interface;
|
||||
struct in_addr netmask;
|
||||
{
|
||||
note ("set_netmask %s: %s",
|
||||
interface -> name, inet_ntoa (netmask));
|
||||
#if 0
|
||||
int sock;
|
||||
struct ifreq ifr;
|
||||
|
||||
if (ioctl (interface -> rfdesc, SIOCGIFNETMASK, &ifr) == -1)
|
||||
error ("Can't get old netmask of interface");
|
||||
|
||||
(*(struct sockaddr_in *)&ifr.ifr_netmask).sin_addr = netmask;
|
||||
if (ioctl (interface -> rfdesc, SIOCSIFNETMASK, &ifr) == -1)
|
||||
error ("Can't set new netmask");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the broadcast address (in network byte order!) of this interface. */
|
||||
void set_broadcast_addr(interface, broadcast_addr)
|
||||
struct interface_info *interface;
|
||||
struct in_addr broadcast_addr;
|
||||
{
|
||||
note ("set_broadcast_addr %s: %s",
|
||||
interface -> name, inet_ntoa (broadcast_addr));
|
||||
#if 0
|
||||
int sock;
|
||||
struct ifreq ifr;
|
||||
|
||||
if (ioctl(interface -> rfdesc, SIOCGIFBRDADDR, &ifr) == -1)
|
||||
error("Can't get old broadcast address of interface");
|
||||
|
||||
(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr = broadcast_addr;
|
||||
if (ioctl(sock, SIOCSIFBRDADDR, &ifr) == -1) {
|
||||
error("Can't set new broadcast address");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the IP address (in network byte order!) of this interface. */
|
||||
void set_ip_address(interface, ip_addr)
|
||||
struct interface_info *interface;
|
||||
struct in_addr ip_addr;
|
||||
{
|
||||
note ("set_ip_address %s: %s",
|
||||
interface -> name, inet_ntoa (ip_addr));
|
||||
#if 0
|
||||
int sock;
|
||||
struct ifreq ifr;
|
||||
|
||||
strncpy(ifr.ifr_name, interface->name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
|
||||
error ("Can't get old IP address of interface");
|
||||
|
||||
(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr = ip_addr;
|
||||
if (ioctl(sock, SIOCSIFADDR, &ifr) < 0)
|
||||
error("Can't set IP address");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
71
socket.c
71
socket.c
@@ -40,9 +40,17 @@
|
||||
* Enterprises, see ``http://www.vix.com''.
|
||||
*/
|
||||
|
||||
/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu).
|
||||
* This sockopt allows a socket to be bound to a particular interface,
|
||||
* thus enabling the use of DHCPD on a multihomed host.
|
||||
* If SO_BINDTODEVICE is defined in your system header files, the use of
|
||||
* this sockopt will be automatically enabled.
|
||||
* I have implemented it under Linux; other systems should be doable also.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: socket.c,v 1.16 1996/08/27 09:54:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: socket.c,v 1.17 1997/01/02 12:00:18 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -62,6 +70,8 @@ int if_register_socket (info, interface)
|
||||
struct sockaddr_in name;
|
||||
int sock;
|
||||
int flag;
|
||||
|
||||
#ifndef SO_BINDTODEVICE
|
||||
static int once = 0;
|
||||
|
||||
/* Make sure only one interface is registered. */
|
||||
@@ -72,22 +82,8 @@ int if_register_socket (info, interface)
|
||||
"you must compile in BPF or NIT support. If neither ",
|
||||
"option is supported on your system, please let us ",
|
||||
"know.");
|
||||
|
||||
/* Technically, we need to know what interface every packet
|
||||
comes in on, which means that we can only operate on a
|
||||
machine with a single interface configured. However,
|
||||
we generally don't expect to get broadcast packets on
|
||||
point-to-point interfaces, so we can bend the rules a bit
|
||||
and not count them. This won't allow DHCP-over-PPP,
|
||||
but it's probably right in a lot of cases, and the issue
|
||||
will have to be revisited when DHCP-over-PPP support is
|
||||
done. Currently we determine whether an interface is
|
||||
point-to-point by seeing if it has a link-level address.
|
||||
This only works on 4.4BSD and derivative networking. */
|
||||
#ifdef AF_LINK
|
||||
if (info -> hw_address.hlen) /* XXX */
|
||||
once = 1;
|
||||
#endif
|
||||
once = 1;
|
||||
|
||||
/* Set up the address we're going to bind to. */
|
||||
name.sin_family = AF_INET;
|
||||
@@ -111,10 +107,26 @@ int if_register_socket (info, interface)
|
||||
(char *)&flag, sizeof flag) < 0)
|
||||
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
|
||||
|
||||
#ifndef USE_SOCKET_FALLBACK
|
||||
/* The following will make all-ones broadcasts go out this interface
|
||||
* on those platforms which use the standard sockets API (assuming
|
||||
* the OS-specific routines called by enable_sending() are present
|
||||
* for this platform). */
|
||||
if_enable (info);
|
||||
#endif
|
||||
|
||||
/* Bind the socket to this interface's IP address. */
|
||||
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
||||
error ("Can't bind to dhcp address: %m");
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
/* Bind this socket to this interface. */
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *)interface, sizeof(*interface)) < 0) {
|
||||
error("setting SO_BINDTODEVICE");
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
||||
@@ -197,3 +209,30 @@ size_t fallback_discard (interface)
|
||||
(struct sockaddr *)&from, &flen);
|
||||
}
|
||||
#endif /* USE_SOCKET_RECEIVE */
|
||||
|
||||
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||
/* If we're using the standard socket API without SO_BINDTODEVICE,
|
||||
* we need this kludge to force DHCP broadcasts to go out
|
||||
* this interface, even though it's not available for general
|
||||
* use until we get a lease!
|
||||
* This should work _OK_, but it will cause ALL all-ones
|
||||
* broadcasts on this host to go out this interface--it
|
||||
* could interfere with other interfaces. And God help you
|
||||
* if you run this on multiple interfaces simultaneously.
|
||||
* SO_BINDTODEVICE really is better! */
|
||||
void if_enable (interface)
|
||||
struct interface_info *interface;
|
||||
{
|
||||
#ifndef SO_BINDTODEVICE
|
||||
struct in_addr broad_addr;
|
||||
broad_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
|
||||
/* Delete old routes for broadcast address. */
|
||||
remove_routes(NULL, &broad_addr);
|
||||
|
||||
/* Add a route for broadcast address to this interface. */
|
||||
/* POTENTIAL PROBLEM: Don't do this to more than one interface! */
|
||||
add_route_direct(interface, &broad_addr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user