diff options
author | cvs2git <source@isc.org> | 1997-02-26 05:21:56 +0000 |
---|---|---|
committer | cvs2git <source@isc.org> | 1997-02-26 05:21:56 +0000 |
commit | 916b761fa5b6f5e10f0d958da3402a6b6ff16ec1 (patch) | |
tree | 45af485e573041a5be7411320dbc8dd7be5a0066 | |
parent | d13e8f28c07ad6d7f37215781119cc4164f9d42d (diff) | |
download | isc-dhcp-916b761fa5b6f5e10f0d958da3402a6b6ff16ec1.tar.gz |
This commit was manufactured by cvs2git to create tag 'DHCP_970225'.DHCP_970225
-rw-r--r-- | common/alloc.c | 247 | ||||
-rw-r--r-- | common/bpf.c | 384 | ||||
-rw-r--r-- | common/conflex.c | 521 | ||||
-rw-r--r-- | common/dispatch.c | 719 | ||||
-rw-r--r-- | common/errwarn.c | 261 | ||||
-rw-r--r-- | common/hash.c | 174 | ||||
-rw-r--r-- | common/inet.c | 154 | ||||
-rw-r--r-- | common/memory.c | 873 | ||||
-rw-r--r-- | common/nit.c | 345 | ||||
-rw-r--r-- | common/options.c | 545 | ||||
-rw-r--r-- | common/packet.c | 314 | ||||
-rw-r--r-- | common/print.c | 185 | ||||
-rw-r--r-- | common/raw.c | 130 | ||||
-rw-r--r-- | common/socket.c | 229 | ||||
-rw-r--r-- | common/tables.c | 690 | ||||
-rw-r--r-- | common/tree.c | 408 |
16 files changed, 0 insertions, 6179 deletions
diff --git a/common/alloc.c b/common/alloc.c deleted file mode 100644 index dcf4672d..00000000 --- a/common/alloc.c +++ /dev/null @@ -1,247 +0,0 @@ -/* alloc.c - - Memory allocation... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: alloc.c,v 1.9 1996/08/28 01:19:42 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -struct dhcp_packet *dhcp_free_list; -struct packet *packet_free_list; - -VOIDPTR dmalloc (size, name) - int size; - char *name; -{ - VOIDPTR foo = (VOIDPTR)malloc (size); - if (!foo) - warn ("No memory for %s.", name); - memset (foo, 0, size); - return foo; -} - -void dfree (ptr, name) - VOIDPTR ptr; - char *name; -{ - if (!ptr) { - warn ("dfree %s: free on null pointer.", name); - return; - } - free (ptr); -} - -struct packet *new_packet (name) - char *name; -{ - struct packet *rval; - rval = (struct packet *)dmalloc (sizeof (struct packet), name); - return rval; -} - -struct dhcp_packet *new_dhcp_packet (name) - char *name; -{ - struct dhcp_packet *rval; - rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet), - name); - return rval; -} - -struct tree *new_tree (name) - char *name; -{ - struct tree *rval = dmalloc (sizeof (struct tree), name); - return rval; -} - -struct tree_cache *new_tree_cache (name) - char *name; -{ - struct tree_cache *rval = dmalloc (sizeof (struct tree_cache), name); - return rval; -} - -struct hash_table *new_hash_table (count, name) - int count; - char *name; -{ - struct hash_table *rval = dmalloc (sizeof (struct hash_table) - - (DEFAULT_HASH_SIZE - * sizeof (struct hash_bucket *)) - + (count - * sizeof (struct hash_bucket *)), - name); - rval -> hash_count = count; - return rval; -} - -struct hash_bucket *new_hash_bucket (name) - char *name; -{ - struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), name); - return rval; -} - -struct lease *new_leases (n, name) - int n; - char *name; -{ - struct lease *rval = dmalloc (n * sizeof (struct lease), name); - return rval; -} - -struct lease *new_lease (name) - char *name; -{ - struct lease *rval = dmalloc (sizeof (struct lease), name); - return rval; -} - -struct subnet *new_subnet (name) - char *name; -{ - struct subnet *rval = dmalloc (sizeof (struct subnet), name); - return rval; -} - -struct class *new_class (name) - char *name; -{ - struct class *rval = dmalloc (sizeof (struct class), name); - return rval; -} - -struct shared_network *new_shared_network (name) - char *name; -{ - struct shared_network *rval = - dmalloc (sizeof (struct shared_network), name); - return rval; -} - -struct group *new_group (name) - char *name; -{ - struct group *rval = - dmalloc (sizeof (struct group), name); - return rval; -} - -void free_group (ptr, name) - struct group *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_shared_network (ptr, name) - struct shared_network *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_class (ptr, name) - struct class *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_subnet (ptr, name) - struct subnet *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_lease (ptr, name) - struct lease *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_hash_bucket (ptr, name) - struct hash_bucket *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_hash_table (ptr, name) - struct hash_table *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_tree_cache (ptr, name) - struct tree_cache *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_packet (ptr, name) - struct packet *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_dhcp_packet (ptr, name) - struct dhcp_packet *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} - -void free_tree (ptr, name) - struct tree *ptr; - char *name; -{ - dfree ((VOIDPTR)ptr, name); -} diff --git a/common/bpf.c b/common/bpf.c deleted file mode 100644 index d223a9f8..00000000 --- a/common/bpf.c +++ /dev/null @@ -1,384 +0,0 @@ -/* bpf.c - - BPF socket interface code, originally contributed by Archie Cobbs. */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: bpf.c,v 1.17 1997/02/26 05:20:52 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> - -#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" - -/* Reinitializes the specified interface after an address change. This - is not required for packet-filter APIs. */ - -#ifdef USE_BPF_SEND -void if_reinitialize_send (info) - struct interface_info *info; -{ -} -#endif - -#ifdef USE_BPF_RECEIVE -void if_reinitialize_receive (info) - struct interface_info *info; -{ -} -#endif - -/* Called by get_interface_list for each interface that's discovered. - Opens a packet filter for each interface and adds it to the select - mask. */ - -int if_register_bpf (info) - struct interface_info *info; -{ - int sock; - char filename[50]; - int b; - - /* Open a BPF device */ - for (b = 0; 1; b++) { -#ifndef NO_SNPRINTF - snprintf(filename, sizeof(filename), BPF_FORMAT, b); -#else - sprintf(filename, BPF_FORMAT, b); -#endif - sock = open (filename, O_RDWR, 0); - if (sock < 0) { - if (errno == EBUSY) { - continue; - } else { - error ("Can't find free bpf: %m"); - } - } else { - break; - } - } - - /* Set the BPF device to point at this interface. */ - if (ioctl (sock, BIOCSETIF, info -> ifp) < 0) - error ("Can't attach interface %s to bpf device %s: %m", - info -> name, filename); - - return sock; -} -#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */ - -#ifdef USE_BPF_SEND -void if_register_send (info) - struct interface_info *info; -{ - /* If we're using the bpf API for sending and receiving, - we don't need to register this interface twice. */ -#ifndef USE_BPF_RECEIVE - info -> wfdesc = if_register_bpf (info, interface); -#else - info -> wfdesc = info -> rfdesc; -#endif - note ("Sending on BPF/%s/%s/%s", - info -> name, - print_hw_addr (info -> hw_address.htype, - info -> hw_address.hlen, - info -> hw_address.haddr), - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} -#endif /* USE_BPF_SEND */ - -#ifdef USE_BPF_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 [] = { - /* 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), - - /* Make sure it's a UDP packet... */ - BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23), - BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), - - /* Make sure this isn't a fragment... */ - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), - BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), - - /* Get the IP header length... */ - BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14), - - /* Make sure it's to the right port... */ - BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16), - BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */ - - /* If we passed all the tests, ask for the whole packet. */ - BPF_STMT(BPF_RET+BPF_K, (u_int)-1), - - /* Otherwise, drop it. */ - BPF_STMT(BPF_RET+BPF_K, 0), -}; - -void if_register_receive (info) - struct interface_info *info; -{ - int flag = 1; - struct bpf_version v; - u_int32_t addr; - struct bpf_program p; - u_int32_t bits; - - /* Open a BPF device and hang it on this interface... */ - info -> rfdesc = if_register_bpf (info); - - /* Make sure the BPF version is in range... */ - if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0) - error ("Can't get BPF version: %m"); - - if (v.bv_major != BPF_MAJOR_VERSION || - v.bv_minor < BPF_MINOR_VERSION) - error ("Kernel BPF version out of range - recompile dhcpd!"); - - /* Set immediate mode so that reads return as soon as a packet - comes in, rather than waiting for the input buffer to fill with - packets. */ - if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0) - error ("Can't set immediate mode on bpf device: %m"); - -#ifdef NEED_OSF_PFILT_HACKS - /* Allow the copyall flag to be set... */ - if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0) - error ("Can't set ALLOWCOPYALL: %m"); - - /* Clear all the packet filter mode bits first... */ - bits = 0; - if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0) - error ("Can't clear pfilt bits: %m"); - - /* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */ - bits = ENBATCH | ENCOPYALL | ENBPFHDR; - if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0) - error ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m"); -#endif - /* Get the required BPF buffer length from the kernel. */ - if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0) - error ("Can't get bpf buffer length: %m"); - info -> rbuf = malloc (info -> rbuf_max); - if (!info -> rbuf) - error ("Can't allocate %d bytes for bpf input buffer."); - info -> rbuf_offset = 0; - info -> rbuf_len = 0; - - /* Set up the bpf filter program structure. */ - p.bf_len = sizeof filter / sizeof (struct bpf_insn); - p.bf_insns = 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); - - if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0) - error ("Can't install packet filter program: %m"); - note ("Listening on BPF/%s/%s/%s", - info -> name, - print_hw_addr (info -> hw_address.htype, - info -> hw_address.hlen, - info -> hw_address.haddr), - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} -#endif /* USE_BPF_RECEIVE */ - -#ifdef USE_BPF_SEND -size_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; - struct dhcp_packet *raw; - size_t len; - struct in_addr from; - struct sockaddr_in *to; - struct hardware *hto; -{ - int bufp = 0; - unsigned char buf [256]; - struct iovec iov [2]; - - /* Assemble the headers... */ - assemble_hw_header (interface, buf, &bufp, hto); - assemble_udp_ip_header (interface, buf, &bufp, from.s_addr, - to -> sin_addr.s_addr, to -> sin_port, - (unsigned char *)raw, len); - - /* Fire it off */ - iov [0].iov_base = (char *)buf; - iov [0].iov_len = bufp; - iov [1].iov_base = (char *)raw; - iov [1].iov_len = len; - - return writev(interface -> wfdesc, iov, 2); -} -#endif /* USE_BPF_SEND */ - -#ifdef USE_BPF_RECEIVE -size_t receive_packet (interface, buf, len, from, hfrom) - struct interface_info *interface; - unsigned char *buf; - size_t len; - struct sockaddr_in *from; - struct hardware *hfrom; -{ - int length = 0; - int offset = 0; - struct bpf_hdr hdr; - - /* All this complexity is because BPF doesn't guarantee - that only one packet will be returned at a time. We're - getting what we deserve, though - this is a terrible abuse - of the BPF interface. Sigh. */ - - /* Process packets until we get one we can return or until we've - done a read and gotten nothing we can return... */ - - do { - /* If the buffer is empty, fill it. */ - if (interface -> rbuf_offset == interface -> rbuf_len) { - length = read (interface -> rfdesc, - interface -> rbuf, - interface -> rbuf_max); - if (length <= 0) - return length; - interface -> rbuf_offset = 0; - interface -> rbuf_len = length; - } - - /* If there isn't room for a whole bpf header, something went - wrong, but we'll ignore it and hope it goes away... XXX */ - if (interface -> rbuf_len - - interface -> rbuf_offset < sizeof hdr) { - interface -> rbuf_offset = interface -> rbuf_len; - continue; - } - - /* Copy out a bpf header... */ - memcpy (&hdr, &interface -> rbuf [interface -> rbuf_offset], - sizeof hdr); - - /* If the bpf header plus data doesn't fit in what's left - of the buffer, stick head in sand yet again... */ - if (interface -> rbuf_offset + - hdr.bh_hdrlen + hdr.bh_caplen > interface -> rbuf_len) { - interface -> rbuf_offset = interface -> rbuf_len; - continue; - } - - /* If the captured data wasn't the whole packet, or if - the packet won't fit in the input buffer, all we - can do is drop it. */ - if (hdr.bh_caplen != hdr.bh_datalen) { - interface -> rbuf_offset += - hdr.bh_hdrlen = hdr.bh_caplen; - continue; - } - - /* Skip over the BPF header... */ - interface -> rbuf_offset += hdr.bh_hdrlen; - - /* Decode the physical header... */ - offset = decode_hw_header (interface, - interface -> rbuf, - interface -> rbuf_offset, - hfrom); - - /* If a physical layer checksum failed (dunno of any - physical layer that supports this, but WTH), skip this - packet. */ - if (offset < 0) { - interface -> rbuf_offset += hdr.bh_caplen; - continue; - } - interface -> rbuf_offset += offset; - hdr.bh_caplen -= offset; - - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header (interface, - interface -> rbuf, - interface -> rbuf_offset, - from, - (unsigned char *)0, - hdr.bh_caplen); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) { - interface -> rbuf_offset += hdr.bh_caplen; - continue; - } - interface -> rbuf_offset += offset; - hdr.bh_caplen -= offset; - - /* If there's not enough room to stash the packet data, - we have to skip it (this shouldn't happen in real - life, though). */ - if (hdr.bh_caplen > len) { - interface -> rbuf_offset += hdr.bh_caplen; - continue; - } - - /* Copy out the data in the packet... */ - memcpy (buf, interface -> rbuf + interface -> rbuf_offset, - hdr.bh_caplen); - interface -> rbuf_offset += hdr.bh_caplen; - return hdr.bh_caplen; - } while (!length); - return 0; -} -#endif diff --git a/common/conflex.c b/common/conflex.c deleted file mode 100644 index a13f2660..00000000 --- a/common/conflex.c +++ /dev/null @@ -1,521 +0,0 @@ -/* conflex.c - - Lexical scanner for dhcpd config file... */ - -/* - * Copyright (c) 1995, 1996, 1997 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: conflex.c,v 1.22 1997/02/22 12:23:40 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" -#include "dhctoken.h" -#include <ctype.h> - -int lexline; -int lexchar; -char *token_line; -char *prev_line; -char *cur_line; -char *tlname; - -static char line1 [81]; -static char line2 [81]; -static int lpos; -static int line; -static int tlpos; -static int tline; -static int token; -static int ugflag; -static char *tval; -static char tokbuf [1500]; - -#ifdef OLD_LEXER -char comments [4096]; -int comment_index; -#endif - - -static int get_char PROTO ((FILE *)); -static int get_token PROTO ((FILE *)); -static void skip_to_eol PROTO ((FILE *)); -static int read_string PROTO ((FILE *)); -static int read_number PROTO ((int, FILE *)); -static int read_num_or_name PROTO ((int, FILE *)); -static int intern PROTO ((char *, int)); - -void new_parse (name) - char *name; -{ - tlname = name; - lpos = line = 1; - cur_line = line1; - prev_line = line2; - token_line = cur_line; - cur_line [0] = prev_line [0] = 0; - warnings_occurred = 0; -} - -static int get_char (cfile) - FILE *cfile; -{ - int c = getc (cfile); - if (!ugflag) { - if (c == EOL) { - if (cur_line == line1) { - cur_line = line2; - prev_line = line1; - } else { - cur_line = line2; - prev_line = line1; - } - line++; - lpos = 1; - cur_line [0] = 0; - } else if (c != EOF) { - if (lpos <= 81) { - cur_line [lpos - 1] = c; - cur_line [lpos] = 0; - } - lpos++; - } - } else - ugflag = 0; - return c; -} - -static int get_token (cfile) - FILE *cfile; -{ - int c; - int ttok; - static char tb [2]; - int l, p, u; - - do { - l = line; - p = lpos; - u = ugflag; - - c = get_char (cfile); -#ifdef OLD_LEXER - if (c == '\n' && p == 1 && !u - && comment_index < sizeof comments) - comments [comment_index++] = '\n'; -#endif - - if (isascii (c) && isspace (c)) - continue; - if (c == '#') { -#ifdef OLD_LEXER - if (comment_index < sizeof comments) - comments [comment_index++] = '#'; -#endif - skip_to_eol (cfile); - continue; - } - if (c == '"') { - lexline = l; - lexchar = p; - ttok = read_string (cfile); - break; - } - if ((isascii (c) && isdigit (c)) || c == '-') { - lexline = l; - lexchar = p; - ttok = read_number (c, cfile); - break; - } else if (isascii (c) && isalpha (c)) { - lexline = l; - lexchar = p; - ttok = read_num_or_name (c, cfile); - break; - } else { - lexline = l; - lexchar = p; - tb [0] = c; - tb [1] = 0; - tval = tb; - ttok = c; - break; - } - } while (1); - return ttok; -} - -int next_token (rval, cfile) - char **rval; - FILE *cfile; -{ - int rv; - - if (token) { - if (lexline != tline) - token_line = cur_line; - lexchar = tlpos; - lexline = tline; - rv = token; - token = 0; - } else { - rv = get_token (cfile); - token_line = cur_line; - } - if (rval) - *rval = tval; -#ifdef DEBUG_TOKENS - fprintf (stderr, "%s:%d ", tval, rv); -#endif - return rv; -} - -int peek_token (rval, cfile) - char **rval; - FILE *cfile; -{ - int x; - - if (!token) { - tlpos = lexchar; - tline = lexline; - token = get_token (cfile); - if (lexline != tline) - token_line = prev_line; - x = lexchar; lexchar = tlpos; tlpos = x; - x = lexline; lexline = tline; tline = x; - } - if (rval) - *rval = tval; -#ifdef DEBUG_TOKENS - fprintf (stderr, "(%s:%d) ", tval, token); -#endif - return token; -} - -static void skip_to_eol (cfile) - FILE *cfile; -{ - int c; - do { - c = get_char (cfile); - if (c == EOF) - return; -#ifdef OLD_LEXER - if (comment_index < sizeof (comments)) - comments [comment_index++] = c; -#endif - if (c == EOL) { - return; - } - } while (1); -} - -static int read_string (cfile) - FILE *cfile; -{ - int i; - int bs = 0; - int c; - - for (i = 0; i < sizeof tokbuf; i++) { - c = get_char (cfile); - if (c == EOF) { - parse_warn ("eof in string constant"); - break; - } - if (bs) { - bs = 0; - tokbuf [i] = c; - } else if (c == '\\') - bs = 1; - else if (c == '"') - break; - else - tokbuf [i] = c; - } - /* Normally, I'd feel guilty about this, but we're talking about - strings that'll fit in a DHCP packet here... */ - if (i == sizeof tokbuf) { - parse_warn ("string constant larger than internal buffer"); - --i; - } - tokbuf [i] = 0; - tval = tokbuf; - return STRING; -} - -static int read_number (c, cfile) - int c; - FILE *cfile; -{ - int seenx = 0; - int i = 0; - int token = NUMBER; - - tokbuf [i++] = c; - for (; i < sizeof tokbuf; i++) { - c = get_char (cfile); - if (!seenx && c == 'x') { - seenx = 1; -#ifndef OLD_LEXER - } else if (isascii (c) && !isxdigit (c) && - (c == '-' || c == '_' || isalpha (c))) { - token = NAME; - } else if (isascii (c) && !isdigit (c) && isxdigit (c)) { - token = NUMBER_OR_NAME; -#endif - } else if (!isascii (c) || !isxdigit (c)) { - ungetc (c, cfile); - ugflag = 1; - break; - } - tokbuf [i] = c; - } - if (i == sizeof tokbuf) { - parse_warn ("numeric token larger than internal buffer"); - --i; - } - tokbuf [i] = 0; - tval = tokbuf; - return token; -} - -static int read_num_or_name (c, cfile) - int c; - FILE *cfile; -{ - int i = 0; - int rv = NUMBER_OR_NAME; - tokbuf [i++] = c; - for (; i < sizeof tokbuf; i++) { - c = get_char (cfile); - if (!isascii (c) || - (c != '-' && c != '_' && !isalnum (c))) { - ungetc (c, cfile); - ugflag = 1; - break; - } - if (!isxdigit (c)) - rv = NAME; - tokbuf [i] = c; - } - if (i == sizeof tokbuf) { - parse_warn ("token larger than internal buffer"); - --i; - } - tokbuf [i] = 0; - tval = tokbuf; - return intern (tval, rv); -} - -static int intern (atom, dfv) - char *atom; - int dfv; -{ - if (!isascii (atom [0])) - return dfv; - - switch (tolower (atom [0])) { - case 'a': - if (!strcasecmp (atom + 1, "llow")) - return ALLOW; - if (!strcasecmp (atom + 1, "lias")) - return ALIAS; - break; - case 'b': - if (!strcasecmp (atom + 1, "ootp")) - return BOOTP; - if (!strcasecmp (atom + 1, "ooting")) - return BOOTING; - if (!strcasecmp (atom + 1, "oot-unknown-clients")) - return BOOT_UNKNOWN_CLIENTS; - case 'c': - if (!strcasecmp (atom + 1, "lass")) - return CLASS; - if (!strcasecmp (atom + 1, "iaddr")) - return CIADDR; - if (!strcasecmp (atom + 1, "lient-identifier")) - return CLIENT_IDENTIFIER; - break; - case 'd': - if (!strcasecmp (atom + 1, "eny")) - return DENY; - if (!strncasecmp (atom + 1, "efault", 6)) { - if (!atom [7]) - return DEFAULT; - if (!strcasecmp (atom + 7, "-lease-time")) - return DEFAULT_LEASE_TIME; - break; - } - if (!strncasecmp (atom + 1, "ynamic-bootp", 12)) { - if (!atom [13]) - return DYNAMIC_BOOTP; - if (!strcasecmp (atom + 13, "-lease-cutoff")) - return DYNAMIC_BOOTP_LEASE_CUTOFF; - if (!strcasecmp (atom + 13, "-lease-length")) - return DYNAMIC_BOOTP_LEASE_LENGTH; - break; - } - break; - case 'e': - if (!strcasecmp (atom + 1, "thernet")) - return ETHERNET; - if (!strcasecmp (atom + 1, "nds")) - return ENDS; - if (!strcasecmp (atom + 1, "xpire")) - return EXPIRE; - break; - case 'f': - if (!strcasecmp (atom + 1, "ilename")) - return FILENAME; - if (!strcasecmp (atom + 1, "ixed-address")) - return FIXED_ADDR; - break; - case 'g': - if (!strcasecmp (atom + 1, "iaddr")) - return GIADDR; - if (!strcasecmp (atom + 1, "roup")) - return GROUP; - if (!strcasecmp (atom + 1, "et-lease-hostnames")) - return GET_LEASE_HOSTNAMES; - break; - case 'h': - if (!strcasecmp (atom + 1, "ost")) - return HOST; - if (!strcasecmp (atom + 1, "ardware")) - return HARDWARE; - break; - case 'i': - if (!strcasecmp (atom + 1, "nterface")) - return INTERFACE; - break; - case 'l': - if (!strcasecmp (atom + 1, "ease")) - return LEASE; - break; - case 'm': - if (!strcasecmp (atom + 1, "ax-lease-time")) - return MAX_LEASE_TIME; - if (!strncasecmp (atom + 1, "edi", 3)) { - if (!strcasecmp (atom + 4, "a")) - return MEDIA; - if (!strcasecmp (atom + 4, "um")) - return MEDIUM; - break; - } - break; - case 'n': - if (!strcasecmp (atom + 1, "etmask")) - return NETMASK; - if (!strcasecmp (atom + 1, "ext-server")) - return NEXT_SERVER; - break; - case 'o': - if (!strcasecmp (atom + 1, "ption")) - return OPTION; - if (!strcasecmp (atom + 1, "ne-lease-per-client")) - return ONE_LEASE_PER_CLIENT; - break; - case 'p': - if (!strcasecmp (atom + 1, "acket")) - return PACKET; - break; - case 'r': - if (!strcasecmp (atom + 1, "ange")) - return RANGE; - if (!strcasecmp (atom + 1, "equest")) - return REQUEST; - if (!strcasecmp (atom + 1, "equire")) - return REQUIRE; - if (!strcasecmp (atom + 1, "etry")) - return RETRY; - if (!strcasecmp (atom + 1, "enew")) - return RENEW; - if (!strcasecmp (atom + 1, "ebind")) - return REBIND; - break; - case 's': - if (!strcasecmp (atom + 1, "tarts")) - return STARTS; - if (!strcasecmp (atom + 1, "iaddr")) - return SIADDR; - if (!strcasecmp (atom + 1, "ubnet")) - return SUBNET; - if (!strcasecmp (atom + 1, "hared-network")) - return SHARED_NETWORK; - if (!strcasecmp (atom + 1, "erver-name")) - return SERVER_NAME; - if (!strcasecmp (atom + 1, "erver-identifier")) - return SERVER_IDENTIFIER; - if (!strcasecmp (atom + 1, "elect-timeout")) - return SELECT_TIMEOUT; - if (!strcasecmp (atom + 1, "end")) - return SEND; - if (!strcasecmp (atom + 1, "cript")) - return SCRIPT; - break; - case 't': - if (!strcasecmp (atom + 1, "imestamp")) - return TIMESTAMP; - if (!strcasecmp (atom + 1, "imeout")) - return TIMEOUT; - if (!strcasecmp (atom + 1, "oken-ring")) - return TOKEN_RING; - break; - case 'u': - if (!strcasecmp (atom + 1, "id")) - return UID; - if (!strcasecmp (atom + 1, "ser-class")) - return USER_CLASS; - if (!strcasecmp (atom + 1, "se-host-decl-names")) - return USE_HOST_DECL_NAMES; - if (!strcasecmp (atom + 1, "nknown-clients")) - return UNKNOWN_CLIENTS; - break; - case 'v': - if (!strcasecmp (atom + 1, "endor-class")) - return VENDOR_CLASS; - break; - case 'y': - if (!strcasecmp (atom + 1, "iaddr")) - return YIADDR; - break; - } - return dfv; -} diff --git a/common/dispatch.c b/common/dispatch.c deleted file mode 100644 index 5f602750..00000000 --- a/common/dispatch.c +++ /dev/null @@ -1,719 +0,0 @@ -/* dispatch.c - - Network input dispatcher... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: dispatch.c,v 1.33 1997/02/22 12:26:41 mellon Exp $ Copyright (c) 1995, 1996 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 timeout *timeouts; -static struct timeout *free_timeouts; -static int interfaces_invalidated; - -static void got_one PROTO ((struct interface_info *, int)); - -/* 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 - subnet it's on, and add it to the list of interfaces. */ - -void discover_interfaces (state) - int state; -{ - struct interface_info *tmp; - struct interface_info *last; - char buf [8192]; - struct ifconf ic; - struct ifreq ifr; - int i; - int sock; - int address_count = 0; - struct subnet *subnet; - struct shared_network *share; - struct sockaddr_in foo; - int ir; -#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) - error ("Can't create addrlist socket"); - - /* Get the interface configuration information... */ - ic.ifc_len = sizeof buf; - ic.ifc_ifcu.ifcu_buf = (caddr_t)buf; - i = ioctl(sock, SIOCGIFCONF, &ic); - - if (i < 0) - error ("ioctl: SIOCGIFCONF: %m"); - - /* If we already have a list of interfaces, and we're running as - a DHCP server, the interfaces were requested. */ - if (interfaces && - (state == DISCOVER_SERVER || state == DISCOVER_RELAY)) - ir = 0; - else - ir = INTERFACE_REQUESTED; - - /* Cycle through the list of interfaces looking for IP addresses. - Go through twice; once to count the number if addresses, and a - second time to copy them into an array of addresses. */ - for (i = 0; i < ic.ifc_len;) { - struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i); -#ifdef HAVE_SA_LEN - i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len; -#else - i += sizeof *ifp; -#endif - -#ifdef ALIAS_NAMES_PERMUTED - if ((s = strrchr (ifp -> ifr_name, ':'))) { - *s = 0; - } -#endif - - - /* See if this is the sort of interface we want to - deal with. */ - strcpy (ifr.ifr_name, ifp -> ifr_name); - if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0) - error ("Can't get interface flags for %s: %m", - ifr.ifr_name); - - /* Skip loopback, point-to-point and down interfaces, - except don't skip down interfaces if we're trying to - get a list of configurable interfaces. */ - if ((ifr.ifr_flags & IFF_LOOPBACK) || - (ifr.ifr_flags & IFF_POINTOPOINT) || - (!(ifr.ifr_flags & IFF_UP) && - state != DISCOVER_UNCONFIGURED)) - continue; - - /* See if we've seen an interface that matches this one. */ - for (tmp = interfaces; tmp; tmp = tmp -> next) - if (!strcmp (tmp -> name, ifp -> ifr_name)) - break; - - /* If there isn't already an interface by this name, - allocate one. */ - if (!tmp) { - tmp = ((struct interface_info *) - dmalloc (sizeof *tmp, "get_interface_list")); - if (!tmp) - error ("Insufficient memory to %s %s", - "record interface", ifp -> ifr_name); - strcpy (tmp -> name, ifp -> ifr_name); - tmp -> next = interfaces; - tmp -> flags = ir; - interfaces = tmp; - } - - /* If we have the capability, extract link information - and record it in a linked list. */ -#ifdef AF_LINK - if (ifp -> ifr_addr.sa_family == AF_LINK) { - struct sockaddr_dl *foo = ((struct sockaddr_dl *) - (&ifp -> ifr_addr)); - tmp -> hw_address.hlen = foo -> sdl_alen; - tmp -> hw_address.htype = HTYPE_ETHER; /* XXX */ - memcpy (tmp -> hw_address.haddr, - LLADDR (foo), foo -> sdl_alen); - } else -#endif /* AF_LINK */ - - if (ifp -> ifr_addr.sa_family == AF_INET) { - struct iaddr addr; - -#if defined (SIOCGIFHWADDR) && !defined (AF_LINK) - struct ifreq ifr; - struct sockaddr sa; - int b, sk; - - /* Read the hardware address from this interface. */ - ifr = *ifp; - if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0) - error ("Can't get hardware address for %s: %m", - ifr.ifr_name); - - sa = *(struct sockaddr *)&ifr.ifr_hwaddr; - - switch (sa.sa_family) { - case ARPHRD_LOOPBACK: - /* ignore loopback interface */ - break; - - case ARPHRD_ETHER: - tmp -> hw_address.hlen = 6; - tmp -> hw_address.htype = ARPHRD_ETHER; - memcpy (tmp -> hw_address.haddr, - sa.sa_data, 6); - break; - - case ARPHRD_METRICOM: - tmp -> hw_address.hlen = 6; - tmp -> hw_address.htype = ARPHRD_METRICOM; - memcpy (tmp -> hw_address.haddr, - sa.sa_data, 6); - break; - - default: - error ("%s: unknown hardware address type %d", - ifr.ifr_name, sa.sa_family); - } -#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */ - - /* Get a pointer to the address... */ - memcpy (&foo, &ifp -> ifr_addr, - sizeof ifp -> ifr_addr); - - /* We don't want the loopback interface. */ - if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK)) - continue; - - - /* If this is the first real IP address we've - 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); -#else - int len = sizeof *ifp; -#endif - tif = (struct ifreq *)malloc (len); - if (!tif) - error ("no space to remember ifp."); - memcpy (tif, ifp, len); - tmp -> ifp = ifp; - tmp -> primary_address = foo.sin_addr; - } - - /* Grab the address... */ - addr.len = 4; - memcpy (addr.iabuf, &foo.sin_addr.s_addr, - addr.len); - - /* If there's a registered subnet for this address, - connect it together... */ - if ((subnet = find_subnet (addr))) { - /* If this interface has multiple aliases - on the same subnet, ignore all but the - first we encounter. */ - if (!subnet -> interface) { - subnet -> interface = tmp; - subnet -> interface_address = addr; - } else if (subnet -> interface != tmp) { - warn ("Multiple %s %s: %s %s", - "interfaces match the", - "same subnet", - subnet -> interface -> name, - tmp -> name); - } - share = subnet -> shared_network; - if (tmp -> shared_network && - tmp -> shared_network != share) { - warn ("Interface %s matches %s", - tmp -> name, - "multiple shared networks"); - } else { - tmp -> shared_network = share; - } - - if (!share -> interface) { - share -> interface = tmp; - } else if (share -> interface != tmp) { - warn ("Multiple %s %s: %s %s", - "interfaces match the", - "same shared network", - share -> interface -> name, - tmp -> name); - } - } - } - } - - /* 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) - return; - - /* Weed out the interfaces that did not have IP addresses. */ - last = (struct interface_info *)0; - for (tmp = interfaces; tmp; tmp = tmp -> next) { - if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) { - if ((tmp -> flags & INTERFACE_REQUESTED) != ir) - error ("%s: not found", tmp -> name); - if (!last) - interfaces = interfaces -> next; - else - last -> next = tmp -> next; - - /* Remember the interface in case we need to know - about it later. */ - tmp -> next = dummy_interfaces; - dummy_interfaces = tmp; - continue; - } - last = tmp; - - memcpy (&foo, &tmp -> ifp -> ifr_addr, - sizeof tmp -> ifp -> ifr_addr); - - /* We must have a subnet declaration for each interface. */ - if (!tmp -> shared_network && (state == DISCOVER_SERVER)) - error ("No subnet declaration for %s (%s).", - tmp -> name, inet_ntoa (foo.sin_addr)); - - /* Find subnets that don't have valid interface - addresses... */ - for (subnet = (tmp -> shared_network - ? tmp -> shared_network -> subnets - : (struct subnet *)0); - subnet; subnet = subnet -> next_sibling) { - if (!subnet -> interface_address.len) { - /* Set the interface address for this subnet - to the first address we found. */ - subnet -> interface_address.len = 4; - memcpy (subnet -> interface_address.iabuf, - &foo.sin_addr.s_addr, 4); - } - } - - /* Register the interface... */ - if_register_receive (tmp); - if_register_send (tmp); - } - - 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); -#endif -} - -void reinitialize_interfaces () -{ - struct interface_info *ip; - - for (ip = interfaces; ip; ip = ip -> next) { - if_reinitialize_receive (ip); - if_reinitialize_send (ip); - } - -#ifdef USE_FALLBACK - if_reinitialize_fallback (&fallback_interface); -#endif - - interfaces_invalidated = 1; -} - -#ifdef USE_POLL -/* Wait for packets to come in using poll(). Anyway, when a packet - comes in, call receive_packet to receive the packet and possibly - strip hardware addressing information from it, and then call - do_packet to try to do something with it. - - As you can see by comparing this with the code that uses select(), - below, this is gratuitously complex. Quelle surprise, eh? This is - SysV we're talking about, after all, and even in the 90's, it - wouldn't do for SysV to make networking *easy*, would it? Rant, - rant... */ - -void dispatch (parse) - int parse; -{ - struct interface_info *l; - int nfds = 0; - struct pollfd *fds; - int count; - int i; - int to_msec; - - nfds = 0; - for (l = interfaces; l; l = l -> next) { - ++nfds; - } -#ifdef USE_FALLBACK - ++nfds; -#endif - fds = (struct pollfd *)malloc ((nfds) * sizeof (struct pollfd)); - if (!fds) - error ("Can't allocate poll structures."); - - do { - /* Call any expired timeouts, and then if there's - still a timeout registered, time out the select - call then. */ - another: - if (timeouts) { - struct timeout *t; - if (timeouts -> when <= cur_time) { - t = timeouts; - timeouts = timeouts -> next; - (*(t -> func)) (t -> interface); - t -> next = free_timeouts; - free_timeouts = t; - goto another; - } - /* Figure timeout in milliseconds, and check for - potential overflow. We assume that integers - are 32 bits, which is harmless if they're 64 - bits - we'll just get extra timeouts in that - case. Lease times would have to be quite - long in order for a 32-bit integer to overflow, - anyway. */ - to_msec = timeouts -> when - cur_time; - if (to_msec > 2147483) - to_msec = 2147483; - to_msec *= 1000; - } else - to_msec = -1; - - /* Set up the descriptors to be polled. */ - i = 0; - for (l = interfaces; l; l = l -> next) { - fds [i].fd = l -> rfdesc; - fds [i].events = POLLIN; - fds [i].revents = 0; - ++i; - } - -#ifdef USE_FALLBACK - fds [i].fd = fallback_interface.wfdesc; - fds [i].events = POLLIN; - fds [i].revents = 0; - ++i; -#endif - - /* Wait for a packet or a timeout... XXX */ - count = poll (fds, nfds, to_msec); - - /* Get the current time... */ - GET_TIME (&cur_time); - - /* Not likely to be transitory... */ - if (count < 0) - error ("poll: %m"); - - i = 0; - for (l = interfaces; l; l = l -> next) { - if ((fds [i].revents & POLLIN)) { - fds [i].revents = 0; - got_one (l, parse); - if (interfaces_invalidated) - break; - } - ++i; - } -#ifdef USE_FALLBACK - if ((fds [i].revents & POLLIN) && !interfaces_invalidated) - fallback_discard (&fallback_interface); -#endif - interfaces_invalidated = 0; - } while (1); -} -#else -/* Wait for packets to come in using select(). When one does, call - receive_packet to receive the packet and possibly strip hardware - addressing information from it, and then call do_packet to try to - do something with it. */ - -void dispatch (parse) - int parse; -{ - fd_set r, w, x; - struct interface_info *l; - int max = 0; - int count; - struct timeval tv, *tvp; - - FD_ZERO (&w); - FD_ZERO (&x); - - do { - /* Call any expired timeouts, and then if there's - still a timeout registered, time out the select - call then. */ - another: - if (timeouts) { - struct timeout *t; - if (timeouts -> when <= cur_time) { - t = timeouts; - timeouts = timeouts -> next; - (*(t -> func)) (t -> interface); - t -> next = free_timeouts; - free_timeouts = t; - goto another; - } - tv.tv_sec = timeouts -> when - cur_time; - tv.tv_usec = 0; - tvp = &tv; - } else - tvp = (struct timeval *)0; - - /* Set up the read mask. */ - FD_ZERO (&r); - - for (l = interfaces; l; l = l -> next) { - FD_SET (l -> rfdesc, &r); - FD_SET (l -> rfdesc, &x); - if (l -> rfdesc > max) - max = l -> rfdesc; - } -#ifdef USE_FALLBACK - FD_SET (fallback_interface.wfdesc, &r); - if (fallback_interface.wfdesc > max) - max = fallback_interface.wfdesc; -#endif - - /* Wait for a packet or a timeout... XXX */ - count = select (max + 1, &r, &w, &x, tvp); - - /* Get the current time... */ - GET_TIME (&cur_time); - - /* Not likely to be transitory... */ - if (count < 0) - error ("select: %m"); - - for (l = interfaces; l; l = l -> next) { - if (!FD_ISSET (l -> rfdesc, &r)) - continue; - got_one (l, parse); - if (interfaces_invalidated) - break; - } -#ifdef USE_FALLBACK - if (FD_ISSET (fallback_interface.wfdesc, &r) && - !interfaces_invalidated) - fallback_discard (&fallback_interface); -#endif - interfaces_invalidated = 1; - } while (1); -} -#endif /* USE_POLL */ - -static void got_one (l, parse) - struct interface_info *l; - int parse; -{ - struct sockaddr_in from; - struct hardware hfrom; - struct iaddr ifrom; - int result; - static unsigned char packbuf [4095]; /* Packet input buffer. - Must be as large as largest - possible MTU. */ - - if ((result = receive_packet (l, packbuf, sizeof packbuf, - &from, &hfrom)) < 0) { - warn ("receive_packet failed on %s: %m", l -> name); - return; - } - if (result == 0) - return; - - if (parse) { - ifrom.len = 4; - memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len); - - do_packet (l, packbuf, result, - from.sin_port, ifrom, &hfrom); - } else - relay (l, (struct dhcp_packet *)packbuf, result); -} - -void do_packet (interface, packbuf, len, from_port, from, hfrom) - struct interface_info *interface; - unsigned char *packbuf; - int len; - unsigned short from_port; - struct iaddr from; - struct hardware *hfrom; -{ - struct packet tp; - struct dhcp_packet tdp; - - memcpy (&tdp, packbuf, len); - memset (&tp, 0, sizeof tp); - tp.raw = &tdp; - tp.packet_length = len; - tp.client_port = from_port; - tp.client_addr = from; - tp.interface = interface; - tp.haddr = hfrom; - - parse_options (&tp); - if (tp.options_valid && - tp.options [DHO_DHCP_MESSAGE_TYPE].data) - tp.packet_type = - tp.options [DHO_DHCP_MESSAGE_TYPE].data [0]; - if (tp.packet_type) - dhcp (&tp); - else if (tdp.op == BOOTREQUEST) - bootp (&tp); -} - -int locate_network (packet) - struct packet *packet; -{ - struct iaddr ia; - - /* If this came through a gateway, find the corresponding subnet... */ - if (packet -> raw -> giaddr.s_addr) { - struct subnet *subnet; - ia.len = 4; - memcpy (ia.iabuf, &packet -> raw -> giaddr, 4); - subnet = find_subnet (ia); - if (subnet) - packet -> shared_network = subnet -> shared_network; - else - packet -> shared_network = (struct shared_network *)0; - } else { - packet -> shared_network = - packet -> interface -> shared_network; - } - if (packet -> shared_network) - return 1; - return 0; -} - -void add_timeout (when, where, what) - TIME when; - void (*where) (struct interface_info *); - struct interface_info *what; -{ - struct timeout *t, *q; - - /* See if this timeout supersedes an existing timeout. */ - t = (struct timeout *)0; - for (q = timeouts; q; q = q -> next) { - if (q -> func == where && q -> interface == what) { - if (t) - t -> next = q -> next; - else - timeouts = q -> next; - break; - } - t = q; - } - - /* If we didn't supersede a timeout, allocate a timeout - structure now. */ - if (!q) { - if (free_timeouts) { - q = free_timeouts; - free_timeouts = q -> next; - q -> func = where; - q -> interface = what; - } else { - q = (struct timeout *)malloc (sizeof (struct timeout)); - if (!q) - error ("Can't allocate timeout structure!"); - q -> func = where; - q -> interface = what; - } - } - - q -> when = when; - - /* Now sort this timeout into the timeout list. */ - - /* Beginning of list? */ - if (!timeouts || timeouts -> when > q -> when) { - q -> next = timeouts; - timeouts = q; - return; - } - - /* Middle of list? */ - for (t = timeouts; t -> next; t = t -> next) { - if (t -> next -> when > q -> when) { - q -> next = t -> next; - t -> next = q; - return; - } - } - - /* End of list. */ - t -> next = q; - q -> next = (struct timeout *)0; -} - -void cancel_timeout (where, what) - void (*where) (struct interface_info *); - struct interface_info *what; -{ - struct timeout *t, *q; - - /* Look for this timeout on the list, and unlink it if we find it. */ - t = (struct timeout *)0; - for (q = timeouts; q; q = q -> next) { - if (q -> func == where && q -> interface == what) { - if (t) - t -> next = q -> next; - else - timeouts = q -> next; - break; - } - t = q; - } - - /* If we found the timeout, put it on the free list. */ - if (q) { - q -> next = free_timeouts; - free_timeouts = q; - } -} diff --git a/common/errwarn.c b/common/errwarn.c deleted file mode 100644 index 34e0d81e..00000000 --- a/common/errwarn.c +++ /dev/null @@ -1,261 +0,0 @@ -/* errwarn.c - - Errors and warnings... */ - -/* - * Copyright (c) 1996 The Internet Software Consortium. - * All Rights Reserved. - * Copyright (c) 1995 RadioMail Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of RadioMail Corporation, the Internet Software - * Consortium nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION, 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 RADIOMAIL CORPORATION 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 was written for RadioMail Corporation by Ted Lemon - * under a contract with Vixie Enterprises. Further modifications have - * been made for the Internet Software Consortium under a contract - * with Vixie Laboratories. - */ - -#ifndef lint -static char copyright[] = -"$Id: errwarn.c,v 1.14 1997/02/22 12:26:12 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" -#include <errno.h> - -static void do_percentm PROTO ((char *obuf, char *ibuf)); - -static char mbuf [1024]; -static char fbuf [1024]; - -int warnings_occurred; - -/* Log an error message, then exit... */ - -void error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT) - KandR (char *fmt;) - va_dcl -{ - va_list list; - extern int logged_in; - - do_percentm (fbuf, fmt); - - VA_start (list, fmt); - vsnprintf (mbuf, sizeof mbuf, fbuf, list); - va_end (list); - -#ifndef DEBUG - syslog (log_priority | LOG_ERR, mbuf); -#endif - - /* Also log it to stderr? */ - if (log_perror) { - write (2, mbuf, strlen (mbuf)); - write (2, "\n", 1); - } - - syslog (LOG_CRIT, "exiting."); - if (log_perror) { - fprintf (stderr, "exiting.\n"); - fflush (stderr); - } - cleanup (); - exit (1); -} - -/* Log a warning message... */ - -int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT) - KandR (char *fmt;) - va_dcl -{ - va_list list; - - do_percentm (fbuf, fmt); - - VA_start (list, fmt); - vsnprintf (mbuf, sizeof mbuf, fbuf, list); - va_end (list); - -#ifndef DEBUG - syslog (log_priority | LOG_ERR, mbuf); -#endif - - if (log_perror) { - write (2, mbuf, strlen (mbuf)); - write (2, "\n", 1); - } - - return 0; -} - -/* Log a note... */ - -int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT) - KandR (char *fmt;) - va_dcl -{ - va_list list; - - do_percentm (fbuf, fmt); - - VA_start (list, fmt); - vsnprintf (mbuf, sizeof mbuf, fbuf, list); - va_end (list); - -#ifndef DEBUG - syslog (log_priority | LOG_INFO, mbuf); -#endif - - if (log_perror) { - write (2, mbuf, strlen (mbuf)); - write (2, "\n", 1); - } - - return 0; -} - -/* Log a debug message... */ - -int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT) - KandR (char *fmt;) - va_dcl -{ - va_list list; - - do_percentm (fbuf, fmt); - - VA_start (list, fmt); - vsnprintf (mbuf, sizeof mbuf, fbuf, list); - va_end (list); - -#ifndef DEBUG - syslog (log_priority | LOG_DEBUG, mbuf); -#endif - - if (log_perror) { - write (2, mbuf, strlen (mbuf)); - write (2, "\n", 1); - } - - return 0; -} - -/* Find %m in the input string and substitute an error message string. */ - -static void do_percentm (obuf, ibuf) - char *obuf; - char *ibuf; -{ - char *s = ibuf; - char *p = obuf; - int infmt = 0; - - while (*s) - { - if (infmt) - { - if (*s == 'm') - { - strcpy (p - 1, strerror (errno)); - p += strlen (p); - ++s; - } - else - *p++ = *s++; - infmt = 0; - } - else - { - if (*s == '%') - infmt = 1; - *p++ = *s++; - } - } - *p = 0; -} - - -int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT) - KandR (char *fmt;) - va_dcl -{ - va_list list; - static char spaces [] = " "; - - do_percentm (mbuf, fmt); -#ifndef NO_SNPRINTF - snprintf (fbuf, sizeof fbuf, "%s line %d: %s", - tlname, lexline, mbuf); -#else - sprintf (fbuf, "%s line %d: %s", - tlname, lexline, mbuf); -#endif - - VA_start (list, fmt); - vsnprintf (mbuf, sizeof mbuf, fbuf, list); - va_end (list); - -#ifndef DEBUG - syslog (log_priority | LOG_ERR, mbuf); - syslog (log_priority | LOG_ERR, token_line); - if (lexline < 81) - syslog (log_priority | LOG_ERR, - "%s^", &spaces [sizeof spaces - lexchar]); -#endif - - if (log_perror) { - write (2, mbuf, strlen (mbuf)); - write (2, "\n", 1); - write (2, token_line, strlen (token_line)); - write (2, "\n", 1); - write (2, spaces, lexchar - 1); - write (2, "^\n", 2); - } - - warnings_occurred = 1; - - return 0; -} - -#ifdef NO_STRERROR -char *strerror (err) - int err; -{ - extern char *sys_errlist []; - extern int sys_nerr; - static char errbuf [128]; - - if (err < 0 || err >= sys_nerr) { - sprintf (errbuf, "Error %d", err); - return errbuf; - } - return sys_errlist [err]; -} -#endif /* NO_STRERROR */ diff --git a/common/hash.c b/common/hash.c deleted file mode 100644 index e8e93752..00000000 --- a/common/hash.c +++ /dev/null @@ -1,174 +0,0 @@ -/* hash.c - - Routines for manipulating hash tables... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: hash.c,v 1.9 1996/09/09 07:04:45 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -static INLINE int do_hash PROTO ((char *, int, int)); - -struct hash_table *new_hash () -{ - struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, "new_hash"); - if (!rv) - return rv; - memset (&rv -> buckets [0], 0, - DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *)); - return rv; -} - -static INLINE int do_hash (name, len, size) - char *name; - int len; - int size; -{ - register int accum = 0; - register unsigned char *s = (unsigned char *)name; - int i = len; - if (i) { - while (i--) { - /* Add the character in... */ - accum += *s++; - /* Add carry back in... */ - while (accum > 255) { - accum = (accum & 255) + (accum >> 8); - } - } - } else { - while (*s) { - /* Add the character in... */ - accum += *s++; - /* Add carry back in... */ - while (accum > 255) { - accum = (accum & 255) + (accum >> 8); - } - } - } - return accum % size; -} - -void add_hash (table, name, len, pointer) - struct hash_table *table; - int len; - char *name; - unsigned char *pointer; -{ - int hashno; - struct hash_bucket *bp; - - if (!table) - return; - - hashno = do_hash (name, len, table -> hash_count); - bp = new_hash_bucket ("add_hash"); - - if (!bp) { - warn ("Can't add %s to hash table.", name); - return; - } - bp -> name = name; - bp -> value = pointer; - bp -> next = table -> buckets [hashno]; - bp -> len = len; - table -> buckets [hashno] = bp; -} - -void delete_hash_entry (table, name, len) - struct hash_table *table; - int len; - char *name; -{ - int hashno; - struct hash_bucket *bp, *pbp = (struct hash_bucket *)0; - - if (!table) - return; - - hashno = do_hash (name, len, table -> hash_count); - - /* Go through the list looking for an entry that matches; - if we find it, delete it. */ - for (bp = table -> buckets [hashno]; bp; bp = bp -> next) { - if ((!bp -> len && !strcmp (bp -> name, name)) || - (bp -> len == len && - !memcmp (bp -> name, name, len))) { - if (pbp) { - pbp -> next = bp -> next; - } else { - table -> buckets [hashno] = bp -> next; - } - free_hash_bucket (bp, "delete_hash_entry"); - break; - } - pbp = bp; /* jwg, 9/6/96 - nice catch! */ - } -} - -unsigned char *hash_lookup (table, name, len) - struct hash_table *table; - char *name; - int len; -{ - int hashno; - struct hash_bucket *bp; - - if (!table) - return (unsigned char *)0; - hashno = do_hash (name, len, table -> hash_count); - - if (len) { - for (bp = table -> buckets [hashno]; bp; bp = bp -> next) { - if (len == bp -> len - && !memcmp (bp -> name, name, len)) - return bp -> value; - } - } else { - for (bp = table -> buckets [hashno]; bp; bp = bp -> next) - if (!strcmp (bp -> name, name)) - return bp -> value; - } - return (unsigned char *)0; -} - diff --git a/common/inet.c b/common/inet.c deleted file mode 100644 index 000d9718..00000000 --- a/common/inet.c +++ /dev/null @@ -1,154 +0,0 @@ -/* inet.c - - Subroutines to manipulate internet addresses in a safely portable - way... */ - -/* - * Copyright (c) 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#include "dhcpd.h" - -/* Return just the network number of an internet address... */ - -struct iaddr subnet_number (addr, mask) - struct iaddr addr; - struct iaddr mask; -{ - int i; - struct iaddr rv; - - rv.len = 0; - - /* Both addresses must have the same length... */ - if (addr.len != mask.len) - return rv; - - rv.len = addr.len; - for (i = 0; i < rv.len; i++) - rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i]; - return rv; -} - -/* Combine a network number and a integer to produce an internet address. - This won't work for subnets with more than 32 bits of host address, but - maybe this isn't a problem. */ - -struct iaddr ip_addr (subnet, mask, host_address) - struct iaddr subnet; - struct iaddr mask; - u_int32_t host_address; -{ - int i, j, k; - u_int32_t swaddr; - struct iaddr rv; - unsigned char habuf [sizeof swaddr]; - - swaddr = htonl (host_address); - memcpy (habuf, &swaddr, sizeof swaddr); - - /* Combine the subnet address and the host address. If - the host address is bigger than can fit in the subnet, - return a zero-length iaddr structure. */ - rv = subnet; - j = rv.len - sizeof habuf; - for (i = sizeof habuf - 1; i >= 0; i--) { - if (mask.iabuf [i + j]) { - if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) { - rv.len = 0; - return rv; - } - for (k = i - 1; k >= 0; k--) { - if (habuf [k]) { - rv.len = 0; - return rv; - } - } - rv.iabuf [i + j] |= habuf [i]; - break; - } else - rv.iabuf [i + j] = habuf [i]; - } - - return rv; -} - -u_int32_t host_addr (addr, mask) - struct iaddr addr; - struct iaddr mask; -{ - int i; - u_int32_t swaddr; - struct iaddr rv; - - rv.len = 0; - - /* Mask out the network bits... */ - rv.len = addr.len; - for (i = 0; i < rv.len; i++) - rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i]; - - /* Copy out up to 32 bits... */ - memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr); - - /* Swap it and return it. */ - return ntohl (swaddr); -} - -int addr_eq (addr1, addr2) - struct iaddr addr1, addr2; -{ - if (addr1.len != addr2.len) - return 0; - return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0; -} - -char *piaddr (addr) - struct iaddr addr; -{ - static char pbuf [4 * 16]; - char *s = pbuf; - int i; - - if (addr.len == 0) { - strcpy (s, "<null address>"); - } - for (i = 0; i < addr.len; i++) { - sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]); - s += strlen (s); - } - return pbuf; -} diff --git a/common/memory.c b/common/memory.c deleted file mode 100644 index 437c9137..00000000 --- a/common/memory.c +++ /dev/null @@ -1,873 +0,0 @@ -/* memory.c - - Memory-resident database... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: memory.c,v 1.23 1996/12/31 02:02:54 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -static struct subnet *subnets; -static struct shared_network *shared_networks; -static struct hash_table *host_hw_addr_hash; -static struct hash_table *host_uid_hash; -static struct hash_table *lease_uid_hash; -static struct hash_table *lease_ip_addr_hash; -static struct hash_table *lease_hw_addr_hash; -static struct lease *dangling_leases; - -static struct hash_table *vendor_class_hash; -static struct hash_table *user_class_hash; - -void enter_host (hd) - struct host_decl *hd; -{ - struct host_decl *hp = (struct host_decl *)0; - struct host_decl *np = (struct host_decl *)0; - - hd -> n_ipaddr = (struct host_decl *)0; - - if (hd -> interface.hlen) { - if (!host_hw_addr_hash) - host_hw_addr_hash = new_hash (); - else - hp = (struct host_decl *) - hash_lookup (host_hw_addr_hash, - hd -> interface.haddr, - hd -> interface.hlen); - - /* If there isn't already a host decl matching this - address, add it to the hash table. */ - if (!hp) - add_hash (host_hw_addr_hash, - hd -> interface.haddr, hd -> interface.hlen, - (unsigned char *)hd); - } - - /* If there was already a host declaration for this hardware - address, add this one to the end of the list. */ - - if (hp) { - for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr) - ; - np -> n_ipaddr = hd; - } - - if (hd -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) { - if (!tree_evaluate (hd -> group -> options - [DHO_DHCP_CLIENT_IDENTIFIER])) - return; - - /* If there's no uid hash, make one; otherwise, see if - there's already an entry in the hash for this host. */ - if (!host_uid_hash) { - host_uid_hash = new_hash (); - hp = (struct host_decl *)0; - } else - hp = (struct host_decl *) hash_lookup - (host_uid_hash, - hd -> group -> options - [DHO_DHCP_CLIENT_IDENTIFIER] -> value, - hd -> group -> options - [DHO_DHCP_CLIENT_IDENTIFIER] -> len); - - /* If there's already a host declaration for this - client identifier, add this one to the end of the - list. Otherwise, add it to the hash table. */ - if (hp) { - /* Don't link it in twice... */ - if (!np) { - for (np = hp; np -> n_ipaddr; - np = np -> n_ipaddr) - ; - np -> n_ipaddr = hd; - } - } else { - add_hash (host_uid_hash, - hd -> group -> options - [DHO_DHCP_CLIENT_IDENTIFIER] -> value, - hd -> group -> options - [DHO_DHCP_CLIENT_IDENTIFIER] -> len, - (unsigned char *)hd); - } - } -} - -struct host_decl *find_hosts_by_haddr (htype, haddr, hlen) - int htype; - unsigned char *haddr; - int hlen; -{ - struct host_decl *foo; - - foo = (struct host_decl *)hash_lookup (host_hw_addr_hash, - haddr, hlen); - return foo; -} - -struct host_decl *find_hosts_by_uid (data, len) - unsigned char *data; - int len; -{ - struct host_decl *foo; - - foo = (struct host_decl *)hash_lookup (host_uid_hash, data, len); - return foo; -} - -/* More than one host_decl can be returned by find_hosts_by_haddr or - find_hosts_by_uid, and each host_decl can have multiple addresses. - Loop through the list of hosts, and then for each host, through the - list of addresses, looking for an address that's in the same shared - network as the one specified. Store the matching address through - the addr pointer, update the host pointer to point at the host_decl - that matched, and return the subnet that matched. */ - -struct subnet *find_host_for_network (host, addr, share) - struct host_decl **host; - struct iaddr *addr; - struct shared_network *share; -{ - int i; - struct subnet *subnet; - struct iaddr ip_address; - struct host_decl *hp; - - for (hp = *host; hp; hp = hp -> n_ipaddr) { - if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) - continue; - for (i = 0; i < hp -> fixed_addr -> len; i += 4) { - ip_address.len = 4; - memcpy (ip_address.iabuf, - hp -> fixed_addr -> value + i, 4); - subnet = find_grouped_subnet (share, ip_address); - if (subnet) { - *addr = ip_address; - *host = hp; - return subnet; - } - } - } - return (struct subnet *)0; -} - -void new_address_range (low, high, subnet, dynamic) - struct iaddr low, high; - struct subnet *subnet; - int dynamic; -{ - struct lease *address_range, *lp, *plp; - struct iaddr net; - int min, max, i; - char lowbuf [16], highbuf [16], netbuf [16]; - struct shared_network *share = subnet -> shared_network; - struct hostent *h; - struct in_addr ia; - - /* All subnets should have attached shared network structures. */ - if (!share) { - strcpy (netbuf, piaddr (subnet -> net)); - error ("No shared network for network %s (%s)", - netbuf, piaddr (subnet -> netmask)); - } - - /* Initialize the hash table if it hasn't been done yet. */ - if (!lease_uid_hash) - lease_uid_hash = new_hash (); - if (!lease_ip_addr_hash) - lease_ip_addr_hash = new_hash (); - if (!lease_hw_addr_hash) - lease_hw_addr_hash = new_hash (); - - /* Make sure that high and low addresses are in same subnet. */ - net = subnet_number (low, subnet -> netmask); - if (!addr_eq (net, subnet_number (high, subnet -> netmask))) { - strcpy (lowbuf, piaddr (low)); - strcpy (highbuf, piaddr (high)); - strcpy (netbuf, piaddr (subnet -> netmask)); - error ("Address range %s to %s, netmask %s spans %s!", - lowbuf, highbuf, netbuf, "multiple subnets"); - } - - /* Get the high and low host addresses... */ - max = host_addr (high, subnet -> netmask); - min = host_addr (low, subnet -> netmask); - - /* Allow range to be specified high-to-low as well as low-to-high. */ - if (min > max) { - max = min; - min = host_addr (high, subnet -> netmask); - } - - /* Get a lease structure for each address in the range. */ - address_range = new_leases (max - min + 1, "new_address_range"); - if (!address_range) { - strcpy (lowbuf, piaddr (low)); - strcpy (highbuf, piaddr (high)); - error ("No memory for address range %s-%s.", lowbuf, highbuf); - } - memset (address_range, 0, (sizeof *address_range) * (max - min + 1)); - - /* Fill in the last lease if it hasn't been already... */ - if (!share -> last_lease) { - share -> last_lease = &address_range [0]; - } - - /* Fill out the lease structures with some minimal information. */ - for (i = 0; i < max - min + 1; i++) { - address_range [i].ip_addr = - ip_addr (subnet -> net, subnet -> netmask, i + min); - address_range [i].starts = - address_range [i].timestamp = MIN_TIME; - address_range [i].ends = MIN_TIME; - address_range [i].subnet = subnet; - address_range [i].shared_network = share; - address_range [i].flags = dynamic ? DYNAMIC_BOOTP_OK : 0; - - memcpy (&ia, address_range [i].ip_addr.iabuf, 4); - - if (subnet -> group -> get_lease_hostnames) { - h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET); - if (!h) - warn ("No hostname for %s", inet_ntoa (ia)); - else { - address_range [i].hostname = - malloc (strlen (h -> h_name) + 1); - if (!address_range [i].hostname) - error ("no memory for hostname %s.", - h -> h_name); - strcpy (address_range [i].hostname, - h -> h_name); - } - } - - /* Link this entry into the list. */ - address_range [i].next = share -> leases; - address_range [i].prev = (struct lease *)0; - share -> leases = &address_range [i]; - if (address_range [i].next) - address_range [i].next -> prev = share -> leases; - add_hash (lease_ip_addr_hash, - address_range [i].ip_addr.iabuf, - address_range [i].ip_addr.len, - (unsigned char *)&address_range [i]); - } - - /* Find out if any dangling leases are in range... */ - plp = (struct lease *)0; - for (lp = dangling_leases; lp; lp = lp -> next) { - struct iaddr lnet; - int lhost; - - lnet = subnet_number (lp -> ip_addr, subnet -> netmask); - lhost = host_addr (lp -> ip_addr, subnet -> netmask); - - /* If it's in range, fill in the real lease structure with - the dangling lease's values, and remove the lease from - the list of dangling leases. */ - if (addr_eq (lnet, subnet -> net) && - lhost >= i && lhost <= max) { - if (plp) { - plp -> next = lp -> next; - } else { - dangling_leases = lp -> next; - } - lp -> next = (struct lease *)0; - supersede_lease (&address_range [lhost - i], lp, 0); - free_lease (lp, "new_address_range"); - } else - plp = lp; - } -} - -struct subnet *find_subnet (addr) - struct iaddr addr; -{ - struct subnet *rv; - - for (rv = subnets; rv; rv = rv -> next_subnet) { - if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) - return rv; - } - return (struct subnet *)0; -} - -struct subnet *find_grouped_subnet (share, addr) - struct shared_network *share; - struct iaddr addr; -{ - struct subnet *rv; - - for (rv = share -> subnets; rv; rv = rv -> next_sibling) { - if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) - return rv; - } - return (struct subnet *)0; -} - -/* Enter a new subnet into the subnet list. */ - -void enter_subnet (subnet) - struct subnet *subnet; -{ - struct subnet *scan; - - /* Check for duplicates... */ - for (scan = subnets; scan; scan = scan -> next_subnet) { - if (addr_eq (subnet_number (subnet -> net, scan -> netmask), - scan -> net) || - addr_eq (subnet_number (scan -> net, subnet -> netmask), - subnet -> net)) { - char n1buf [16]; - int i, j; - for (i = 0; i < 32; i++) - if (subnet -> netmask.iabuf [3 - (i >> 3)] - & (1 << (i & 7))) - break; - for (j = 0; j < 32; j++) - if (scan -> netmask.iabuf [3 - (j >> 3)] - & (1 << (j & 7))) - break; - strcpy (n1buf, piaddr (subnet -> net)); - error ("subnet %s/%d conflicts with subnet %s/%d", - n1buf, i, piaddr (scan -> net), j); - } - } - - /* XXX Sort the nets into a balanced tree to make searching quicker. */ - subnet -> next_subnet = subnets; - subnets = subnet; -} - -/* Enter a new shared network into the shared network list. */ - -void enter_shared_network (share) - struct shared_network *share; -{ - /* XXX Sort the nets into a balanced tree to make searching quicker. */ - share -> next = shared_networks; - shared_networks = share; -} - -/* Enter a lease into the system. This is called by the parser each - time it reads in a new lease. If the subnet for that lease has - already been read in (usually the case), just update that lease; - otherwise, allocate temporary storage for the lease and keep it around - until we're done reading in the config file. */ - -void enter_lease (lease) - struct lease *lease; -{ - struct lease *comp = find_lease_by_ip_addr (lease -> ip_addr); - - /* If we don't have a place for this lease yet, save it for - later. */ - if (!comp) { - comp = new_lease ("enter_lease"); - if (!comp) { - error ("No memory for lease %s\n", - piaddr (lease -> ip_addr)); - } - *comp = *lease; - lease -> next = dangling_leases; - lease -> prev = (struct lease *)0; - dangling_leases = lease; - } else { - supersede_lease (comp, lease, 0); - } -} - -/* Replace the data in an existing lease with the data in a new lease; - adjust hash tables to suit, and insertion sort the lease into the - list of leases by expiry time so that we can always find the oldest - lease. */ - -int supersede_lease (comp, lease, commit) - struct lease *comp, *lease; - int commit; -{ - int enter_uid = 0; - int enter_hwaddr = 0; - struct lease *lp; - - /* Static leases are not currently kept in the database... */ - if (lease -> flags & STATIC_LEASE) - return 1; - - /* If the existing lease hasn't expired and has a different - unique identifier or, if it doesn't have a unique - identifier, a different hardware address, then the two - leases are in conflict. If the existing lease has a uid - and the new one doesn't, but they both have the same - hardware address, and dynamic bootp is allowed on this - lease, then we allow that, in case a dynamic BOOTP lease is - requested *after* a DHCP lease has been assigned. */ - - if (comp -> ends > cur_time && - ((comp -> uid && (lease -> uid || - !(lease -> flags & DYNAMIC_BOOTP_OK)) && - (comp -> uid_len != lease -> uid_len || - memcmp (comp -> uid, lease -> uid, comp -> uid_len))) || - (!comp -> uid && - ((comp -> hardware_addr.htype != - lease -> hardware_addr.htype) || - (comp -> hardware_addr.hlen != - lease -> hardware_addr.hlen) || - memcmp (comp -> hardware_addr.haddr, - lease -> hardware_addr.haddr, - comp -> hardware_addr.hlen))))) { - warn ("Lease conflict at %s", - piaddr (comp -> ip_addr)); - return 0; - } else { - /* If there's a Unique ID, dissociate it from the hash - table if necessary, and always free it. */ - if (comp -> uid) { - if (comp -> uid != lease -> uid) { - uid_hash_delete (comp); - enter_uid = 1; - free (comp -> uid); - comp -> uid = (unsigned char *)0; - } - } else - enter_uid = 1; - - if (comp -> hardware_addr.htype && - ((comp -> hardware_addr.hlen != - lease -> hardware_addr.hlen) || - (comp -> hardware_addr.htype != - lease -> hardware_addr.htype) || - memcmp (comp -> hardware_addr.haddr, - lease -> hardware_addr.haddr, - comp -> hardware_addr.hlen))) { - hw_hash_delete (comp); - enter_hwaddr = 1; - } else if (!comp -> hardware_addr.htype) - enter_hwaddr = 1; - - /* Copy the data files, but not the linkages. */ - comp -> starts = lease -> starts; - comp -> offered_expiry = lease -> offered_expiry; - comp -> timestamp = lease -> timestamp; - comp -> uid = lease -> uid; - comp -> uid_len = lease -> uid_len; - comp -> host = lease -> host; - comp -> hardware_addr = lease -> hardware_addr; - comp -> state = lease -> state; - comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) | - (comp -> flags & ~EPHEMERAL_FLAGS)); - - /* Record the lease in the uid hash if necessary. */ - if (enter_uid && lease -> uid) { - uid_hash_add (comp); - } - - /* Record it in the hardware address hash if necessary. */ - if (enter_hwaddr && lease -> hardware_addr.htype) { - hw_hash_add (comp); - } - - /* Remove the lease from its current place in the - timeout sequence. */ - if (comp -> prev) { - comp -> prev -> next = comp -> next; - } else { - comp -> shared_network -> leases = comp -> next; - } - if (comp -> next) { - comp -> next -> prev = comp -> prev; - } - if (comp -> shared_network -> last_lease == comp) { - comp -> shared_network -> last_lease = comp -> prev; - } - - /* Find the last insertion point... */ - if (comp == comp -> shared_network -> insertion_point || - !comp -> shared_network -> insertion_point) { - lp = comp -> shared_network -> leases; - } else { - lp = comp -> shared_network -> insertion_point; - } - - if (!lp) { - /* Nothing on the list yet? Just make comp the - head of the list. */ - comp -> shared_network -> leases = comp; - comp -> shared_network -> last_lease = comp; - } else if (lp -> ends > lease -> ends) { - /* Skip down the list until we run out of list - or find a place for comp. */ - while (lp -> next && lp -> ends > lease -> ends) { - lp = lp -> next; - } - if (lp -> ends > lease -> ends) { - /* If we ran out of list, put comp - at the end. */ - lp -> next = comp; - comp -> prev = lp; - comp -> next = (struct lease *)0; - comp -> shared_network -> last_lease = comp; - } else { - /* If we didn't, put it between lp and - the previous item on the list. */ - if ((comp -> prev = lp -> prev)) - comp -> prev -> next = comp; - comp -> next = lp; - lp -> prev = comp; - } - } else { - /* Skip up the list until we run out of list - or find a place for comp. */ - while (lp -> prev && lp -> ends < lease -> ends) { - lp = lp -> prev; - } - if (lp -> ends < lease -> ends) { - /* If we ran out of list, put comp - at the beginning. */ - lp -> prev = comp; - comp -> next = lp; - comp -> prev = (struct lease *)0; - comp -> shared_network -> leases = comp; - } else { - /* If we didn't, put it between lp and - the next item on the list. */ - if ((comp -> next = lp -> next)) - comp -> next -> prev = comp; - comp -> prev = lp; - lp -> next = comp; - } - } - comp -> shared_network -> insertion_point = comp; - comp -> ends = lease -> ends; - } - - /* Return zero if we didn't commit the lease to permanent storage; - nonzero if we did. */ - return commit && write_lease (comp) && commit_leases (); -} - -/* Release the specified lease and re-hash it as appropriate. */ - -void release_lease (lease) - struct lease *lease; -{ - struct lease lt; - - lt = *lease; - lt.ends = cur_time; - supersede_lease (lease, <, 1); -} - -/* Abandon the specified lease (set its timeout to infinity and its - particulars to zero, and re-hash it as appropriate. */ - -void abandon_lease (lease) - struct lease *lease; -{ - struct lease lt; - - lt = *lease; - lt.ends = 0xFFFFFFFF; - warn ("Abandoning IP address %s\n", - piaddr (lease -> ip_addr)); - lt.hardware_addr.htype = -1; - lt.hardware_addr.hlen = 0; - lt.uid = (unsigned char *)0; - lt.uid_len = 0; - supersede_lease (lease, <, 1); -} - -/* Locate the lease associated with a given IP address... */ - -struct lease *find_lease_by_ip_addr (addr) - struct iaddr addr; -{ - struct lease *lease = (struct lease *)hash_lookup (lease_ip_addr_hash, - addr.iabuf, - addr.len); - return lease; -} - -struct lease *find_lease_by_uid (uid, len) - unsigned char *uid; - int len; -{ - struct lease *lease = (struct lease *)hash_lookup (lease_uid_hash, - uid, len); - return lease; -} - -struct lease *find_lease_by_hw_addr (hwaddr, hwlen) - unsigned char *hwaddr; - int hwlen; -{ - struct lease *lease = (struct lease *)hash_lookup (lease_hw_addr_hash, - hwaddr, hwlen); - return lease; -} - -/* Add the specified lease to the uid hash. */ - -void uid_hash_add (lease) - struct lease *lease; -{ - struct lease *head = - find_lease_by_uid (lease -> uid, lease -> uid_len); - struct lease *scan; - -#ifdef DEBUG - if (lease -> n_uid) - abort (); -#endif - - /* If it's not in the hash, just add it. */ - if (!head) - add_hash (lease_uid_hash, lease -> uid, - lease -> uid_len, (unsigned char *)lease); - else { - /* Otherwise, attach it to the end of the list. */ - for (scan = head; scan -> n_uid; scan = scan -> n_uid) -#ifdef DEBUG - if (scan == lease) - abort () -#endif - ; - scan -> n_uid = lease; - } -} - -/* Delete the specified lease from the uid hash. */ - -void uid_hash_delete (lease) - struct lease *lease; -{ - struct lease *head = - find_lease_by_uid (lease -> uid, lease -> uid_len); - struct lease *scan; - - /* If it's not in the hash, we have no work to do. */ - if (!head) { - lease -> n_uid = (struct lease *)0; - return; - } - - /* If the lease we're freeing is at the head of the list, - remove the hash table entry and add a new one with the - next lease on the list (if there is one). */ - if (head == lease) { - delete_hash_entry (lease_uid_hash, - lease -> uid, lease -> uid_len); - if (lease -> n_uid) - add_hash (lease_uid_hash, - lease -> n_uid -> uid, - lease -> n_uid -> uid_len, - (unsigned char *)(lease -> n_uid)); - } else { - /* Otherwise, look for the lease in the list of leases - attached to the hash table entry, and remove it if - we find it. */ - for (scan = head; scan -> n_uid; scan = scan -> n_uid) { - if (scan -> n_uid == lease) { - scan -> n_uid = scan -> n_uid -> n_uid; - break; - } - } - } - lease -> n_uid = (struct lease *)0; -} - -/* Add the specified lease to the hardware address hash. */ - -void hw_hash_add (lease) - struct lease *lease; -{ - struct lease *head = - find_lease_by_hw_addr (lease -> hardware_addr.haddr, - lease -> hardware_addr.hlen); - struct lease *scan; - - /* If it's not in the hash, just add it. */ - if (!head) - add_hash (lease_hw_addr_hash, - lease -> hardware_addr.haddr, - lease -> hardware_addr.hlen, - (unsigned char *)lease); - else { - /* Otherwise, attach it to the end of the list. */ - for (scan = head; scan -> n_hw; scan = scan -> n_hw) - ; - scan -> n_hw = lease; - } -} - -/* Delete the specified lease from the hardware address hash. */ - -void hw_hash_delete (lease) - struct lease *lease; -{ - struct lease *head = - find_lease_by_hw_addr (lease -> hardware_addr.haddr, - lease -> hardware_addr.hlen); - struct lease *scan; - - /* If it's not in the hash, we have no work to do. */ - if (!head) { - lease -> n_hw = (struct lease *)0; - return; - } - - /* If the lease we're freeing is at the head of the list, - remove the hash table entry and add a new one with the - next lease on the list (if there is one). */ - if (head == lease) { - delete_hash_entry (lease_hw_addr_hash, - lease -> hardware_addr.haddr, - lease -> hardware_addr.hlen); - if (lease -> n_hw) - add_hash (lease_hw_addr_hash, - lease -> n_hw -> hardware_addr.haddr, - lease -> n_hw -> hardware_addr.hlen, - (unsigned char *)(lease -> n_hw)); - } else { - /* Otherwise, look for the lease in the list of leases - attached to the hash table entry, and remove it if - we find it. */ - for (scan = head; scan -> n_hw; scan = scan -> n_hw) { - if (scan -> n_hw == lease) { - scan -> n_hw = scan -> n_hw -> n_hw; - break; - } - } - } - lease -> n_hw = (struct lease *)0; -} - - -struct class *add_class (type, name) - int type; - char *name; -{ - struct class *class = new_class ("add_class"); - char *tname = (char *)malloc (strlen (name) + 1); - - if (!vendor_class_hash) - vendor_class_hash = new_hash (); - if (!user_class_hash) - user_class_hash = new_hash (); - - if (!tname || !class || !vendor_class_hash || !user_class_hash) - return (struct class *)0; - - memset (class, 0, sizeof *class); - strcpy (tname, name); - class -> name = tname; - - if (type) - add_hash (user_class_hash, - tname, strlen (tname), (unsigned char *)class); - else - add_hash (vendor_class_hash, - tname, strlen (tname), (unsigned char *)class); - return class; -} - -struct class *find_class (type, name, len) - int type; - char *name; - int len; -{ - struct class *class = - (struct class *)hash_lookup (type - ? user_class_hash - : vendor_class_hash, name, len); - return class; -} - -struct group *clone_group (group, caller) - struct group *group; - char *caller; -{ - struct group *g = new_group (caller); - if (!g) - error ("%s: can't allocate new group", caller); - *g = *group; - return g; -} - -/* Write all interesting leases to permanent storage. */ - -void write_leases () -{ - struct lease *l; - struct shared_network *s; - - for (s = shared_networks; s; s = s -> next) { - for (l = s -> leases; l; l = l -> next) { - if (l -> hardware_addr.hlen || l -> uid_len) - if (!write_lease (l)) - error ("Can't rewrite lease database"); - } - } - if (!commit_leases ()) - error ("Can't commit leases to new database: %m"); -} - -void dump_subnets () -{ - struct lease *l; - struct shared_network *s; - struct subnet *n; - - for (s = shared_networks; s; s = s -> next) { - for (n = subnets; n; n = n -> next_sibling) { - debug ("Subnet %s", piaddr (n -> net)); - debug (" netmask %s", - piaddr (n -> netmask)); - } - for (l = s -> leases; l; l = l -> next) { - print_lease (l); - } - debug ("Last Lease:"); - print_lease (s -> last_lease); - } -} diff --git a/common/nit.c b/common/nit.c deleted file mode 100644 index 4c84f8ba..00000000 --- a/common/nit.c +++ /dev/null @@ -1,345 +0,0 @@ -/* nit.c - - Network Interface Tap (NIT) network interface code, by Ted Lemon - with one crucial tidbit of help from Stu Grossmen. */ - -/* - * Copyright (c) 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. */ - -#ifndef lint -static char copyright[] = -"$Id: nit.c,v 1.13 1997/02/26 05:20:53 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" -#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE) -#include <sys/ioctl.h> -#include <sys/uio.h> - -#include <sys/time.h> -#include <net/nit.h> -#include <net/nit_if.h> -#include <net/nit_pf.h> -#include <net/nit_buf.h> -#include <sys/stropts.h> -#include <net/packetfilt.h> - -#include <netinet/in_systm.h> -#include "includes/netinet/ip.h" -#include "includes/netinet/udp.h" -#include "includes/netinet/if_ether.h" - -/* Reinitializes the specified interface after an address change. This - is not required for packet-filter APIs. */ - -#ifdef USE_NIT_SEND -void if_reinitialize_send (info) - struct interface_info *info; -{ -} -#endif - -#ifdef USE_NIT_RECEIVE -void if_reinitialize_receive (info) - struct interface_info *info; -{ -} -#endif - -/* Called by get_interface_list for each interface that's discovered. - Opens a packet filter for each interface and adds it to the select - mask. */ - -int if_register_nit (info) - struct interface_info *info; -{ - int sock; - char filename[50]; - struct ifreq ifr; - struct strioctl sio; - - /* Open a NIT device */ - sock = open ("/dev/nit", O_RDWR); - if (sock < 0) - error ("Can't open NIT device for %s: %m", info -> name); - - /* Set the NIT device to point at this interface. */ - sio.ic_cmd = NIOCBIND; - sio.ic_len = sizeof *(info -> ifp); - sio.ic_dp = (char *)(info -> ifp); - sio.ic_timout = INFTIM; - if (ioctl (sock, I_STR, &sio) < 0) - error ("Can't attach interface %s to nit device: %m", - info -> name); - - /* Get the low-level address... */ - sio.ic_cmd = SIOCGIFADDR; - sio.ic_len = sizeof ifr; - sio.ic_dp = (char *)𝔦 - sio.ic_timout = INFTIM; - if (ioctl (sock, I_STR, &sio) < 0) - error ("Can't get physical layer address for %s: %m", - info -> name); - - /* XXX code below assumes ethernet interface! */ - info -> hw_address.hlen = 6; - info -> hw_address.htype = ARPHRD_ETHER; - memcpy (info -> hw_address.haddr, ifr.ifr_ifru.ifru_addr.sa_data, 6); - - if (ioctl (sock, I_PUSH, "pf") < 0) - error ("Can't push packet filter onto NIT for %s: %m", - info -> name); - - return sock; -} -#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */ - -#ifdef USE_NIT_SEND -void if_register_send (info) - struct interface_info *info; -{ - /* If we're using the nit API for sending and receiving, - we don't need to register this interface twice. */ -#ifndef USE_NIT_RECEIVE - struct packetfilt pf; - struct strioctl sio; - - info -> wfdesc = if_register_nit (info); - - pf.Pf_Priority = 0; - pf.Pf_FilterLen = 1; - pf.Pf_Filter [0] = ENF_PUSHZERO; - - /* Set up an NIT filter that rejects everything... */ - sio.ic_cmd = NIOCSETF; - sio.ic_len = sizeof pf; - sio.ic_dp = (char *)&pf; - sio.ic_timout = INFTIM; - if (ioctl (info -> wfdesc, I_STR, &sio) < 0) - error ("Can't set NIT filter: %m"); -#else - info -> wfdesc = info -> rfdesc; -#endif - note ("Sending on NIT/%s/%s", - print_hw_addr (info -> hw_address.htype, - info -> hw_address.hlen, - info -> hw_address.haddr), - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} -#endif /* USE_NIT_SEND */ - -#ifdef USE_NIT_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 NIT program! XXX */ - -void if_register_receive (info) - struct interface_info *info; -{ - int flag = 1; - u_int32_t x; - struct packetfilt pf; - struct strioctl sio; - u_int16_t addr [2]; - struct timeval t; - - /* Open a NIT device and hang it on this interface... */ - info -> rfdesc = if_register_nit (info); - - /* Set the snap length to 0, which means always take the whole - packet. */ - x = 0; - if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0) - error ("Can't set NIT snap length on %s: %m", info -> name); - - /* Set the stream to byte stream mode */ - if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0) - note ("I_SRDOPT failed on %s: %m", info -> name); - -#if 0 - /* Push on the chunker... */ - if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0) - error ("Can't push chunker onto NIT STREAM: %m"); - - /* Set the timeout to zero. */ - t.tv_sec = 0; - t.tv_usec = 0; - if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0) - error ("Can't set chunk timeout: %m"); -#endif - - /* Ask for no header... */ - x = 0; - if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0) - error ("Can't set NIT flags on %s: %m", info -> name); - - /* Set up the NIT filter program. */ - /* XXX Unlike the BPF filter program, this one won't work if the - XXX IP packet is fragmented or if there are options on the IP - XXX header. */ - pf.Pf_Priority = 0; - pf.Pf_FilterLen = 0; - - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6; - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND; - pf.Pf_Filter [pf.Pf_FilterLen++] = htons (ETHERTYPE_IP); - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT; - pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP); - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11; - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND; - pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF); - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND; - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18; - pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND; - pf.Pf_Filter [pf.Pf_FilterLen++] = local_port; - - /* Install the filter... */ - sio.ic_cmd = NIOCSETF; - sio.ic_len = sizeof pf; - sio.ic_dp = (char *)&pf; - sio.ic_timout = INFTIM; - if (ioctl (info -> rfdesc, I_STR, &sio) < 0) - error ("Can't set NIT filter on %s: %m", info -> name); - - note ("Listening on NIT/%s/%s", - print_hw_addr (info -> hw_address.htype, - info -> hw_address.hlen, - info -> hw_address.haddr), - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} -#endif /* USE_NIT_RECEIVE */ - -#ifdef USE_NIT_SEND -size_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; - struct dhcp_packet *raw; - size_t len; - struct in_addr from; - struct sockaddr_in *to; - struct hardware *hto; -{ - int bufp; - unsigned char buf [1536 + sizeof (struct sockaddr)]; - struct sockaddr *junk; - struct strbuf ctl, data; - int hw_end; - struct sockaddr_in foo; - - /* Start with the sockaddr struct... */ - junk = (struct sockaddr *)&buf [0]; - bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0]; - - /* Assemble the headers... */ - assemble_hw_header (interface, buf, &bufp, hto); - hw_end = bufp; - assemble_udp_ip_header (interface, buf, &bufp, from.s_addr, - to -> sin_addr.s_addr, to -> sin_port, - raw, len); - - /* Copy the data into the buffer (yuk). */ - memcpy (buf + bufp, raw, len); - - /* Set up the sockaddr structure... */ -#if USE_SIN_LEN - junk -> sa_len = hw_end - 2; /* XXX */ -#endif - junk -> sa_family = AF_UNSPEC; - -#if 0 /* Already done. */ - memcpy (junk.sa_data, buf, hw_len); -#endif - - /* Set up the msg_buf structure... */ - ctl.buf = (char *)&buf [0]; - ctl.maxlen = ctl.len = hw_end; - data.buf = (char *)&buf [hw_end]; - data.maxlen = data.len = bufp + len - hw_end; - - return putmsg (interface -> wfdesc, &ctl, &data, 0); -} -#endif /* USE_NIT_SEND */ - -#ifdef USE_NIT_RECEIVE -size_t receive_packet (interface, buf, len, from, hfrom) - struct interface_info *interface; - unsigned char *buf; - size_t len; - struct sockaddr_in *from; - struct hardware *hfrom; -{ - int nread; - int length = 0; - int offset = 0; - unsigned char ibuf [1536]; - int bufix = 0; - - length = read (interface -> rfdesc, ibuf, sizeof ibuf); - if (length <= 0) - return length; - - /* Decode the physical header... */ - offset = decode_hw_header (interface, ibuf, bufix, hfrom); - - /* If a physical layer checksum failed (dunno of any - physical layer that supports this, but WTH), skip this - packet. */ - if (offset < 0) { - return 0; - } - - bufix += offset; - length -= offset; - - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header (interface, ibuf, bufix, - from, (unsigned char *)0, length); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) - return 0; - - bufix += offset; - length -= offset; - - /* Copy out the data in the packet... */ - memcpy (buf, &ibuf [bufix], length); - return length; -} -#endif diff --git a/common/options.c b/common/options.c deleted file mode 100644 index 6d18ad5e..00000000 --- a/common/options.c +++ /dev/null @@ -1,545 +0,0 @@ -/* options.c - - DHCP options parsing and reassembly. */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: options.c,v 1.22 1997/02/22 08:32:04 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#define DHCP_OPTION_DATA -#include "dhcpd.h" - -/* Parse all available options out of the specified packet. */ - -void parse_options (packet) - struct packet *packet; -{ - /* Initially, zero all option pointers. */ - memset (packet -> options, 0, sizeof (packet -> options)); - - /* If we don't see the magic cookie, there's nothing to parse. */ - if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) { - packet -> options_valid = 0; - return; - } - - /* Go through the options field, up to the end of the packet - or the End field. */ - parse_option_buffer (packet, &packet -> raw -> options [4], - packet -> packet_length - DHCP_FIXED_NON_UDP - 4); - /* If we parsed a DHCP Option Overload option, parse more - options out of the buffer(s) containing them. */ - if (packet -> options_valid - && packet -> options [DHO_DHCP_OPTION_OVERLOAD].data) { - if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1) - parse_option_buffer (packet, - packet -> raw -> file, - sizeof packet -> raw -> file); - if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2) - parse_option_buffer (packet, - packet -> raw -> sname, - sizeof packet -> raw -> sname); - } -} - -/* Parse options out of the specified buffer, storing addresses of option - values in packet -> options and setting packet -> options_valid if no - errors are encountered. */ - -void parse_option_buffer (packet, buffer, length) - struct packet *packet; - unsigned char *buffer; - int length; -{ - unsigned char *s, *t; - unsigned char *end = buffer + length; - int len; - int code; - - for (s = buffer; *s != DHO_END && s < end; ) { - code = s [0]; - /* Pad options don't have a length - just skip them. */ - if (code == DHO_PAD) { - ++s; - continue; - } - /* All other fields (except end, see above) have a - one-byte length. */ - len = s [1]; - - /* If the length is outrageous, the options are bad. */ - if (s + len + 2 > end) { - warn ("Option %s length %d overflows input buffer.", - dhcp_options [code].name, - len); - packet -> options_valid = 0; - return; - } - /* If we haven't seen this option before, just make - space for it and copy it there. */ - if (!packet -> options [code].data) { - if (!(t = (unsigned char *)malloc (len + 1))) - error ("Can't allocate storage for option %s.", - dhcp_options [code].name); - /* Copy and NUL-terminate the option (in case it's an - ASCII string. */ - memcpy (t, &s [2], len); - t [len] = 0; - packet -> options [code].len = len; - packet -> options [code].data = t; - } else { - /* If it's a repeat, concatenate it to whatever - we last saw. This is really only required - for clients, but what the heck... */ - t = (unsigned char *) - malloc (len - + packet -> options [code].len - + 1); - if (!t) - error ("Can't expand storage for option %s.", - dhcp_options [code].name); - memcpy (t, packet -> options [code].data, - packet -> options [code].len); - memcpy (t + packet -> options [code].len, - &s [2], len); - packet -> options [code].len += len; - t [packet -> options [code].len] = 0; - free (packet -> options [code].data); - packet -> options [code].data = t; - } - s += len + 2; - } - packet -> options_valid = 1; -} - -/* cons options into a big buffer, and then split them out into the - three seperate buffers if needed. This allows us to cons up a set - of vendor options using the same routine. */ - -int cons_options (inpacket, outpacket, options, overload, terminate) - struct packet *inpacket; - struct dhcp_packet *outpacket; - struct tree_cache **options; - int overload; /* Overload flags that may be set. */ - int terminate; -{ - unsigned char priority_list [300]; - int priority_len; - unsigned char buffer [4096]; /* Really big buffer... */ - int main_buffer_size; - int mainbufix, bufix; - int option_size; - int length; - - /* If the client has provided a maximum DHCP message size, - use that. Otherwise, we use the default MTU size (576 bytes). */ - /* XXX Maybe it would be safe to assume that we can send a packet - to the client that's as big as the one it sent us, even if it - didn't specify a large MTU. */ - if (inpacket && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) { - main_buffer_size = - (getUShort (inpacket -> options - [DHO_DHCP_MAX_MESSAGE_SIZE].data) - - DHCP_FIXED_LEN); - /* Enforce a minimum packet size... */ - if (main_buffer_size < (576 - DHCP_FIXED_LEN)) - main_buffer_size = 576 - DHCP_FIXED_LEN; - } else - main_buffer_size = 576 - DHCP_FIXED_LEN; - - /* Preload the option priority list with mandatory options. */ - priority_len = 0; - priority_list [priority_len++] = DHO_DHCP_MESSAGE_TYPE; - priority_list [priority_len++] = DHO_DHCP_SERVER_IDENTIFIER; - priority_list [priority_len++] = DHO_DHCP_LEASE_TIME; - priority_list [priority_len++] = DHO_DHCP_MESSAGE; - - /* If the client has provided a list of options that it wishes - returned, use it to prioritize. Otherwise, prioritize - based on the default priority list. */ - - if (inpacket && - inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) { - memcpy (&priority_list [priority_len], - inpacket -> options - [DHO_DHCP_PARAMETER_REQUEST_LIST].data, - inpacket -> options - [DHO_DHCP_PARAMETER_REQUEST_LIST].len); - priority_len += - inpacket -> options - [DHO_DHCP_PARAMETER_REQUEST_LIST].len; - } else { - memcpy (&priority_list [priority_len], - dhcp_option_default_priority_list, - sizeof_dhcp_option_default_priority_list); - priority_len += sizeof_dhcp_option_default_priority_list; - } - - /* Copy the options into the big buffer... */ - option_size = store_options (buffer, - (main_buffer_size - 7 + - ((overload & 1) ? DHCP_FILE_LEN : 0) + - ((overload & 2) ? DHCP_SNAME_LEN : 0)), - options, priority_list, priority_len, - main_buffer_size, - (main_buffer_size + - ((overload & 1) ? DHCP_FILE_LEN : 0)), - terminate); - - /* Put the cookie up front... */ - memcpy (outpacket -> options, DHCP_OPTIONS_COOKIE, 4); - mainbufix = 4; - - /* If we're going to have to overload, store the overload - option at the beginning. If we can, though, just store the - whole thing in the packet's option buffer and leave it at - that. */ - if (option_size <= main_buffer_size - mainbufix) { - memcpy (&outpacket -> options [mainbufix], - buffer, option_size); - mainbufix += option_size; - if (mainbufix < main_buffer_size) - outpacket -> options [mainbufix++] - = DHO_END; - length = DHCP_FIXED_NON_UDP + mainbufix; - } else { - outpacket -> options [mainbufix++] = - DHO_DHCP_OPTION_OVERLOAD; - outpacket -> options [mainbufix++] = 1; - if (option_size > main_buffer_size - mainbufix + DHCP_FILE_LEN) - outpacket -> options [mainbufix++] = 3; - else - outpacket -> options [mainbufix++] = 1; - - memcpy (&outpacket -> options [mainbufix], - buffer, main_buffer_size - mainbufix); - bufix = main_buffer_size - mainbufix; - length = DHCP_FIXED_NON_UDP + mainbufix; - if (overload & 1) { - if (option_size - bufix <= DHCP_FILE_LEN) { - memcpy (outpacket -> file, - &buffer [bufix], option_size - bufix); - mainbufix = option_size - bufix; - if (mainbufix < DHCP_FILE_LEN) - outpacket -> file [mainbufix++] - = DHO_END; - while (mainbufix < DHCP_FILE_LEN) - outpacket -> file [mainbufix++] - = DHO_PAD; - } else { - memcpy (outpacket -> file, - &buffer [bufix], DHCP_FILE_LEN); - bufix += DHCP_FILE_LEN; - } - } - if ((overload & 2) && option_size < bufix) { - memcpy (outpacket -> sname, - &buffer [bufix], option_size - bufix); - - mainbufix = option_size - bufix; - if (mainbufix < DHCP_SNAME_LEN) - outpacket -> file [mainbufix++] - = DHO_END; - while (mainbufix < DHCP_SNAME_LEN) - outpacket -> file [mainbufix++] - = DHO_PAD; - } - } - return length; -} - -/* Store all the requested options into the requested buffer. */ - -int store_options (buffer, buflen, options, priority_list, priority_len, - first_cutoff, second_cutoff, terminate) - unsigned char *buffer; - int buflen; - struct tree_cache **options; - unsigned char *priority_list; - int priority_len; - int first_cutoff, second_cutoff; - int terminate; -{ - int bufix = 0; - int option_stored [256]; - int i; - int ix; - int tto; - - /* Zero out the stored-lengths array. */ - memset (option_stored, 0, sizeof option_stored); - - /* Copy out the options in the order that they appear in the - priority list... */ - for (i = 0; i < priority_len; i++) { - /* Code for next option to try to store. */ - int code = priority_list [i]; - int optstart; - - /* Number of bytes left to store (some may already - have been stored by a previous pass). */ - int length; - - /* If no data is available for this option, skip it. */ - if (!options [code]) { - continue; - } - - /* The client could ask for things that are mandatory, - in which case we should avoid storing them twice... */ - if (option_stored [code]) - continue; - option_stored [code] = 1; - - /* Find the value of the option... */ - if (!tree_evaluate (options [code])) { - continue; - } - - /* We should now have a constant length for the option. */ - length = options [code] -> len; - - /* Do we add a NUL? */ - if (terminate && dhcp_options [code].format [0] == 't') { - length++; - tto = 1; - } else { - tto = 0; - } - - /* Try to store the option. */ - - /* If the option's length is more than 255, we must store it - in multiple hunks. Store 255-byte hunks first. However, - in any case, if the option data will cross a buffer - boundary, split it across that boundary. */ - - ix = 0; - - optstart = bufix; - while (length) { - unsigned char incr = length > 255 ? 255 : length; - - /* If this hunk of the buffer will cross a - boundary, only go up to the boundary in this - pass. */ - if (bufix < first_cutoff && - bufix + incr > first_cutoff) - incr = first_cutoff - bufix; - else if (bufix < second_cutoff && - bufix + incr > second_cutoff) - incr = second_cutoff - bufix; - - /* If this option is going to overflow the buffer, - skip it. */ - if (bufix + 2 + incr > buflen) { - bufix = optstart; - break; - } - - /* Everything looks good - copy it in! */ - buffer [bufix] = code; - buffer [bufix + 1] = incr; - if (tto && incr == length) { - memcpy (buffer + bufix + 2, - options [code] -> value + ix, - incr - 1); - buffer [bufix + 2 + incr - 1] = 0; - } else { - memcpy (buffer + bufix + 2, - options [code] -> value + ix, incr); - } - length -= incr; - ix += incr; - bufix += 2 + incr; - } - } - return bufix; -} - -/* Format the specified option so that a human can easily read it. */ - -char *pretty_print_option (code, data, len, emit_commas) - unsigned char code; - unsigned char *data; - int len; - int emit_commas; -{ - static char optbuf [32768]; /* XXX */ - int hunksize = 0; - int numhunk = -1; - int numelem = 0; - char fmtbuf [32]; - int i, j; - char *op = optbuf; - unsigned char *dp = data; - struct in_addr foo; - - /* Figure out the size of the data. */ - for (i = 0; dhcp_options [code].format [i]; i++) { - if (!numhunk) { - warn ("%s: Excess information in format string: %s\n", - dhcp_options [code].name, - &(dhcp_options [code].format [i])); - break; - } - numelem++; - fmtbuf [i] = dhcp_options [code].format [i]; - switch (dhcp_options [code].format [i]) { - case 'A': - --numelem; - fmtbuf [i] = 0; - numhunk = 0; - break; - case 't': - fmtbuf [i] = 't'; - fmtbuf [i + 1] = 0; - numhunk = -2; - break; - case 'I': - case 'l': - case 'L': - hunksize += 4; - break; - case 's': - case 'S': - hunksize += 2; - break; - case 'b': - case 'B': - case 'f': - hunksize++; - break; - case 'e': - break; - default: - warn ("%s: garbage in format string: %s\n", - dhcp_options [code].name, - &(dhcp_options [code].format [i])); - break; - } - } - - /* Check for too few bytes... */ - if (hunksize > len) { - warn ("%s: expecting at least %d bytes; got %d", - dhcp_options [code].name, - hunksize, len); - return "<error>"; - } - /* Check for too many bytes... */ - if (numhunk == -1 && hunksize < len) - warn ("%s: %d extra bytes", - dhcp_options [code].name, - len - hunksize); - - /* If this is an array, compute its size. */ - if (!numhunk) - numhunk = len / hunksize; - /* See if we got an exact number of hunks. */ - if (numhunk > 0 && numhunk * hunksize < len) - warn ("%s: %d extra bytes at end of array\n", - dhcp_options [code].name, - len - numhunk * hunksize); - - /* A one-hunk array prints the same as a single hunk. */ - if (numhunk < 0) - numhunk = 1; - - /* Cycle through the array (or hunk) printing the data. */ - for (i = 0; i < numhunk; i++) { - for (j = 0; j < numelem; j++) { - switch (fmtbuf [j]) { - case 't': - *op++ = '"'; - strcpy (op, dp); - op += strlen (dp); - *op++ = '"'; - *op = 0; - break; - case 'I': - foo.s_addr = htonl (getULong (dp)); - strcpy (op, inet_ntoa (foo)); - dp += 4; - break; - case 'l': - sprintf (op, "%ld", (long)getLong (dp)); - dp += 4; - break; - case 'L': - sprintf (op, "%ld", - (unsigned long)getULong (dp)); - dp += 4; - break; - case 's': - sprintf (op, "%d", getShort (dp)); - dp += 2; - break; - case 'S': - sprintf (op, "%d", getUShort (dp)); - dp += 2; - break; - case 'b': - sprintf (op, "%d", *(char *)dp++); - break; - case 'B': - sprintf (op, "%d", *dp++); - break; - case 'f': - strcpy (op, *dp++ ? "true" : "false"); - break; - default: - warn ("Unexpected format code %c", fmtbuf [j]); - } - op += strlen (op); - if (j + 1 < numelem) - *op++ = ' '; - } - if (i + 1 < numhunk) { - if (emit_commas) - *op++ = ','; - *op++ = ' '; - } - - } - return optbuf; -} diff --git a/common/packet.c b/common/packet.c deleted file mode 100644 index 1fc9a0bb..00000000 --- a/common/packet.c +++ /dev/null @@ -1,314 +0,0 @@ -/* packet.c - - Packet assembly code, originally contributed by Archie Cobbs. */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: packet.c,v 1.12 1997/02/18 14:32:51 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" -#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING) -#include <netinet/in_systm.h> -#include "includes/netinet/ip.h" -#include "includes/netinet/udp.h" -#include "includes/netinet/if_ether.h" - -static u_int32_t checksum PROTO ((unsigned char *, int, u_int32_t)); -static u_int32_t wrapsum PROTO ((u_int32_t)); - -/* Compute the easy part of the checksum on a range of bytes. */ - -static u_int32_t checksum (buf, nbytes, sum) - unsigned char *buf; - int nbytes; - u_int32_t sum; -{ - int i; - -#ifdef DEBUG_CHECKSUM - debug ("checksum (%x %d %x)", buf, nbytes, sum); -#endif - - /* Checksum all the pairs of bytes first... */ - for (i = 0; i < (nbytes & ~1); i += 2) { -#ifdef DEBUG_CHECKSUM_VERBOSE - debug ("sum = %x", sum); -#endif - sum += (u_int16_t) ntohs(*((u_int16_t *)buf)++); - } - - /* If there's a single byte left over, checksum it, too. Network - byte order is big-endian, so the remaining byte is the high byte. */ - if (i < nbytes) { -#ifdef DEBUG_CHECKSUM_VERBOSE - debug ("sum = %x", sum); -#endif - sum += (*buf) << 8; - } - - return sum; -} - -/* Fold the upper sixteen bits of the checksum down into the lower bits, - complement the sum, and then put it into network byte order. */ - -static u_int32_t wrapsum (sum) - u_int32_t sum; -{ -#ifdef DEBUG_CHECKSUM - debug ("wrapsum (%x)", sum); -#endif - - while (sum > 0x10000) { - sum = (sum >> 16) + (sum & 0xFFFF); -#ifdef DEBUG_CHECKSUM_VERBOSE - debug ("sum = %x", sum); -#endif - sum += (sum >> 16); -#ifdef DEBUG_CHECKSUM_VERBOSE - debug ("sum = %x", sum); -#endif - } - sum = sum ^ 0xFFFF; -#ifdef DEBUG_CHECKSUM_VERBOSE - debug ("sum = %x", sum); -#endif - -#ifdef DEBUG_CHECKSUM - debug ("wrapsum returns %x", htons (sum)); -#endif - return htons(sum); -} -#endif /* PACKET_ASSEMBLY || PACKET_DECODING */ - -#ifdef PACKET_ASSEMBLY -/* Assemble an hardware header... */ -/* XXX currently only supports ethernet; doesn't check for other types. */ - -void assemble_hw_header (interface, buf, bufix, to) - struct interface_info *interface; - unsigned char *buf; - int *bufix; - struct hardware *to; -{ - struct ether_header eh; - - if (to && to -> hlen == 6) /* XXX */ - memcpy (eh.ether_dhost, to -> haddr, sizeof eh.ether_dhost); - else - memset (eh.ether_dhost, 0xff, sizeof (eh.ether_dhost)); - if (interface -> hw_address.hlen == sizeof (eh.ether_shost)) - memcpy (eh.ether_shost, interface -> hw_address.haddr, - sizeof (eh.ether_shost)); - else - memset (eh.ether_shost, 0x00, sizeof (eh.ether_shost)); - -#ifdef BROKEN_FREEBSD_BPF /* Fixed in FreeBSD 2.2 */ - eh.ether_type = ETHERTYPE_IP; -#else - eh.ether_type = htons (ETHERTYPE_IP); -#endif - - memcpy (&buf [*bufix], &eh, sizeof eh); - *bufix += sizeof eh; -} - -/* UDP header and IP header assembled together for convenience. */ - -void assemble_udp_ip_header (interface, buf, bufix, - from, to, port, data, len) - struct interface_info *interface; - unsigned char *buf; - int *bufix; - u_int32_t from; - u_int32_t to; - u_int16_t port; - unsigned char *data; - int len; -{ - struct ip ip; - struct udphdr udp; - - /* Fill out the IP header */ - ip.ip_v = 4; - ip.ip_hl = 5; - ip.ip_tos = IPTOS_LOWDELAY; - ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len); - ip.ip_id = 0; - ip.ip_off = 0; - ip.ip_ttl = 16; - ip.ip_p = IPPROTO_UDP; - ip.ip_sum = 0; - ip.ip_src.s_addr = from; - ip.ip_dst.s_addr = to; - - /* Checksum the IP header... */ - ip.ip_sum = wrapsum (checksum ((unsigned char *)&ip, sizeof ip, 0)); - - /* Copy the ip header into the buffer... */ - memcpy (&buf [*bufix], &ip, sizeof ip); - *bufix += sizeof ip; - - /* Fill out the UDP header */ - udp.uh_sport = local_port; /* XXX */ - udp.uh_dport = port; /* XXX */ - udp.uh_ulen = htons(sizeof(udp) + len); - memset (&udp.uh_sum, 0, sizeof udp.uh_sum); - - /* Compute UDP checksums, including the ``pseudo-header'', the UDP - header and the data. */ - -#if 0 - udp.uh_sum = - wrapsum (checksum ((unsigned char *)&udp, sizeof udp, - checksum (data, len, - checksum ((unsigned char *) - &ip.ip_src, - sizeof ip.ip_src, - IPPROTO_UDP + - (u_int32_t) - ntohs (udp.uh_ulen))))); -#endif - - /* Copy the udp header into the buffer... */ - memcpy (&buf [*bufix], &udp, sizeof udp); - *bufix += sizeof udp; -} -#endif /* PACKET_ASSEMBLY */ - -#ifdef PACKET_DECODING -/* Decode a hardware header... */ -/* XXX currently only supports ethernet; doesn't check for other types. */ - -size_t decode_hw_header (interface, buf, bufix, from) - struct interface_info *interface; - unsigned char *buf; - int bufix; - struct hardware *from; -{ - struct ether_header eh; - - memcpy (&eh, buf + bufix, sizeof eh); - -#ifdef USERLAND_FILTER - if (ntohs (eh.ether_type) != ETHERTYPE_IP) - return -1; -#endif - memcpy (from -> haddr, eh.ether_shost, sizeof (eh.ether_shost)); - from -> htype = ARPHRD_ETHER; - from -> hlen = sizeof eh.ether_shost; - - return sizeof eh; -} - -/* UDP header and IP header decoded together for convenience. */ - -size_t decode_udp_ip_header (interface, buf, bufix, from, data, len) - struct interface_info *interface; - unsigned char *buf; - int bufix; - struct sockaddr_in *from; - unsigned char *data; - int len; -{ - struct ip *ip; - struct udphdr *udp; - u_int32_t ip_len = (buf [bufix] & 0xf) << 2; - u_int32_t sum, usum; - - ip = (struct ip *)(buf + bufix); - udp = (struct udphdr *)(buf + bufix + ip_len); - -#ifdef USERLAND_FILTER - /* Is it a UDP packet? */ - if (ip -> ip_p != IPPROTO_UDP) - return -1; - - /* Is it to the port we're serving? */ - if (udp -> uh_dport != local_port) - return -1; -#endif /* USERLAND_FILTER */ - - /* Check the IP header checksum - it should be zero. */ - if (wrapsum (checksum (buf + bufix, ip_len, 0))) { - note ("Bad IP checksum: %x", - wrapsum (checksum (buf + bufix, sizeof *ip, 0))); - return -1; - } - - /* Copy out the IP source address... */ - memcpy (&from -> sin_addr, &ip -> ip_src, 4); - - /* Compute UDP checksums, including the ``pseudo-header'', the UDP - header and the data. If the UDP checksum field is zero, we're - not supposed to do a checksum. */ - - if (!data) { - data = buf + bufix + ip_len + sizeof *udp; - len -= ip_len + sizeof *udp; - } - -#if 0 - usum = udp -> uh_sum; - udp -> uh_sum = 0; - - sum = wrapsum (checksum ((unsigned char *)udp, sizeof *udp, - checksum (data, len, - checksum ((unsigned char *) - &ip -> ip_src, - sizeof ip -> ip_src, - IPPROTO_UDP + - (u_int32_t) - ntohs (udp -> uh_ulen))))); - - if (usum && usum != sum) { - note ("Bad udp checksum: %x %x", usum, sum); - return -1; - } -#endif - - /* Copy out the port... */ - memcpy (&from -> sin_port, &udp -> uh_sport, sizeof udp -> uh_sport); - - return ip_len + sizeof *udp; -} -#endif /* PACKET_DECODING */ diff --git a/common/print.c b/common/print.c deleted file mode 100644 index e43b58c0..00000000 --- a/common/print.c +++ /dev/null @@ -1,185 +0,0 @@ -/* print.c - - Turn data structures into printable text. */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: print.c,v 1.12 1997/02/22 08:32:05 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -char *print_hw_addr (htype, hlen, data) - int htype; - int hlen; - unsigned char *data; -{ - static char habuf [49]; - char *s; - int i; - - if (htype == 0 || hlen == 0) { - strcpy (habuf, "<null>"); - } else { - s = habuf; - for (i = 0; i < hlen; i++) { - sprintf (s, "%x", data [i]); - s += strlen (s); - *s++ = ':'; - } - *--s = 0; - } - return habuf; -} - -void print_lease (lease) - struct lease *lease; -{ - struct tm *t; - char tbuf [32]; - - debug (" Lease %s", - piaddr (lease -> ip_addr)); - - t = gmtime (&lease -> starts); - strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t); - debug (" start %s", tbuf); - - t = gmtime (&lease -> ends); - strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t); - debug (" end %s", tbuf); - - t = gmtime (&lease -> timestamp); - strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t); - debug (" stamp %s", tbuf); - - debug (" hardware addr = %s", - print_hw_addr (lease -> hardware_addr.htype, - lease -> hardware_addr.hlen, - lease -> hardware_addr.haddr)); - debug (" host %s state %x", - lease -> host ? lease -> host -> name : "<none>", - lease -> state); -} - -void dump_packet (tp) - struct packet *tp; -{ - struct dhcp_packet *tdp = tp -> raw; - - debug ("packet length %d", tp -> packet_length); - debug ("op = %d htype = %d hlen = %d hops = %d", - tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops); - debug ("xid = %x secs = %d flags = %x", - tdp -> xid, tdp -> secs, tdp -> flags); - debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr)); - debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr)); - debug ("siaddr = %s", inet_ntoa (tdp -> siaddr)); - debug ("giaddr = %s", inet_ntoa (tdp -> giaddr)); - debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x", - ((unsigned char *)(tdp -> chaddr)) [0], - ((unsigned char *)(tdp -> chaddr)) [1], - ((unsigned char *)(tdp -> chaddr)) [2], - ((unsigned char *)(tdp -> chaddr)) [3], - ((unsigned char *)(tdp -> chaddr)) [4], - ((unsigned char *)(tdp -> chaddr)) [5]); - debug ("filename = %s", tdp -> file); - debug ("server_name = %s", tdp -> sname); - if (tp -> options_valid) { - int i; - - for (i = 0; i < 256; i++) { - if (tp -> options [i].data) - debug (" %s = %s", - dhcp_options [i].name, - pretty_print_option - (i, tp -> options [i].data, - tp -> options [i].len, 1)); - } - } - debug (""); -} - -void dump_raw (buf, len) - unsigned char *buf; - int len; -{ - int i; - char lbuf [80]; - int lbix = 0; - - lbuf [0] = 0; - - for (i = 0; i < len; i++) { - if ((i & 15) == 0) { - if (lbix) - note (lbuf); - sprintf (lbuf, "%03x:", i); - lbix = 4; - } else if ((i & 7) == 0) - lbuf [lbix++] = ' '; - sprintf (&lbuf [lbix], " %02x", buf [i]); - lbix += 3; - } - note (lbuf); -} - -void hash_dump (table) - struct hash_table *table; -{ - int i; - struct hash_bucket *bp; - - if (!table) - return; - - for (i = 0; i < table -> hash_count; i++) { - if (!table -> buckets [i]) - continue; - note ("hash bucket %d:", i); - for (bp = table -> buckets [i]; bp; bp = bp -> next) { - if (bp -> len) - dump_raw (bp -> name, bp -> len); - else - note (bp -> name); - } - } -} diff --git a/common/raw.c b/common/raw.c deleted file mode 100644 index 6d764169..00000000 --- a/common/raw.c +++ /dev/null @@ -1,130 +0,0 @@ -/* socket.c - - BSD raw socket interface code... */ - -/* XXX - - It's not clear how this should work, and that lack of clarity is - terribly detrimental to the NetBSD 1.1 kernel - it crashes and - burns. - - Using raw sockets ought to be a big win over using BPF or something - like it, because you don't need to deal with the complexities of - the physical layer, but it appears not to be possible with existing - raw socket implementations. This may be worth revisiting in the - future. For now, this code can probably be considered a curiosity. - Sigh. */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. */ - -#ifndef lint -static char copyright[] = -"$Id: raw.c,v 1.10 1997/02/19 10:51:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -#if defined (USE_RAW_SEND) -#include <sys/uio.h> - -/* Generic interface registration routine... */ -void if_register_send (info) - struct interface_info *info; -{ - struct sockaddr_in name; - int sock; - struct socklist *tmp; - int flag; - - /* Set up the address we're going to connect to. */ - name.sin_family = AF_INET; - name.sin_port = local_port; - name.sin_addr.s_addr = htonl (INADDR_BROADCAST); - memset (name.sin_zero, 0, sizeof (name.sin_zero)); - - /* List addresses on which we're listening. */ - note ("Sending on %s, port %d", - piaddr (info -> address), htons (local_port)); - if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) - error ("Can't create dhcp socket: %m"); - - /* Set the BROADCAST option so that we can broadcast DHCP responses. */ - flag = 1; - if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, - &flag, sizeof flag) < 0) - error ("Can't set SO_BROADCAST option on dhcp socket: %m"); - - /* Set the IP_HDRINCL flag so that we can supply our own IP - headers... */ - if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0) - error ("Can't set IP_HDRINCL flag: %m"); - - info -> wfdesc = sock; - note ("Sending on Raw/%s/%s", - info -> name, - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} - -size_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; - struct dhcp_packet *raw; - size_t len; - struct in_addr from; - struct sockaddr_in *to; - struct hardware *hto; -{ - unsigned char buf [256]; - int bufp = 0; - struct iovec iov [2]; - - /* Assemble the headers... */ - assemble_udp_ip_header (interface, buf, &bufp, from.s_addr, - to -> sin_addr.s_addr, to -> sin_port, - (unsigned char *)raw, len); - - /* Fire it off */ - iov [0].iov_base = (char *)buf; - iov [0].iov_len = bufp; - iov [1].iov_base = (char *)raw; - iov [1].iov_len = len; - - return writev(interface -> wfdesc, iov, 2); -} -#endif /* USE_SOCKET_SEND */ diff --git a/common/socket.c b/common/socket.c deleted file mode 100644 index d9cee6e2..00000000 --- a/common/socket.c +++ /dev/null @@ -1,229 +0,0 @@ -/* socket.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 - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu). - * This sockopt allows a socket to be bound to a particular interface, - * thus enabling the use of DHCPD on a multihomed host. - * If SO_BINDTODEVICE is defined in your system header files, the use of - * this sockopt will be automatically enabled. - * I have implemented it under Linux; other systems should be doable also. - */ - -#ifndef lint -static char copyright[] = -"$Id: socket.c,v 1.20 1997/02/26 05:20:53 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -#ifdef USE_SOCKET_FALLBACK -# define USE_SOCKET_SEND -# define if_register_send if_register_fallback -# define send_packet send_fallback -# define if_reinitialize_send if_reinitialize_fallback -#endif - -static int once = 0; - -/* Reinitializes the specified interface after an address change. This - is not required for packet-filter APIs. */ - -#ifdef USE_SOCKET_SEND -void if_reinitialize_send (info) - struct interface_info *info; -{ -#if 0 -#ifndef USE_SOCKET_RECEIVE - once = 0; - close (info -> wfdesc); -#endif - if_register_send (info); -#endif -} -#endif - -#ifdef USE_SOCKET_RECEIVE -void if_reinitialize_receive (info) - struct interface_info *info; -{ -#if 0 - once = 0; - close (info -> rfdesc); - if_register_receive (info); -#endif -} -#endif - -#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) -/* Generic interface registration routine... */ -int if_register_socket (info) - struct interface_info *info; -{ - struct sockaddr_in name; - int sock; - int flag; - -#ifndef SO_BINDTODEVICE - /* Make sure only one interface is registered. */ - if (once) - error ("The standard socket API can only support %s%s%s%s%s", - "hosts with a single network interface. If you must ", - "run dhcpd on a host with multiple interfaces, ", - "you must compile in BPF or NIT support. If neither ", - "option is supported on your system, please let us ", - "know."); - once = 1; -#endif - - /* Set up the address we're going to bind to. */ - name.sin_family = AF_INET; - name.sin_port = local_port; - name.sin_addr.s_addr = INADDR_ANY; - memset (name.sin_zero, 0, sizeof (name.sin_zero)); - - /* Make a socket... */ - if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - error ("Can't create dhcp socket: %m"); - - /* Set the REUSEADDR option so that we don't fail to start if - we're being restarted. */ - flag = 1; - if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&flag, sizeof flag) < 0) - error ("Can't set SO_REUSEADDR option on dhcp socket: %m"); - - /* Set the BROADCAST option so that we can broadcast DHCP responses. */ - if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, - (char *)&flag, sizeof flag) < 0) - error ("Can't set SO_BROADCAST option on dhcp socket: %m"); - - /* Bind the socket to this interface's IP address. */ - if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0) - error ("Can't bind to dhcp address: %m"); - -#ifdef SO_BINDTODEVICE - /* Bind this socket to this interface. */ - if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE, - (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) { - error("setting SO_BINDTODEVICE"); - } -#endif - - return sock; -} -#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */ - -#ifdef USE_SOCKET_SEND -void if_register_send (info) - struct interface_info *info; -{ -#ifndef USE_SOCKET_RECEIVE - info -> wfdesc = if_register_socket (info); -#else - info -> wfdesc = info -> rfdesc; -#endif - note ("Sending on Socket/%s/%s", - info -> name, - (info -> shared_network ? - info -> shared_network -> name : "unattached")); - -} -#endif /* USE_SOCKET_SEND */ - -#ifdef USE_SOCKET_RECEIVE -void if_register_receive (info) - struct interface_info *info; -{ - /* If we're using the socket API for sending and receiving, - we don't need to register this interface twice. */ - info -> rfdesc = if_register_socket (info); - note ("Listening on Socket/%s/%s", - info -> name, - (info -> shared_network ? - info -> shared_network -> name : "unattached")); -} -#endif /* USE_SOCKET_RECEIVE */ - -#ifdef USE_SOCKET_SEND -size_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; - struct dhcp_packet *raw; - size_t len; - struct in_addr from; - struct sockaddr_in *to; - struct hardware *hto; -{ - return sendto (interface -> wfdesc, (char *)raw, len, 0, - (struct sockaddr *)to, sizeof *to); -} -#endif /* USE_SOCKET_SEND */ - -#ifdef USE_SOCKET_RECEIVE -size_t receive_packet (interface, buf, len, from, hfrom) - struct interface_info *interface; - unsigned char *buf; - size_t len; - struct sockaddr_in *from; - struct hardware *hfrom; -{ - int flen = sizeof *from; - - return recvfrom (interface -> rfdesc, buf, len, 0, - (struct sockaddr *)from, &flen); -} -#endif /* USE_SOCKET_RECEIVE */ - -#ifdef USE_SOCKET_FALLBACK -/* This just reads in a packet and silently discards it. */ - -size_t fallback_discard (interface) - struct interface_info *interface; -{ - char buf [1540]; - struct sockaddr_in from; - int flen = sizeof from; - - return recvfrom (interface -> wfdesc, buf, sizeof buf, 0, - (struct sockaddr *)&from, &flen); -} -#endif /* USE_SOCKET_RECEIVE */ diff --git a/common/tables.c b/common/tables.c deleted file mode 100644 index e5c6ca27..00000000 --- a/common/tables.c +++ /dev/null @@ -1,690 +0,0 @@ -/* tables.c - - Tables of information... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: tables.c,v 1.11 1996/09/11 06:34:25 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -/* DHCP Option names, formats and codes, from RFC1533. - - Format codes: - - e - end of data - I - IP address - l - 32-bit signed integer - L - 32-bit unsigned integer - s - 16-bit signed integer - S - 16-bit unsigned integer - b - 8-bit signed integer - B - 8-bit unsigned integer - t - ASCII text - f - flag (true or false) - A - array of whatever precedes (e.g., IA means array of IP addresses) -*/ - -struct universe dhcp_universe; -struct option dhcp_options [256] = { - { "pad", "", &dhcp_universe, 0 }, - { "subnet-mask", "I", &dhcp_universe, 1 }, - { "time-offset", "l", &dhcp_universe, 2 }, - { "routers", "IA", &dhcp_universe, 3 }, - { "time-servers", "IA", &dhcp_universe, 4 }, - { "name-servers", "IA", &dhcp_universe, 5 }, - { "domain-name-servers", "IA", &dhcp_universe, 6 }, - { "log-servers", "IA", &dhcp_universe, 7 }, - { "cookie-servers", "IA", &dhcp_universe, 8 }, - { "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 }, - { "boot-size", "S", &dhcp_universe, 13 }, - { "merit-dump", "t", &dhcp_universe, 14 }, - { "domain-name", "t", &dhcp_universe, 15 }, - { "swap-server", "I", &dhcp_universe, 16 }, - { "root-path", "t", &dhcp_universe, 17 }, - { "extensions-path", "t", &dhcp_universe, 18 }, - { "ip-forwarding", "f", &dhcp_universe, 19 }, - { "non-local-source-routing", "f", &dhcp_universe, 20 }, - { "policy-filter", "IIA", &dhcp_universe, 21 }, - { "max-dgram-reassembly", "S", &dhcp_universe, 22 }, - { "default-ip-ttl", "B", &dhcp_universe, 23 }, - { "path-mtu-aging-timeout", "L", &dhcp_universe, 24 }, - { "path-mtu-plateau-table", "SA", &dhcp_universe, 25 }, - { "interface-mtu", "S", &dhcp_universe, 26 }, - { "all-subnets-local", "f", &dhcp_universe, 27 }, - { "broadcast-address", "I", &dhcp_universe, 28 }, - { "perform-mask-discovery", "f", &dhcp_universe, 29 }, - { "mask-supplier", "f", &dhcp_universe, 30 }, - { "router-discovery", "f", &dhcp_universe, 31 }, - { "router-solicitation-address", "I", &dhcp_universe, 32 }, - { "static-routes", "IIA", &dhcp_universe, 33 }, - { "trailer-encapsulation", "f", &dhcp_universe, 34 }, - { "arp-cache-timeout", "L", &dhcp_universe, 35 }, - { "ieee802-3-encapsulation", "f", &dhcp_universe, 36 }, - { "default-tcp-ttl", "B", &dhcp_universe, 37 }, - { "tcp-keepalive-interval", "L", &dhcp_universe, 38 }, - { "tcp-keepalive-garbage", "f", &dhcp_universe, 39 }, - { "nis-domain", "t", &dhcp_universe, 40 }, - { "nis-servers", "IA", &dhcp_universe, 41 }, - { "ntp-servers", "IA", &dhcp_universe, 42 }, - { "vendor-encapsulated-options", "t", &dhcp_universe, 43 }, - { "netbios-name-servers", "IA", &dhcp_universe, 44 }, - { "netbios-dd-server", "IA", &dhcp_universe, 45 }, - { "netbios-node-type", "B", &dhcp_universe, 46 }, - { "netbios-scope", "t", &dhcp_universe, 47 }, - { "font-servers", "IA", &dhcp_universe, 48 }, - { "x-display-manager", "IA", &dhcp_universe, 49 }, - { "dhcp-requested-address", "I", &dhcp_universe, 50 }, - { "dhcp-lease-time", "L", &dhcp_universe, 51 }, - { "dhcp-option-overload", "B", &dhcp_universe, 52 }, - { "dhcp-message-type", "B", &dhcp_universe, 53 }, - { "dhcp-server-identifier", "I", &dhcp_universe, 54 }, - { "dhcp-parameter-request-list", "BA", &dhcp_universe, 55 }, - { "dhcp-message", "t", &dhcp_universe, 56 }, - { "dhcp-max-message-size", "S", &dhcp_universe, 57 }, - { "dhcp-renewal-time", "L", &dhcp_universe, 58 }, - { "dhcp-rebinding-time", "L", &dhcp_universe, 59 }, - { "dhcp-class-identifier", "t", &dhcp_universe, 60 }, - { "dhcp-client-identifier", "X", &dhcp_universe, 61 }, - { "option-62", "X", &dhcp_universe, 62 }, - { "option-63", "X", &dhcp_universe, 63 }, - { "option-64", "X", &dhcp_universe, 64 }, - { "option-65", "X", &dhcp_universe, 65 }, - { "option-66", "X", &dhcp_universe, 66 }, - { "option-67", "X", &dhcp_universe, 67 }, - { "option-68", "X", &dhcp_universe, 68 }, - { "option-69", "X", &dhcp_universe, 69 }, - { "option-70", "X", &dhcp_universe, 70 }, - { "option-71", "X", &dhcp_universe, 71 }, - { "option-72", "X", &dhcp_universe, 72 }, - { "option-73", "X", &dhcp_universe, 73 }, - { "option-74", "X", &dhcp_universe, 74 }, - { "option-75", "X", &dhcp_universe, 75 }, - { "option-76", "X", &dhcp_universe, 76 }, - { "dhcp-user-class-identifier", "t", &dhcp_universe, 77 }, - { "option-78", "X", &dhcp_universe, 78 }, - { "option-79", "X", &dhcp_universe, 79 }, - { "option-80", "X", &dhcp_universe, 80 }, - { "option-81", "X", &dhcp_universe, 81 }, - { "option-82", "X", &dhcp_universe, 82 }, - { "option-83", "X", &dhcp_universe, 83 }, - { "option-84", "X", &dhcp_universe, 84 }, - { "option-85", "X", &dhcp_universe, 85 }, - { "option-86", "X", &dhcp_universe, 86 }, - { "option-87", "X", &dhcp_universe, 87 }, - { "option-88", "X", &dhcp_universe, 88 }, - { "option-89", "X", &dhcp_universe, 89 }, - { "option-90", "X", &dhcp_universe, 90 }, - { "option-91", "X", &dhcp_universe, 91 }, - { "option-92", "X", &dhcp_universe, 92 }, - { "option-93", "X", &dhcp_universe, 93 }, - { "option-94", "X", &dhcp_universe, 94 }, - { "option-95", "X", &dhcp_universe, 95 }, - { "option-96", "X", &dhcp_universe, 96 }, - { "option-97", "X", &dhcp_universe, 97 }, - { "option-98", "X", &dhcp_universe, 98 }, - { "option-99", "X", &dhcp_universe, 99 }, - { "option-100", "X", &dhcp_universe, 100 }, - { "option-101", "X", &dhcp_universe, 101 }, - { "option-102", "X", &dhcp_universe, 102 }, - { "option-103", "X", &dhcp_universe, 103 }, - { "option-104", "X", &dhcp_universe, 104 }, - { "option-105", "X", &dhcp_universe, 105 }, - { "option-106", "X", &dhcp_universe, 106 }, - { "option-107", "X", &dhcp_universe, 107 }, - { "option-108", "X", &dhcp_universe, 108 }, - { "option-109", "X", &dhcp_universe, 109 }, - { "option-110", "X", &dhcp_universe, 110 }, - { "option-111", "X", &dhcp_universe, 111 }, - { "option-112", "X", &dhcp_universe, 112 }, - { "option-113", "X", &dhcp_universe, 113 }, - { "option-114", "X", &dhcp_universe, 114 }, - { "option-115", "X", &dhcp_universe, 115 }, - { "option-116", "X", &dhcp_universe, 116 }, - { "option-117", "X", &dhcp_universe, 117 }, - { "option-118", "X", &dhcp_universe, 118 }, - { "option-119", "X", &dhcp_universe, 119 }, - { "option-120", "X", &dhcp_universe, 120 }, - { "option-121", "X", &dhcp_universe, 121 }, - { "option-122", "X", &dhcp_universe, 122 }, - { "option-123", "X", &dhcp_universe, 123 }, - { "option-124", "X", &dhcp_universe, 124 }, - { "option-125", "X", &dhcp_universe, 125 }, - { "option-126", "X", &dhcp_universe, 126 }, - { "option-127", "X", &dhcp_universe, 127 }, - { "option-128", "X", &dhcp_universe, 128 }, - { "option-129", "X", &dhcp_universe, 129 }, - { "option-130", "X", &dhcp_universe, 130 }, - { "option-131", "X", &dhcp_universe, 131 }, - { "option-132", "X", &dhcp_universe, 132 }, - { "option-133", "X", &dhcp_universe, 133 }, - { "option-134", "X", &dhcp_universe, 134 }, - { "option-135", "X", &dhcp_universe, 135 }, - { "option-136", "X", &dhcp_universe, 136 }, - { "option-137", "X", &dhcp_universe, 137 }, - { "option-138", "X", &dhcp_universe, 138 }, - { "option-139", "X", &dhcp_universe, 139 }, - { "option-140", "X", &dhcp_universe, 140 }, - { "option-141", "X", &dhcp_universe, 141 }, - { "option-142", "X", &dhcp_universe, 142 }, - { "option-143", "X", &dhcp_universe, 143 }, - { "option-144", "X", &dhcp_universe, 144 }, - { "option-145", "X", &dhcp_universe, 145 }, - { "option-146", "X", &dhcp_universe, 146 }, - { "option-147", "X", &dhcp_universe, 147 }, - { "option-148", "X", &dhcp_universe, 148 }, - { "option-149", "X", &dhcp_universe, 149 }, - { "option-150", "X", &dhcp_universe, 150 }, - { "option-151", "X", &dhcp_universe, 151 }, - { "option-152", "X", &dhcp_universe, 152 }, - { "option-153", "X", &dhcp_universe, 153 }, - { "option-154", "X", &dhcp_universe, 154 }, - { "option-155", "X", &dhcp_universe, 155 }, - { "option-156", "X", &dhcp_universe, 156 }, - { "option-157", "X", &dhcp_universe, 157 }, - { "option-158", "X", &dhcp_universe, 158 }, - { "option-159", "X", &dhcp_universe, 159 }, - { "option-160", "X", &dhcp_universe, 160 }, - { "option-161", "X", &dhcp_universe, 161 }, - { "option-162", "X", &dhcp_universe, 162 }, - { "option-163", "X", &dhcp_universe, 163 }, - { "option-164", "X", &dhcp_universe, 164 }, - { "option-165", "X", &dhcp_universe, 165 }, - { "option-166", "X", &dhcp_universe, 166 }, - { "option-167", "X", &dhcp_universe, 167 }, - { "option-168", "X", &dhcp_universe, 168 }, - { "option-169", "X", &dhcp_universe, 169 }, - { "option-170", "X", &dhcp_universe, 170 }, - { "option-171", "X", &dhcp_universe, 171 }, - { "option-172", "X", &dhcp_universe, 172 }, - { "option-173", "X", &dhcp_universe, 173 }, - { "option-174", "X", &dhcp_universe, 174 }, - { "option-175", "X", &dhcp_universe, 175 }, - { "option-176", "X", &dhcp_universe, 176 }, - { "option-177", "X", &dhcp_universe, 177 }, - { "option-178", "X", &dhcp_universe, 178 }, - { "option-179", "X", &dhcp_universe, 179 }, - { "option-180", "X", &dhcp_universe, 180 }, - { "option-181", "X", &dhcp_universe, 181 }, - { "option-182", "X", &dhcp_universe, 182 }, - { "option-183", "X", &dhcp_universe, 183 }, - { "option-184", "X", &dhcp_universe, 184 }, - { "option-185", "X", &dhcp_universe, 185 }, - { "option-186", "X", &dhcp_universe, 186 }, - { "option-187", "X", &dhcp_universe, 187 }, - { "option-188", "X", &dhcp_universe, 188 }, - { "option-189", "X", &dhcp_universe, 189 }, - { "option-190", "X", &dhcp_universe, 190 }, - { "option-191", "X", &dhcp_universe, 191 }, - { "option-192", "X", &dhcp_universe, 192 }, - { "option-193", "X", &dhcp_universe, 193 }, - { "option-194", "X", &dhcp_universe, 194 }, - { "option-195", "X", &dhcp_universe, 195 }, - { "option-196", "X", &dhcp_universe, 196 }, - { "option-197", "X", &dhcp_universe, 197 }, - { "option-198", "X", &dhcp_universe, 198 }, - { "option-199", "X", &dhcp_universe, 199 }, - { "option-200", "X", &dhcp_universe, 200 }, - { "option-201", "X", &dhcp_universe, 201 }, - { "option-202", "X", &dhcp_universe, 202 }, - { "option-203", "X", &dhcp_universe, 203 }, - { "option-204", "X", &dhcp_universe, 204 }, - { "option-205", "X", &dhcp_universe, 205 }, - { "option-206", "X", &dhcp_universe, 206 }, - { "option-207", "X", &dhcp_universe, 207 }, - { "option-208", "X", &dhcp_universe, 208 }, - { "option-209", "X", &dhcp_universe, 209 }, - { "option-210", "X", &dhcp_universe, 210 }, - { "option-211", "X", &dhcp_universe, 211 }, - { "option-212", "X", &dhcp_universe, 212 }, - { "option-213", "X", &dhcp_universe, 213 }, - { "option-214", "X", &dhcp_universe, 214 }, - { "option-215", "X", &dhcp_universe, 215 }, - { "option-216", "X", &dhcp_universe, 216 }, - { "option-217", "X", &dhcp_universe, 217 }, - { "option-218", "X", &dhcp_universe, 218 }, - { "option-219", "X", &dhcp_universe, 219 }, - { "option-220", "X", &dhcp_universe, 220 }, - { "option-221", "X", &dhcp_universe, 221 }, - { "option-222", "X", &dhcp_universe, 222 }, - { "option-223", "X", &dhcp_universe, 223 }, - { "option-224", "X", &dhcp_universe, 224 }, - { "option-225", "X", &dhcp_universe, 225 }, - { "option-226", "X", &dhcp_universe, 226 }, - { "option-227", "X", &dhcp_universe, 227 }, - { "option-228", "X", &dhcp_universe, 228 }, - { "option-229", "X", &dhcp_universe, 229 }, - { "option-230", "X", &dhcp_universe, 230 }, - { "option-231", "X", &dhcp_universe, 231 }, - { "option-232", "X", &dhcp_universe, 232 }, - { "option-233", "X", &dhcp_universe, 233 }, - { "option-234", "X", &dhcp_universe, 234 }, - { "option-235", "X", &dhcp_universe, 235 }, - { "option-236", "X", &dhcp_universe, 236 }, - { "option-237", "X", &dhcp_universe, 237 }, - { "option-238", "X", &dhcp_universe, 238 }, - { "option-239", "X", &dhcp_universe, 239 }, - { "option-240", "X", &dhcp_universe, 240 }, - { "option-241", "X", &dhcp_universe, 241 }, - { "option-242", "X", &dhcp_universe, 242 }, - { "option-243", "X", &dhcp_universe, 243 }, - { "option-244", "X", &dhcp_universe, 244 }, - { "option-245", "X", &dhcp_universe, 245 }, - { "option-246", "X", &dhcp_universe, 246 }, - { "option-247", "X", &dhcp_universe, 247 }, - { "option-248", "X", &dhcp_universe, 248 }, - { "option-249", "X", &dhcp_universe, 249 }, - { "option-250", "X", &dhcp_universe, 250 }, - { "option-251", "X", &dhcp_universe, 251 }, - { "option-252", "X", &dhcp_universe, 252 }, - { "option-253", "X", &dhcp_universe, 253 }, - { "option-254", "X", &dhcp_universe, 254 }, - { "option-end", "e", &dhcp_universe, 255 }, -}; - -/* Default dhcp option priority list (this is ad hoc and should not be - mistaken for a carefully crafted and optimized list). */ -unsigned char dhcp_option_default_priority_list [] = { - DHO_DHCP_REQUESTED_ADDRESS, - DHO_DHCP_OPTION_OVERLOAD, - DHO_DHCP_MAX_MESSAGE_SIZE, - DHO_DHCP_RENEWAL_TIME, - DHO_DHCP_REBINDING_TIME, - DHO_DHCP_CLASS_IDENTIFIER, - DHO_DHCP_CLIENT_IDENTIFIER, - DHO_SUBNET_MASK, - DHO_TIME_OFFSET, - DHO_ROUTERS, - DHO_TIME_SERVERS, - DHO_NAME_SERVERS, - DHO_DOMAIN_NAME_SERVERS, - DHO_HOST_NAME, - DHO_LOG_SERVERS, - DHO_COOKIE_SERVERS, - DHO_LPR_SERVERS, - DHO_IMPRESS_SERVERS, - DHO_RESOURCE_LOCATION_SERVERS, - DHO_HOST_NAME, - DHO_BOOT_SIZE, - DHO_MERIT_DUMP, - DHO_DOMAIN_NAME, - DHO_SWAP_SERVER, - DHO_ROOT_PATH, - DHO_EXTENSIONS_PATH, - DHO_IP_FORWARDING, - DHO_NON_LOCAL_SOURCE_ROUTING, - DHO_POLICY_FILTER, - DHO_MAX_DGRAM_REASSEMBLY, - DHO_DEFAULT_IP_TTL, - DHO_PATH_MTU_AGING_TIMEOUT, - DHO_PATH_MTU_PLATEAU_TABLE, - DHO_INTERFACE_MTU, - DHO_ALL_SUBNETS_LOCAL, - DHO_BROADCAST_ADDRESS, - DHO_PERFORM_MASK_DISCOVERY, - DHO_MASK_SUPPLIER, - DHO_ROUTER_DISCOVERY, - DHO_ROUTER_SOLICITATION_ADDRESS, - DHO_STATIC_ROUTES, - DHO_TRAILER_ENCAPSULATION, - DHO_ARP_CACHE_TIMEOUT, - DHO_IEEE802_3_ENCAPSULATION, - DHO_DEFAULT_TCP_TTL, - DHO_TCP_KEEPALIVE_INTERVAL, - DHO_TCP_KEEPALIVE_GARBAGE, - DHO_NIS_DOMAIN, - DHO_NIS_SERVERS, - DHO_NTP_SERVERS, - DHO_VENDOR_ENCAPSULATED_OPTIONS, - DHO_NETBIOS_NAME_SERVERS, - DHO_NETBIOS_DD_SERVER, - DHO_NETBIOS_NODE_TYPE, - DHO_NETBIOS_SCOPE, - DHO_FONT_SERVERS, - DHO_X_DISPLAY_MANAGER, - DHO_DHCP_PARAMETER_REQUEST_LIST, - - /* Presently-undefined options... */ - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, -}; - -int sizeof_dhcp_option_default_priority_list = - sizeof dhcp_option_default_priority_list; - - -char *hardware_types [] = { - "unknown-0", - "ethernet", - "unknown-2", - "unknown-3", - "unknown-4", - "unknown-5", - "token-ring", - "unknown-7", - "unknown-8", - "unknown-9", - "unknown-10", - "unknown-11", - "unknown-12", - "unknown-13", - "unknown-14", - "unknown-15", - "unknown-16", - "unknown-17", - "unknown-18", - "unknown-19", - "unknown-20", - "unknown-21", - "unknown-22", - "unknown-23", - "unknown-24", - "unknown-25", - "unknown-26", - "unknown-27", - "unknown-28", - "unknown-29", - "unknown-30", - "unknown-31", - "unknown-32", - "unknown-33", - "unknown-34", - "unknown-35", - "unknown-36", - "unknown-37", - "unknown-38", - "unknown-39", - "unknown-40", - "unknown-41", - "unknown-42", - "unknown-43", - "unknown-44", - "unknown-45", - "unknown-46", - "unknown-47", - "unknown-48", - "unknown-49", - "unknown-50", - "unknown-51", - "unknown-52", - "unknown-53", - "unknown-54", - "unknown-55", - "unknown-56", - "unknown-57", - "unknown-58", - "unknown-59", - "unknown-60", - "unknown-61", - "unknown-62", - "unknown-63", - "unknown-64", - "unknown-65", - "unknown-66", - "unknown-67", - "unknown-68", - "unknown-69", - "unknown-70", - "unknown-71", - "unknown-72", - "unknown-73", - "unknown-74", - "unknown-75", - "unknown-76", - "unknown-77", - "unknown-78", - "unknown-79", - "unknown-80", - "unknown-81", - "unknown-82", - "unknown-83", - "unknown-84", - "unknown-85", - "unknown-86", - "unknown-87", - "unknown-88", - "unknown-89", - "unknown-90", - "unknown-91", - "unknown-92", - "unknown-93", - "unknown-94", - "unknown-95", - "unknown-96", - "unknown-97", - "unknown-98", - "unknown-99", - "unknown-100", - "unknown-101", - "unknown-102", - "unknown-103", - "unknown-104", - "unknown-105", - "unknown-106", - "unknown-107", - "unknown-108", - "unknown-109", - "unknown-110", - "unknown-111", - "unknown-112", - "unknown-113", - "unknown-114", - "unknown-115", - "unknown-116", - "unknown-117", - "unknown-118", - "unknown-119", - "unknown-120", - "unknown-121", - "unknown-122", - "unknown-123", - "unknown-124", - "unknown-125", - "unknown-126", - "unknown-127", - "unknown-128", - "unknown-129", - "unknown-130", - "unknown-131", - "unknown-132", - "unknown-133", - "unknown-134", - "unknown-135", - "unknown-136", - "unknown-137", - "unknown-138", - "unknown-139", - "unknown-140", - "unknown-141", - "unknown-142", - "unknown-143", - "unknown-144", - "unknown-145", - "unknown-146", - "unknown-147", - "unknown-148", - "unknown-149", - "unknown-150", - "unknown-151", - "unknown-152", - "unknown-153", - "unknown-154", - "unknown-155", - "unknown-156", - "unknown-157", - "unknown-158", - "unknown-159", - "unknown-160", - "unknown-161", - "unknown-162", - "unknown-163", - "unknown-164", - "unknown-165", - "unknown-166", - "unknown-167", - "unknown-168", - "unknown-169", - "unknown-170", - "unknown-171", - "unknown-172", - "unknown-173", - "unknown-174", - "unknown-175", - "unknown-176", - "unknown-177", - "unknown-178", - "unknown-179", - "unknown-180", - "unknown-181", - "unknown-182", - "unknown-183", - "unknown-184", - "unknown-185", - "unknown-186", - "unknown-187", - "unknown-188", - "unknown-189", - "unknown-190", - "unknown-191", - "unknown-192", - "unknown-193", - "unknown-194", - "unknown-195", - "unknown-196", - "unknown-197", - "unknown-198", - "unknown-199", - "unknown-200", - "unknown-201", - "unknown-202", - "unknown-203", - "unknown-204", - "unknown-205", - "unknown-206", - "unknown-207", - "unknown-208", - "unknown-209", - "unknown-210", - "unknown-211", - "unknown-212", - "unknown-213", - "unknown-214", - "unknown-215", - "unknown-216", - "unknown-217", - "unknown-218", - "unknown-219", - "unknown-220", - "unknown-221", - "unknown-222", - "unknown-223", - "unknown-224", - "unknown-225", - "unknown-226", - "unknown-227", - "unknown-228", - "unknown-229", - "unknown-230", - "unknown-231", - "unknown-232", - "unknown-233", - "unknown-234", - "unknown-235", - "unknown-236", - "unknown-237", - "unknown-238", - "unknown-239", - "unknown-240", - "unknown-241", - "unknown-242", - "unknown-243", - "unknown-244", - "unknown-245", - "unknown-246", - "unknown-247", - "unknown-248", - "unknown-249", - "unknown-250", - "unknown-251", - "unknown-252", - "unknown-253", - "unknown-254", - "unknown-255" }; - - - -struct hash_table universe_hash; - -void initialize_universes() -{ - int i; - - dhcp_universe.name = "dhcp"; - dhcp_universe.hash = new_hash (); - if (!dhcp_universe.hash) - error ("Can't allocate dhcp option hash table."); - for (i = 0; i < 256; i++) { - dhcp_universe.options [i] = &dhcp_options [i]; - add_hash (dhcp_universe.hash, dhcp_options [i].name, 0, - (unsigned char *)&dhcp_options [i]); - } - universe_hash.hash_count = DEFAULT_HASH_SIZE; - add_hash (&universe_hash, dhcp_universe.name, 0, - (unsigned char *)&dhcp_universe); -} diff --git a/common/tree.c b/common/tree.c deleted file mode 100644 index 8168522a..00000000 --- a/common/tree.c +++ /dev/null @@ -1,408 +0,0 @@ -/* tree.c - - Routines for manipulating parse trees... */ - -/* - * Copyright (c) 1995, 1996 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 - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This software has been written for the Internet Software Consortium - * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. - */ - -#ifndef lint -static char copyright[] = -"$Id: tree.c,v 1.9 1996/08/27 09:55:50 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; -#endif /* not lint */ - -#include "dhcpd.h" - -static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *, - struct tree *)); -static TIME do_host_lookup PROTO ((int *, unsigned char **, int *, - struct dns_host_entry *)); -static void do_data_copy PROTO ((int *, unsigned char **, int *, - unsigned char *, int)); - -pair cons (car, cdr) - caddr_t car; - pair cdr; -{ - pair foo = (pair)dmalloc (sizeof *foo, "cons"); - if (!foo) - error ("no memory for cons."); - foo -> car = car; - foo -> cdr = cdr; - return foo; -} - -struct tree_cache *tree_cache (tree) - struct tree *tree; -{ - struct tree_cache *tc; - - tc = new_tree_cache ("tree_cache"); - if (!tc) - return 0; - tc -> value = (unsigned char *)0; - tc -> len = tc -> buf_size = 0; - tc -> timeout = 0; - tc -> tree = tree; - return tc; -} - -struct tree *tree_host_lookup (name) - char *name; -{ - struct tree *nt; - nt = new_tree ("tree_host_lookup"); - if (!nt) - error ("No memory for host lookup tree node."); - nt -> op = TREE_HOST_LOOKUP; - nt -> data.host_lookup.host = enter_dns_host (name); - return nt; -} - -struct dns_host_entry *enter_dns_host (name) - char *name; -{ - struct dns_host_entry *dh; - - if (!(dh = (struct dns_host_entry *)dmalloc - (sizeof (struct dns_host_entry), "enter_dns_host")) - || !(dh -> hostname = dmalloc (strlen (name) + 1, - "enter_dns_host"))) - error ("Can't allocate space for new host."); - strcpy (dh -> hostname, name); - dh -> data = (unsigned char *)0; - dh -> data_len = 0; - dh -> buf_len = 0; - dh -> timeout = 0; - return dh; -} - -struct tree *tree_const (data, len) - unsigned char *data; - int len; -{ - struct tree *nt; - if (!(nt = new_tree ("tree_const")) - || !(nt -> data.const_val.data = - (unsigned char *)dmalloc (len, "tree_const"))) - error ("No memory for constant data tree node."); - nt -> op = TREE_CONST; - memcpy (nt -> data.const_val.data, data, len); - nt -> data.const_val.len = len; - return nt; -} - -struct tree *tree_concat (left, right) - struct tree *left, *right; -{ - struct tree *nt; - - /* If we're concatenating a null tree to a non-null tree, just - return the non-null tree; if both trees are null, return - a null tree. */ - if (!left) - return right; - if (!right) - return left; - - /* If both trees are constant, combine them. */ - if (left -> op == TREE_CONST && right -> op == TREE_CONST) { - unsigned char *buf = dmalloc (left -> data.const_val.len - + right -> data.const_val.len, - "tree_concat"); - if (!buf) - error ("No memory to concatenate constants."); - memcpy (buf, left -> data.const_val.data, - left -> data.const_val.len); - memcpy (buf + left -> data.const_val.len, - right -> data.const_val.data, - right -> data.const_val.len); - dfree (left -> data.const_val.data, "tree_concat"); - dfree (right -> data.const_val.data, "tree_concat"); - left -> data.const_val.data = buf; - left -> data.const_val.len += right -> data.const_val.len; - free_tree (right, "tree_concat"); - return left; - } - - /* Otherwise, allocate a new node to concatenate the two. */ - if (!(nt = new_tree ("tree_concat"))) - error ("No memory for data tree concatenation node."); - nt -> op = TREE_CONCAT; - nt -> data.concat.left = left; - nt -> data.concat.right = right; - return nt; -} - -struct tree *tree_limit (tree, limit) - struct tree *tree; - int limit; -{ - struct tree *rv; - - /* If the tree we're limiting is constant, limit it now. */ - if (tree -> op == TREE_CONST) { - if (tree -> data.const_val.len > limit) - tree -> data.const_val.len = limit; - return tree; - } - - /* Otherwise, put in a node which enforces the limit on evaluation. */ - rv = new_tree ("tree_limit"); - if (!rv) - return (struct tree *)0; - rv -> op = TREE_LIMIT; - rv -> data.limit.tree = tree; - rv -> data.limit.limit = limit; - return rv; -} - -int tree_evaluate (tree_cache) - struct tree_cache *tree_cache; -{ - unsigned char *bp = tree_cache -> value; - int bc = tree_cache -> buf_size; - int bufix = 0; - - /* If there's no tree associated with this cache, it evaluates - to a constant and that was detected at startup. */ - if (!tree_cache -> tree) - return 1; - - /* Try to evaluate the tree without allocating more memory... */ - tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc, - tree_cache -> tree); - - /* No additional allocation needed? */ - if (bufix <= bc) { - tree_cache -> len = bufix; - return 1; - } - - /* If we can't allocate more memory, return with what we - have (maybe nothing). */ - if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate"))) - return 0; - - /* Record the change in conditions... */ - bc = bufix; - bufix = 0; - - /* Note that the size of the result shouldn't change on the - second call to tree_evaluate_recurse, since we haven't - changed the ``current'' time. */ - tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree); - - /* Free the old buffer if needed, then store the new buffer - location and size and return. */ - if (tree_cache -> value) - dfree (tree_cache -> value, "tree_evaluate"); - tree_cache -> value = bp; - tree_cache -> len = bufix; - tree_cache -> buf_size = bc; - return 1; -} - -static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree) - int *bufix; - unsigned char **bufp; - int *bufcount; - struct tree *tree; -{ - int limit; - TIME t1, t2; - - switch (tree -> op) { - case TREE_CONCAT: - t1 = tree_evaluate_recurse (bufix, bufp, bufcount, - tree -> data.concat.left); - t2 = tree_evaluate_recurse (bufix, bufp, bufcount, - tree -> data.concat.right); - if (t1 > t2) - return t2; - return t1; - - case TREE_HOST_LOOKUP: - return do_host_lookup (bufix, bufp, bufcount, - tree -> data.host_lookup.host); - - case TREE_CONST: - do_data_copy (bufix, bufp, bufcount, - tree -> data.const_val.data, - tree -> data.const_val.len); - t1 = MAX_TIME; - return t1; - - case TREE_LIMIT: - limit = *bufix + tree -> data.limit.limit; - t1 = tree_evaluate_recurse (bufix, bufp, bufcount, - tree -> data.limit.tree); - *bufix = limit; - return t1; - - default: - warn ("Bad node id in tree: %d."); - t1 = MAX_TIME; - return t1; - } -} - -static TIME do_host_lookup (bufix, bufp, bufcount, dns) - int *bufix; - unsigned char **bufp; - int *bufcount; - struct dns_host_entry *dns; -{ - struct hostent *h; - int i; - int new_len; - -#ifdef DEBUG_EVAL - debug ("time: now = %d dns = %d %d diff = %d", - cur_time, dns -> timeout, cur_time - dns -> timeout); -#endif - - /* If the record hasn't timed out, just copy the data and return. */ - if (cur_time <= dns -> timeout) { -#ifdef DEBUG_EVAL - debug ("easy copy: %x %d %x", - dns -> data, dns -> data_len, - dns -> data ? *(int *)(dns -> data) : 0); -#endif - do_data_copy (bufix, bufp, bufcount, - dns -> data, dns -> data_len); - return dns -> timeout; - } -#ifdef DEBUG_EVAL - debug ("Looking up %s", dns -> hostname); -#endif - - /* Otherwise, look it up... */ - h = gethostbyname (dns -> hostname); - if (!h) { - switch (h_errno) { - case HOST_NOT_FOUND: - warn ("%s: host unknown.", dns -> hostname); - break; - case TRY_AGAIN: - warn ("%s: temporary name server failure", - dns -> hostname); - break; - case NO_RECOVERY: - warn ("%s: name server failed", dns -> hostname); - break; - case NO_DATA: - warn ("%s: no A record associated with address", - dns -> hostname); - } - - /* Okay to try again after a minute. */ - return cur_time + 60; - } - -#ifdef DEBUG_EVAL - debug ("Lookup succeeded; first address is %x", - h -> h_addr_list [0]); -#endif - - /* Count the number of addresses we got... */ - for (i = 0; h -> h_addr_list [i]; i++) - ; - - /* Do we need to allocate more memory? */ - new_len = i * h -> h_length; - if (dns -> buf_len < i) { - unsigned char *buf = - (unsigned char *)dmalloc (new_len, "do_host_lookup"); - /* If we didn't get more memory, use what we have. */ - if (!buf) { - new_len = dns -> buf_len; - if (!dns -> buf_len) { - dns -> timeout = cur_time + 60; - return dns -> timeout; - } - } else { - if (dns -> data) - dfree (dns -> data, "do_host_lookup"); - dns -> data = buf; - dns -> buf_len = new_len; - } - } - - /* Addresses are conveniently stored one to the buffer, so we - have to copy them out one at a time... :'( */ - for (i = 0; i < new_len / h -> h_length; i++) { - memcpy (dns -> data + h -> h_length * i, - h -> h_addr_list [i], h -> h_length); - } -#ifdef DEBUG_EVAL - debug ("dns -> data: %x h -> h_addr_list [0]: %x", - *(int *)(dns -> data), h -> h_addr_list [0]); -#endif - dns -> data_len = new_len; - - /* Set the timeout for an hour from now. - XXX This should really use the time on the DNS reply. */ - dns -> timeout = cur_time + 3600; - -#ifdef DEBUG_EVAL - debug ("hard copy: %x %d %x", - dns -> data, dns -> data_len, *(int *)(dns -> data)); -#endif - do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len); - return dns -> timeout; -} - -static void do_data_copy (bufix, bufp, bufcount, data, len) - int *bufix; - unsigned char **bufp; - int *bufcount; - unsigned char *data; - int len; -{ - int space = *bufcount - *bufix; - - /* If there's more space than we need, use only what we need. */ - if (space > len) - space = len; - - /* Copy as much data as will fit, then increment the buffer index - by the amount we actually had to copy, which could be more. */ - if (space > 0) - memcpy (*bufp + *bufix, data, space); - *bufix += len; -} |