mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-03 07:45:20 +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 \
|
CSRC = options.c errwarn.c convert.c \
|
||||||
tree.c memory.c alloc.c print.c hash.c tables.c inet.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 \
|
COBJ = options.o errwarn.o convert.o \
|
||||||
tree.o memory.o alloc.o print.o hash.o tables.o inet.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
|
XOBJ = dhcpxlt.o xconflex.o
|
||||||
SRCS = dhcpd.c dhcp.c bootp.c conflex.c confpars.c db.c
|
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
|
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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -368,3 +368,25 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
extern int h_errno;
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
#include <sys/time.h> /* gettimeofday()*/
|
#include <sys/time.h> /* gettimeofday()*/
|
||||||
#include <linux/time.h> /* also necessary */
|
#include <linux/time.h> /* also necessary */
|
||||||
|
@@ -52,6 +52,10 @@ extern int h_errno;
|
|||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#define ifr_netmask ifr_addr
|
||||||
|
|
||||||
/* Varargs stuff... */
|
/* Varargs stuff... */
|
||||||
#include <stdarg.h>
|
#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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -368,3 +368,25 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -162,6 +162,44 @@ void discover_interfaces (serverP)
|
|||||||
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
||||||
struct iaddr addr;
|
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... */
|
/* Get a pointer to the address... */
|
||||||
memcpy (&foo, &ifp -> ifr_addr,
|
memcpy (&foo, &ifp -> ifr_addr,
|
||||||
sizeof ifp -> ifr_addr);
|
sizeof ifp -> ifr_addr);
|
||||||
|
20
common/nit.c
20
common/nit.c
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -329,3 +329,21 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
#endif
|
#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''.
|
* 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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -62,6 +70,8 @@ int if_register_socket (info, interface)
|
|||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
int sock;
|
int sock;
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
|
#ifndef SO_BINDTODEVICE
|
||||||
static int once = 0;
|
static int once = 0;
|
||||||
|
|
||||||
/* Make sure only one interface is registered. */
|
/* 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 ",
|
"you must compile in BPF or NIT support. If neither ",
|
||||||
"option is supported on your system, please let us ",
|
"option is supported on your system, please let us ",
|
||||||
"know.");
|
"know.");
|
||||||
|
once = 1;
|
||||||
/* 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 */
|
|
||||||
#endif
|
#endif
|
||||||
once = 1;
|
|
||||||
|
|
||||||
/* Set up the address we're going to bind to. */
|
/* Set up the address we're going to bind to. */
|
||||||
name.sin_family = AF_INET;
|
name.sin_family = AF_INET;
|
||||||
@@ -111,10 +107,26 @@ int if_register_socket (info, interface)
|
|||||||
(char *)&flag, sizeof flag) < 0)
|
(char *)&flag, sizeof flag) < 0)
|
||||||
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
|
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. */
|
/* Bind the socket to this interface's IP address. */
|
||||||
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
||||||
error ("Can't bind to dhcp address: %m");
|
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;
|
return sock;
|
||||||
}
|
}
|
||||||
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
||||||
@@ -197,3 +209,30 @@ size_t fallback_discard (interface)
|
|||||||
(struct sockaddr *)&from, &flen);
|
(struct sockaddr *)&from, &flen);
|
||||||
}
|
}
|
||||||
#endif /* USE_SOCKET_RECEIVE */
|
#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 DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
||||||
|
|
||||||
#define BOOTP_MIN_LEN 300
|
#define BOOTP_MIN_LEN 300
|
||||||
|
#define DHCP_MIN_LEN 548
|
||||||
|
|
||||||
struct dhcp_packet {
|
struct dhcp_packet {
|
||||||
u_int8_t op; /* Message opcode/type */
|
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,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* bpf.c */
|
/* bpf.c */
|
||||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
|
#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,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_BPF_SEND)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* nit.c */
|
/* nit.c */
|
||||||
#ifdef USE_NIT_SEND
|
#ifdef USE_NIT_SEND
|
||||||
@@ -484,6 +490,9 @@ size_t receive_packet PROTO ((struct interface_info *,
|
|||||||
unsigned char *, size_t,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_BPF_SEND)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* raw.c */
|
/* raw.c */
|
||||||
#ifdef USE_RAW_SEND
|
#ifdef USE_RAW_SEND
|
||||||
@@ -541,6 +550,27 @@ void dhcpack PROTO ((struct packet *));
|
|||||||
void dhcpnak PROTO ((struct packet *));
|
void dhcpnak PROTO ((struct packet *));
|
||||||
void send_discover PROTO ((struct interface_info *));
|
void send_discover PROTO ((struct interface_info *));
|
||||||
void send_request PROTO ((struct packet *));
|
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 */
|
/* db.c */
|
||||||
int write_lease PROTO ((struct lease *));
|
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_date PROTO ((FILE *, jrefproto, char *));
|
||||||
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
||||||
void indent PROTO ((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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -162,6 +162,44 @@ void discover_interfaces (serverP)
|
|||||||
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
if (ifp -> ifr_addr.sa_family == AF_INET) {
|
||||||
struct iaddr addr;
|
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... */
|
/* Get a pointer to the address... */
|
||||||
memcpy (&foo, &ifp -> ifr_addr,
|
memcpy (&foo, &ifp -> ifr_addr,
|
||||||
sizeof ifp -> ifr_addr);
|
sizeof ifp -> ifr_addr);
|
||||||
|
@@ -60,6 +60,9 @@ typedef unsigned long u_int32_t;
|
|||||||
extern int h_errno;
|
extern int h_errno;
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
#include <sys/time.h> /* gettimeofday()*/
|
#include <sys/time.h> /* gettimeofday()*/
|
||||||
#include <linux/time.h> /* also necessary */
|
#include <linux/time.h> /* also necessary */
|
||||||
|
@@ -52,6 +52,10 @@ extern int h_errno;
|
|||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#define ifr_netmask ifr_addr
|
||||||
|
|
||||||
/* Varargs stuff... */
|
/* Varargs stuff... */
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@@ -52,6 +52,7 @@
|
|||||||
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
||||||
|
|
||||||
#define BOOTP_MIN_LEN 300
|
#define BOOTP_MIN_LEN 300
|
||||||
|
#define DHCP_MIN_LEN 548
|
||||||
|
|
||||||
struct dhcp_packet {
|
struct dhcp_packet {
|
||||||
u_int8_t op; /* Message opcode/type */
|
u_int8_t op; /* Message opcode/type */
|
||||||
|
@@ -451,6 +451,9 @@ size_t receive_packet PROTO ((struct interface_info *,
|
|||||||
unsigned char *, size_t,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* bpf.c */
|
/* bpf.c */
|
||||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
|
#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,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_BPF_SEND)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* nit.c */
|
/* nit.c */
|
||||||
#ifdef USE_NIT_SEND
|
#ifdef USE_NIT_SEND
|
||||||
@@ -484,6 +490,9 @@ size_t receive_packet PROTO ((struct interface_info *,
|
|||||||
unsigned char *, size_t,
|
unsigned char *, size_t,
|
||||||
struct sockaddr_in *, struct hardware *));
|
struct sockaddr_in *, struct hardware *));
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (USE_BPF_SEND)
|
||||||
|
void if_enable PROTO ((struct interface_info *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* raw.c */
|
/* raw.c */
|
||||||
#ifdef USE_RAW_SEND
|
#ifdef USE_RAW_SEND
|
||||||
@@ -541,6 +550,27 @@ void dhcpack PROTO ((struct packet *));
|
|||||||
void dhcpnak PROTO ((struct packet *));
|
void dhcpnak PROTO ((struct packet *));
|
||||||
void send_discover PROTO ((struct interface_info *));
|
void send_discover PROTO ((struct interface_info *));
|
||||||
void send_request PROTO ((struct packet *));
|
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 */
|
/* db.c */
|
||||||
int write_lease PROTO ((struct lease *));
|
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_date PROTO ((FILE *, jrefproto, char *));
|
||||||
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
|
||||||
void indent PROTO ((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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -329,3 +329,21 @@ size_t receive_packet (interface, buf, len, from, hfrom)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* route.c
|
||||||
|
|
||||||
BSD socket interface code... */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Routines for updating routing tables and configuring interfaces.
|
||||||
* modification, are permitted provided that the following conditions
|
*
|
||||||
* are met:
|
* 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
|
* Permission to use, copy, modify, and distribute this
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* software and its documentation for any purpose and without
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* fee is hereby granted, provided that the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice appear in all copies. Stanford University
|
||||||
* documentation and/or other materials provided with the distribution.
|
* makes no representations about the suitability of this
|
||||||
* 3. Neither the name of The Internet Software Consortium nor the names
|
* software for any purpose. It is provided "as is" without
|
||||||
* of its contributors may be used to endorse or promote products derived
|
* express or implied warranty.
|
||||||
* 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''.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
#if defined (OLD_ROUTE_HACK)
|
/* Add a route to this destination through this interface. */
|
||||||
#include <net/route.h>
|
void add_route_direct(interface, destination)
|
||||||
|
struct interface_info *interface;
|
||||||
route_hack (sock)
|
struct in_addr destination;
|
||||||
int sock;
|
|
||||||
{
|
{
|
||||||
int rsock = socket (PF_ROUTE, SOCK_RAW, AF_INET);
|
note ("add_route_direct %s: %s",
|
||||||
struct rt_msghdr
|
interface -> name, inet_ntoa (destination));
|
||||||
|
#if 0
|
||||||
|
struct in_addr directmask;
|
||||||
|
|
||||||
if (rsock < 0)
|
directmask.s_addr = htonl (INADDR_BROADCAST); /* this addr only */
|
||||||
error ("Can't make routing socket: %m");
|
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''.
|
* 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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -62,6 +70,8 @@ int if_register_socket (info, interface)
|
|||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
int sock;
|
int sock;
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
|
#ifndef SO_BINDTODEVICE
|
||||||
static int once = 0;
|
static int once = 0;
|
||||||
|
|
||||||
/* Make sure only one interface is registered. */
|
/* 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 ",
|
"you must compile in BPF or NIT support. If neither ",
|
||||||
"option is supported on your system, please let us ",
|
"option is supported on your system, please let us ",
|
||||||
"know.");
|
"know.");
|
||||||
|
once = 1;
|
||||||
/* 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 */
|
|
||||||
#endif
|
#endif
|
||||||
once = 1;
|
|
||||||
|
|
||||||
/* Set up the address we're going to bind to. */
|
/* Set up the address we're going to bind to. */
|
||||||
name.sin_family = AF_INET;
|
name.sin_family = AF_INET;
|
||||||
@@ -111,10 +107,26 @@ int if_register_socket (info, interface)
|
|||||||
(char *)&flag, sizeof flag) < 0)
|
(char *)&flag, sizeof flag) < 0)
|
||||||
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
|
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. */
|
/* Bind the socket to this interface's IP address. */
|
||||||
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
|
||||||
error ("Can't bind to dhcp address: %m");
|
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;
|
return sock;
|
||||||
}
|
}
|
||||||
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
|
||||||
@@ -197,3 +209,30 @@ size_t fallback_discard (interface)
|
|||||||
(struct sockaddr *)&from, &flen);
|
(struct sockaddr *)&from, &flen);
|
||||||
}
|
}
|
||||||
#endif /* USE_SOCKET_RECEIVE */
|
#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