BPF socket interface code, originally contributed by Archie Cobbs. */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
+ * Copyright (c) 1995, 1996, 1998, 1999
+ * The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#ifndef lint
static char copyright[] =
-"$Id: bpf.c,v 1.19 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bpf.c,v 1.20 1999/02/14 18:41:11 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
-#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
+#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE) \
+ || defined (USE_LPF_RECEIVE)
+# if defined (USE_LPF_RECEIVE)
+# include <asm/types.h>
+# include <linux/filter.h>
+# define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */
+# else
+# include <sys/ioctl.h>
+# include <sys/uio.h>
+# include <net/bpf.h>
+# if defined (NEED_OSF_PFILT_HACKS)
+# include <net/pfilt.h>
+# endif
+# endif
-#include <net/bpf.h>
-#ifdef NEED_OSF_PFILT_HACKS
-#include <net/pfilt.h>
-#endif
#include <netinet/in_systm.h>
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
+#endif
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
Opens a packet filter for each interface and adds it to the select
mask. */
+#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
int if_register_bpf (info)
struct interface_info *info;
{
if (errno == EBUSY) {
continue;
} else {
+ if (!b)
+ error ("No bpf devices.%s%s%s",
+ " Please read the README",
+ " section for your operating",
+ " system.");
error ("Can't find free bpf: %m");
}
} else {
}
#endif /* USE_BPF_SEND */
-#ifdef USE_BPF_RECEIVE
+#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)
/* Packet filter program...
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the BPF program! XXX */
-struct bpf_insn filter [] = {
+struct bpf_insn dhcp_bpf_filter [] = {
/* Make sure this is an IP packet... */
BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
BPF_STMT(BPF_RET+BPF_K, 0),
};
+int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
+#endif
+
+#if defined (USE_BPF_RECEIVE)
void if_register_receive (info)
struct interface_info *info;
{
info -> rbuf_len = 0;
/* Set up the bpf filter program structure. */
- p.bf_len = sizeof filter / sizeof (struct bpf_insn);
- p.bf_insns = filter;
+ p.bf_len = dhcp_bpf_filter_len;
+ p.bf_insns = dhcp_bpf_filter;
/* Patch the server port into the BPF program...
XXX changes to filter program may require changes
to the insn number(s) used below! XXX */
- filter [8].k = ntohs (local_port);
+ dhcp_bpf_filter [8].k = ntohs (local_port);
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
error ("Can't install packet filter program: %m");
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,
} while (!length);
return 0;
}
+
+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
Network input dispatcher... */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: discover.c,v 1.2 1998/11/11 07:50:51 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: discover.c,v 1.3 1999/02/14 18:45:30 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
-struct interface_info *interfaces, *dummy_interfaces;
+struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
extern int interfaces_invalidated;
int quiet_interface_discovery;
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *));
-static void got_one PROTO ((struct protocol *));
-
/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
For each interface that's of type INET and not the loopback interface,
register that interface with the network I/O software, figure out what
struct shared_network *share;
struct sockaddr_in foo;
int ir;
+ struct ifreq *tif;
#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)
else
ir = INTERFACE_REQUESTED;
- /* Cycle through the list of interfaces looking for IP addresses.
- Go through twice; once to count the number of addresses, and a
- second time to copy them into an array of addresses. */
+ /* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
#ifdef HAVE_SA_LEN
- if (ifp -> ifr_addr.sa_len)
+ if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
else
#endif
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) {
-#ifdef ARPHRD_LOOPBACK
- case ARPHRD_LOOPBACK:
- /* ignore loopback interface */
- break;
-#endif
-
- case ARPHRD_ETHER:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_ETHER;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
- break;
-
-#ifndef ARPHRD_IEEE802
-# define ARPHRD_IEEE802 HTYPE_IEEE802
-#endif
- case ARPHRD_IEEE802:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_IEEE802;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
- break;
-
-#ifdef ARPHRD_FDDI
- case ARPHRD_FDDI:
- tmp -> hw_address.hlen = 16;
- tmp -> hw_address.htype = ARPHRD_FDDI;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 16);
-
- break;
-#endif
-
-#ifdef ARPHRD_METRICOM
- case ARPHRD_METRICOM:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_METRICOM;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
-
- break;
-#endif
-
- 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);
found, keep a pointer to ifreq structure in
which we found it. */
if (!tmp -> ifp) {
- struct ifreq *tif;
#ifdef HAVE_SA_LEN
int len = ((sizeof ifp -> ifr_name) +
ifp -> ifr_addr.sa_len);
}
}
+#if defined (LINUX_SLASHPROC_DISCOVERY)
+ /* On Linux, interfaces that don't have IP addresses don't show up
+ in the SIOCGIFCONF syscall. We got away with this prior to
+ Linux 2.1 because we would give each interface an IP address of
+ 0.0.0.0 before trying to boot, but that doesn't work after 2.1
+ because we're using LPF, because we can't configure interfaces
+ with IP addresses of 0.0.0.0 anymore (grumble). This only
+ matters for the DHCP client, of course - the relay agent and
+ server should only care about interfaces that are configured
+ with IP addresses anyway.
+
+ The PROCDEV_DEVICE (/proc/net/dev) is a kernel-supplied file
+ that, when read, prints a human readable network status. We
+ extract the names of the network devices by skipping the first
+ two lines (which are header) and then parsing off everything
+ up to the colon in each subsequent line - these lines start
+ with the interface name, then a colon, then a bunch of
+ statistics. Yes, Virgina, this is a kludge, but you work
+ with what you have. */
+
+ if (state == DISCOVER_UNCONFIGURED) {
+ FILE *proc_dev;
+ char buffer [256];
+ int skip = 2;
+
+ proc_dev = fopen (PROCDEV_DEVICE, "r");
+ if (!proc_dev)
+ error ("%s: %m", PROCDEV_DEVICE);
+
+ while (fgets (buffer, sizeof buffer, proc_dev)) {
+ char *name = buffer;
+ char *sep;
+
+ /* Skip the first two blocks, which are header
+ lines. */
+ if (skip) {
+ --skip;
+ continue;
+ }
+
+ sep = strrchr (buffer, ':');
+ if (sep)
+ *sep = '\0';
+ while (*name == ' ')
+ name++;
+
+ /* See if we've seen an interface that matches
+ this one. */
+ for (tmp = interfaces; tmp; tmp = tmp -> next)
+ if (!strcmp (tmp -> name, name))
+ break;
+
+ /* If we found one, nothing more to do.. */
+ if (tmp)
+ continue;
+
+ /* Otherwise, allocate one. */
+ tmp = ((struct interface_info *)
+ dmalloc (sizeof *tmp, "discover_interfaces"));
+ if (!tmp)
+ error ("Insufficient memory to %s %s",
+ "record interface", name);
+ memset (tmp, 0, sizeof *tmp);
+ strcpy (tmp -> name, name);
+
+ tmp -> flags = ir;
+ tmp -> next = interfaces;
+ interfaces = tmp;
+ }
+ fclose (proc_dev);
+ }
+#endif
+
+ /* Now cycle through all the interfaces we found, looking for
+ hardware addresses. */
+#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
+ for (tmp = interfaces; tmp; tmp = tmp -> next) {
+ struct ifreq ifr;
+ struct sockaddr sa;
+ int b, sk;
+
+ if (!tmp -> ifp) {
+ /* Make up an ifreq structure. */
+ tif = (struct ifreq *)malloc (sizeof (struct ifreq));
+ if (!tif)
+ error ("no space to remember ifp.");
+ memset (tif, 0, sizeof (struct ifreq));
+ strcpy (tif -> ifr_name, tmp -> name);
+ tmp -> ifp = tif;
+ }
+
+ /* Read the hardware address from this interface. */
+ ifr = *tmp -> ifp;
+ if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+
+ sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
+
+ switch (sa.sa_family) {
+#ifdef ARPHRD_LOOPBACK
+ case ARPHRD_LOOPBACK:
+ /* ignore loopback interface */
+ break;
+#endif
+
+ case ARPHRD_ETHER:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_ETHER;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+
+#ifndef ARPHRD_IEEE802
+# define ARPHRD_IEEE802 HTYPE_IEEE802
+#endif
+ case ARPHRD_IEEE802:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_IEEE802;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+
+#ifndef ARPHRD_FDDI
+# define ARPHRD_FDDI HTYPE_FDDI
+#endif
+ case ARPHRD_FDDI:
+ tmp -> hw_address.hlen = 16;
+ tmp -> hw_address.htype = HTYPE_FDDI; /* XXX */
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 16);
+ break;
+
+#ifdef ARPHRD_METRICOM
+ case ARPHRD_METRICOM:
+ tmp -> hw_address.hlen = 6;
+ tmp -> hw_address.htype = ARPHRD_METRICOM;
+ memcpy (tmp -> hw_address.haddr, sa.sa_data, 6);
+ break;
+#endif
+
+ default:
+ error ("%s: unknown hardware address type %d",
+ ifr.ifr_name, sa.sa_family);
+ }
+ }
+#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
+
/* If we're just trying to get a list of interfaces that we might
be able to configure, we can quit now. */
if (state == DISCOVER_UNCONFIGURED)
close (sock);
-#ifdef USE_FALLBACK
- strcpy (fallback_interface.name, "fallback");
- fallback_interface.shared_network = &fallback_network;
- fallback_network.name = "fallback-net";
- if_register_fallback (&fallback_interface);
- add_protocol ("fallback", fallback_interface.wfdesc,
- fallback_discard, &fallback_interface);
-#endif
+ maybe_setup_fallback ();
+}
+
+struct interface_info *setup_fallback ()
+{
+ fallback_interface =
+ ((struct interface_info *)
+ dmalloc (sizeof *fallback_interface, "discover_interfaces"));
+ if (!fallback_interface)
+ error ("Insufficient memory to record fallback interface.");
+ memset (fallback_interface, 0, sizeof *fallback_interface);
+ strcpy (fallback_interface -> name, "fallback");
+ fallback_interface -> shared_network =
+ new_shared_network ("parse_statement");
+ if (!fallback_interface -> shared_network)
+ error ("No memory for shared subnet");
+ memset (fallback_interface -> shared_network, 0,
+ sizeof (struct shared_network));
+ fallback_interface -> shared_network -> name = "fallback-net";
+ return fallback_interface;
}
void reinitialize_interfaces ()
if_reinitialize_send (ip);
}
-#ifdef USE_FALLBACK
- if_reinitialize_fallback (&fallback_interface);
-#endif
+ if (fallback_interface)
+ if_reinitialize_send (fallback_interface);
interfaces_invalidated = 1;
}
-static void got_one (l)
+
+void got_one (l)
struct protocol *l;
{
struct sockaddr_in from;
Data Link Provider Interface (DLPI) network interface code. */
/*
- * Copyright (c) 1998 The Internet Software Consortium.
+ * Copyright (c) 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
# define ABS(x) ((x) >= 0 ? (x) : 0-(x))
# endif
+#ifndef lint
+static char copyright[] =
+"$Id: dlpi.c,v 1.3 1999/02/14 18:48:05 mellon Exp $ Copyright (c) 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
static int strioctl PROTO ((int fd, int cmd, int timeout, int len, char *dp));
#define DLPI_MAXDLBUF 8192 /* Buffer size */
case DL_ETHER:
info -> hw_address.htype = HTYPE_ETHER;
break;
+ case DL_FDDI:
+ info -> hw_address.htype = HTYPE_FDDI;
+ break;
default:
error ("%s: unknown DLPI MAC type %d",
info -> name,
int saplen;
int rslt;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
dbuflen = 0;
/* Assemble the headers... */
rslt = write (interface -> wfdesc, dbuf, dbuflen);
#else
/* XXX: Assumes ethernet, with two byte SAP */
- sap [0] = 0; /* ETHERTYPE_IP, high byte */
- sap [1] = 0x80; /* ETHERTYPE_IP, low byte */
+ sap [0] = 0x08; /* ETHERTYPE_IP, high byte */
+ sap [1] = 0x0; /* ETHERTYPE_IP, low byte */
saplen = -2; /* -2 indicates a two byte SAP at the end
of the address */
}
#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 */
with one crucial tidbit of help from Stu Grossmen. */
/*
- * Copyright (c) 1996 The Internet Software Consortium.
+ * Copyright (c) 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#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.16 1999/02/14 18:50:25 mellon Exp $ Copyright (c) 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
int hw_end;
struct sockaddr_in foo;
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
/* Start with the sockaddr struct... */
junk = (struct sockaddr *)&buf [0];
bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
Turn data structures into printable text. */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: print.c,v 1.18 1998/11/05 18:44:11 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: print.c,v 1.19 1999/02/14 18:55:01 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
debug (" stamp %s", tbuf);
debug (" hardware addr = %s",
BSD socket interface code... */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#ifndef lint
static char copyright[] =
-"$Id: socket.c,v 1.27 1998/03/15 20:54:20 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: socket.c,v 1.28 1999/02/14 18:55:32 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
int sock;
int flag;
-#ifndef SO_BINDTODEVICE
+#ifndef SO_BINDTODEVICE && !defined (USE_FALLBACK)
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s",
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
-#ifdef SO_BINDTODEVICE
+#if defined (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");
+ error("setsockopt: SO_BINDTODEVICE: %m");
}
#endif
}
#endif /* USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_FALLBACK
+#ifdef USE_SOCKET_SEND
/* This just reads in a packet and silently discards it. */
void fallback_discard (protocol)
if (status < 0)
warn ("fallback_discard: %m");
}
-#endif /* USE_SOCKET_RECEIVE */
+#endif /* USE_SOCKET_SEND */
+
+#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
+int can_unicast_without_arp ()
+{
+ return 0;
+}
+
+/* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise,
+ do not. */
+
+void maybe_setup_fallback ()
+{
+#if defined (SO_BINDTODEVICE)
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ fbi -> wfdesc = if_register_socket (fbi);
+ add_protocol ("fallback",
+ fbi -> wfdesc, fallback_discard, fbi);
+ }
+#endif
+}
+#endif /* USE_SOCKET_SEND && !USE_SOCKET_FALLBACK */
Tables of information... */
/*
- * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: tables.c,v 1.17 1998/11/05 18:44:41 mellon Exp $ Copyright (c) 1995, 1996, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tables.c,v 1.18 1999/02/14 18:56:37 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
{ "lpr-servers", "IA", &dhcp_universe, 9 },
{ "impress-servers", "IA", &dhcp_universe, 10 },
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
- { "host-name", "t", &dhcp_universe, 12 },
+ { "host-name", "X", &dhcp_universe, 12 },
{ "boot-size", "S", &dhcp_universe, 13 },
{ "merit-dump", "t", &dhcp_universe, 14 },
{ "domain-name", "t", &dhcp_universe, 15 },
"unknown-5",
"token-ring",
"unknown-7",
- "unknown-8",
+ "fddi",
"unknown-9",
"unknown-10",
"unknown-11",
{ "filename", "t", &server_universe, 15 },
{ "server-name", "t", &server_universe, 16 },
{ "next-server", "I", &server_universe, 17 },
- { "option-18", "X", &server_universe, 18 },
+ { "authoritative", "f", &server_universe, 18 },
{ "option-19", "X", &server_universe, 19 },
{ "option-20", "X", &server_universe, 20 },
{ "option-21", "X", &server_universe, 21 },
Ultrix PacketFilter interface code.
/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
- * All rights reserved.
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#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.4 1999/02/14 18:57:19 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
unsigned char buf [256];
struct iovec iov [2];
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
memcpy (buf, &ibuf [bufix], length);
return length;
}
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
#endif
Based on a configuration originally supplied by Jonathan Stone. */
/*
- * Copyright (c) 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
typedef unsigned long u_int32_t;
#endif /* __BIT_TYPES_DEFINED__ */
+typedef u_int8_t u8;
+typedef u_int16_t u16;
+typedef u_int32_t u32;
+
#include <syslog.h>
#include <sys/types.h>
#include <string.h>
#include <net/if.h>
#include <net/route.h>
-#if defined (LINUX_1_X)
+#if LINUX_MAJOR == 1
# include <linux/if_arp.h>
# include <linux/time.h> /* also necessary */
#else
#define GET_TIME(x) time ((x))
#if defined (USE_DEFAULT_NETWORK)
+# if (LINUX_MAJOR >= 2) && (LINUX_MINOR >= 1)
+# define USE_LPF
+# define LINUX_SLASHPROC_DISCOVERY
+# define PROCDEV_DEVICE "/proc/net/dev"
+# else
# define USE_SOCKETS
# define IGNORE_HOSTUNREACH
+# endif
#endif
#define ALIAS_NAMES_PERMUTED
System dependencies for Solaris 2.x (tested on 2.5 with gcc)... */
/*
- * Copyright (c) 1996, 1998 The Internet Software Consortium.
+ * Copyright (c) 1996, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/* By default, use the DLPI API for receiving and sending packets. */
#if defined (USE_DEFAULT_NETWORK)
-# define USE_DLPI
-# define USE_DLPI_RAW
-# define USE_DLPI_PFMOD
-# define DLPI_FIRST_SEND_WAIT 6
+# if defined (__sparc)
+/* On sparc systems, use the DLPI API, which allows multiple interfaces
+ to be supported. DLPI is currently buggy on non-sparc machines.
+ It's unclear whether this is an O.S. bug or an endianness bug in
+ the DLPI code. */
+# define USE_DLPI
+# define USE_DLPI_PFMOD
+# else
+/* On non-sparc systems, use BSD Socket API for receiving and sending
+ packets. This actually works pretty well on Solaris, which doesn't
+ censor the all-ones broadcast address. */
+# define USE_SOCKETS
+# endif /* defined (__sparc) */
#endif
#define USE_POLL
System dependencies for Ultrix 4.2 (tested on 4.2a+multicast)... */
/*
- * Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
+ * Copyright (c) 1996, 1998, 1999 The Internet Software Consortium.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#define u_int16_t unsigned short
#define u_int32_t unsigned long
+#define ssize_t size_t
+
/* The jmp_buf type is an array on ultrix, so we can't dereference it
and must declare it differently. */
#define jbp_decl(x) jmp_buf x
Protocol structures... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/* Possible values for hardware type (htype) field... */
#define HTYPE_ETHER 1 /* Ethernet 10Mbps */
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
+#define HTYPE_FDDI 8 /* FDDI... */
/* Magic cookie validating dhcp options field (and bootp vendor
extensions field). */
!defined (USE_BPF) && \
!defined (USE_BPF_SEND) && \
!defined (USE_BPF_RECEIVE) && \
+ !defined (USE_LPF) && \
+ !defined (USE_LPF_SEND) && \
+ !defined (USE_LPF_RECEIVE) && \
!defined (USE_NIT) && \
!defined (USE_NIT_SEND) && \
!defined (USE_NIT_RECEIVE) && \
# define USE_DEFAULT_NETWORK
#endif
+#if !defined (TIME_MAX)
+# define TIME_MAX 2147483647
+#endif
/* Porting::
# define USE_BPF_RECEIVE
#endif
+#ifdef USE_LPF
+# define USE_LPF_SEND
+# define USE_LPF_RECEIVE
+#endif
+
#ifdef USE_NIT
# define USE_NIT_SEND
# define USE_NIT_RECEIVE
fallback. */
#if defined (USE_BPF_SEND) || defined (USE_NIT_SEND) || \
- defined (USE_DLPI_SEND) || defined (USE_UPF_SEND)
+ defined (USE_DLPI_SEND) || defined (USE_UPF_SEND) || defined (USE_LPF_SEND)
# define USE_SOCKET_FALLBACK
# define USE_FALLBACK
#endif
#if defined (USE_RAW_SEND) || defined (USE_BPF_SEND) || \
defined (USE_NIT_SEND) || defined (USE_UPF_SEND) || \
- defined (USE_DLPI_SEND)
+ defined (USE_DLPI_SEND) || defined (USE_LPF_SEND)
# define PACKET_ASSEMBLY
#endif
#if defined (USE_RAW_RECEIVE) || defined (USE_BPF_SEND) || \
defined (USE_NIT_RECEIVE) || defined (USE_UPF_RECEIVE) || \
- defined (USE_DLPI_RECEIVE)
+ defined (USE_DLPI_RECEIVE) || defined (USE_LPF_RECEIVE)
# define PACKET_DECODING
#endif
DHCP/BOOTP Relay Agent. */
/*
- * Copyright (c) 1997, 1998 The Internet Software Consortium.
+ * Copyright (c) 1997, 1998, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifndef lint
static char copyright[] =
-"$Id: dhcrelay.c,v 1.16 1998/11/06 00:15:13 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcrelay.c,v 1.17 1999/02/14 19:04:05 mellon Exp $ Copyright (c) 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
forward_untouched, /* Forward without changes. */
discard } agent_relay_mode = forward_and_replace;
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
u_int16_t local_port;
u_int16_t remote_port;
int log_priority;
struct sockaddr_in to;
} *servers;
+static char copyright [] =
+"Copyright 1997, 1998, 1999 The Internet Software Consortium.";
+static char arr [] = "All rights reserved.";
+static char message [] = "Internet Software Consortium DHCP Relay Agent V3.0-alpha 19990213";
+static char contrib [] = "\nPlease contribute if you find this software useful.";
+static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
+
int main (argc, argv, envp)
int argc;
char **argv, **envp;
}
}
+ if (!quiet) {
+ note (message);
+ note (copyright);
+ note (arr);
+ note (contrib);
+ note (url);
+ }
+
/* Default to the DHCP/BOOTP port. */
if (!local_port) {
ent = getservbyname ("dhcps", "udp");
/* If it's a bootreply, forward it to the client. */
if (packet -> op == BOOTREPLY) {
-#ifdef USE_FALLBACK
- if (!(packet -> flags & htons (BOOTP_BROADCAST))) {
+ if (!(packet -> flags & htons (BOOTP_BROADCAST)) &&
+ can_unicast_without_arp ()) {
to.sin_addr = packet -> yiaddr;
to.sin_port = remote_port;
- } else
-#endif
- {
+ } else {
to.sin_addr.s_addr = htonl (INADDR_BROADCAST);
to.sin_port = remote_port;
}
/* Otherwise, it's a BOOTREQUEST, so forward it to all the
servers. */
for (sp = servers; sp; sp = sp -> next) {
- if (
-#ifdef USE_FALLBACK
- send_fallback (&fallback_interface,
- (struct packet *)0,
- packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#else
- send_packet (interfaces,
+ if (send_packet ((fallback_interface
+ ? fallback_interface : interfaces),
(struct packet *)0,
packet, length, ip -> primary_address,
- &sp -> to, (struct hardware *)0)
-#endif
- < 0) {
+ &sp -> to, (struct hardware *)0) < 0) {
debug ("send_packet: %m");
++client_packet_errors;
} else {