diff options
-rw-r--r-- | common/bpf.c | 68 | ||||
-rw-r--r-- | common/discover.c | 262 | ||||
-rw-r--r-- | common/dlpi.c | 33 | ||||
-rw-r--r-- | common/nit.c | 24 | ||||
-rw-r--r-- | common/print.c | 10 | ||||
-rw-r--r-- | common/socket.c | 42 | ||||
-rw-r--r-- | common/tables.c | 10 | ||||
-rw-r--r-- | common/upf.c | 26 | ||||
-rw-r--r-- | includes/cf/linux.h | 14 | ||||
-rw-r--r-- | includes/cf/sunos5-5.h | 19 | ||||
-rw-r--r-- | includes/cf/ultrix.h | 5 | ||||
-rw-r--r-- | includes/dhcp.h | 3 | ||||
-rw-r--r-- | includes/osdep.h | 17 | ||||
-rw-r--r-- | relay/dhcrelay.c | 45 |
14 files changed, 414 insertions, 164 deletions
diff --git a/common/bpf.c b/common/bpf.c index e47aa1f7..b0ede130 100644 --- a/common/bpf.c +++ b/common/bpf.c @@ -3,8 +3,8 @@ 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 @@ -42,22 +42,30 @@ #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. */ @@ -80,6 +88,7 @@ void if_reinitialize_receive (info) 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; { @@ -99,6 +108,11 @@ int if_register_bpf (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 { @@ -137,12 +151,12 @@ void if_register_send (info) } #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), @@ -169,6 +183,10 @@ struct bpf_insn filter [] = { 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; { @@ -220,13 +238,13 @@ void if_register_receive (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"); @@ -255,6 +273,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) unsigned char buf [256]; struct iovec iov [2]; + if (!strcmp (interface -> name, "fallback")) + return send_fallback (interface, packet, raw, + len, from, to, hto); + /* Assemble the headers... */ assemble_hw_header (interface, buf, &bufp, hto); assemble_udp_ip_header (interface, buf, &bufp, from.s_addr, @@ -383,4 +405,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) } 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 diff --git a/common/discover.c b/common/discover.c index a1699a4e..a6a8b19f 100644 --- a/common/discover.c +++ b/common/discover.c @@ -3,7 +3,7 @@ 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 @@ -42,13 +42,13 @@ #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; @@ -56,8 +56,6 @@ void (*bootp_packet_handler) PROTO ((struct interface_info *, struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *)); -static void got_one PROTO ((struct protocol *)); - /* 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 @@ -78,12 +76,10 @@ void discover_interfaces (state) 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) @@ -108,13 +104,11 @@ void discover_interfaces (state) 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 @@ -194,69 +188,6 @@ void discover_interfaces (state) 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); @@ -270,7 +201,6 @@ void discover_interfaces (state) 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); @@ -329,6 +259,150 @@ void discover_interfaces (state) } } +#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) @@ -392,14 +466,26 @@ void discover_interfaces (state) close (sock); -#ifdef USE_FALLBACK - strcpy (fallback_interface.name, "fallback"); - fallback_interface.shared_network = &fallback_network; - fallback_network.name = "fallback-net"; - if_register_fallback (&fallback_interface); - add_protocol ("fallback", fallback_interface.wfdesc, - fallback_discard, &fallback_interface); -#endif + maybe_setup_fallback (); +} + +struct interface_info *setup_fallback () +{ + fallback_interface = + ((struct interface_info *) + dmalloc (sizeof *fallback_interface, "discover_interfaces")); + if (!fallback_interface) + error ("Insufficient memory to record fallback interface."); + memset (fallback_interface, 0, sizeof *fallback_interface); + strcpy (fallback_interface -> name, "fallback"); + fallback_interface -> shared_network = + new_shared_network ("parse_statement"); + if (!fallback_interface -> shared_network) + error ("No memory for shared subnet"); + memset (fallback_interface -> shared_network, 0, + sizeof (struct shared_network)); + fallback_interface -> shared_network -> name = "fallback-net"; + return fallback_interface; } void reinitialize_interfaces () @@ -411,13 +497,13 @@ 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; diff --git a/common/dlpi.c b/common/dlpi.c index 7d02ec0b..192539bc 100644 --- a/common/dlpi.c +++ b/common/dlpi.c @@ -3,7 +3,7 @@ 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 @@ -120,6 +120,11 @@ # 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 */ @@ -222,6 +227,9 @@ int if_register_dlpi (info) 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, @@ -460,6 +468,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) int saplen; int rslt; + if (!strcmp (interface -> name, "fallback")) + return send_fallback (interface, packet, raw, + len, from, to, hto); + dbuflen = 0; /* Assemble the headers... */ @@ -478,8 +490,8 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) 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 */ @@ -1226,4 +1238,19 @@ static void sigalrm (sig) } #endif /* !defined (USE_POLL) */ +int can_unicast_without_arp () +{ + return 1; +} + +void maybe_setup_fallback () +{ + struct interface_info *fbi; + fbi = setup_fallback (); + if (fbi) { + if_register_fallback (fbi); + add_protocol ("fallback", fallback_interface -> wfdesc, + fallback_discard, fallback_interface); + } +} #endif /* USE_DLPI */ diff --git a/common/nit.c b/common/nit.c index 0633f1d3..0581bd3d 100644 --- a/common/nit.c +++ b/common/nit.c @@ -4,7 +4,7 @@ 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 @@ -42,7 +42,7 @@ #ifndef lint static char copyright[] = -"$Id: nit.c,v 1.15 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; +"$Id: nit.c,v 1.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" @@ -264,6 +264,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) int hw_end; struct sockaddr_in foo; + if (!strcmp (interface -> name, "fallback")) + return send_fallback (interface, packet, raw, + len, from, to, hto); + /* Start with the sockaddr struct... */ junk = (struct sockaddr *)&buf [0]; bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0]; @@ -344,4 +348,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) memcpy (buf, &ibuf [bufix], length); return length; } + +int can_unicast_without_arp () +{ + return 1; +} + +void maybe_setup_fallback () +{ + struct interface_info *fbi; + fbi = setup_fallback (); + if (fbi) { + if_register_fallback (fbi); + add_protocol ("fallback", fallback_interface -> wfdesc, + fallback_discard, fallback_interface); + } +} #endif diff --git a/common/print.c b/common/print.c index 4c900f13..98b0a2b2 100644 --- a/common/print.c +++ b/common/print.c @@ -3,7 +3,7 @@ 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 @@ -42,7 +42,7 @@ #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" @@ -80,15 +80,15 @@ void print_lease (lease) 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", diff --git a/common/socket.c b/common/socket.c index fbef4321..03063edb 100644 --- a/common/socket.c +++ b/common/socket.c @@ -3,8 +3,8 @@ 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 @@ -50,7 +50,7 @@ #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" @@ -102,7 +102,7 @@ int if_register_socket (info) 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", @@ -136,11 +136,12 @@ int if_register_socket (info) 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 @@ -236,7 +237,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) } #endif /* USE_SOCKET_RECEIVE */ -#ifdef USE_SOCKET_FALLBACK +#ifdef USE_SOCKET_SEND /* This just reads in a packet and silently discards it. */ void fallback_discard (protocol) @@ -253,4 +254,27 @@ 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 */ diff --git a/common/tables.c b/common/tables.c index 8fef1414..841dbb21 100644 --- a/common/tables.c +++ b/common/tables.c @@ -3,7 +3,7 @@ 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 @@ -42,7 +42,7 @@ #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" @@ -78,7 +78,7 @@ struct option dhcp_options [256] = { { "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 }, @@ -333,7 +333,7 @@ char *hardware_types [] = { "unknown-5", "token-ring", "unknown-7", - "unknown-8", + "fddi", "unknown-9", "unknown-10", "unknown-11", @@ -862,7 +862,7 @@ struct option server_options [256] = { { "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 }, diff --git a/common/upf.c b/common/upf.c index 498b6e6c..fea90fb8 100644 --- a/common/upf.c +++ b/common/upf.c @@ -3,8 +3,8 @@ 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 @@ -42,7 +42,7 @@ #ifndef lint static char copyright[] = -"$Id: upf.c,v 1.3 1997/10/20 21:47:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; +"$Id: upf.c,v 1.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" @@ -232,6 +232,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) unsigned char buf [256]; struct iovec iov [2]; + if (!strcmp (interface -> name, "fallback")) + return send_fallback (interface, packet, raw, + len, from, to, hto); + /* Assemble the headers... */ assemble_hw_header (interface, buf, &bufp, hto); assemble_udp_ip_header (interface, buf, &bufp, from.s_addr, @@ -295,4 +299,20 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) memcpy (buf, &ibuf [bufix], length); return length; } + +int can_unicast_without_arp () +{ + return 1; +} + +void maybe_setup_fallback () +{ + struct interface_info *fbi; + fbi = setup_fallback (); + if (fbi) { + if_register_fallback (fbi); + add_protocol ("fallback", fallback_interface -> wfdesc, + fallback_discard, fallback_interface); + } +} #endif diff --git a/includes/cf/linux.h b/includes/cf/linux.h index 4386a7e2..13523b93 100644 --- a/includes/cf/linux.h +++ b/includes/cf/linux.h @@ -5,7 +5,7 @@ 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 @@ -48,6 +48,10 @@ typedef unsigned short u_int16_t; 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> @@ -63,7 +67,7 @@ extern int h_errno; #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 @@ -103,8 +107,14 @@ extern int h_errno; #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 diff --git a/includes/cf/sunos5-5.h b/includes/cf/sunos5-5.h index a5b7cd85..4edf5332 100644 --- a/includes/cf/sunos5-5.h +++ b/includes/cf/sunos5-5.h @@ -3,7 +3,7 @@ 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 @@ -119,10 +119,19 @@ extern int h_errno; /* 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 diff --git a/includes/cf/ultrix.h b/includes/cf/ultrix.h index 76662b28..c04ccce2 100644 --- a/includes/cf/ultrix.h +++ b/includes/cf/ultrix.h @@ -3,7 +3,8 @@ 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 @@ -71,6 +72,8 @@ extern int h_errno; #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 diff --git a/includes/dhcp.h b/includes/dhcp.h index 840c86d6..3508e0cc 100644 --- a/includes/dhcp.h +++ b/includes/dhcp.h @@ -3,7 +3,7 @@ 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 @@ -84,6 +84,7 @@ struct dhcp_packet { /* 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). */ diff --git a/includes/osdep.h b/includes/osdep.h index 4ea4cd86..68167915 100644 --- a/includes/osdep.h +++ b/includes/osdep.h @@ -51,6 +51,9 @@ !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) && \ @@ -59,6 +62,9 @@ # define USE_DEFAULT_NETWORK #endif +#if !defined (TIME_MAX) +# define TIME_MAX 2147483647 +#endif /* Porting:: @@ -141,6 +147,11 @@ # 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 @@ -165,7 +176,7 @@ 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 @@ -178,7 +189,7 @@ #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 @@ -190,7 +201,7 @@ #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 diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 3ffb959b..7bd7c279 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -3,7 +3,7 @@ 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 @@ -42,7 +42,7 @@ #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" @@ -99,10 +99,6 @@ enum { forward_and_append, /* Forward and append our own relay option. */ 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; @@ -112,6 +108,13 @@ struct server_list { 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; @@ -209,6 +212,14 @@ int main (argc, 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"); @@ -323,13 +334,11 @@ void relay (ip, packet, length, from_port, from, hfrom) /* If it's a bootreply, forward it to the client. */ if (packet -> op == BOOTREPLY) { -#ifdef USE_FALLBACK - if (!(packet -> flags & htons (BOOTP_BROADCAST))) { + if (!(packet -> flags & htons (BOOTP_BROADCAST)) && + can_unicast_without_arp ()) { to.sin_addr = packet -> yiaddr; to.sin_port = remote_port; - } else -#endif - { + } else { to.sin_addr.s_addr = htonl (INADDR_BROADCAST); to.sin_port = remote_port; } @@ -398,19 +407,11 @@ void relay (ip, packet, length, from_port, from, hfrom) /* Otherwise, it's a BOOTREQUEST, so forward it to all the servers. */ for (sp = servers; sp; sp = sp -> next) { - if ( -#ifdef USE_FALLBACK - send_fallback (&fallback_interface, - (struct packet *)0, - packet, length, ip -> primary_address, - &sp -> to, (struct hardware *)0) -#else - send_packet (interfaces, + if (send_packet ((fallback_interface + ? fallback_interface : interfaces), (struct packet *)0, packet, length, ip -> primary_address, - &sp -> to, (struct hardware *)0) -#endif - < 0) { + &sp -> to, (struct hardware *)0) < 0) { debug ("send_packet: %m"); ++client_packet_errors; } else { |