summaryrefslogtreecommitdiffstats
path: root/contrib/isc-dhcp/common
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2005-06-29 01:46:40 +0000
committerbrooks <brooks@FreeBSD.org>2005-06-29 01:46:40 +0000
commitbd7fc02cf00f7446a4fc2151d3367d5e935dacae (patch)
treec334ad76a77de064f9dde5e545e004461813e6a5 /contrib/isc-dhcp/common
parent37efc775b590475026ff6366785a1b78bcb697f5 (diff)
downloadFreeBSD-src-bd7fc02cf00f7446a4fc2151d3367d5e935dacae.zip
FreeBSD-src-bd7fc02cf00f7446a4fc2151d3367d5e935dacae.tar.gz
Remove isc-dhcp files from HEAD now that we're using the OpenBSD
dhclient. Reminded by: ru Approved by: re (blanket dhclient)
Diffstat (limited to 'contrib/isc-dhcp/common')
-rw-r--r--contrib/isc-dhcp/common/Makefile.dist95
-rw-r--r--contrib/isc-dhcp/common/alloc.c1317
-rw-r--r--contrib/isc-dhcp/common/bpf.c548
-rw-r--r--contrib/isc-dhcp/common/comapi.c949
-rw-r--r--contrib/isc-dhcp/common/conflex.c1073
-rw-r--r--contrib/isc-dhcp/common/ctrace.c293
-rw-r--r--contrib/isc-dhcp/common/dhcp-eval.5477
-rw-r--r--contrib/isc-dhcp/common/dhcp-options.51523
-rw-r--r--contrib/isc-dhcp/common/discover.c1138
-rw-r--r--contrib/isc-dhcp/common/dispatch.c238
-rw-r--r--contrib/isc-dhcp/common/dlpi.c1336
-rw-r--r--contrib/isc-dhcp/common/dns.c953
-rw-r--r--contrib/isc-dhcp/common/ethernet.c98
-rw-r--r--contrib/isc-dhcp/common/execute.c1052
-rw-r--r--contrib/isc-dhcp/common/fddi.c97
-rw-r--r--contrib/isc-dhcp/common/icmp.c317
-rw-r--r--contrib/isc-dhcp/common/inet.c233
-rw-r--r--contrib/isc-dhcp/common/iscprint.c539
-rw-r--r--contrib/isc-dhcp/common/lpf.c410
-rw-r--r--contrib/isc-dhcp/common/memory.c161
-rw-r--r--contrib/isc-dhcp/common/nit.c420
-rw-r--r--contrib/isc-dhcp/common/options.c2248
-rw-r--r--contrib/isc-dhcp/common/packet.c339
-rw-r--r--contrib/isc-dhcp/common/parse.c4844
-rw-r--r--contrib/isc-dhcp/common/print.c1405
-rw-r--r--contrib/isc-dhcp/common/raw.c144
-rw-r--r--contrib/isc-dhcp/common/resolv.c203
-rw-r--r--contrib/isc-dhcp/common/socket.c371
-rw-r--r--contrib/isc-dhcp/common/tables.c1241
-rw-r--r--contrib/isc-dhcp/common/tr.c335
-rw-r--r--contrib/isc-dhcp/common/tree.c4095
-rw-r--r--contrib/isc-dhcp/common/upf.c371
32 files changed, 0 insertions, 28863 deletions
diff --git a/contrib/isc-dhcp/common/Makefile.dist b/contrib/isc-dhcp/common/Makefile.dist
deleted file mode 100644
index 8d4e043..0000000
--- a/contrib/isc-dhcp/common/Makefile.dist
+++ /dev/null
@@ -1,95 +0,0 @@
-# Makefile.dist
-#
-# Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# Internet Systems Consortium, Inc.
-# 950 Charter Street
-# Redwood City, CA 94063
-# <info@isc.org>
-# http://www.isc.org/
-
-CATMANPAGES = dhcp-options.cat5 dhcp-eval.cat5
-SEDMANPAGES = dhcp-options.man5 dhcp-eval.man5
-SRC = raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c socket.c \
- lpf.c dlpi.c packet.c tr.c ethernet.c iscprint.c memory.c print.c \
- options.c inet.c tree.c tables.c alloc.c fddi.c ctrace.c dns.c \
- resolv.c execute.c discover.c comapi.c
-OBJ = raw.o parse.o nit.o icmp.o dispatch.o conflex.o upf.o bpf.o socket.o \
- lpf.o dlpi.o packet.o tr.o ethernet.o iscprint.o memory.o print.o \
- options.o inet.o tree.o tables.o alloc.o fddi.o ctrace.o dns.o \
- resolv.o execute.o discover.o comapi.o
-MAN = dhcp-options.5 dhcp-eval.5
-
-INCLUDES = -I$(TOP) $(BINDINC) -I$(TOP)/includes
-CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
-
-all: libdhcp.a $(CATMANPAGES)
-
-libdhcp.a: $(OBJ)
- rm -f libdhcp.a
- ar cruv libdhcp.a $(OBJ)
- $(RANLIB) libdhcp.a
-
-install: all
- for dir in $(FFMANDIR); do \
- foo=""; \
- for bar in `echo $(DESTDIR)$${dir} |tr / ' '`; do \
- foo=$${foo}/$$bar; \
- if [ ! -d $$foo ]; then \
- mkdir $$foo; \
- chmod 755 $$foo; \
- fi; \
- done; \
- done
- $(MANINSTALL) $(MANFROM) dhcp-options.$(MANCAT)5 $(MANTO) \
- $(DESTDIR)$(FFMANDIR)/dhcp-options$(FFMANEXT)
- $(MANINSTALL) $(MANFROM) dhcp-eval.$(MANCAT)5 $(MANTO) \
- $(DESTDIR)$(FFMANDIR)/dhcp-eval$(FFMANEXT)
-
-depend:
- $(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRC)
-
-clean:
- -rm -f $(OBJ)
-
-realclean: clean
- -rm -f libdhcp.a $(CATMANPAGES) $(SEDMANPAGES) *~ #*
-
-distclean: realclean
- -rm -f Makefile
-
-links:
- @for foo in $(SRC) $(MAN); do \
- if [ ! -b $$foo ]; then \
- rm -f $$foo; \
- fi; \
- ln -s $(TOP)/common/$$foo $$foo; \
- done
-
-dhcp-options.cat5: dhcp-options.man5
- nroff -man dhcp-options.man5 >dhcp-options.cat5
-
-dhcp-options.man5: dhcp-options.5
- sed -e "s#ETCDIR#$(ETC)#g" -e "s#DBDIR#$(VARDB)#g" \
- -e "s#RUNDIR#$(VARRUN)#g" < dhcp-options.5 >dhcp-options.man5
-
-dhcp-eval.cat5: dhcp-eval.man5
- nroff -man dhcp-eval.man5 >dhcp-eval.cat5
-
-dhcp-eval.man5: dhcp-eval.5
- sed -e "s#ETCDIR#$(ETC)#g" -e "s#DBDIR#$(VARDB)#g" \
- -e "s#RUNDIR#$(VARRUN)#g" < dhcp-eval.5 >dhcp-eval.man5
-
-# Dependencies (semi-automatically-generated)
diff --git a/contrib/isc-dhcp/common/alloc.c b/contrib/isc-dhcp/common/alloc.c
deleted file mode 100644
index 39edd81..0000000
--- a/contrib/isc-dhcp/common/alloc.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/* alloc.c
-
- Memory allocation... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: alloc.c,v 1.53.2.10 2004/06/10 17:59:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <omapip/omapip_p.h>
-
-struct dhcp_packet *dhcp_free_list;
-struct packet *packet_free_list;
-
-int option_chain_head_allocate (ptr, file, line)
- struct option_chain_head **ptr;
- const char *file;
- int line;
-{
- int size;
- struct option_chain_head *h;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_chain_head *)0;
-#endif
- }
-
- h = dmalloc (sizeof *h, file, line);
- if (h) {
- memset (h, 0, sizeof *h);
- return option_chain_head_reference (ptr, h, file, line);
- }
- return 0;
-}
-
-int option_chain_head_reference (ptr, bp, file, line)
- struct option_chain_head **ptr;
- struct option_chain_head *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_chain_head *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int option_chain_head_dereference (ptr, file, line)
- struct option_chain_head **ptr;
- const char *file;
- int line;
-{
- int i;
- struct option_chain_head *option_chain_head;
- pair car, cdr;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- option_chain_head = *ptr;
- *ptr = (struct option_chain_head *)0;
- --option_chain_head -> refcnt;
- rc_register (file, line, ptr, option_chain_head,
- option_chain_head -> refcnt, 1, RC_MISC);
- if (option_chain_head -> refcnt > 0)
- return 1;
-
- if (option_chain_head -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (option_chain_head);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- /* If there are any options on this head, free them. */
- for (car = option_chain_head -> first; car; car = cdr) {
- cdr = car -> cdr;
- if (car -> car)
- option_cache_dereference ((struct option_cache **)
- (&car -> car), MDL);
- dfree (car, MDL);
- car = cdr;
- }
-
- dfree (option_chain_head, file, line);
- return 1;
-}
-
-int group_allocate (ptr, file, line)
- struct group **ptr;
- const char *file;
- int line;
-{
- int size;
- struct group *g;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct group *)0;
-#endif
- }
-
- g = dmalloc (sizeof *g, file, line);
- if (g) {
- memset (g, 0, sizeof *g);
- return group_reference (ptr, g, file, line);
- }
- return 0;
-}
-
-int group_reference (ptr, bp, file, line)
- struct group **ptr;
- struct group *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct group *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int group_dereference (ptr, file, line)
- struct group **ptr;
- const char *file;
- int line;
-{
- int i;
- struct group *group;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- group = *ptr;
- *ptr = (struct group *)0;
- --group -> refcnt;
- rc_register (file, line, ptr, group, group -> refcnt, 1, RC_MISC);
- if (group -> refcnt > 0)
- return 1;
-
- if (group -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (group);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (group -> object)
- group_object_dereference (&group -> object, file, line);
- if (group -> subnet)
- subnet_dereference (&group -> subnet, file, line);
- if (group -> shared_network)
- shared_network_dereference (&group -> shared_network,
- file, line);
- if (group -> statements)
- executable_statement_dereference (&group -> statements,
- file, line);
- if (group -> next)
- group_dereference (&group -> next, file, line);
- dfree (group, file, line);
- return 1;
-}
-
-struct dhcp_packet *new_dhcp_packet (file, line)
- const char *file;
- int line;
-{
- struct dhcp_packet *rval;
- rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
- file, line);
- return rval;
-}
-
-struct protocol *new_protocol (file, line)
- const char *file;
- int line;
-{
- struct protocol *rval = dmalloc (sizeof (struct protocol), file, line);
- return rval;
-}
-
-struct domain_search_list *new_domain_search_list (file, line)
- const char *file;
- int line;
-{
- struct domain_search_list *rval =
- dmalloc (sizeof (struct domain_search_list), file, line);
- return rval;
-}
-
-struct name_server *new_name_server (file, line)
- const char *file;
- int line;
-{
- struct name_server *rval =
- dmalloc (sizeof (struct name_server), file, line);
- return rval;
-}
-
-void free_name_server (ptr, file, line)
- struct name_server *ptr;
- const char *file;
- int line;
-{
- dfree ((VOIDPTR)ptr, file, line);
-}
-
-struct option *new_option (file, line)
- const char *file;
- int line;
-{
- struct option *rval =
- dmalloc (sizeof (struct option), file, line);
- if (rval)
- memset (rval, 0, sizeof *rval);
- return rval;
-}
-
-void free_option (ptr, file, line)
- struct option *ptr;
- const char *file;
- int line;
-{
-/* XXX have to put all options on heap before this is possible. */
-#if 0
- if (ptr -> name)
- dfree ((VOIDPTR)option -> name, file, line);
- dfree ((VOIDPTR)ptr, file, line);
-#endif
-}
-
-struct universe *new_universe (file, line)
- const char *file;
- int line;
-{
- struct universe *rval =
- dmalloc (sizeof (struct universe), file, line);
- return rval;
-}
-
-void free_universe (ptr, file, line)
- struct universe *ptr;
- const char *file;
- int line;
-{
- dfree ((VOIDPTR)ptr, file, line);
-}
-
-void free_domain_search_list (ptr, file, line)
- struct domain_search_list *ptr;
- const char *file;
- int line;
-{
- dfree ((VOIDPTR)ptr, file, line);
-}
-
-void free_protocol (ptr, file, line)
- struct protocol *ptr;
- const char *file;
- int line;
-{
- dfree ((VOIDPTR)ptr, file, line);
-}
-
-void free_dhcp_packet (ptr, file, line)
- struct dhcp_packet *ptr;
- const char *file;
- int line;
-{
- dfree ((VOIDPTR)ptr, file, line);
-}
-
-struct client_lease *new_client_lease (file, line)
- const char *file;
- int line;
-{
- return (struct client_lease *)dmalloc (sizeof (struct client_lease),
- file, line);
-}
-
-void free_client_lease (lease, file, line)
- struct client_lease *lease;
- const char *file;
- int line;
-{
- dfree (lease, file, line);
-}
-
-pair free_pairs;
-
-pair new_pair (file, line)
- const char *file;
- int line;
-{
- pair foo;
-
- if (free_pairs) {
- foo = free_pairs;
- free_pairs = foo -> cdr;
- memset (foo, 0, sizeof *foo);
- dmalloc_reuse (foo, file, line, 0);
- return foo;
- }
-
- foo = dmalloc (sizeof *foo, file, line);
- if (!foo)
- return foo;
- memset (foo, 0, sizeof *foo);
- return foo;
-}
-
-void free_pair (foo, file, line)
- pair foo;
- const char *file;
- int line;
-{
- foo -> cdr = free_pairs;
- free_pairs = foo;
- dmalloc_reuse (free_pairs, (char *)0, 0, 0);
-}
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void relinquish_free_pairs ()
-{
- pair pf, pc;
-
- for (pf = free_pairs; pf; pf = pc) {
- pc = pf -> cdr;
- dfree (pf, MDL);
- }
- free_pairs = (pair)0;
-}
-#endif
-
-struct expression *free_expressions;
-
-int expression_allocate (cptr, file, line)
- struct expression **cptr;
- const char *file;
- int line;
-{
- struct expression *rval;
-
- if (free_expressions) {
- rval = free_expressions;
- free_expressions = rval -> data.not;
- dmalloc_reuse (rval, file, line, 1);
- } else {
- rval = dmalloc (sizeof (struct expression), file, line);
- if (!rval)
- return 0;
- }
- memset (rval, 0, sizeof *rval);
- return expression_reference (cptr, rval, file, line);
-}
-
-int expression_reference (ptr, src, file, line)
- struct expression **ptr;
- struct expression *src;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct expression *)0;
-#endif
- }
- *ptr = src;
- src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-void free_expression (expr, file, line)
- struct expression *expr;
- const char *file;
- int line;
-{
- expr -> data.not = free_expressions;
- free_expressions = expr;
- dmalloc_reuse (free_expressions, (char *)0, 0, 0);
-}
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void relinquish_free_expressions ()
-{
- struct expression *e, *n;
-
- for (e = free_expressions; e; e = n) {
- n = e -> data.not;
- dfree (e, MDL);
- }
- free_expressions = (struct expression *)0;
-}
-#endif
-
-struct binding_value *free_binding_values;
-
-int binding_value_allocate (cptr, file, line)
- struct binding_value **cptr;
- const char *file;
- int line;
-{
- struct binding_value *rval;
-
- if (free_binding_values) {
- rval = free_binding_values;
- free_binding_values = rval -> value.bv;
- dmalloc_reuse (rval, file, line, 1);
- } else {
- rval = dmalloc (sizeof (struct binding_value), file, line);
- if (!rval)
- return 0;
- }
- memset (rval, 0, sizeof *rval);
- return binding_value_reference (cptr, rval, file, line);
-}
-
-int binding_value_reference (ptr, src, file, line)
- struct binding_value **ptr;
- struct binding_value *src;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct binding_value *)0;
-#endif
- }
- *ptr = src;
- src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-void free_binding_value (bv, file, line)
- struct binding_value *bv;
- const char *file;
- int line;
-{
- bv -> value.bv = free_binding_values;
- free_binding_values = bv;
- dmalloc_reuse (free_binding_values, (char *)0, 0, 0);
-}
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void relinquish_free_binding_values ()
-{
- struct binding_value *b, *n;
-
- for (b = free_binding_values; b; b = n) {
- n = b -> value.bv;
- dfree (b, MDL);
- }
- free_binding_values = (struct binding_value *)0;
-}
-#endif
-
-int fundef_allocate (cptr, file, line)
- struct fundef **cptr;
- const char *file;
- int line;
-{
- struct fundef *rval;
-
- rval = dmalloc (sizeof (struct fundef), file, line);
- if (!rval)
- return 0;
- memset (rval, 0, sizeof *rval);
- return fundef_reference (cptr, rval, file, line);
-}
-
-int fundef_reference (ptr, src, file, line)
- struct fundef **ptr;
- struct fundef *src;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct fundef *)0;
-#endif
- }
- *ptr = src;
- src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-struct option_cache *free_option_caches;
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void relinquish_free_option_caches ()
-{
- struct option_cache *o, *n;
-
- for (o = free_option_caches; o; o = n) {
- n = (struct option_cache *)(o -> expression);
- dfree (o, MDL);
- }
- free_option_caches = (struct option_cache *)0;
-}
-#endif
-
-int option_cache_allocate (cptr, file, line)
- struct option_cache **cptr;
- const char *file;
- int line;
-{
- struct option_cache *rval;
-
- if (free_option_caches) {
- rval = free_option_caches;
- free_option_caches =
- (struct option_cache *)(rval -> expression);
- dmalloc_reuse (rval, file, line, 0);
- } else {
- rval = dmalloc (sizeof (struct option_cache), file, line);
- if (!rval)
- return 0;
- }
- memset (rval, 0, sizeof *rval);
- return option_cache_reference (cptr, rval, file, line);
-}
-
-int option_cache_reference (ptr, src, file, line)
- struct option_cache **ptr;
- struct option_cache *src;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_cache *)0;
-#endif
- }
- *ptr = src;
- src -> refcnt++;
- rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int buffer_allocate (ptr, len, file, line)
- struct buffer **ptr;
- unsigned len;
- const char *file;
- int line;
-{
- struct buffer *bp;
-
- bp = dmalloc (len + sizeof *bp, file, line);
- if (!bp)
- return 0;
- memset (bp, 0, sizeof *bp);
- bp -> refcnt = 0;
- return buffer_reference (ptr, bp, file, line);
-}
-
-int buffer_reference (ptr, bp, file, line)
- struct buffer **ptr;
- struct buffer *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct buffer *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int buffer_dereference (ptr, file, line)
- struct buffer **ptr;
- const char *file;
- int line;
-{
- struct buffer *bp;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (!*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- (*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
- if (!(*ptr) -> refcnt) {
- dfree ((*ptr), file, line);
- } else if ((*ptr) -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (*ptr);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- *ptr = (struct buffer *)0;
- return 1;
-}
-
-int dns_host_entry_allocate (ptr, hostname, file, line)
- struct dns_host_entry **ptr;
- const char *hostname;
- const char *file;
- int line;
-{
- struct dns_host_entry *bp;
-
- bp = dmalloc (strlen (hostname) + sizeof *bp, file, line);
- if (!bp)
- return 0;
- memset (bp, 0, sizeof *bp);
- bp -> refcnt = 0;
- strcpy (bp -> hostname, hostname);
- return dns_host_entry_reference (ptr, bp, file, line);
-}
-
-int dns_host_entry_reference (ptr, bp, file, line)
- struct dns_host_entry **ptr;
- struct dns_host_entry *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct dns_host_entry *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int dns_host_entry_dereference (ptr, file, line)
- struct dns_host_entry **ptr;
- const char *file;
- int line;
-{
- struct dns_host_entry *bp;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- (*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
- if (!(*ptr) -> refcnt)
- dfree ((*ptr), file, line);
- if ((*ptr) -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (*ptr);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- *ptr = (struct dns_host_entry *)0;
- return 1;
-}
-
-int option_state_allocate (ptr, file, line)
- struct option_state **ptr;
- const char *file;
- int line;
-{
- unsigned size;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_state *)0;
-#endif
- }
-
- size = sizeof **ptr + (universe_count - 1) * sizeof (VOIDPTR);
- *ptr = dmalloc (size, file, line);
- if (*ptr) {
- memset (*ptr, 0, size);
- (*ptr) -> universe_count = universe_count;
- (*ptr) -> refcnt = 1;
- rc_register (file, line,
- ptr, *ptr, (*ptr) -> refcnt, 0, RC_MISC);
- return 1;
- }
- return 0;
-}
-
-int option_state_reference (ptr, bp, file, line)
- struct option_state **ptr;
- struct option_state *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_state *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int option_state_dereference (ptr, file, line)
- struct option_state **ptr;
- const char *file;
- int line;
-{
- int i;
- struct option_state *options;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- options = *ptr;
- *ptr = (struct option_state *)0;
- --options -> refcnt;
- rc_register (file, line, ptr, options, options -> refcnt, 1, RC_MISC);
- if (options -> refcnt > 0)
- return 1;
-
- if (options -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (options);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- /* Loop through the per-universe state. */
- for (i = 0; i < options -> universe_count; i++)
- if (options -> universes [i] &&
- universes [i] -> option_state_dereference)
- ((*(universes [i] -> option_state_dereference))
- (universes [i], options, file, line));
- dfree (options, file, line);
- return 1;
-}
-
-int executable_statement_allocate (ptr, file, line)
- struct executable_statement **ptr;
- const char *file;
- int line;
-{
- struct executable_statement *bp;
-
- bp = dmalloc (sizeof *bp, file, line);
- if (!bp)
- return 0;
- memset (bp, 0, sizeof *bp);
- return executable_statement_reference (ptr, bp, file, line);
-}
-
-int executable_statement_reference (ptr, bp, file, line)
- struct executable_statement **ptr;
- struct executable_statement *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct executable_statement *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-static struct packet *free_packets;
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void relinquish_free_packets ()
-{
- struct packet *p, *n;
- for (p = free_packets; p; p = n) {
- n = (struct packet *)(p -> raw);
- dfree (p, MDL);
- }
- free_packets = (struct packet *)0;
-}
-#endif
-
-int packet_allocate (ptr, file, line)
- struct packet **ptr;
- const char *file;
- int line;
-{
- int size;
- struct packet *p;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct packet *)0;
-#endif
- }
-
- if (free_packets) {
- p = free_packets;
- free_packets = (struct packet *)(p -> raw);
- dmalloc_reuse (p, file, line, 1);
- } else {
- p = dmalloc (sizeof *p, file, line);
- }
- if (p) {
- memset (p, 0, sizeof *p);
- return packet_reference (ptr, p, file, line);
- }
- return 0;
-}
-
-int packet_reference (ptr, bp, file, line)
- struct packet **ptr;
- struct packet *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct packet *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int packet_dereference (ptr, file, line)
- struct packet **ptr;
- const char *file;
- int line;
-{
- int i;
- struct packet *packet;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- packet = *ptr;
- *ptr = (struct packet *)0;
- --packet -> refcnt;
- rc_register (file, line, ptr, packet, packet -> refcnt, 1, RC_MISC);
- if (packet -> refcnt > 0)
- return 1;
-
- if (packet -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (packet);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (packet -> options)
- option_state_dereference (&packet -> options, file, line);
- if (packet -> interface)
- interface_dereference (&packet -> interface, MDL);
- if (packet -> shared_network)
- shared_network_dereference (&packet -> shared_network, MDL);
- for (i = 0; i < packet -> class_count && i < PACKET_MAX_CLASSES; i++) {
- if (packet -> classes [i])
- omapi_object_dereference ((omapi_object_t **)
- &packet -> classes [i], MDL);
- }
- packet -> raw = (struct dhcp_packet *)free_packets;
- free_packets = packet;
- dmalloc_reuse (free_packets, (char *)0, 0, 0);
- return 1;
-}
-
-int dns_zone_allocate (ptr, file, line)
- struct dns_zone **ptr;
- const char *file;
- int line;
-{
- int size;
- struct dns_zone *d;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct dns_zone *)0;
-#endif
- }
-
- d = dmalloc (sizeof *d, file, line);
- if (d) {
- memset (d, 0, sizeof *d);
- return dns_zone_reference (ptr, d, file, line);
- }
- return 0;
-}
-
-int dns_zone_reference (ptr, bp, file, line)
- struct dns_zone **ptr;
- struct dns_zone *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct dns_zone *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-int binding_scope_allocate (ptr, file, line)
- struct binding_scope **ptr;
- const char *file;
- int line;
-{
- struct binding_scope *bp;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- bp = dmalloc (sizeof *bp, file, line);
- if (!bp)
- return 0;
- memset (bp, 0, sizeof *bp);
- binding_scope_reference (ptr, bp, file, line);
- return 1;
-}
-
-int binding_scope_reference (ptr, bp, file, line)
- struct binding_scope **ptr;
- struct binding_scope *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct binding_scope *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
- return 1;
-}
-
-/* Make a copy of the data in data_string, upping the buffer reference
- count if there's a buffer. */
-
-void data_string_copy (dest, src, file, line)
- struct data_string *dest;
- struct data_string *src;
- const char *file;
- int line;
-{
- if (src -> buffer)
- buffer_reference (&dest -> buffer, src -> buffer, file, line);
- dest -> data = src -> data;
- dest -> terminated = src -> terminated;
- dest -> len = src -> len;
-}
-
-/* Release the reference count to a data string's buffer (if any) and
- zero out the other information, yielding the null data string. */
-
-void data_string_forget (data, file, line)
- struct data_string *data;
- const char *file;
- int line;
-{
- if (data -> buffer)
- buffer_dereference (&data -> buffer, file, line);
- memset (data, 0, sizeof *data);
-}
-
-/* Make a copy of the data in data_string, upping the buffer reference
- count if there's a buffer. */
-
-void data_string_truncate (dp, len)
- struct data_string *dp;
- int len;
-{
- if (len < dp -> len) {
- dp -> terminated = 0;
- dp -> len = len;
- }
-}
diff --git a/contrib/isc-dhcp/common/bpf.c b/contrib/isc-dhcp/common/bpf.c
deleted file mode 100644
index 9c32153..0000000
--- a/contrib/isc-dhcp/common/bpf.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/* bpf.c
-
- BPF socket interface code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software was contributed to Internet Systems Consortium
- * by Archie Cobbs.
- *
- * Patches for FDDI support on Digital Unix were written by Bill
- * Stapleton, and maintained for a while by Mike Meredith before he
- * managed to get me to integrate them.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: bpf.c,v 1.48.2.6 2004/06/17 20:54:38 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE) \
- || defined (USE_LPF_RECEIVE)
-# if defined (USE_LPF_RECEIVE)
-# include <asm/types.h>
-# include <linux/filter.h>
-# define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */
-# else
-# include <sys/ioctl.h>
-# include <sys/uio.h>
-# include <net/bpf.h>
-# if defined (NEED_OSF_PFILT_HACKS)
-# include <net/pfilt.h>
-# endif
-# endif
-
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-#endif
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#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. */
-
-#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
-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++) {
- /* %Audit% 31 bytes max. %2004.06.17,Safe% */
- sprintf(filename, BPF_FORMAT, b);
- sock = open (filename, O_RDWR, 0);
- if (sock < 0) {
- if (errno == EBUSY) {
- continue;
- } else {
- if (!b)
- log_fatal ("No bpf devices.%s%s%s",
- " Please read the README",
- " section for your operating",
- " system.");
- log_fatal ("Can't find free bpf: %m");
- }
- } else {
- break;
- }
- }
-
- /* Set the BPF device to point at this interface. */
- if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
- log_fatal ("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
- if (!quiet_interface_discovery)
- log_info ("Sending on BPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_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
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling output on BPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_BPF_SEND */
-
-#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)
-/* Packet filter program...
- XXX Changes to the filter program may require changes to the constant
- offsets used in if_register_send to patch the BPF program! XXX */
-
-struct bpf_insn dhcp_bpf_filter [] = {
- /* Make sure this is an IP packet... */
- BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
-
- /* 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),
-};
-
-#if defined (DEC_FDDI)
-struct bpf_insn *bpf_fddi_filter;
-#endif
-
-int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-#if defined (HAVE_TR_SUPPORT)
-struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
- /* if we want to get clever, insert the program here */
-
- /* 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),
-};
-
-int dhcp_bpf_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
- sizeof (struct bpf_insn));
-#endif /* HAVE_TR_SUPPORT */
-#endif /* USE_LPF_RECEIVE || USE_BPF_RECEIVE */
-
-#if defined (USE_BPF_RECEIVE)
-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;
-#ifdef DEC_FDDI
- int link_layer;
-#endif /* DEC_FDDI */
-
- /* 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)
- log_fatal ("Can't get BPF version: %m");
-
- if (v.bv_major != BPF_MAJOR_VERSION ||
- v.bv_minor < BPF_MINOR_VERSION)
- log_fatal ("BPF version mismatch - recompile DHCP!");
-
- /* 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)
- log_fatal ("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)
- log_fatal ("Can't set ALLOWCOPYALL: %m");
-
- /* Clear all the packet filter mode bits first... */
- bits = 0;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- log_fatal ("Can't clear pfilt bits: %m");
-
- /* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
- bits = ENBATCH | ENCOPYALL | ENBPFHDR;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- log_fatal ("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)
- log_fatal ("Can't get bpf buffer length: %m");
- info -> rbuf = dmalloc (info -> rbuf_max, MDL);
- if (!info -> rbuf)
- log_fatal ("Can't allocate %ld bytes for bpf input buffer.",
- (long)(info -> rbuf_max));
- info -> rbuf_offset = 0;
- info -> rbuf_len = 0;
-
- /* Set up the bpf filter program structure. */
- p.bf_len = dhcp_bpf_filter_len;
-
-#ifdef DEC_FDDI
- /* See if this is an FDDI interface, flag it for later. */
- if (ioctl(info -> rfdesc, BIOCGDLT, &link_layer) >= 0 &&
- link_layer == DLT_FDDI) {
- if (!bpf_fddi_filter) {
- bpf_fddi_filter = dmalloc (sizeof bpf_fddi_filter,
- MDL);
- if (!bpf_fddi_filter)
- log_fatal ("No memory for FDDI filter.");
- memcpy (bpf_fddi_filter,
- dhcp_bpf_filter, sizeof dhcp_bpf_filter);
- /* Patch the BPF program to account for the difference
- in length between ethernet headers (14), FDDI and
- 802.2 headers (16 +8=24, +10).
- XXX changes to filter program may require changes to
- XXX the insn number(s) used below! */
- bpf_fddi_filter[0].k += 10;
- bpf_fddi_filter[2].k += 10;
- bpf_fddi_filter[4].k += 10;
- bpf_fddi_filter[6].k += 10;
- bpf_fddi_filter[7].k += 10;
- }
- p.bf_insns = bpf_fddi_filter;
- } else
-#endif /* DEC_FDDI */
- p.bf_insns = dhcp_bpf_filter;
-
- /* Patch the server port into the BPF program...
- XXX changes to filter program may require changes
- to the insn number(s) used below! XXX */
- dhcp_bpf_filter [8].k = ntohs (local_port);
-
- if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
- log_fatal ("Can't install packet filter program: %m");
- if (!quiet_interface_discovery)
- log_info ("Listening on BPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_receive (info)
- struct interface_info *info;
-{
- close (info -> rfdesc);
- info -> rfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling input on BPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_BPF_RECEIVE */
-
-#ifdef USE_BPF_SEND
-ssize_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 hbufp = 0, ibufp = 0;
- double hw [4];
- double ip [32];
- struct iovec iov [3];
- int result;
- int fudge;
-
- if (!strcmp (interface -> name, "fallback"))
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
- assemble_udp_ip_header (interface,
- (unsigned char *)ip, &ibufp, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- (unsigned char *)raw, len);
-
- /* Fire it off */
- iov [0].iov_base = ((char *)hw);
- iov [0].iov_len = hbufp;
- iov [1].iov_base = ((char *)ip);
- iov [1].iov_len = ibufp;
- iov [2].iov_base = (char *)raw;
- iov [2].iov_len = len;
-
- result = writev(interface -> wfdesc, iov, 3);
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_BPF_SEND */
-
-#ifdef USE_BPF_RECEIVE
-ssize_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,
- (size_t)interface -> rbuf_max);
- if (length <= 0) {
-#ifdef __FreeBSD__
- if (errno == ENXIO) {
-#else
- if (errno == EIO) {
-#endif
- dhcp_interface_remove
- ((omapi_object_t *)interface,
- (omapi_object_t *)0);
- }
- return length;
- }
- interface -> rbuf_offset = 0;
- interface -> rbuf_len = BPF_WORDALIGN (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 =
- BPF_WORDALIGN (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 =
- BPF_WORDALIGN (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 =
- BPF_WORDALIGN (interface -> rbuf_offset +
- hdr.bh_caplen);
- continue;
- }
- interface -> rbuf_offset = 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 =
- BPF_WORDALIGN (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 =
- BPF_WORDALIGN (interface -> rbuf_offset +
- hdr.bh_caplen);
- return hdr.bh_caplen;
- } while (!length);
- return 0;
-}
-
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-void maybe_setup_fallback ()
-{
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- if_register_fallback (fbi);
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-}
-#endif
diff --git a/contrib/isc-dhcp/common/comapi.c b/contrib/isc-dhcp/common/comapi.c
deleted file mode 100644
index 9f0b965..0000000
--- a/contrib/isc-dhcp/common/comapi.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/* omapi.c
-
- OMAPI object interfaces for the DHCP server. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1999-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-/* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
- provided the funding that resulted in this code and the entire
- OMAPI support library being written, and Brian helped brainstorm
- and refine the requirements. To the extent that this code is
- useful, you have Brian and BCtel to thank. Any limitations in the
- code are a result of mistakes on my part. -- Ted Lemon */
-
-#ifndef lint
-static char copyright[] =
-"$Id: comapi.c,v 1.9.2.7 2004/06/10 17:59:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <omapip/omapip_p.h>
-
-OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet)
-OMAPI_OBJECT_ALLOC (shared_network, struct shared_network,
- dhcp_type_shared_network)
-OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group)
-OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control)
-
-omapi_object_type_t *dhcp_type_interface;
-omapi_object_type_t *dhcp_type_group;
-omapi_object_type_t *dhcp_type_shared_network;
-omapi_object_type_t *dhcp_type_subnet;
-omapi_object_type_t *dhcp_type_control;
-dhcp_control_object_t *dhcp_control_object;
-
-void dhcp_common_objects_setup ()
-{
- isc_result_t status;
-
- status = omapi_object_type_register (&dhcp_type_control,
- "control",
- dhcp_control_set_value,
- dhcp_control_get_value,
- dhcp_control_destroy,
- dhcp_control_signal_handler,
- dhcp_control_stuff_values,
- dhcp_control_lookup,
- dhcp_control_create,
- dhcp_control_remove, 0, 0, 0,
- sizeof (dhcp_control_object_t),
- 0, RC_MISC);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register control object type: %s",
- isc_result_totext (status));
- status = dhcp_control_allocate (&dhcp_control_object, MDL);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't make initial control object: %s",
- isc_result_totext (status));
- dhcp_control_object -> state = server_startup;
-
- status = omapi_object_type_register (&dhcp_type_group,
- "group",
- dhcp_group_set_value,
- dhcp_group_get_value,
- dhcp_group_destroy,
- dhcp_group_signal_handler,
- dhcp_group_stuff_values,
- dhcp_group_lookup,
- dhcp_group_create,
- dhcp_group_remove, 0, 0, 0,
- sizeof (struct group_object), 0,
- RC_MISC);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register group object type: %s",
- isc_result_totext (status));
-
- status = omapi_object_type_register (&dhcp_type_subnet,
- "subnet",
- dhcp_subnet_set_value,
- dhcp_subnet_get_value,
- dhcp_subnet_destroy,
- dhcp_subnet_signal_handler,
- dhcp_subnet_stuff_values,
- dhcp_subnet_lookup,
- dhcp_subnet_create,
- dhcp_subnet_remove, 0, 0, 0,
- sizeof (struct subnet), 0,
- RC_MISC);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register subnet object type: %s",
- isc_result_totext (status));
-
- status = omapi_object_type_register
- (&dhcp_type_shared_network,
- "shared-network",
- dhcp_shared_network_set_value,
- dhcp_shared_network_get_value,
- dhcp_shared_network_destroy,
- dhcp_shared_network_signal_handler,
- dhcp_shared_network_stuff_values,
- dhcp_shared_network_lookup,
- dhcp_shared_network_create,
- dhcp_shared_network_remove, 0, 0, 0,
- sizeof (struct shared_network), 0, RC_MISC);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register shared network object type: %s",
- isc_result_totext (status));
-
- interface_setup ();
-}
-
-isc_result_t dhcp_group_set_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_typed_data_t *value)
-{
- struct group_object *group;
- isc_result_t status;
- int foo;
-
- if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)h;
-
- /* XXX For now, we can only set these values on new group objects.
- XXX Soon, we need to be able to update group objects. */
- if (!omapi_ds_strcmp (name, "name")) {
- if (group -> name)
- return ISC_R_EXISTS;
- if (value -> type == omapi_datatype_data ||
- value -> type == omapi_datatype_string) {
- group -> name = dmalloc (value -> u.buffer.len + 1,
- MDL);
- if (!group -> name)
- return ISC_R_NOMEMORY;
- memcpy (group -> name,
- value -> u.buffer.value,
- value -> u.buffer.len);
- group -> name [value -> u.buffer.len] = 0;
- } else
- return ISC_R_INVALIDARG;
- return ISC_R_SUCCESS;
- }
-
- if (!omapi_ds_strcmp (name, "statements")) {
- if (group -> group && group -> group -> statements)
- return ISC_R_EXISTS;
- if (!group -> group) {
- if (!clone_group (&group -> group, root_group, MDL))
- return ISC_R_NOMEMORY;
- }
- if (value -> type == omapi_datatype_data ||
- value -> type == omapi_datatype_string) {
- struct parse *parse;
- int lose = 0;
- parse = (struct parse *)0;
- status = new_parse (&parse, -1,
- (char *)value -> u.buffer.value,
- value -> u.buffer.len,
- "network client", 0);
- if (status != ISC_R_SUCCESS)
- return status;
- if (!(parse_executable_statements
- (&group -> group -> statements, parse, &lose,
- context_any))) {
- end_parse (&parse);
- return ISC_R_BADPARSE;
- }
- end_parse (&parse);
- return ISC_R_SUCCESS;
- } else
- return ISC_R_INVALIDARG;
- }
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> set_value) {
- status = ((*(h -> inner -> type -> set_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
- return status;
- }
-
- return ISC_R_NOTFOUND;
-}
-
-
-isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_value_t **value)
-{
- struct group_object *group;
- isc_result_t status;
- struct data_string ip_addrs;
-
- if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)h;
-
- if (!omapi_ds_strcmp (name, "name"))
- return omapi_make_string_value (value,
- name, group -> name, MDL);
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> get_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line)
-{
- struct group_object *group, *t;
- isc_result_t status;
-
- if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)h;
-
- if (group -> name) {
- if (group_name_hash) {
- t = (struct group_object *)0;
- if (group_hash_lookup (&t, group_name_hash,
- group -> name,
- strlen (group -> name), MDL)) {
- group_hash_delete (group_name_hash,
- group -> name,
- strlen (group -> name),
- MDL);
- group_object_dereference (&t, MDL);
- }
- }
- dfree (group -> name, file, line);
- group -> name = (char *)0;
- }
- if (group -> group)
- group_dereference (&group -> group, MDL);
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_group_signal_handler (omapi_object_t *h,
- const char *name, va_list ap)
-{
- struct group_object *group, *t;
- isc_result_t status;
- int updatep = 0;
-
- if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)h;
-
- if (!strcmp (name, "updated")) {
- /* A group object isn't valid if a subgroup hasn't yet been
- associated with it. */
- if (!group -> group)
- return ISC_R_INVALIDARG;
-
- /* Group objects always have to have names. */
- if (!group -> name) {
- char hnbuf [64];
- sprintf (hnbuf, "ng%08lx%08lx",
- (unsigned long)cur_time,
- (unsigned long)group);
- group -> name = dmalloc (strlen (hnbuf) + 1, MDL);
- if (!group -> name)
- return ISC_R_NOMEMORY;
- strcpy (group -> name, hnbuf);
- }
-
- supersede_group (group, 1);
- updatep = 1;
- }
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> signal_handler))
- (h -> inner, name, ap));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- if (updatep)
- return ISC_R_SUCCESS;
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_group_stuff_values (omapi_object_t *c,
- omapi_object_t *id,
- omapi_object_t *h)
-{
- struct group_object *group;
- isc_result_t status;
-
- if (h -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)h;
-
- /* Write out all the values. */
- if (group -> name) {
- status = omapi_connection_put_name (c, "name");
- if (status != ISC_R_SUCCESS)
- return status;
- status = omapi_connection_put_string (c, group -> name);
- if (status != ISC_R_SUCCESS)
- return status;
- }
-
- /* Write out the inner object, if any. */
- if (h -> inner && h -> inner -> type -> stuff_values) {
- status = ((*(h -> inner -> type -> stuff_values))
- (c, id, h -> inner));
- if (status == ISC_R_SUCCESS)
- return status;
- }
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_group_lookup (omapi_object_t **lp,
- omapi_object_t *id, omapi_object_t *ref)
-{
- omapi_value_t *tv = (omapi_value_t *)0;
- isc_result_t status;
- struct group_object *group;
-
- if (!ref)
- return ISC_R_NOKEYS;
-
- /* First see if we were sent a handle. */
- status = omapi_get_value_str (ref, id, "handle", &tv);
- if (status == ISC_R_SUCCESS) {
- status = omapi_handle_td_lookup (lp, tv -> value);
-
- omapi_value_dereference (&tv, MDL);
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Don't return the object if the type is wrong. */
- if ((*lp) -> type != dhcp_type_group) {
- omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
- }
- }
-
- /* Now look for a name. */
- status = omapi_get_value_str (ref, id, "name", &tv);
- if (status == ISC_R_SUCCESS) {
- group = (struct group_object *)0;
- if (group_name_hash &&
- group_hash_lookup (&group, group_name_hash,
- (const char *)
- tv -> value -> u.buffer.value,
- tv -> value -> u.buffer.len, MDL)) {
- omapi_value_dereference (&tv, MDL);
-
- if (*lp && *lp != (omapi_object_t *)group) {
- group_object_dereference (&group, MDL);
- omapi_object_dereference (lp, MDL);
- return ISC_R_KEYCONFLICT;
- } else if (!*lp) {
- /* XXX fix so that hash lookup itself creates
- XXX the reference. */
- omapi_object_reference (lp,
- (omapi_object_t *)group,
- MDL);
- group_object_dereference (&group, MDL);
- }
- } else if (!*lp)
- return ISC_R_NOTFOUND;
- }
-
- /* If we get to here without finding a group, no valid key was
- specified. */
- if (!*lp)
- return ISC_R_NOKEYS;
-
- if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) {
- omapi_object_dereference (lp, MDL);
- return ISC_R_NOTFOUND;
- }
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_group_create (omapi_object_t **lp,
- omapi_object_t *id)
-{
- struct group_object *group;
- isc_result_t status;
- group = (struct group_object *)0;
-
- status = group_object_allocate (&group, MDL);
- if (status != ISC_R_SUCCESS)
- return status;
- group -> flags = GROUP_OBJECT_DYNAMIC;
- status = omapi_object_reference (lp, (omapi_object_t *)group, MDL);
- group_object_dereference (&group, MDL);
- return status;
-}
-
-isc_result_t dhcp_group_remove (omapi_object_t *lp,
- omapi_object_t *id)
-{
- struct group_object *group;
- isc_result_t status;
- if (lp -> type != dhcp_type_group)
- return ISC_R_INVALIDARG;
- group = (struct group_object *)lp;
-
- group -> flags |= GROUP_OBJECT_DELETED;
- if (group_write_hook) {
- if (!(*group_write_hook) (group))
- return ISC_R_IOERROR;
- }
-
- status = dhcp_group_destroy ((omapi_object_t *)group, MDL);
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_control_set_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_typed_data_t *value)
-{
- dhcp_control_object_t *control;
- isc_result_t status;
- int foo;
- unsigned long newstate;
-
- if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
- control = (dhcp_control_object_t *)h;
-
- if (!omapi_ds_strcmp (name, "state")) {
- status = omapi_get_int_value (&newstate, value);
- if (status != ISC_R_SUCCESS)
- return status;
- status = dhcp_set_control_state (control -> state, newstate);
- if (status == ISC_R_SUCCESS)
- control -> state = value -> u.integer;
- return status;
- }
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> set_value) {
- status = ((*(h -> inner -> type -> set_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
- return status;
- }
-
- return ISC_R_NOTFOUND;
-}
-
-
-isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_value_t **value)
-{
- dhcp_control_object_t *control;
- isc_result_t status;
- struct data_string ip_addrs;
-
- if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
- control = (dhcp_control_object_t *)h;
-
- if (!omapi_ds_strcmp (name, "state"))
- return omapi_make_int_value (value,
- name, (int)control -> state, MDL);
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> get_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_control_destroy (omapi_object_t *h,
- const char *file, int line)
-{
- dhcp_control_object_t *control, *t;
- isc_result_t status;
-
- if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
-
- /* Can't destroy the control object. */
- return ISC_R_NOPERM;
-}
-
-isc_result_t dhcp_control_signal_handler (omapi_object_t *h,
- const char *name, va_list ap)
-{
- dhcp_control_object_t *control, *t;
- isc_result_t status;
- int updatep = 0;
-
- if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
- control = (dhcp_control_object_t *)h;
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> signal_handler))
- (h -> inner, name, ap));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_control_stuff_values (omapi_object_t *c,
- omapi_object_t *id,
- omapi_object_t *h)
-{
- dhcp_control_object_t *control;
- isc_result_t status;
-
- if (h -> type != dhcp_type_control)
- return ISC_R_INVALIDARG;
- control = (dhcp_control_object_t *)h;
-
- /* Write out all the values. */
- status = omapi_connection_put_name (c, "state");
- if (status != ISC_R_SUCCESS)
- return status;
- status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
- if (status != ISC_R_SUCCESS)
- return status;
- status = omapi_connection_put_uint32 (c, control -> state);
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Write out the inner object, if any. */
- if (h -> inner && h -> inner -> type -> stuff_values) {
- status = ((*(h -> inner -> type -> stuff_values))
- (c, id, h -> inner));
- if (status == ISC_R_SUCCESS)
- return status;
- }
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_control_lookup (omapi_object_t **lp,
- omapi_object_t *id, omapi_object_t *ref)
-{
- omapi_value_t *tv = (omapi_value_t *)0;
- isc_result_t status;
- dhcp_control_object_t *control;
-
- /* First see if we were sent a handle. */
- if (ref) {
- status = omapi_get_value_str (ref, id, "handle", &tv);
- if (status == ISC_R_SUCCESS) {
- status = omapi_handle_td_lookup (lp, tv -> value);
-
- omapi_value_dereference (&tv, MDL);
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Don't return the object if the type is wrong. */
- if ((*lp) -> type != dhcp_type_control) {
- omapi_object_dereference (lp, MDL);
- return ISC_R_INVALIDARG;
- }
- }
- }
-
- /* Otherwise, stop playing coy - there's only one control object,
- so we can just return it. */
- dhcp_control_reference ((dhcp_control_object_t **)lp,
- dhcp_control_object, MDL);
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_control_create (omapi_object_t **lp,
- omapi_object_t *id)
-{
- /* Can't create a control object - there can be only one. */
- return ISC_R_NOPERM;
-}
-
-isc_result_t dhcp_control_remove (omapi_object_t *lp,
- omapi_object_t *id)
-{
- /* Form is emptiness; emptiness form. The control object
- cannot go out of existance. */
- return ISC_R_NOPERM;
-}
-
-isc_result_t dhcp_subnet_set_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_typed_data_t *value)
-{
- struct subnet *subnet;
- isc_result_t status;
- int foo;
-
- if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
- subnet = (struct subnet *)h;
-
- /* No values to set yet. */
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> set_value) {
- status = ((*(h -> inner -> type -> set_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
- return status;
- }
-
- return ISC_R_NOTFOUND;
-}
-
-
-isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_value_t **value)
-{
- struct subnet *subnet;
- isc_result_t status;
-
- if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
- subnet = (struct subnet *)h;
-
- /* No values to get yet. */
-
- /* Try to find some inner object that can provide the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> get_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line)
-{
- struct subnet *subnet;
- isc_result_t status;
-
- if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
- subnet = (struct subnet *)h;
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
- if (subnet -> next_subnet)
- subnet_dereference (&subnet -> next_subnet, file, line);
- if (subnet -> next_sibling)
- subnet_dereference (&subnet -> next_sibling, file, line);
- if (subnet -> shared_network)
- shared_network_dereference (&subnet -> shared_network,
- file, line);
- if (subnet -> interface)
- interface_dereference (&subnet -> interface, file, line);
- if (subnet -> group)
- group_dereference (&subnet -> group, file, line);
-#endif
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h,
- const char *name, va_list ap)
-{
- struct subnet *subnet;
- isc_result_t status;
- int updatep = 0;
-
- if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
- subnet = (struct subnet *)h;
-
- /* Can't write subnets yet. */
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> signal_handler))
- (h -> inner, name, ap));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- if (updatep)
- return ISC_R_SUCCESS;
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c,
- omapi_object_t *id,
- omapi_object_t *h)
-{
- struct subnet *subnet;
- isc_result_t status;
-
- if (h -> type != dhcp_type_subnet)
- return ISC_R_INVALIDARG;
- subnet = (struct subnet *)h;
-
- /* Can't stuff subnet values yet. */
-
- /* Write out the inner object, if any. */
- if (h -> inner && h -> inner -> type -> stuff_values) {
- status = ((*(h -> inner -> type -> stuff_values))
- (c, id, h -> inner));
- if (status == ISC_R_SUCCESS)
- return status;
- }
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_subnet_lookup (omapi_object_t **lp,
- omapi_object_t *id,
- omapi_object_t *ref)
-{
- omapi_value_t *tv = (omapi_value_t *)0;
- isc_result_t status;
- struct subnet *subnet;
-
- /* Can't look up subnets yet. */
-
- /* If we get to here without finding a subnet, no valid key was
- specified. */
- if (!*lp)
- return ISC_R_NOKEYS;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_subnet_create (omapi_object_t **lp,
- omapi_object_t *id)
-{
- return ISC_R_NOTIMPLEMENTED;
-}
-
-isc_result_t dhcp_subnet_remove (omapi_object_t *lp,
- omapi_object_t *id)
-{
- return ISC_R_NOTIMPLEMENTED;
-}
-
-isc_result_t dhcp_shared_network_set_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_typed_data_t *value)
-{
- struct shared_network *shared_network;
- isc_result_t status;
- int foo;
-
- if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
- shared_network = (struct shared_network *)h;
-
- /* No values to set yet. */
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> set_value) {
- status = ((*(h -> inner -> type -> set_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
- return status;
- }
-
- return ISC_R_NOTFOUND;
-}
-
-
-isc_result_t dhcp_shared_network_get_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_value_t **value)
-{
- struct shared_network *shared_network;
- isc_result_t status;
-
- if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
- shared_network = (struct shared_network *)h;
-
- /* No values to get yet. */
-
- /* Try to find some inner object that can provide the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> get_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_shared_network_destroy (omapi_object_t *h,
- const char *file, int line)
-{
- struct shared_network *shared_network;
- isc_result_t status;
-
- if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
- shared_network = (struct shared_network *)h;
-
-#if defined (DEBUG_MEMORY_LEAKAGE) || \
- defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
- if (shared_network -> next)
- shared_network_dereference (&shared_network -> next,
- file, line);
- if (shared_network -> name) {
- dfree (shared_network -> name, file, line);
- shared_network -> name = 0;
- }
- if (shared_network -> subnets)
- subnet_dereference (&shared_network -> subnets, file, line);
- if (shared_network -> interface)
- interface_dereference (&shared_network -> interface,
- file, line);
- if (shared_network -> pools)
- omapi_object_dereference ((omapi_object_t **)
- &shared_network -> pools, file, line);
- if (shared_network -> group)
- group_dereference (&shared_network -> group, file, line);
-#if defined (FAILOVER_PROTOCOL)
- if (shared_network -> failover_peer)
- omapi_object_dereference ((omapi_object_t **)
- &shared_network -> failover_peer,
- file, line);
-#endif
-#endif /* DEBUG_MEMORY_LEAKAGE */
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h,
- const char *name,
- va_list ap)
-{
- struct shared_network *shared_network;
- isc_result_t status;
- int updatep = 0;
-
- if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
- shared_network = (struct shared_network *)h;
-
- /* Can't write shared_networks yet. */
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> signal_handler))
- (h -> inner, name, ap));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- if (updatep)
- return ISC_R_SUCCESS;
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c,
- omapi_object_t *id,
- omapi_object_t *h)
-{
- struct shared_network *shared_network;
- isc_result_t status;
-
- if (h -> type != dhcp_type_shared_network)
- return ISC_R_INVALIDARG;
- shared_network = (struct shared_network *)h;
-
- /* Can't stuff shared_network values yet. */
-
- /* Write out the inner object, if any. */
- if (h -> inner && h -> inner -> type -> stuff_values) {
- status = ((*(h -> inner -> type -> stuff_values))
- (c, id, h -> inner));
- if (status == ISC_R_SUCCESS)
- return status;
- }
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp,
- omapi_object_t *id,
- omapi_object_t *ref)
-{
- omapi_value_t *tv = (omapi_value_t *)0;
- isc_result_t status;
- struct shared_network *shared_network;
-
- /* Can't look up shared_networks yet. */
-
- /* If we get to here without finding a shared_network, no valid key was
- specified. */
- if (!*lp)
- return ISC_R_NOKEYS;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_shared_network_create (omapi_object_t **lp,
- omapi_object_t *id)
-{
- return ISC_R_NOTIMPLEMENTED;
-}
-
-isc_result_t dhcp_shared_network_remove (omapi_object_t *lp,
- omapi_object_t *id)
-{
- return ISC_R_NOTIMPLEMENTED;
-}
-
diff --git a/contrib/isc-dhcp/common/conflex.c b/contrib/isc-dhcp/common/conflex.c
deleted file mode 100644
index a8a5039..0000000
--- a/contrib/isc-dhcp/common/conflex.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* conflex.c
-
- Lexical scanner for dhcpd config file... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: conflex.c,v 1.92.2.7 2004/06/10 17:59:14 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <ctype.h>
-
-static int get_char PROTO ((struct parse *));
-static enum dhcp_token get_token PROTO ((struct parse *));
-static void skip_to_eol PROTO ((struct parse *));
-static enum dhcp_token read_string PROTO ((struct parse *));
-static enum dhcp_token read_number PROTO ((int, struct parse *));
-static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
-static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
-
-isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
- struct parse **cfile;
- int file;
- char *inbuf;
- unsigned buflen;
- const char *name;
- int eolp;
-{
- struct parse *tmp;
-
- tmp = dmalloc (sizeof (struct parse), MDL);
- if (!tmp)
- return ISC_R_NOMEMORY;
- memset (tmp, 0, sizeof *tmp);
-
- tmp -> token = 0;
- tmp -> tlname = name;
- tmp -> lpos = tmp -> line = 1;
- tmp -> cur_line = tmp -> line1;
- tmp -> prev_line = tmp -> line2;
- tmp -> token_line = tmp -> cur_line;
- tmp -> cur_line [0] = tmp -> prev_line [0] = 0;
- tmp -> warnings_occurred = 0;
- tmp -> file = file;
- tmp -> eol_token = eolp;
-
- tmp -> bufix = 0;
- tmp -> buflen = buflen;
- if (inbuf) {
- tmp -> bufsiz = 0;
- tmp -> inbuf = inbuf;
- } else {
- tmp -> inbuf = dmalloc (8192, MDL);
- if (!tmp -> inbuf) {
- dfree (tmp, MDL);
- return ISC_R_NOMEMORY;
- }
- tmp -> bufsiz = 8192;
- }
-
- *cfile = tmp;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t end_parse (cfile)
- struct parse **cfile;
-{
- if ((*cfile) -> bufsiz)
- dfree ((*cfile) -> inbuf, MDL);
- dfree (*cfile, MDL);
- *cfile = (struct parse *)0;
- return ISC_R_SUCCESS;
-}
-
-static int get_char (cfile)
- struct parse *cfile;
-{
- /* My kingdom for WITH... */
- int c;
-
- if (cfile -> bufix == cfile -> buflen) {
- if (cfile -> file != -1) {
- cfile -> buflen =
- read (cfile -> file,
- cfile -> inbuf, cfile -> bufsiz);
- if (cfile -> buflen == 0) {
- c = EOF;
- cfile -> bufix = 0;
- } else if (cfile -> buflen < 0) {
- c = EOF;
- cfile -> bufix = cfile -> buflen = 0;
- } else {
- c = cfile -> inbuf [0];
- cfile -> bufix = 1;
- }
- } else
- c = EOF;
- } else {
- c = cfile -> inbuf [cfile -> bufix];
- cfile -> bufix++;
- }
-
- if (!cfile -> ugflag) {
- if (c == EOL) {
- if (cfile -> cur_line == cfile -> line1) {
- cfile -> cur_line = cfile -> line2;
- cfile -> prev_line = cfile -> line1;
- } else {
- cfile -> cur_line = cfile -> line1;
- cfile -> prev_line = cfile -> line2;
- }
- cfile -> line++;
- cfile -> lpos = 1;
- cfile -> cur_line [0] = 0;
- } else if (c != EOF) {
- if (cfile -> lpos <= 80) {
- cfile -> cur_line [cfile -> lpos - 1] = c;
- cfile -> cur_line [cfile -> lpos] = 0;
- }
- cfile -> lpos++;
- }
- } else
- cfile -> ugflag = 0;
- return c;
-}
-
-static enum dhcp_token get_token (cfile)
- struct parse *cfile;
-{
- int c;
- enum dhcp_token ttok;
- static char tb [2];
- int l, p, u;
-
- do {
- l = cfile -> line;
- p = cfile -> lpos;
- u = cfile -> ugflag;
-
- c = get_char (cfile);
-#ifdef OLD_LEXER
- if (c == '\n' && p == 1 && !u
- && cfile -> comment_index < sizeof cfile -> comments)
- cfile -> comments [cfile -> comment_index++] = '\n';
-#endif
-
- if (!(c == '\n' && cfile -> eol_token)
- && isascii (c) && isspace (c))
- continue;
- if (c == '#') {
-#ifdef OLD_LEXER
- if (cfile -> comment_index < sizeof cfile -> comments)
- cfile -> comments [cfile -> comment_index++] = '#';
-#endif
- skip_to_eol (cfile);
- continue;
- }
- if (c == '"') {
- cfile -> lexline = l;
- cfile -> lexchar = p;
- ttok = read_string (cfile);
- break;
- }
- if ((isascii (c) && isdigit (c)) || c == '-') {
- cfile -> lexline = l;
- cfile -> lexchar = p;
- ttok = read_number (c, cfile);
- break;
- } else if (isascii (c) && isalpha (c)) {
- cfile -> lexline = l;
- cfile -> lexchar = p;
- ttok = read_num_or_name (c, cfile);
- break;
- } else if (c == EOF) {
- ttok = END_OF_FILE;
- cfile -> tlen = 0;
- break;
- } else {
- cfile -> lexline = l;
- cfile -> lexchar = p;
- tb [0] = c;
- tb [1] = 0;
- cfile -> tval = tb;
- cfile -> tlen = 1;
- ttok = c;
- break;
- }
- } while (1);
- return ttok;
-}
-
-enum dhcp_token next_token (rval, rlen, cfile)
- const char **rval;
- unsigned *rlen;
- struct parse *cfile;
-{
- int rv;
-
- if (cfile -> token) {
- if (cfile -> lexline != cfile -> tline)
- cfile -> token_line = cfile -> cur_line;
- cfile -> lexchar = cfile -> tlpos;
- cfile -> lexline = cfile -> tline;
- rv = cfile -> token;
- cfile -> token = 0;
- } else {
- rv = get_token (cfile);
- cfile -> token_line = cfile -> cur_line;
- }
- if (rval)
- *rval = cfile -> tval;
- if (rlen)
- *rlen = cfile -> tlen;
-#ifdef DEBUG_TOKENS
- fprintf (stderr, "%s:%d ", cfile -> tval, rv);
-#endif
- return rv;
-}
-
-enum dhcp_token peek_token (rval, rlen, cfile)
- const char **rval;
- unsigned int *rlen;
- struct parse *cfile;
-{
- int x;
-
- if (!cfile -> token) {
- cfile -> tlpos = cfile -> lexchar;
- cfile -> tline = cfile -> lexline;
- cfile -> token = get_token (cfile);
- if (cfile -> lexline != cfile -> tline)
- cfile -> token_line = cfile -> prev_line;
-
- x = cfile -> lexchar;
- cfile -> lexchar = cfile -> tlpos;
- cfile -> tlpos = x;
-
- x = cfile -> lexline;
- cfile -> lexline = cfile -> tline;
- cfile -> tline = x;
- }
- if (rval)
- *rval = cfile -> tval;
- if (rlen)
- *rlen = cfile -> tlen;
-#ifdef DEBUG_TOKENS
- fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
-#endif
- return cfile -> token;
-}
-
-static void skip_to_eol (cfile)
- struct parse *cfile;
-{
- int c;
- do {
- c = get_char (cfile);
- if (c == EOF)
- return;
-#ifdef OLD_LEXER
- if (cfile -> comment_index < sizeof (cfile -> comments))
- comments [cfile -> comment_index++] = c;
-#endif
- if (c == EOL) {
- return;
- }
- } while (1);
-}
-
-static enum dhcp_token read_string (cfile)
- struct parse *cfile;
-{
- int i;
- int bs = 0;
- int c;
- int value;
- int hex;
-
- for (i = 0; i < sizeof cfile -> tokbuf; i++) {
- again:
- c = get_char (cfile);
- if (c == EOF) {
- parse_warn (cfile, "eof in string constant");
- break;
- }
- if (bs == 1) {
- switch (c) {
- case 't':
- cfile -> tokbuf [i] = '\t';
- break;
- case 'r':
- cfile -> tokbuf [i] = '\r';
- break;
- case 'n':
- cfile -> tokbuf [i] = '\n';
- break;
- case 'b':
- cfile -> tokbuf [i] = '\b';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- hex = 0;
- value = c - '0';
- ++bs;
- goto again;
- case 'x':
- hex = 1;
- value = 0;
- ++bs;
- goto again;
- default:
- cfile -> tokbuf [i] = c;
- bs = 0;
- break;
- }
- bs = 0;
- } else if (bs > 1) {
- if (hex) {
- if (c >= '0' && c <= '9') {
- value = value * 16 + (c - '0');
- } else if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- } else if (c >= 'A' && c <= 'F') {
- value = value * 16 + (c - 'A' + 10);
- } else {
- parse_warn (cfile,
- "invalid hex digit: %x",
- c);
- bs = 0;
- continue;
- }
- if (++bs == 4) {
- cfile -> tokbuf [i] = value;
- bs = 0;
- } else
- goto again;
- } else {
- if (c >= '0' && c <= '9') {
- value = value * 8 + (c - '0');
- } else {
- if (value != 0) {
- parse_warn (cfile,
- "invalid octal digit %x",
- c);
- continue;
- } else
- cfile -> tokbuf [i] = 0;
- bs = 0;
- }
- if (++bs == 4) {
- cfile -> tokbuf [i] = value;
- bs = 0;
- } else
- goto again;
- }
- } else if (c == '\\') {
- bs = 1;
- goto again;
- } else if (c == '"')
- break;
- else
- cfile -> 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 cfile -> tokbuf) {
- parse_warn (cfile,
- "string constant larger than internal buffer");
- --i;
- }
- cfile -> tokbuf [i] = 0;
- cfile -> tlen = i;
- cfile -> tval = cfile -> tokbuf;
- return STRING;
-}
-
-static enum dhcp_token read_number (c, cfile)
- int c;
- struct parse *cfile;
-{
- int seenx = 0;
- int i = 0;
- int token = NUMBER;
-
- cfile -> tokbuf [i++] = c;
- for (; i < sizeof cfile -> 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)) {
- if (c != EOF) {
- cfile -> bufix--;
- cfile -> ugflag = 1;
- }
- break;
- }
- cfile -> tokbuf [i] = c;
- }
- if (i == sizeof cfile -> tokbuf) {
- parse_warn (cfile,
- "numeric token larger than internal buffer");
- --i;
- }
- cfile -> tokbuf [i] = 0;
- cfile -> tlen = i;
- cfile -> tval = cfile -> tokbuf;
- return token;
-}
-
-static enum dhcp_token read_num_or_name (c, cfile)
- int c;
- struct parse *cfile;
-{
- int i = 0;
- enum dhcp_token rv = NUMBER_OR_NAME;
- cfile -> tokbuf [i++] = c;
- for (; i < sizeof cfile -> tokbuf; i++) {
- c = get_char (cfile);
- if (!isascii (c) ||
- (c != '-' && c != '_' && !isalnum (c))) {
- if (c != EOF) {
- cfile -> bufix--;
- cfile -> ugflag = 1;
- }
- break;
- }
- if (!isxdigit (c))
- rv = NAME;
- cfile -> tokbuf [i] = c;
- }
- if (i == sizeof cfile -> tokbuf) {
- parse_warn (cfile, "token larger than internal buffer");
- --i;
- }
- cfile -> tokbuf [i] = 0;
- cfile -> tlen = i;
- cfile -> tval = cfile -> tokbuf;
- return intern (cfile -> tval, rv);
-}
-
-static enum dhcp_token intern (atom, dfv)
- char *atom;
- enum dhcp_token dfv;
-{
- if (!isascii (atom [0]))
- return dfv;
-
- switch (tolower (atom [0])) {
- case '-':
- if (atom [1] == 0)
- return MINUS;
- break;
-
- case 'a':
- if (!strncasecmp (atom + 1, "uth", 3)) {
- if (!strncasecmp (atom + 3, "uthenticat", 10)) {
- if (!strcasecmp (atom + 13, "ed"))
- return AUTHENTICATED;
- if (!strcasecmp (atom + 13, "ion"))
- return AUTHENTICATION;
- break;
- }
- if (!strcasecmp (atom + 1, "uthoritative"))
- return AUTHORITATIVE;
- break;
- }
- if (!strcasecmp (atom + 1, "nd"))
- return AND;
- if (!strcasecmp (atom + 1, "ppend"))
- return APPEND;
- if (!strcasecmp (atom + 1, "llow"))
- return ALLOW;
- if (!strcasecmp (atom + 1, "lias"))
- return ALIAS;
- if (!strcasecmp (atom + 1, "lgorithm"))
- return ALGORITHM;
- if (!strcasecmp (atom + 1, "bandoned"))
- return TOKEN_ABANDONED;
- if (!strcasecmp (atom + 1, "dd"))
- return TOKEN_ADD;
- if (!strcasecmp (atom + 1, "ll"))
- return ALL;
- if (!strcasecmp (atom + 1, "t"))
- return AT;
- if (!strcasecmp (atom + 1, "rray"))
- return ARRAY;
- if (!strcasecmp (atom + 1, "ddress"))
- return ADDRESS;
- if (!strcasecmp (atom + 1, "ctive"))
- return TOKEN_ACTIVE;
- break;
- case 'b':
- if (!strcasecmp (atom + 1, "ackup"))
- return TOKEN_BACKUP;
- if (!strcasecmp (atom + 1, "ootp"))
- return TOKEN_BOOTP;
- if (!strcasecmp (atom + 1, "inding"))
- return BINDING;
- if (!strcasecmp (atom + 1, "inary-to-ascii"))
- return BINARY_TO_ASCII;
- if (!strcasecmp (atom + 1, "ackoff-cutoff"))
- return BACKOFF_CUTOFF;
- if (!strcasecmp (atom + 1, "ooting"))
- return BOOTING;
- if (!strcasecmp (atom + 1, "oot-unknown-clients"))
- return BOOT_UNKNOWN_CLIENTS;
- if (!strcasecmp (atom + 1, "reak"))
- return BREAK;
- if (!strcasecmp (atom + 1, "illing"))
- return BILLING;
- if (!strcasecmp (atom + 1, "oolean"))
- return BOOLEAN;
- if (!strcasecmp (atom + 1, "alance"))
- return BALANCE;
- if (!strcasecmp (atom + 1, "ound"))
- return BOUND;
- break;
- case 'c':
- if (!strcasecmp (atom + 1, "ase"))
- return CASE;
- if (!strcasecmp (atom + 1, "ommit"))
- return COMMIT;
- if (!strcasecmp (atom + 1, "ode"))
- return CODE;
- if (!strcasecmp (atom + 1, "onfig-option"))
- return CONFIG_OPTION;
- if (!strcasecmp (atom + 1, "heck"))
- return CHECK;
- if (!strcasecmp (atom + 1, "lass"))
- return CLASS;
- if (!strcasecmp (atom + 1, "lose"))
- return TOKEN_CLOSE;
- if (!strcasecmp (atom + 1, "reate"))
- return TOKEN_CREATE;
- if (!strcasecmp (atom + 1, "iaddr"))
- return CIADDR;
- if (!strncasecmp (atom + 1, "lient", 5)) {
- if (!strcasecmp (atom + 6, "-identifier"))
- return CLIENT_IDENTIFIER;
- if (!strcasecmp (atom + 6, "-hostname"))
- return CLIENT_HOSTNAME;
- if (!strcasecmp (atom + 6, "-state"))
- return CLIENT_STATE;
- if (!strcasecmp (atom + 6, "-updates"))
- return CLIENT_UPDATES;
- if (!strcasecmp (atom + 6, "s"))
- return CLIENTS;
- }
- if (!strcasecmp (atom + 1, "oncat"))
- return CONCAT;
- if (!strcasecmp (atom + 1, "onnect"))
- return CONNECT;
- if (!strcasecmp (atom + 1, "ommunications-interrupted"))
- return COMMUNICATIONS_INTERRUPTED;
- if (!strcasecmp (atom + 1, "ltt"))
- return CLTT;
- break;
- case 'd':
- if (!strcasecmp (atom + 1, "ns-update"))
- return DNS_UPDATE;
- if (!strcasecmp (atom + 1, "ns-delete"))
- return DNS_DELETE;
- if (!strcasecmp (atom + 1, "omain"))
- return DOMAIN;
- if (!strcasecmp (atom + 1, "omain-name"))
- return DOMAIN_NAME;
- if (!strcasecmp (atom + 1, "o-forward-update"))
- return DO_FORWARD_UPDATE;
- if (!strcasecmp (atom + 1, "ebug"))
- return TOKEN_DEBUG;
- if (!strcasecmp (atom + 1, "eny"))
- return DENY;
- if (!strcasecmp (atom + 1, "eleted"))
- return TOKEN_DELETED;
- if (!strcasecmp (atom + 1, "elete"))
- return TOKEN_DELETE;
- 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", 6)) {
- if (!atom [7])
- return DYNAMIC;
- if (!strncasecmp (atom + 7, "-bootp", 6)) {
- 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;
- }
- }
- if (!strcasecmp (atom + 1, "uplicates"))
- return DUPLICATES;
- if (!strcasecmp (atom + 1, "eclines"))
- return DECLINES;
- if (!strncasecmp (atom + 1, "efine", 5)) {
- if (!strcasecmp (atom + 6, "d"))
- return DEFINED;
- if (!atom [6])
- return DEFINE;
- }
- break;
- case 'e':
- if (isascii (atom [1]) && tolower (atom [1]) == 'x') {
- if (!strcasecmp (atom + 2, "tract-int"))
- return EXTRACT_INT;
- if (!strcasecmp (atom + 2, "ists"))
- return EXISTS;
- if (!strcasecmp (atom + 2, "piry"))
- return EXPIRY;
- if (!strcasecmp (atom + 2, "pire"))
- return EXPIRE;
- if (!strcasecmp (atom + 2, "pired"))
- return TOKEN_EXPIRED;
- }
- if (!strcasecmp (atom + 1, "ncode-int"))
- return ENCODE_INT;
- if (!strcasecmp (atom + 1, "thernet"))
- return ETHERNET;
- if (!strcasecmp (atom + 1, "nds"))
- return ENDS;
- if (!strncasecmp (atom + 1, "ls", 2)) {
- if (!strcasecmp (atom + 3, "e"))
- return ELSE;
- if (!strcasecmp (atom + 3, "if"))
- return ELSIF;
- break;
- }
- if (!strcasecmp (atom + 1, "rror"))
- return ERROR;
- if (!strcasecmp (atom + 1, "val"))
- return EVAL;
- if (!strcasecmp (atom + 1, "ncapsulate"))
- return ENCAPSULATE;
- break;
- case 'f':
- if (!strcasecmp (atom + 1, "atal"))
- return FATAL;
- if (!strcasecmp (atom + 1, "ilename"))
- return FILENAME;
- if (!strcasecmp (atom + 1, "ixed-address"))
- return FIXED_ADDR;
- if (!strcasecmp (atom + 1, "ddi"))
- return FDDI;
- if (!strcasecmp (atom + 1, "ormerr"))
- return NS_FORMERR;
- if (!strcasecmp (atom + 1, "unction"))
- return FUNCTION;
- if (!strcasecmp (atom + 1, "ailover"))
- return FAILOVER;
- if (!strcasecmp (atom + 1, "ree"))
- return TOKEN_FREE;
- 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, "ba"))
- return HBA;
- if (!strcasecmp (atom + 1, "ost"))
- return HOST;
- if (!strcasecmp (atom + 1, "ost-decl-name"))
- return HOST_DECL_NAME;
- if (!strcasecmp (atom + 1, "ardware"))
- return HARDWARE;
- if (!strcasecmp (atom + 1, "ostname"))
- return HOSTNAME;
- if (!strcasecmp (atom + 1, "elp"))
- return TOKEN_HELP;
- break;
- case 'i':
- if (!strcasecmp (atom + 1, "nclude"))
- return INCLUDE;
- if (!strcasecmp (atom + 1, "nteger"))
- return INTEGER;
- if (!strcasecmp (atom + 1, "nfinite"))
- return INFINITE;
- if (!strcasecmp (atom + 1, "nfo"))
- return INFO;
- if (!strcasecmp (atom + 1, "p-address"))
- return IP_ADDRESS;
- if (!strcasecmp (atom + 1, "nitial-interval"))
- return INITIAL_INTERVAL;
- if (!strcasecmp (atom + 1, "nterface"))
- return INTERFACE;
- if (!strcasecmp (atom + 1, "dentifier"))
- return IDENTIFIER;
- if (!strcasecmp (atom + 1, "f"))
- return IF;
- if (!strcasecmp (atom + 1, "s"))
- return IS;
- if (!strcasecmp (atom + 1, "gnore"))
- return IGNORE;
- break;
- case 'k':
- if (!strcasecmp (atom + 1, "nown"))
- return KNOWN;
- if (!strcasecmp (atom + 1, "ey"))
- return KEY;
- break;
- case 'l':
- if (!strcasecmp (atom + 1, "ease"))
- return LEASE;
- if (!strcasecmp (atom + 1, "eased-address"))
- return LEASED_ADDRESS;
- if (!strcasecmp (atom + 1, "ease-time"))
- return LEASE_TIME;
- if (!strcasecmp (atom + 1, "imit"))
- return LIMIT;
- if (!strcasecmp (atom + 1, "et"))
- return LET;
- if (!strcasecmp (atom + 1, "oad"))
- return LOAD;
- if (!strcasecmp (atom + 1, "og"))
- return LOG;
- break;
- case 'm':
- if (!strncasecmp (atom + 1, "ax", 2)) {
- if (!atom [3])
- return TOKEN_MAX;
- if (!strcasecmp (atom + 3, "-lease-time"))
- return MAX_LEASE_TIME;
- if (!strcasecmp (atom + 3, "-transmit-idle"))
- return MAX_TRANSMIT_IDLE;
- if (!strcasecmp (atom + 3, "-response-delay"))
- return MAX_RESPONSE_DELAY;
- if (!strcasecmp (atom + 3, "-unacked-updates"))
- return MAX_UNACKED_UPDATES;
- }
- if (!strncasecmp (atom + 1, "in-", 3)) {
- if (!strcasecmp (atom + 4, "lease-time"))
- return MIN_LEASE_TIME;
- if (!strcasecmp (atom + 4, "secs"))
- return MIN_SECS;
- break;
- }
- if (!strncasecmp (atom + 1, "edi", 3)) {
- if (!strcasecmp (atom + 4, "a"))
- return MEDIA;
- if (!strcasecmp (atom + 4, "um"))
- return MEDIUM;
- break;
- }
- if (!strcasecmp (atom + 1, "atch"))
- return MATCH;
- if (!strcasecmp (atom + 1, "embers"))
- return MEMBERS;
- if (!strcasecmp (atom + 1, "y"))
- return MY;
- if (!strcasecmp (atom + 1, "clt"))
- return MCLT;
- break;
- case 'n':
- if (!strcasecmp (atom + 1, "ormal"))
- return NORMAL;
- if (!strcasecmp (atom + 1, "ameserver"))
- return NAMESERVER;
- if (!strcasecmp (atom + 1, "etmask"))
- return NETMASK;
- if (!strcasecmp (atom + 1, "ever"))
- return NEVER;
- if (!strcasecmp (atom + 1, "ext-server"))
- return NEXT_SERVER;
- if (!strcasecmp (atom + 1, "ot"))
- return TOKEN_NOT;
- if (!strcasecmp (atom + 1, "o"))
- return NO;
- if (!strcasecmp (atom + 1, "s-update"))
- return NS_UPDATE;
- if (!strcasecmp (atom + 1, "oerror"))
- return NS_NOERROR;
- if (!strcasecmp (atom + 1, "otauth"))
- return NS_NOTAUTH;
- if (!strcasecmp (atom + 1, "otimp"))
- return NS_NOTIMP;
- if (!strcasecmp (atom + 1, "otzone"))
- return NS_NOTZONE;
- if (!strcasecmp (atom + 1, "xdomain"))
- return NS_NXDOMAIN;
- if (!strcasecmp (atom + 1, "xrrset"))
- return NS_NXRRSET;
- if (!strcasecmp (atom + 1, "ull"))
- return TOKEN_NULL;
- if (!strcasecmp (atom + 1, "ext"))
- return TOKEN_NEXT;
- if (!strcasecmp (atom + 1, "ew"))
- return TOKEN_NEW;
- break;
- case 'o':
- if (!strcasecmp (atom + 1, "mapi"))
- return OMAPI;
- if (!strcasecmp (atom + 1, "r"))
- return OR;
- if (!strcasecmp (atom + 1, "n"))
- return ON;
- if (!strcasecmp (atom + 1, "pen"))
- return TOKEN_OPEN;
- if (!strcasecmp (atom + 1, "ption"))
- return OPTION;
- if (!strcasecmp (atom + 1, "ne-lease-per-client"))
- return ONE_LEASE_PER_CLIENT;
- if (!strcasecmp (atom + 1, "f"))
- return OF;
- if (!strcasecmp (atom + 1, "wner"))
- return OWNER;
- break;
- case 'p':
- if (!strcasecmp (atom + 1, "repend"))
- return PREPEND;
- if (!strcasecmp (atom + 1, "acket"))
- return PACKET;
- if (!strcasecmp (atom + 1, "ool"))
- return POOL;
- if (!strcasecmp (atom + 1, "seudo"))
- return PSEUDO;
- if (!strcasecmp (atom + 1, "eer"))
- return PEER;
- if (!strcasecmp (atom + 1, "rimary"))
- return PRIMARY;
- if (!strncasecmp (atom + 1, "artner", 6)) {
- if (!atom [7])
- return PARTNER;
- if (!strcasecmp (atom + 7, "-down"))
- return PARTNER_DOWN;
- }
- if (!strcasecmp (atom + 1, "ort"))
- return PORT;
- if (!strcasecmp (atom + 1, "otential-conflict"))
- return POTENTIAL_CONFLICT;
- if (!strcasecmp (atom + 1, "ick-first-value") ||
- !strcasecmp (atom + 1, "ick"))
- return PICK;
- if (!strcasecmp (atom + 1, "aused"))
- return PAUSED;
- break;
- case 'r':
- if (!strcasecmp (atom + 1, "esolution-interrupted"))
- return RESOLUTION_INTERRUPTED;
- if (!strcasecmp (atom + 1, "ange"))
- return RANGE;
- if (!strcasecmp (atom + 1, "ecover"))
- return RECOVER;
- if (!strcasecmp (atom + 1, "ecover-done"))
- return RECOVER_DONE;
- if (!strcasecmp (atom + 1, "ecover-wait"))
- return RECOVER_WAIT;
- if (!strcasecmp (atom + 1, "econtact-interval"))
- return RECONTACT_INTERVAL;
- if (!strcasecmp (atom + 1, "equest"))
- return REQUEST;
- if (!strcasecmp (atom + 1, "equire"))
- return REQUIRE;
- if (!strcasecmp (atom + 1, "equire"))
- return REQUIRE;
- if (!strcasecmp (atom + 1, "etry"))
- return RETRY;
- if (!strcasecmp (atom + 1, "eturn"))
- return RETURN;
- if (!strcasecmp (atom + 1, "enew"))
- return RENEW;
- if (!strcasecmp (atom + 1, "ebind"))
- return REBIND;
- if (!strcasecmp (atom + 1, "eboot"))
- return REBOOT;
- if (!strcasecmp (atom + 1, "eject"))
- return REJECT;
- if (!strcasecmp (atom + 1, "everse"))
- return REVERSE;
- if (!strcasecmp (atom + 1, "elease"))
- return RELEASE;
- if (!strcasecmp (atom + 1, "efused"))
- return NS_REFUSED;
- if (!strcasecmp (atom + 1, "eleased"))
- return TOKEN_RELEASED;
- if (!strcasecmp (atom + 1, "eset"))
- return TOKEN_RESET;
- if (!strcasecmp (atom + 1, "eserved"))
- return TOKEN_RESERVED;
- if (!strcasecmp (atom + 1, "emove"))
- return REMOVE;
- if (!strcasecmp (atom + 1, "efresh"))
- return REFRESH;
- break;
- case 's':
- if (!strcasecmp (atom + 1, "tate"))
- return STATE;
- if (!strcasecmp (atom + 1, "ecret"))
- return SECRET;
- if (!strcasecmp (atom + 1, "ervfail"))
- return NS_SERVFAIL;
- if (!strcasecmp (atom + 1, "witch"))
- return SWITCH;
- if (!strcasecmp (atom + 1, "igned"))
- return SIGNED;
- if (!strcasecmp (atom + 1, "tring"))
- return STRING_TOKEN;
- if (!strcasecmp (atom + 1, "uffix"))
- return SUFFIX;
- if (!strcasecmp (atom + 1, "earch"))
- return SEARCH;
- if (!strcasecmp (atom + 1, "tarts"))
- return STARTS;
- if (!strcasecmp (atom + 1, "iaddr"))
- return SIADDR;
- if (!strcasecmp (atom + 1, "hared-network"))
- return SHARED_NETWORK;
- if (!strcasecmp (atom + 1, "econdary"))
- return SECONDARY;
- if (!strcasecmp (atom + 1, "erver-name"))
- return SERVER_NAME;
- if (!strcasecmp (atom + 1, "erver-identifier"))
- return SERVER_IDENTIFIER;
- if (!strcasecmp (atom + 1, "erver"))
- return SERVER;
- if (!strcasecmp (atom + 1, "elect-timeout"))
- return SELECT_TIMEOUT;
- if (!strcasecmp (atom + 1, "elect"))
- return SELECT;
- if (!strcasecmp (atom + 1, "end"))
- return SEND;
- if (!strcasecmp (atom + 1, "cript"))
- return SCRIPT;
- if (!strcasecmp (atom + 1, "upersede"))
- return SUPERSEDE;
- if (!strncasecmp (atom + 1, "ub", 2)) {
- if (!strcasecmp (atom + 3, "string"))
- return SUBSTRING;
- if (!strcasecmp (atom + 3, "net"))
- return SUBNET;
- if (!strcasecmp (atom + 3, "class"))
- return SUBCLASS;
- break;
- }
- if (!strcasecmp (atom + 1, "pawn"))
- return SPAWN;
- if (!strcasecmp (atom + 1, "pace"))
- return SPACE;
- if (!strcasecmp (atom + 1, "tatic"))
- return STATIC;
- if (!strcasecmp (atom + 1, "plit"))
- return SPLIT;
- if (!strcasecmp (atom + 1, "et"))
- return TOKEN_SET;
- if (!strcasecmp (atom + 1, "econds"))
- return SECONDS;
- if (!strcasecmp (atom + 1, "hutdown"))
- return SHUTDOWN;
- if (!strcasecmp (atom + 1, "tartup"))
- return STARTUP;
- 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;
- if (!strcasecmp (atom + 1, "ext"))
- return TEXT;
- if (!strcasecmp (atom + 1, "stp"))
- return TSTP;
- if (!strcasecmp (atom + 1, "sfp"))
- return TSFP;
- if (!strcasecmp (atom + 1, "ransmission"))
- return TRANSMISSION;
- break;
- case 'u':
- if (!strcasecmp (atom + 1, "nset"))
- return UNSET;
- if (!strcasecmp (atom + 1, "nsigned"))
- return UNSIGNED;
- if (!strcasecmp (atom + 1, "id"))
- return UID;
- if (!strncasecmp (atom + 1, "se", 2)) {
- if (!strcasecmp (atom + 3, "r-class"))
- return USER_CLASS;
- if (!strcasecmp (atom + 3, "-host-decl-names"))
- return USE_HOST_DECL_NAMES;
- if (!strcasecmp (atom + 3,
- "-lease-addr-for-default-route"))
- return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
- break;
- }
- if (!strncasecmp (atom + 1, "nknown", 6)) {
- if (!strcasecmp (atom + 7, "-clients"))
- return UNKNOWN_CLIENTS;
- if (!strcasecmp (atom + 7, "-state"))
- return UNKNOWN_STATE;
- if (!atom [7])
- return UNKNOWN;
- break;
- }
- if (!strcasecmp (atom + 1, "nauthenticated"))
- return AUTHENTICATED;
- if (!strcasecmp (atom + 1, "pdated-dns-rr"))
- return UPDATED_DNS_RR;
- if (!strcasecmp (atom + 1, "pdate"))
- return UPDATE;
- break;
- case 'v':
- if (!strcasecmp (atom + 1, "endor-class"))
- return VENDOR_CLASS;
- if (!strcasecmp (atom + 1, "endor"))
- return VENDOR;
- break;
- case 'w':
- if (!strcasecmp (atom + 1, "ith"))
- return WITH;
- break;
- case 'y':
- if (!strcasecmp (atom + 1, "iaddr"))
- return YIADDR;
- if (!strcasecmp (atom + 1, "xdomain"))
- return NS_YXDOMAIN;
- if (!strcasecmp (atom + 1, "xrrset"))
- return NS_YXRRSET;
- break;
- case 'z':
- if (!strcasecmp (atom + 1, "one"))
- return ZONE;
- break;
- }
- return dfv;
-}
diff --git a/contrib/isc-dhcp/common/ctrace.c b/contrib/isc-dhcp/common/ctrace.c
deleted file mode 100644
index 790a365..0000000
--- a/contrib/isc-dhcp/common/ctrace.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* trace.c
-
- Subroutines that support dhcp tracing... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 2001-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon, as part of a project for Nominum, Inc. To learn more
- * about Internet Systems Consortium, see http://www.isc.org/. To
- * learn more about Nominum, Inc., see ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: ctrace.c,v 1.3.2.2 2004/06/10 17:59:15 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (TRACING)
-void trace_interface_register (trace_type_t *ttype, struct interface_info *ip)
-{
- trace_interface_packet_t tipkt;
-
- if (trace_record ()) {
- memset (&tipkt, 0, sizeof tipkt);
- memcpy (&tipkt.hw_address,
- &ip -> hw_address, sizeof ip -> hw_address);
- memcpy (&tipkt.primary_address,
- &ip -> primary_address, sizeof ip -> primary_address);
- memcpy (tipkt.name, ip -> name, sizeof ip -> name);
- tipkt.index = htonl (ip -> index);
-
- trace_write_packet (ttype, sizeof tipkt, (char *)&tipkt, MDL);
- }
-}
-
-void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
-{
- trace_interface_packet_t *tipkt;
- struct interface_info *ip;
- struct sockaddr_in *sin;
- struct iaddr addr;
- isc_result_t status;
-
- if (len != sizeof *tipkt) {
- log_error ("trace interface packet size mismatch: %ld != %d",
- (long)(sizeof *tipkt), len);
- return;
- }
- tipkt = (trace_interface_packet_t *)buf;
-
- ip = (struct interface_info *)0;
- status = interface_allocate (&ip, MDL);
- if (status != ISC_R_SUCCESS) {
- foo:
- log_error ("trace_interface_input: %s.",
- isc_result_totext (status));
- return;
- }
- ip -> ifp = dmalloc (sizeof *(ip -> ifp), MDL);
- if (!ip -> ifp) {
- interface_dereference (&ip, MDL);
- status = ISC_R_NOMEMORY;
- goto foo;
- }
-
- memcpy (&ip -> hw_address, &tipkt -> hw_address,
- sizeof ip -> hw_address);
- memcpy (&ip -> primary_address, &tipkt -> primary_address,
- sizeof ip -> primary_address);
- memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
- ip -> index = ntohl (tipkt -> index);
-
- interface_snorf (ip, 0);
- if (dhcp_interface_discovery_hook)
- (*dhcp_interface_discovery_hook) (ip);
-
- /* Fake up an ifp. */
- memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
-#ifdef HAVE_SA_LEN
- ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
-#endif
- sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
- sin -> sin_addr = ip -> primary_address;
-
- addr.len = 4;
- memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
- if (dhcp_interface_setup_hook)
- (*dhcp_interface_setup_hook) (ip, &addr);
- interface_stash (ip);
-
- if (!quiet_interface_discovery) {
- log_info ("Listening on Trace/%s/%s%s%s",
- ip -> name,
- print_hw_addr (ip -> hw_address.hbuf [0],
- ip -> hw_address.hlen - 1,
- &ip -> hw_address.hbuf [1]),
- (ip -> shared_network ? "/" : ""),
- (ip -> shared_network ?
- ip -> shared_network -> name : ""));
- if (strcmp (ip -> name, "fallback")) {
- log_info ("Sending on Trace/%s/%s%s%s",
- ip -> name,
- print_hw_addr (ip -> hw_address.hbuf [0],
- ip -> hw_address.hlen - 1,
- &ip -> hw_address.hbuf [1]),
- (ip -> shared_network ? "/" : ""),
- (ip -> shared_network ?
- ip -> shared_network -> name : ""));
- }
- }
- interface_dereference (&ip, MDL);
-}
-
-void trace_interface_stop (trace_type_t *ttype) {
- /* XXX */
-}
-
-void trace_inpacket_stash (struct interface_info *interface,
- struct dhcp_packet *packet,
- unsigned len,
- unsigned int from_port,
- struct iaddr from,
- struct hardware *hfrom)
-{
- trace_inpacket_t tip;
- trace_iov_t iov [2];
-
- if (!trace_record ())
- return;
- tip.from_port = from_port;
- tip.from = from;
- if (hfrom) {
- tip.hfrom = *hfrom;
- tip.havehfrom = 1;
- } else {
- memset (&tip.hfrom, 0, sizeof tip.hfrom);
- tip.havehfrom = 0;
- }
- tip.index = htonl (interface -> index);
-
- iov [0].buf = (char *)&tip;
- iov [0].len = sizeof tip;
- iov [1].buf = (char *)packet;
- iov [1].len = len;
- trace_write_packet_iov (inpacket_trace, 2, iov, MDL);
-}
-
-void trace_inpacket_input (trace_type_t *ttype, unsigned len, char *buf)
-{
- trace_inpacket_t *tip;
- int index;
-
- if (len < sizeof *tip) {
- log_error ("trace_input_packet: too short - %d", len);
- return;
- }
- tip = (trace_inpacket_t *)buf;
- index = ntohl (tip -> index);
-
- if (index > interface_count ||
- index < 0 ||
- !interface_vector [index]) {
- log_error ("trace_input_packet: unknown interface index %d",
- index);
- return;
- }
-
- if (!bootp_packet_handler) {
- log_error ("trace_input_packet: no bootp packet handler.");
- return;
- }
-
- (*bootp_packet_handler) (interface_vector [index],
- (struct dhcp_packet *)(tip + 1),
- len - sizeof *tip,
- tip -> from_port,
- tip -> from,
- (tip -> havehfrom ?
- &tip -> hfrom
- : (struct hardware *)0));
-}
-
-void trace_inpacket_stop (trace_type_t *ttype) { }
-
-ssize_t trace_packet_send (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)
-{
- trace_outpacket_t tip;
- trace_iov_t iov [2];
-
- if (trace_record ()) {
- if (hto) {
- tip.hto = *hto;
- tip.havehto = 1;
- } else {
- memset (&tip.hto, 0, sizeof tip.hto);
- tip.havehto = 0;
- }
- tip.from.len = 4;
- memcpy (tip.from.iabuf, &from, 4);
- tip.to.len = 4;
- memcpy (tip.to.iabuf, &to -> sin_addr, 4);
- tip.to_port = to -> sin_port;
- tip.index = htonl (interface -> index);
-
- iov [0].buf = (char *)&tip;
- iov [0].len = sizeof tip;
- iov [1].buf = (char *)raw;
- iov [1].len = len;
- trace_write_packet_iov (outpacket_trace, 2, iov, MDL);
- }
- if (!trace_playback ()) {
- return send_packet (interface, packet, raw, len,
- from, to, hto);
- }
- return len;
-}
-
-void trace_outpacket_input (trace_type_t *ttype, unsigned len, char *buf)
-{
- trace_outpacket_t *tip;
- int index;
-
- if (len < sizeof *tip) {
- log_error ("trace_input_packet: too short - %d", len);
- return;
- }
- tip = (trace_outpacket_t *)buf;
- index = ntohl (tip -> index);
-
- if (index > interface_count ||
- index < 0 ||
- !interface_vector [index]) {
- log_error ("trace_input_packet: unknown interface index %d",
- index);
- return;
- }
-
- /* XXX would be nice to somehow take notice of these. */
-}
-
-void trace_outpacket_stop (trace_type_t *ttype) { }
-
-void trace_seed_stash (trace_type_t *ttype, unsigned seed)
-{
- u_int32_t outseed;
- if (!trace_record ())
- return;
- outseed = htonl (seed);
- trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
- return;
-}
-
-void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf)
-{
- u_int32_t *seed;
-
- if (length != sizeof seed) {
- log_error ("trace_seed_input: wrong size (%d)", length);
- }
- seed = (u_int32_t *)buf;
- srandom (ntohl (*seed));
-}
-
-void trace_seed_stop (trace_type_t *ttype) { }
-#endif /* TRACING */
diff --git a/contrib/isc-dhcp/common/dhcp-eval.5 b/contrib/isc-dhcp/common/dhcp-eval.5
deleted file mode 100644
index 48ee31b..0000000
--- a/contrib/isc-dhcp/common/dhcp-eval.5
+++ /dev/null
@@ -1,477 +0,0 @@
-.\" $Id: dhcp-eval.5,v 1.17.2.7 2004/06/10 17:59:15 dhankins Exp $
-.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-.\" Copyright (c) 1996-2003 by Internet Software Consortium
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.\" Internet Systems Consortium, Inc.
-.\" 950 Charter Street
-.\" Redwood City, CA 94063
-.\" <info@isc.org>
-.\" http://www.isc.org/
-.\"
-.\" This software has been written for Internet Systems Consortium
-.\" by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
-.\" To learn more about Internet Systems Consortium, see
-.\" ``http://www.isc.org/''. To learn more about Vixie Enterprises,
-.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
-.\" ``http://www.nominum.com''.
-.TH dhcp-eval 5
-.SH NAME
-dhcp-eval - ISC DHCP conditional evaluation
-.SH DESCRIPTION
-The Internet Systems Consortium DHCP client and server both provide
-the ability to perform conditional behavior depending on the contents
-of packets they receive. The syntax for specifying this conditional
-behaviour is documented here.
-.SH REFERENCE: CONDITIONAL BEHAVIOUR
-Conditional behaviour is specified using the if statement and the else
-or elsif statements. A conditional statement can appear anywhere
-that a regular statement (e.g., an option statement) can appear, and
-can enclose one or more such statements. A typical conditional
-statement in a server might be:
-.PP
-.nf
-if option dhcp-user-class = "accounting" {
- max-lease-time 17600;
- option domain-name "accounting.example.org";
- option domain-name-servers ns1.accounting.example.org,
- ns2.accounting.example.org;
-} elsif option dhcp-user-class = "sales" {
- max-lease-time 17600;
- option domain-name "sales.example.org";
- option domain-name-servers ns1.sales.example.org,
- ns2.sales.example.org;
-} elsif option dhcp-user-class = "engineering" {
- max-lease-time 17600;
- option domain-name "engineering.example.org";
- option domain-name-servers ns1.engineering.example.org,
- ns2.engineering.example.org;
-} else {
- max-lease-time 600;
- option domain-name "misc.example.org";
- option domain-name-servers ns1.misc.example.org,
- ns2.misc.example.org;
-}
-.fi
-.PP
-On the client side, an example of conditional evaluation might be:
-.PP
-.nf
-# example.org filters DNS at its firewall, so we have to use their DNS
-# servers when we connect to their network. If we are not at
-# example.org, prefer our own DNS server.
-if not option domain-name = "example.org" {
- prepend domain-name-servers 127.0.0.1;
-}
-.fi
-.PP
-The
-.B if
-statement and the
-.B elsif
-continuation statement both take boolean expressions as their
-arguments. That is, they take expressions that, when evaluated,
-produce a boolean result. If the expression evaluates to true, then
-the statements enclosed in braces following the
-.B if
-statement are executed, and all subsequent
-.B elsif
-and
-.B else
-clauses are skipped. Otherwise, each subsequent
-.B elsif
-clause's expression is checked, until an elsif clause is encountered
-whose test evaluates to true. If such a clause is found, the
-statements in braces following it are executed, and then any
-subsequent
-.B elsif
-and
-.B else
-clauses are skipped. If all the
-.B if
-and
-.B elsif
-clauses are checked but none
-of their expressions evaluate true, then if there is an
-.B else
-clause, the statements enclosed in braces following the
-.B else
-are evaluated. Boolean expressions that evaluate to null are
-treated as false in conditionals.
-.SH BOOLEAN EXPRESSIONS
-The following is the current list of boolean expressions that are
-supported by the DHCP distribution.
-.PP
-.I data-expression-1 \fB=\fI data-expression-2\fR
-.RS 0.25i
-.PP
-The \fB=\fR operator compares the values of two data expressions,
-returning true if they are the same, false if they are not. If
-either the left-hand side or the right-hand side are null, the
-result is also null.
-.RE
-.PP
-.I boolean-expression-1 \fBand\fI boolean-expression-2\fR
-.PP
-.RS 0.25i
-The \fBand\fR operator evaluates to true if the boolean expression on
-the left-hand side and the boolean expression on the right-hand side
-both evaluate to true. Otherwise, it evaluates to false. If either
-the expression on the left-hand side or the expression on the
-right-hand side are null, the result is null.
-.RE
-.PP
-.I boolean-expression-1 \fBor\fI boolean-expression-2\fR
-.PP
-.RS 0.25i
-The \fBor\fR operator evaluates to true if either the boolean
-expression on the left-hand side or the boolean expression on the
-right-hand side evaluate to true. Otherwise, it evaluates to false.
-If either the expression on the left-hand side or the expression on
-the right-hand side are null, the result is null.
-.RE
-.PP
-.B not \fIboolean-expression
-.PP
-.RS 0.25i
-The \fBnot\fR operator evaluates to true if \fIboolean-expression\fR
-evaluates to false, and returns false if \fIboolean-expression\fR evaluates
-to true. If \fIboolean-expression\fR evaluates to null, the result
-is also null.
-.RE
-.PP
-.B exists \fIoption-name\fR
-.PP
-.RS 0.25i
-The \fBexists\fR expression returns true if the specified option
-exists in the incoming DHCP packet being processed.
-.RE
-.B known
-.PP
-.RS 0.25i
-The \fBknown\fR expression returns true if the client whose request is
-currently being processed is known - that is, if there's a host
-declaration for it.
-.RE
-.B static
-.PP
-.RS 0.25i
-The \fBstatic\fR expression returns true if the lease assigned to the
-client whose request is currently being processed is derived from a static
-address assignment.
-.RE
-.SH DATA EXPRESSIONS
-Several of the boolean expressions above depend on the results of
-evaluating data expressions. A list of these expressions is provided
-here.
-.PP
-.B substring (\fIdata-expr\fB, \fIoffset\fB, \fIlength\fB)\fR
-.PP
-.RS 0.25i
-The \fBsubstring\fR operator evaluates the data expression and returns
-the substring of the result of that evaluation that starts
-\fIoffset\fR bytes from the beginning, continuing for \fIlength\fR
-bytes. \fIOffset\fR and \fIlength\fR are both numeric expressions.
-If \fIdata-expr\fR, \fIoffset\fR or \fIlength\fR evaluate to null,
-then the result is also null. If \fIoffset\fR is greater than or
-equal to the length of the evaluated data, then a zero-length data
-string is returned. If \fIlength\fI is greater then the remaining
-length of the evaluated data after \fIoffset\fR, then a data string
-containing all data from \fIoffset\fR to the end of the evaluated data
-is returned.
-.RE
-.PP
-.B suffix (\fIdata-expr\fB, \fIlength\fB)\fR
-.PP
-.RS 0.25i
-The \fBsuffix\fR operator evaluates \fIdata-expr\fR and returns the
-last \fIlength\fR bytes of the result of that evaluation. \fILength\fR
-is a numeric expression. If \fIdata-expr\fR or \fIlength\fR evaluate
-to null, then the result is also null. If \fIsuffix\fR evaluates to a
-number greater than the length of the evaluated data, then the
-evaluated data is returned.
-.RE
-.PP
-.B option \fIoption-name\fR
-.PP
-.RS 0.25i
-The \fBoption\fR operator returns the contents of the specified option in
-the packet to which the server is responding.
-.RE
-.PP
-.B config-option \fIoption-name\fR
-.PP
-.RS 0.25i
-The \fBconfig-option\fR operator returns the value for the specified option
-that the DHCP client or server has been configured to send.
-.RE
-.PP
-.B hardware
-.PP
-.RS 0.25i
-The \fBhardware\fR operator returns a data string whose first element
-is the type of network interface indicated in packet being considered,
-and whose subsequent elements are client's link-layer address. If
-there is no packet, or if the RFC2131 \fIhlen\fR field is invalid,
-then the result is null. Hardware types include ethernet (1),
-token-ring (6), and fddi (8). Hardware types are specified by the
-IETF, and details on how the type numbers are defined can be found in
-RFC2131 (in the ISC DHCP distribution, this is included in the doc/
-subdirectory).
-.RE
-.PP
-.B packet (\fIoffset\fB, \fIlength\fB)\fR
-.PP
-.RS 0.25i
-The \fBpacket\fR operator returns the specified portion of the packet
-being considered, or null in contexts where no packet is being
-considered. \fIOffset\fR and \fIlength\fR are applied to the
-contents packet as in the \fBsubstring\fR operator.
-.RE
-.PP
-.I string
-.PP
-.RS 0.25i
-A string, enclosed in quotes, may be specified as a data expression,
-and returns the text between the quotes, encoded in ASCII. The
-backslash ('\\') character is treated specially, as in C programming:
-'\\t' means TAB, '\\r' means carriage return, '\\n' means newline, and
-'\\b' means bell. Any octal value can be specified with '\\nnn',
-where nnn is any positive octal number less than 0400. Any
-hexadecimal value can be specified with '\xnn', where nn is any
-positive hexadecimal number less than 0xff.
-.RE
-.PP
-.I colon-separated hexadecimal list
-.PP
-.RS 0.25i
-A list of hexadecimal octet values, separated by colons, may be
-specified as a data expression.
-.RE
-.PP
-.B concat (\fIdata-expr1\fB, ..., \fIdata-exprN\fB)\fR
-.RS 0.25i
-The expressions are evaluated, and the results of each evaluation are
-concatenated in the sequence that the subexpressions are listed. If
-any subexpression evaluates to null, the result of the concatenation
-is null.
-.RE
-.PP
-.B reverse (\fInumeric-expr1\fB, \fIdata-expr2\fB)\fR
-.RS 0.25i
-The two expressions are evaluated, and then the result of evaluating
-the data expression is reversed in place, using hunks of the size
-specified in the numeric expression. For example, if the numeric
-expression evaluates to four, and the data expression evaluates to
-twelve bytes of data, then the reverse expression will evaluate to
-twelve bytes of data, consisting of the last four bytes of the the
-input data, followed by the middle four bytes, followed by the first
-four bytes.
-.RE
-.PP
-.B leased-address
-.RS 0.25i
-In any context where the client whose request is being processed has
-been assigned an IP address, this data expression returns that IP
-address.
-.RE
-.PP
-.B binary-to-ascii (\fInumeric-expr1\fB, \fInumeric-expr2\fB,
-.B \fIdata-expr1\fB,\fR \fIdata-expr2\fB)\fR
-.RS 0.25i
-Converts the result of evaluating data-expr2 into a text string
-containing one number for each element of the result of evaluating
-data-expr2. Each number is separated from the other by the result of
-evaluating data-expr1. The result of evaluating numeric-expr1
-specifies the base (2 through 16) into which the numbers should be
-converted. The result of evaluating numeric-expr2 specifies the
-width in bits of each number, which may be either 8, 16 or 32.
-.PP
-As an example of the preceding three types of expressions, to produce
-the name of a PTR record for the IP address being assigned to a
-client, one could write the following expression:
-.RE
-.PP
-.nf
- concat (binary-to-ascii (10, 8, ".",
- reverse (1, leased-address)),
- ".in-addr.arpa.");
-
-.fi
-.PP
-.B encode-int (\fInumeric-expr\fB, \fIwidth\fB)\fR
-.RS 0.25i
-Numeric-expr is evaluated and encoded as a data string of the
-specified width, in network byte order (most significant byte first).
-If the numeric expression evaluates to the null value, the result is
-also null.
-.PP
-.B pick-first-value (\fIdata-expr1\fR [ ... \fIexpr\fRn ] \fB)\fR
-.RS 0.25i
-The pick-first-value function takes any number of data expressions as
-its arguments. Each expression is evaluated, starting with the first
-in the list, until an expression is found that does not evaluate to a
-null value. That expression is returned, and none of the subsequent
-expressions are evaluated. If all expressions evaluate to a null
-value, the null value is returned.
-.RE
-.PP
-.B host-decl-name
-.RS 0.25i
-The host-decl-name function returns the name of the host declaration
-that matched the client whose request is currently being processed, if
-any. If no host declaration matched, the result is the null value.
-.RE
-.SH NUMERIC EXPRESSIONS
-Numeric expressions are expressions that evaluate to an integer. In
-general, the maximum size of such an integer should not be assumed to
-be representable in fewer than 32 bits, but the precision of such
-integers may be more than 32 bits.
-.PP
-.B extract-int (\fIdata-expr\fB, \fIwidth\fB)\fR
-.PP
-.RS 0.25i
-The \fBextract-int\fR operator extracts an integer value in network
-byte order from the result of evaluating the specified data
-expression. Width is the width in bits of the integer to extract.
-Currently, the only supported widths are 8, 16 and 32. If the
-evaluation of the data expression doesn't provide sufficient bits to
-extract an integer of the specified size, the null value is returned.
-.RE
-.PP
-.B lease-time
-.PP
-.RS 0.25i
-The duration of the current lease - that is, the difference between
-the current time and the time that the lease expires.
-.RE
-.PP
-.I number
-.PP
-.RS 0.25i
-Any number between zero and the maximum representable size may be
-specified as a numeric expression.
-.RE
-.PP
-.B client-state
-.PP
-.RS 0.25i
-The current state of the client instance being processed. This is
-only useful in DHCP client configuration files. Possible values are:
-.TP 2
-.I \(bu
-Booting - DHCP client is in the INIT state, and does not yet have an
-IP address. The next message transmitted will be a DHCPDISCOVER,
-which will be broadcast.
-.TP
-.I \(bu
-Reboot - DHCP client is in the INIT-REBOOT state. It has an IP
-address, but is not yet using it. The next message to be transmitted
-will be a DHCPREQUEST, which will be broadcast. If no response is
-heard, the client will bind to its address and move to the BOUND state.
-.TP
-.I \(bu
-Select - DHCP client is in the SELECTING state - it has received at
-least one DHCPOFFER message, but is waiting to see if it may receive
-other DHCPOFFER messages from other servers. No messages are sent in
-the SELECTING state.
-.TP
-.I \(bu
-Request - DHCP client is in the REQUESTING state - it has received at
-least one DHCPOFFER message, and has chosen which one it will
-request. The next message to be sent will be a DHCPREQUEST message,
-which will be broadcast.
-.TP
-.I \(bu
-Bound - DHCP client is in the BOUND state - it has an IP address. No
-messages are transmitted in this state.
-.TP
-.I \(bu
-Renew - DHCP client is in the RENEWING state - it has an IP address,
-and is trying to contact the server to renew it. The next message to
-be sent will be a DHCPREQUEST message, which will be unicast directly
-to the server.
-.TP
-.I \(bu
-Rebind - DHCP client is in the REBINDING state - it has an IP address,
-and is trying to contact any server to renew it. The next message to
-be sent will be a DHCPREQUEST, which will be broadcast.
-.RE
-.SH REFERENCE: LOGGING
-Logging statements may be used to send information to the standard logging
-channels. A logging statement includes an optional priority (\fBfatal\fR,
-\fBerror\fR, \fBinfo\fR, or \fBdebug\fR), and a data expression.
-.PP
-.B log (\fIpriority\fB, \fIdata-expr\fB)\fR
-.PP
-Logging statements take only a single data expression argument, so if you
-want to output multiple data values, you will need to use the \fBconcat\fR
-operator to concatenate them.
-.RE
-.SH REFERENCE: DYNAMIC DNS UPDATES
-.PP
-The DHCP client and server have the ability to dynamically update the
-Domain Name System. Within the configuration files, you can define
-how you want the Domain Name System to be updated. These updates are
-RFC 2136 compliant so any DNS server supporting RFC 2136 should be
-able to accept updates from the DHCP server.
-.SH SECURITY
-Support for TSIG and DNSSEC is not yet available. When you set your
-DNS server up to allow updates from the DHCP server or client, you may
-be exposing it to unauthorized updates. To avoid this, the best you
-can do right now is to use IP address-based packet filtering to
-prevent unauthorized hosts from submitting update requests.
-Obviously, there is currently no way to provide security for client
-updates - this will require TSIG or DNSSEC, neither of which is yet
-available in the DHCP distribution.
-.PP
-Dynamic DNS (DDNS) updates are performed by using the \fBdns-update\fR
-expression. The \fBdns-update\fR expression is a boolean expression
-that takes four parameters. If the update succeeds, the result is
-true. If it fails, the result is false. The four parameters that the
-are the resource record type (RR), the left hand side of the RR, the
-right hand side of the RR and the ttl that should be applied to the
-record. The simplest example of the use of the function can be found
-in the reference section of the dhcpd.conf file, where events are
-described. In this example several statements are being used to make
-the arguments to the \fBdns-update\f\R.
-.PP
-In the example, the first argument to the first \f\Bdns-update\fR
-expression is a data expression that evaluates to the A RR type. The
-second argument is constructed by concatenating the DHCP host-name
-option with a text string containing the local domain, in this case
-"ssd.example.net". The third argument is constructed by converting
-the address the client has been assigned from a 32-bit number into an
-ascii string with each byte separated by a ".". The fourth argument,
-the TTL, specifies the amount of time remaining in the lease (note
-that this isn't really correct, since the DNS server will pass this
-TTL out whenever a request comes in, even if that is only a few
-seconds before the lease expires).
-.PP
-If the first \fBdns-update\fR statement succeeds, it is followed up
-with a second update to install a PTR RR. The installation of a PTR
-record is similar to installing an A RR except that the left hand side
-of the record is the leased address, reversed, with ".in-addr.arpa"
-concatenated. The right hand side is the fully qualified domain name
-of the client to which the address is being leased.
-.SH SEE ALSO
-dhcpd.conf(5), dhcpd.leases(5), dhclient.conf(5), dhcp-eval(5), dhcpd(8),
-dhclient(8), RFC2132, RFC2131.
-.SH AUTHOR
-The Internet Systems Consortium DHCP Distribution was written by Ted
-Lemon under a contract with Vixie Labs. Funding for
-this project was provided through Internet Systems Consortium.
-Information about Internet Systems Consortium can be found at
-.B http://www.isc.org.
diff --git a/contrib/isc-dhcp/common/dhcp-options.5 b/contrib/isc-dhcp/common/dhcp-options.5
deleted file mode 100644
index 9bb7f94..0000000
--- a/contrib/isc-dhcp/common/dhcp-options.5
+++ /dev/null
@@ -1,1523 +0,0 @@
-.\" $Id: dhcp-options.5,v 1.19.2.11 2004/06/10 17:59:15 dhankins Exp $
-.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
-.\" Copyright (c) 1996-2003 by Internet Software Consortium
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.\" Internet Systems Consortium, Inc.
-.\" 950 Charter Street
-.\" Redwood City, CA 94063
-.\" <info@isc.org>
-.\" http://www.isc.org/
-.\"
-.\" This software has been written for Internet Systems Consortium
-.\" by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
-.\" To learn more about Internet Systems Consortium, see
-.\" ``http://www.isc.org/''. To learn more about Vixie Enterprises,
-.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
-.\" ``http://www.nominum.com''.
-.\"
-.\" $Id: dhcp-options.5,v 1.19.2.10 2003/02/23 03:27:42 dhankins Exp $
-.\" $FreeBSD$
-.\"
-.TH dhcpd-options 5
-.SH NAME
-dhcp-options - Dynamic Host Configuration Protocol options
-.SH DESCRIPTION
-The Dynamic Host Configuration protocol allows the client to receive
-.B options
-from the DHCP server describing the network configuration and various
-services that are available on the network. When configuring
-.B dhcpd(8)
-or
-.B dhclient(8) ,
-options must often be declared. The syntax for declaring options,
-and the names and formats of the options that can be declared, are
-documented here.
-.SH REFERENCE: OPTION STATEMENTS
-.PP
-DHCP \fIoption\fR statements always start with the \fIoption\fR
-keyword, followed by an option name, followed by option data. The
-option names and data formats are described below. It is not
-necessary to exhaustively specify all DHCP options - only those
-options which are needed by clients must be specified.
-.PP
-Option data comes in a variety of formats, as defined below:
-.PP
-The
-.B ip-address
-data type can be entered either as an explicit IP
-address (e.g., 239.254.197.10) or as a domain name (e.g.,
-haagen.isc.org). When entering a domain name, be sure that that
-domain name resolves to a single IP address.
-.PP
-The
-.B int32
-data type specifies a signed 32-bit integer. The
-.B uint32
-data type specifies an unsigned 32-bit integer. The
-.B int16
-and
-.B uint16
-data types specify signed and unsigned 16-bit integers. The
-.B int8
-and
-.B uint8
-data types specify signed and unsigned 8-bit integers.
-Unsigned 8-bit integers are also sometimes referred to as octets.
-.PP
-The
-.B text
-data type specifies an NVT ASCII string, which must be
-enclosed in double quotes - for example, to specify a root-path
-option, the syntax would be
-.nf
-.sp 1
-option root-path "10.0.1.4:/var/tmp/rootfs";
-.fi
-.PP
-The
-.B domain-name
-data type specifies a domain name, which must not
-enclosed in double quotes. This data type is not used for any
-existing DHCP options. The domain name is stored just as if it were
-a text option.
-.PP
-The
-.B flag
-data type specifies a boolean value. Booleans can be either true or
-false (or on or off, if that makes more sense to you).
-.PP
-The
-.B string
-data type specifies either an NVT ASCII string
-enclosed in double quotes, or a series of octets specified in
-hexadecimal, separated by colons. For example:
-.nf
-.sp 1
- option dhcp-client-identifier "CLIENT-FOO";
-or
- option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
-.fi
-.SH SETTING OPTION VALUES USING EXPRESSIONS
-Sometimes it's helpful to be able to set the value of a DHCP option
-based on some value that the client has sent. To do this, you can
-use expression evaluation. The
-.B dhcp-eval(5)
-manual page describes how to write expressions. To assign the result
-of an evaluation to an option, define the option as follows:
-.nf
-.sp 1
- \fBoption \fImy-option \fB= \fIexpression \fB;\fR
-.fi
-.PP
-For example:
-.nf
-.sp 1
- option hostname = binary-to-ascii (16, 8, "-",
- substring (hardware, 1, 6));
-.fi
-.SH STANDARD DHCP OPTIONS
-The documentation for the various options mentioned below is taken
-from the latest IETF draft document on DHCP options. Options not
-listed below may not yet be implemented, but it is possible to use
-such options by defining them in the configuration file. Please see
-the DEFINING NEW OPTIONS heading later in this document for more
-information.
-.PP
-Some of the options documented here are automatically generated by
-the DHCP server or by clients, and cannot be configured by the user.
-The value of such an option can be used in the configuration file of
-the receiving DHCP protocol agent (server or client), for example in
-conditional expressions. However, the value of the option cannot be
-used in the configuration file of the sending agent, because the value
-is determined only \fIafter\fR the configuration file has been
-processed. In the following documentation, such options will be shown
-as "not user configurable"
-.PP
-The standard options are:
-.PP
-.B option \fBall-subnets-local\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client may assume that all
-subnets of the IP network to which the client is connected use the
-same MTU as the subnet of that network to which the client is
-directly connected. A value of true indicates that all subnets share
-the same MTU. A value of false means that the client should assume that
-some subnets of the directly connected network may have smaller MTUs.
-.RE
-.PP
-.B option \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the timeout in seconds for ARP cache entries.
-.RE
-.PP
-.B option \fBbootfile-name\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used to identify a bootstrap file. If supported by the
-client, it should have the same effect as the \fBfilename\fR
-declaration. BOOTP clients are unlikely to support this option. Some
-DHCP clients will support it, and others actually require it.
-.RE
-.PP
-.B option \fBboot-size\fR \fIuint16\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the length in 512-octet blocks of the default
-boot image for the client.
-.RE
-.PP
-.B option \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the broadcast address in use on the client's
-subnet. Legal values for broadcast addresses are specified in
-section 3.2.1.3 of STD 3 (RFC1122).
-.RE
-.PP
-.B option \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The cookie server option specifies a list of RFC 865 cookie
-servers available to the client. Servers should be listed in order
-of preference.
-.RE
-.PP
-.B option \fBdefault-ip-ttl\fR \fIuint8;\fR
-.RS 0.25i
-.PP
-This option specifies the default time-to-live that the client should
-use on outgoing datagrams.
-.RE
-.PP
-.B option \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the default TTL that the client should use when
-sending TCP segments. The minimum value is 1.
-.RE
-.PP
-.B option \fBdhcp-client-identifier\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-This option can be used to specify a DHCP client identifier in a
-host declaration, so that dhcpd can find the host record by matching
-against the client identifier.
-.PP
-Please be aware that some DHCP clients, when configured with client
-identifiers that are ASCII text, will prepend a zero to the ASCII
-text. So you may need to write:
-.nf
-
- option dhcp-client-identifier "\\0foo";
-
-rather than:
-
- option dhcp-client-identifier "foo";
-.fi
-.RE
-.PP
-.B option \fBdhcp-lease-time\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used in a client request (DHCPDISCOVER or DHCPREQUEST)
-to allow the client to request a lease time for the IP address. In a
-server reply (DHCPOFFER), a DHCP server uses this option to specify
-the lease time it is willing to offer.
-.PP
-This option is not directly user configurable in the server; refer to the
-\fImax-lease-time\fR and \fIdefault-lease-time\fR server options in
-.B dhcpd.conf(5).
-.RE
-.PP
-.B option \fBdhcp-max-message-size\fR \fIuint16\fR\fB;\fR
-.RS 0.25i
-.PP
-This option, when sent by the client, specifies the maximum size of
-any response that the server sends to the client. When specified on
-the server, if the client did not send a dhcp-max-message-size option,
-the size specified on the server is used. This works for BOOTP as
-well as DHCP responses.
-.RE
-.PP
-.B option \fBdhcp-message\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used by a DHCP server to provide an error message to a
-DHCP client in a DHCPNAK message in the event of a failure. A client
-may use this option in a DHCPDECLINE message to indicate why the
-client declined the offered parameters.
-.PP
-This option is not user configurable.
-.RE
-.PP
-.B option \fBdhcp-message-type\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-This option, sent by both client and server, specifies the type of DHCP
-message contained in the DHCP packet. Possible values (taken directly from
-RFC2132) are:
-.PP
-.nf
- 1 DHCPDISCOVER
- 2 DHCPOFFER
- 3 DHCPREQUEST
- 4 DHCPDECLINE
- 5 DHCPACK
- 6 DHCPNAK
- 7 DHCPRELEASE
- 8 DHCPINFORM
-.fi
-.PP
-This option is not user configurable.
-.PP
-.RE
-.B option \fBdhcp-option-overload\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used to indicate that the DHCP 'sname' or 'file'
-fields are being overloaded by using them to carry DHCP options. A
-DHCP server inserts this option if the returned parameters will
-exceed the usual space allotted for options.
-.PP
-If this option is present, the client interprets the specified
-additional fields after it concludes interpretation of the standard
-option fields.
-.PP
-Legal values for this option are:
-.PP
-.nf
- 1 the 'file' field is used to hold options
- 2 the 'sname' field is used to hold options
- 3 both fields are used to hold options
-.fi
-.PP
-This option is not user configurable.
-.PP
-.RE
-.PP
-.B option \fBdhcp-parameter-request-list\fR \fIuint16\fR\fB;\fR
-.RS 0.25i
-.PP
-This option, when sent by the client, specifies which options the
-client wishes the server to return. Normally, in the ISC DHCP
-client, this is done using the \fIrequest\fR statement. If this
-option is not specified by the client, the DHCP server will normally
-return every option that is valid in scope and that fits into the
-reply. When this option is specified on the server, the server
-returns the specified options. This can be used to force a client to
-take options that it hasn't requested, and it can also be used to
-tailor the response of the DHCP server for clients that may need a
-more limited set of options than those the server would normally
-return.
-.RE
-.PP
-.B option \fBdhcp-rebinding-time\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the number of seconds from the time a client gets
-an address until the client transitions to the REBINDING state.
-.PP
-This option is not user configurable.
-.PP
-.RE
-.PP
-.B option \fBdhcp-renewal-time\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the number of seconds from the time a client gets
-an address until the client transitions to the RENEWING state.
-.PP
-This option is not user configurable.
-.PP
-.RE
-.PP
-.B option \fBdhcp-requested-address\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used by the client in a DHCPDISCOVER to
-request that a particular IP address be assigned.
-.PP
-This option is not user configurable.
-.PP
-.RE
-.PP
-.B option \fBdhcp-server-identifier\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used in DHCPOFFER and DHCPREQUEST messages, and may
-optionally be included in the DHCPACK and DHCPNAK messages. DHCP
-servers include this option in the DHCPOFFER in order to allow the
-client to distinguish between lease offers. DHCP clients use the
-contents of the 'server identifier' field as the destination address
-for any DHCP messages unicast to the DHCP server. DHCP clients also
-indicate which of several lease offers is being accepted by including
-this option in a DHCPREQUEST message.
-.PP
-The value of this option is the IP address of the server.
-.PP
-This option is not directly user configurable. See the
-\fIserver-identifier\fR server option in
-.B \fIdhcpd.conf(5).
-.PP
-.RE
-.PP
-.B option \fBdomain-name\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the domain name that client should use when
-resolving hostnames via the Domain Name System.
-.RE
-.PP
-.B option \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The domain-name-servers option specifies a list of Domain Name System
-(STD 13, RFC 1035) name servers available to the client. Servers
-should be listed in order of preference.
-.RE
-.PP
-.B option \fBextensions-path\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the name of a file containing additional options
-to be interpreted according to the DHCP option format as specified in
-RFC2132.
-.RE
-.PP
-.B option \fBfinger-server\fR \fIip-address\fR [\fB,\fR
-\fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The Finger server option specifies a list of Finger servers available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of X Window System Font servers available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBhost-name\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the name of the client. The name may or may
-not be qualified with the local domain name (it is preferable to use
-the domain-name option to specify the domain name). See RFC 1035 for
-character set restrictions. This option is only honored by
-.B dhclient-script(8)
-if the hostname for the client machine is not set (i.e., set to the empty
-string in
-.B rc.conf(5)
-).
-.RE
-.PP
-.B option \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should use Ethernet
-Version 2 (RFC 894) or IEEE 802.3 (RFC 1042) encapsulation if the
-interface is an Ethernet. A value of false indicates that the client
-should use RFC 894 encapsulation. A value of true means that the client
-should use RFC 1042 encapsulation.
-.RE
-.PP
-.B option \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-];
-.RS 0.25i
-.PP
-The ien116-name-servers option specifies a list of IEN 116 name servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The impress-server option specifies a list of Imagen Impress servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the MTU to use on this interface. The minimum
-legal value for the MTU is 68.
-.RE
-.PP
-.B option \fBip-forwarding\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether the client should configure its IP
-layer for packet forwarding. A value of false means disable IP
-forwarding, and a value of true means enable IP forwarding.
-.RE
-.PP
-.B option \fBirc-server\fR \fIip-address\fR [\fB,\fR
-\fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The IRC server option specifies a list of IRC servers available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The log-server option specifies a list of MIT-LCS UDP log servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The LPR server option specifies a list of RFC 1179 line printer
-servers available to the client. Servers should be listed in order
-of preference.
-.RE
-.PP
-.B option \fBmask-supplier\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should respond to
-subnet mask requests using ICMP. A value of false indicates that the
-client should not respond. A value of true means that the client should
-respond.
-.RE
-.PP
-.B option \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the maximum size datagram that the client
-should be prepared to reassemble. The minimum legal value is
-576.
-.RE
-.PP
-.B option \fBmerit-dump\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the path-name of a file to which the client's
-core image should be dumped in the event the client crashes. The
-path is formatted as a character string consisting of characters from
-the NVT ASCII character set.
-.RE
-.PP
-.B option \fBmobile-ip-home-agent\fR \fIip-address\fR [\fB,\fR \fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of IP addresses indicating mobile IP
-home agents available to the client. Agents should be listed in
-order of preference, although normally there will be only one such
-agent.
-.RE
-.PP
-.B option \fBnds-context\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The nds-context option specifies the name of the initial Netware
-Directory Service for an NDS client.
-.RE
-.PP
-.B option \fBnds-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The nds-servers option specifies a list of IP addresses of NDS servers.
-.RE
-.PP
-.B option \fBnds-tree-name\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The nds-context option specifies NDS tree name that the NDS client
-should use.
-.RE
-.PP
-.B option \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The NetBIOS datagram distribution server (NBDD) option specifies a
-list of RFC 1001/1002 NBDD servers listed in order of preference.
-.RE
-.PP
-.B option \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...]\fB;\fR
-.RS 0.25i
-.PP
-The NetBIOS name server (NBNS) option specifies a list of RFC
-1001/1002 NBNS name servers listed in order of preference. NetBIOS
-Name Service is currently more commonly referred to as WINS. WINS
-servers can be specified using the netbios-name-servers option.
-.RE
-.PP
-.B option \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-The NetBIOS node type option allows NetBIOS over TCP/IP clients which
-are configurable to be configured as described in RFC 1001/1002. The
-value is specified as a single octet which identifies the client type.
-.PP
-Possible node types are:
-.PP
-.TP 5
-.I 1
-B-node: Broadcast - no WINS
-.TP
-.I 2
-P-node: Peer - WINS only
-.TP
-.I 4
-M-node: Mixed - broadcast, then WINS
-.TP
-.I 8
-H-node: Hybrid - WINS, then broadcast
-.RE
-.PP
-.B option \fBnetbios-scope\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
-parameter for the client as specified in RFC 1001/1002. See RFC1001,
-RFC1002, and RFC1035 for character-set restrictions.
-.RE
-.PP
-.B option \fBnis-domain\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the name of the client's NIS (Sun Network
-Information Services) domain. The domain is formatted as a character
-string consisting of characters from the NVT ASCII character set.
-.RE
-.PP
-.B option \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of IP addresses indicating NIS servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBnisplus-domain\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the name of the client's NIS+ domain. The
-domain is formatted as a character string consisting of characters
-from the NVT ASCII character set.
-.RE
-.PP
-.B option \fBnisplus-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of IP addresses indicating NIS+ servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBnntp-server\fR \fIip-address\fR [\fB,\fR
-\fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The NNTP server option specifies a list of NNTP servesr available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether the client should configure its IP
-layer to allow forwarding of datagrams with non-local source routes
-(see Section 3.3.5 of [4] for a discussion of this topic). A value
-of 0 means disallow forwarding of such datagrams, and a value of true
-means allow forwarding.
-.RE
-.PP
-.B option \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of IP addresses indicating NTP (RFC 1035)
-servers available to the client. Servers should be listed in order
-of preference.
-.RE
-.PP
-.B option \fBnwip-domain\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The name of the NetWare/IP domain that a NetWare/IP client should
-use.
-.RE
-.PP
-.B option \fBnwip-suboptions\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-A sequence of suboptions for NetWare/IP clients - see RFC2242 for
-details. Normally this option is set by specifying specific
-NetWare/IP suboptions - see the NETWARE/IP SUBOPTIONS section for more
-information.
-.RE
-.PP
-.B option \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the timeout (in seconds) to use when aging Path
-MTU values discovered by the mechanism defined in RFC 1191.
-.RE
-.PP
-.B option \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a table of MTU sizes to use when performing
-Path MTU Discovery as defined in RFC 1191. The table is formatted as
-a list of 16-bit unsigned integers, ordered from smallest to largest.
-The minimum MTU value cannot be smaller than 68.
-.RE
-.PP
-.B option \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should perform subnet
-mask discovery using ICMP. A value of false indicates that the client
-should not perform mask discovery. A value of true means that the
-client should perform mask discovery.
-.RE
-.PP
-.nf
-.B option \fBpolicy-filter\fR \fIip-address ip-address\fR
- [\fB,\fR \fIip-address ip-address\fR...]\fB;\fR
-.RE
-.fi
-.RS 0.25i
-.PP
-This option specifies policy filters for non-local source routing.
-The filters consist of a list of IP addresses and masks which specify
-destination/mask pairs with which to filter incoming source routes.
-.PP
-Any source routed datagram whose next-hop address does not match one
-of the filters should be discarded by the client.
-.PP
-See STD 3 (RFC1122) for further information.
-.RE
-.PP
-.B option \fBpop-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The POP3 server option specifies a list of POP3 servers available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBresource-location-servers\fR \fIip-address\fR
- [\fB, \fR\fIip-address\fR...]\fB;\fR
-.fi
-.RS 0.25i
-.PP
-This option specifies a list of RFC 887 Resource Location
-servers available to the client. Servers should be listed in order
-of preference.
-.RE
-.PP
-.B option \fBroot-path\fR \fItext\fB;\fR\fR
-.RS 0.25i
-.PP
-This option specifies the path-name that contains the client's root
-disk. The path is formatted as a character string consisting of
-characters from the NVT ASCII character set.
-.RE
-.PP
-.B option \fBrouter-discovery\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should solicit
-routers using the Router Discovery mechanism defined in RFC 1256.
-A value of false indicates that the client should not perform
-router discovery. A value of true means that the client should perform
-router discovery.
-.RE
-.PP
-.B option \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the address to which the client should transmit
-router solicitation requests.
-.RE
-.PP
-.B option routers \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The routers option specifies a list of IP addresses for routers on the
-client's subnet. Routers should be listed in order of preference.
-.RE
-.PP
-.B option slp-directory-agent \fIboolean ip-address
-[\fB,\fR \fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies two things: the IP addresses of one or more
-Service Location Protocol Directory Agents, and whether the use of
-these addresses is mandatory. If the initial boolean value is true,
-the SLP agent should just use the IP addresses given. If the value
-is false, the SLP agent may additionally do active or passive
-multicast discovery of SLP agents (see RFC2165 for details).
-.PP
-Please note that in this option and the slp-service-scope option, the
-term "SLP Agent" is being used to refer to a Service Location Protocol
-agent running on a machine that is being configured using the DHCP
-protocol.
-.PP
-Also, please be aware that some companies may refer to SLP as NDS.
-If you have an NDS directory agent whose address you need to
-configure, the slp-directory-agent option should work.
-.RE
-.PP
-.B option slp-service-scope \fIboolean text\fR\fB;\fR
-.RS 0.25i
-.PP
-The Service Location Protocol Service Scope Option specifies two
-things: a list of service scopes for SLP, and whether the use of this
-list is mandatory. If the initial boolean value is true, the SLP
-agent should only use the list of scopes provided in this option;
-otherwise, it may use its own static configuration in preference to
-the list provided in this option.
-.PP
-The text string should be a comma-separated list of scopes that the
-SLP agent should use. It may be omitted, in which case the SLP Agent
-will use the aggregated list of scopes of all directory agents known
-to the SLP agent.
-.RE
-.PP
-.B option \fBsmtp-server\fR \fIip-address\fR [\fB,\fR
-\fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The SMTP server option specifies a list of SMTP servers available to
-the client. Servers should be listed in order of preference.
-.RE
-.PP
-.nf
-.B option \fBstatic-routes\fR \fIip-address ip-address\fR
- [\fB,\fR \fIip-address ip-address\fR...]\fB;\fR
-.fi
-.RS 0.25i
-.PP
-This option specifies a list of static routes that the client should
-install in its routing cache. If multiple routes to the same
-destination are specified, they are listed in descending order of
-priority.
-.PP
-The routes consist of a list of IP address pairs. The first address
-is the destination address, and the second address is the router for
-the destination.
-.PP
-The default route (0.0.0.0) is an illegal destination for a static
-route. To specify the default route, use the
-.B routers
-option. Also, please note that this option is not intended for
-classless IP routing - it does not include a subnet mask. Since
-classless IP routing is now the most widely deployed routing standard,
-this option is virtually useless, and is not implemented by any of the
-popular DHCP clients, for example the Microsoft DHCP client.
-.RE
-.PP
-.nf
-.B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR
- [\fB,\fR \fIip-address\fR...]\fB;\fR
-.fi
-.RS 0.25i
-.PP
-The StreetTalk Directory Assistance (STDA) server option specifies a
-list of STDA servers available to the client. Servers should be
-listed in order of preference.
-.RE
-.PP
-.B option \fBstreettalk-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The StreetTalk server option specifies a list of StreetTalk servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option subnet-mask \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-The subnet mask option specifies the client's subnet mask as per RFC
-950. If no subnet mask option is provided anywhere in scope, as a
-last resort dhcpd will use the subnet mask from the subnet declaration
-for the network on which an address is being assigned. However,
-.I any
-subnet-mask option declaration that is in scope for the address being
-assigned will override the subnet mask specified in the subnet
-declaration.
-.RE
-.PP
-.B option \fBsubnet-selection\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-Sent by the client if an address is required in a subnet other than the one
-that would normally be selected (based on the relaying address of the
-connected subnet the request is obtained from). See RFC3011. Note that the
-option number used by this server is 118; this has not always been the
-defined number, and some clients may use a different value. Use of this
-option should be regarded as slightly experimental!
-.RE
-.PP
-This option is not user configurable in the server.
-.PP
-.PP
-.B option \fBswap-server\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-This specifies the IP address of the client's swap server.
-.RE
-.PP
-.B option \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should send TCP
-keepalive messages with an octet of garbage for compatibility with
-older implementations. A value of false indicates that a garbage octet
-should not be sent. A value of true indicates that a garbage octet
-should be sent.
-.RE
-.PP
-.B option \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies the interval (in seconds) that the client TCP
-should wait before sending a keepalive message on a TCP connection.
-The time is specified as a 32-bit unsigned integer. A value of zero
-indicates that the client should not generate keepalive messages on
-connections unless specifically requested by an application.
-.RE
-.PP
-.B option \fBtftp-server-name\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used to identify a TFTP server and, if supported by the
-client, should have the same effect as the \fBserver-name\fR
-declaration. BOOTP clients are unlikely to support this option.
-Some DHCP clients will support it, and others actually require it.
-.RE
-.PP
-.B option time-offset \fIint32\fR\fB;\fR
-.RS 0.25i
-.PP
-The time-offset option specifies the offset of the client's subnet in
-seconds from Coordinated Universal Time (UTC).
-.RE
-.PP
-.B option time-servers \fIip-address\fR [, \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-The time-server option specifies a list of RFC 868 time servers
-available to the client. Servers should be listed in order of
-preference.
-.RE
-.PP
-.B option \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies whether or not the client should negotiate the
-use of trailers (RFC 893 [14]) when using the ARP protocol. A value
-of 0 indicates that the client should not attempt to use trailers. A
-value of true means that the client should attempt to use trailers.
-.RE
-.PP
-.B option \fBuap-servers\fR \fItext\fR\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of URLs, each pointing to a user
-authentication service that is capable of processing authentication
-requests encapsulated in the User Authentication Protocol (UAP). UAP
-servers can accept either HTTP 1.1 or SSLv3 connections. If the list
-includes a URL that does not contain a port component, the normal
-default port is assumed (i.e., port 80 for http and port 443 for
-https). If the list includes a URL that does not contain a path
-component, the path /uap is assumed. If more than one URL is
-specified in this list, the URLs are separated by spaces.
-.RE
-.PP
-.B option \fBuser-class\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used by some DHCP clients as a way for users to
-specify identifying information to the client. This can be used in a
-similar way to the vendor-class-identifier option, but the value of
-the option is specified by the user, not the vendor. Most recent
-DHCP clients have a way in the user interface to specify the value for
-this identifier, usually as a text string.
-.PP
-.B option \fBvendor-class-identifier\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-This option is used by some DHCP clients to identify the vendor
-type and possibly the configuration of a DHCP client. The information
-is a string of bytes whose contents are specific to the vendor and are
-not specified in a standard. To see what vendor class identifier a
-clients are sending, you can write the following in your DHCP server
-configuration file:
-.nf
-.PP
-set vendor-class option vendor-class-identifier;
-.fi
-.PP
-This will result in all entries in the DHCP server lease database file
-for clients that sent vendor-class-identifier options having a set
-statement that looks something like this:
-.nf
-.PP
-set vendor-class "SUNW.Ultra-5_10";
-.fi
-.PP
-The vendor-class-identifier option is normally used by the DHCP server
-to determine the options that are returned in the
-.B vendor-encapsulated-options
-option. Please see the VENDOR ENCAPSULATED OPTIONS section of the
-dhcpd.conf manual page for further information.
-.RE
-.PP
-.B option \fBvendor-encapsulated-options\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The \fBvendor-encapsulated-options\fR option can contain either a
-single vendor-specific value or one or more vendor-specific
-suboptions. This option is not normally specified in the DHCP server
-configuration file - instead, a vendor class is defined for each
-vendor, vendor class suboptions are defined, values for those
-suboptions are defined, and the DHCP server makes up a response on
-that basis.
-.PP
-Some default behaviours for well-known DHCP client vendors (currently,
-the Microsoft Windows 2000 DHCP client) are configured automatically,
-but otherwise this must be configured manually - see the VENDOR
-ENCAPSULATED OPTIONS section of the \fIdhcpd.conf\fI manual page for
-details.
-.RE
-.PP
-.B option \fBwww-server\fR \fIip-address\fR [\fB,\fR
-\fIip-address\fR... ]\fB;\fR
-.RS 0.25i
-.PP
-The WWW server option specifies a list of WWW servers available
-to the client. Servers should be listed in order of preference.
-.RE
-.PP
-.B option \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
-]\fB;\fR
-.RS 0.25i
-.PP
-This option specifies a list of systems that are running the X Window
-System Display Manager and are available to the client. Addresses
-should be listed in order of preference.
-.RE
-.SH RELAY AGENT INFORMATION OPTION
-An IETF draft, draft-ietf-dhc-agent-options-11.txt, defines a series
-of encapsulated options that a relay agent can add to a DHCP packet
-when relaying it to the DHCP server. The server can then make
-address allocation decisions (or whatever other decisions it wants)
-based on these options. The server also returns these options in any
-replies it sends through the relay agent, so that the relay agent can
-use the information in these options for delivery or accounting
-purposes.
-.PP
-The current draft defines two options. To reference
-these options in the dhcp server, specify the option space name,
-"agent", followed by a period, followed by the option name. It is
-not normally useful to define values for these options in the server,
-although it is permissible. These options are not supported in the
-client.
-.PP
-.B option \fBagent.circuit-id\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The circuit-id suboption encodes an agent-local identifier of the
-circuit from which a DHCP client-to-server packet was received. It is
-intended for use by agents in relaying DHCP responses back to the
-proper circuit. The format of this option is currently defined to be
-vendor-dependent, and will probably remain that way, although the
-current draft allows for for the possibility of standardizing the
-format in the future.
-.RE
-.PP
-.B option \fBagent.remote-id\fR \fIstring\fR\fB;\fR
-.RS 0.25i
-.PP
-The remote-id suboption encodes information about the remote host end
-of a circuit. Examples of what it might contain include caller ID
-information, username information, remote ATM address, cable modem ID,
-and similar things. In principal, the meaning is not well-specified,
-and it should generally be assumed to be an opaque object that is
-administratively guaranteed to be unique to a particular remote end of
-a circuit.
-.RE
-.SH THE CLIENT FQDN SUBOPTIONS
-The Client FQDN option, currently defined in the Internet Draft
-draft-ietf-dhc-fqdn-option-00.txt is not a standard yet, but is in
-sufficiently wide use already that we have implemented it. Due to
-the complexity of the option format, we have implemented it as a
-suboption space rather than a single option. In general this
-option should not be configured by the user - instead it should be
-used as part of an automatic DNS update system.
-.PP
-.B option fqdn.no-client-update \fIflag\fB;
-.RS 0.25i
-.PP
-When the client sends this, if it is true, it means the client will not
-attempt to update its A record. When sent by the server to the client,
-it means that the client \fIshould not\fR update its own A record.
-.RE
-.PP
-.B option fqdn.server-update \fIflag\fB;
-.RS 0.25i
-.PP
-When the client sends this to the server, it is requesting that the server
-update its A record. When sent by the server, it means that the server
-has updated (or is about to update) the client's A record.
-.RE
-.PP
-.B option fqdn.encoded \fIflag\fB;
-.RS 0.25i
-.PP
-If true, this indicates that the domain name included in the option is
-encoded in DNS wire format, rather than as plain ASCII text. The client
-normally sets this to false if it doesn't support DNS wire format in the
-FQDN option. The server should always send back the same value that the
-client sent. When this value is set on the configuration side, it controls
-the format in which the \fIfqdn.fqdn\fR suboption is encoded.
-.RE
-.PP
-.B option fqdn.rcode1 \fIflag\fB;
-.PP
-.B option fqdn.rcode1 \fIflag\fB;
-.RS 0.25i
-.PP
-These options specify the result of the updates of the A and PTR records,
-respectively, and are only sent by the DHCP server to the DHCP client.
-The values of these fields are those defined in the DNS protocol specification.
-.RE
-.PP
-.B option fqdn.fqdn \fItext\fB;
-.RS 0.25i
-.PP
-Specifies the domain name that the client wishes to use. This can be a
-fully-qualified domain name, or a single label. If there is no trailing
-'.' character in the name, it is not fully-qualified, and the server will
-generally update that name in some locally-defined domain.
-.RE
-.PP
-.B option fqdn.hostname \fI--never set--\fB;
-.RS 0.25i
-.PP
-This option should never be set, but it can be read back using the \fBoption\fR
-and \fBconfig-option\fR operators in an expression, in which case it returns
-the first label in the \fBfqdn.fqdn\fR suboption - for example, if
-the value of \fBfqdn.fqdn\fR is "foo.example.com.", then \fBfqdn.hostname\fR
-will be "foo".
-.RE
-.PP
-.B option fqdn.domainname \fI--never set--\fB;
-.RS 0.25i
-.PP
-This option should never be set, but it can be read back using the \fBoption\fR
-and \fBconfig-option\fR operators in an expression, in which case it returns
-all labels after the first label in the \fBfqdn.fqdn\fR suboption - for
-example, if the value of \fBfqdn.fqdn\fR is "foo.example.com.",
-then \fBfqdn.hostname\fR will be "example.com.". If this suboption value
-is not set, it means that an unqualified name was sent in the fqdn option,
-or that no fqdn option was sent at all.
-.RE
-.PP
-If you wish to use any of these suboptions, we strongly recommend that you
-refer to the Client FQDN option draft (or standard, when it becomes a
-standard) - the documentation here is sketchy and incomplete in comparison,
-and is just intended for reference by people who already understand the
-Client FQDN option specification.
-.SH THE NETWARE/IP SUBOPTIONS
-RFC2242 defines a set of encapsulated options for Novell NetWare/IP
-clients. To use these options in the dhcp server, specify the option
-space name, "nwip", followed by a period, followed by the option name.
-The following options can be specified:
-.PP
-.B option \fBnwip.nsq-broadcast\fR \fIflag\fR\fB;\fR
-.RS 0.25i
-.PP
-If true, the client should use the NetWare Nearest Server Query to
-locate a NetWare/IP server. The behaviour of the Novell client if
-this suboption is false, or is not present, is not specified.
-.PP
-.RE
-.B option \fBnwip.preferred-dss\fR \fIip-address\fR [\fB,\fR \fIip-address\fR... ]\fR\fB;\fR
-.RS 0.25i
-.PP
-This suboption specifies a list of up to five IP addresses, each of
-which should be the IP address of a NetWare Domain SAP/RIP server
-(DSS).
-.RE
-.PP
-.B option \fBnwip.nearest-nwip-server\fR \fI\fIip-address\fR
- [\fB,\fR \fIip-address\fR...]\fR\fB;\fR
-.RS 0.25i
-.PP
-This suboption specifies a list of up to five IP addresses, each of
-which should be the IP address of a Nearest NetWare IP server.
-.RE
-.PP
-.B option \fBnwip.autoretries\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-Specifies the number of times that a NetWare/IP client should attempt
-to communicate with a given DSS server at startup.
-.RE
-.PP
-.B option \fBnwip.autoretry-secs\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-Specifies the number of seconds that a Netware/IP client should wait
-between retries when attempting to establish communications with a DSS
-server at startup.
-.RE
-.PP
-.B option \fBnwip.nwip-1-1\fR \fIuint8\fR\fB;\fR
-.RS 0.25i
-.PP
-If true, the NetWare/IP client should support NetWare/IP version 1.1
-compatibility. This is only needed if the client will be contacting
-Netware/IP version 1.1 servers.
-.RE
-.PP
-.B option \fBnwip.primary-dss\fR \fIip-address\fR\fB;\fR
-.RS 0.25i
-.PP
-Specifies the IP address of the Primary Domain SAP/RIP Service server
-(DSS) for this NetWare/IP domain. The NetWare/IP administration
-utility uses this value as Primary DSS server when configuring a
-secondary DSS server.
-.RE
-.SH DEFINING NEW OPTIONS
-The Internet Systems Consortium DHCP client and server provide the
-capability to define new options. Each DHCP option has a name, a
-code, and a structure. The name is used by you to refer to the
-option. The code is a number, used by the DHCP server and client to
-refer to an option. The structure describes what the contents of an
-option looks like.
-.PP
-To define a new option, you need to choose a name for it that is not
-in use for some other option - for example, you can't use "host-name"
-because the DHCP protocol already defines a host-name option, which is
-documented earlier in this manual page. If an option name doesn't
-appear in this manual page, you can use it, but it's probably a good
-idea to put some kind of unique string at the beginning so you can be
-sure that future options don't take your name. For example, you
-might define an option, "local-host-name", feeling some confidence
-that no official DHCP option name will ever start with "local".
-.PP
-Once you have chosen a name, you must choose a code. For site-local
-options, all codes between 128 and 254 are reserved for DHCP options,
-so you can pick any one of these. In practice, some vendors have
-interpreted the protocol rather loosely and have used option code
-values greater than 128 themselves. There's no real way to avoid
-this problem, but it's not likely to cause too much trouble in
-practice.
-.PP
-The structure of an option is simply the format in which the option
-data appears. The ISC DHCP server currently supports a few simple
-types, like integers, booleans, strings and IP addresses, and it also
-supports the ability to define arrays of single types or arrays of
-fixed sequences of types.
-.PP
-New options are declared as follows:
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.I definition
-.B ;
-.PP
-The values of
-.I new-name
-and
-.I new-code
-should be the name you have chosen for the new option and the code you
-have chosen. The
-.I definition
-should be the definition of the structure of the option.
-.PP
-The following simple option type definitions are supported:
-.PP
-.B BOOLEAN
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.B boolean
-.B ;
-.PP
-An option of type boolean is a flag with a value of either on or off
-(or true or false). So an example use of the boolean type would be:
-.nf
-
-option use-zephyr code 180 = boolean;
-option use-zephyr on;
-
-.fi
-.B INTEGER
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.I sign
-.B integer
-.I width
-.B ;
-.PP
-The \fIsign\fR token should either be blank, \fIunsigned\fR
-or \fIsigned\fR. The width can be either 8, 16 or 32, and refers to
-the number of bits in the integer. So for example, the following two
-lines show a definition of the sql-connection-max option and its use:
-.nf
-
-option sql-connection-max code 192 = unsigned integer 16;
-option sql-connection-max 1536;
-
-.fi
-.B IP-ADDRESS
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.B ip-address
-.B ;
-.PP
-An option whose structure is an IP address can be expressed either as
-a domain name or as a dotted quad. So the following is an example use
-of the ip-address type:
-.nf
-
-option sql-server-address code 193 = ip-address;
-option sql-server-address sql.example.com;
-
-.fi
-.PP
-.B TEXT
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.B text
-.B ;
-.PP
-An option whose type is text will encode an ASCII text string. For
-example:
-.nf
-
-option sql-default-connection-name code 194 = text;
-option sql-default-connection-name "PRODZA";
-
-.fi
-.PP
-.B DATA STRING
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.B string
-.B ;
-.PP
-An option whose type is a data string is essentially just a collection
-of bytes, and can be specified either as quoted text, like the text
-type, or as a list of hexadecimal contents separated by colons whose
-values must be between 0 and FF. For example:
-.nf
-
-option sql-identification-token code 195 = string;
-option sql-identification-token 17:23:19:a6:42:ea:99:7c:22;
-
-.fi
-.PP
-.B ENCAPSULATION
-.PP
-.B option
-.I new-name
-.B code
-.I new-code
-.B =
-.B encapsulate
-.I identifier
-.B ;
-.PP
-An option whose type is \fBencapsulate\fR will encapsulate the
-contents of the option space specified in \fIidentifier\fR. Examples
-of encapsulated options in the DHCP protocol as it currently exists
-include the vendor-encapsulated-options option, the netware-suboptions
-option and the relay-agent-information option.
-.nf
-
-option space local;
-option local.demo code 1 = text;
-option local-encapsulation code 197 = encapsulate local;
-option local.demo "demo";
-
-.fi
-.PP
-.B ARRAYS
-.PP
-Options can contain arrays of any of the above types except for the
-text and data string types, which aren't currently supported in
-arrays. An example of an array definition is as follows:
-.nf
-
-option kerberos-servers code 200 = array of ip-address;
-option kerberos-servers 10.20.10.1, 10.20.11.1;
-
-.fi
-.B RECORDS
-.PP
-Options can also contain data structures consisting of a sequence of
-data types, which is sometimes called a record type. For example:
-.nf
-
-option contrived-001 code 201 = { boolean, integer 32, text };
-option contrived-001 on 1772 "contrivance";
-
-.fi
-It's also possible to have options that are arrays of records, for
-example:
-.nf
-
-option new-static-routes code 201 = array of {
- ip-address, ip-address, ip-address, integer 8 };
-option static-routes
- 10.0.0.0 255.255.255.0 net-0-rtr.example.com 1,
- 10.0.1.0 255.255.255.0 net-1-rtr.example.com 1,
- 10.2.0.0 255.255.224.0 net-2-0-rtr.example.com 3;
-
-.fi
-.SH VENDOR ENCAPSULATED OPTIONS
-The DHCP protocol defines the \fB vendor-encapsulated-options\fR
-option, which allows vendors to define their own options that will be
-sent encapsulated in a standard DHCP option. The format of the
-.B vendor-encapsulated-options
-option is either a series of bytes whose format is not specified, or
-a sequence of options, each of which consists of a single-byte
-vendor-specific option code, followed by a single-byte length,
-followed by as many bytes of data as are specified in the length (the
-length does not include itself or the option code).
-.PP
-The value of this option can be set in one of two ways. The first
-way is to simply specify the data directly, using a text string or a
-colon-separated list of hexadecimal values. For example:
-.PP
-.nf
-option vendor-encapsulated-options
- 2:4:AC:11:41:1:
- 3:12:73:75:6e:64:68:63:70:2d:73:65:72:76:65:72:31:37:2d:31:
- 4:12:2f:65:78:70:6f:72:74:2f:72:6f:6f:74:2f:69:38:36:70:63;
-.fi
-.PP
-The second way of setting the value of this option is to have the DHCP
-server generate a vendor-specific option buffer. To do this, you
-must do four things: define an option space, define some options in
-that option space, provide values for them, and specify that that
-option space should be used to generate the
-.B vendor-encapsulated-options
-option.
-.PP
-To define a new option space in which vendor options can be stored,
-use the \fRoption space\fP statement:
-.PP
-.B option
-.B space
-.I name
-.B ;
-.PP
-The name can then be used in option definitions, as described earlier in
-this document. For example:
-.nf
-
-option space SUNW;
-option SUNW.server-address code 2 = ip-address;
-option SUNW.server-name code 3 = text;
-option SUNW.root-path code 4 = text;
-
-.fi
-Once you have defined an option space and the format of some options,
-you can set up scopes that define values for those options, and you
-can say when to use them. For example, suppose you want to handle
-two different classes of clients. Using the option space definition
-shown in the previous example, you can send different option values to
-different clients based on the vendor-class-identifier option that the
-clients send, as follows:
-.PP
-.nf
-class "vendor-classes" {
- match option vendor-class-identifier;
-}
-
-option SUNW.server-address 172.17.65.1;
-option SUNW.server-name "sundhcp-server17-1";
-
-subclass "vendor-classes" "SUNW.Ultra-5_10" {
- vendor-option-space SUNW;
- option SUNW.root-path "/export/root/sparc";
-}
-
-subclass "vendor-classes" "SUNW.i86pc" {
- vendor-option-space SUNW;
- option SUNW.root-path "/export/root/i86pc";
-}
-.fi
-.PP
-As you can see in the preceding example, regular scoping rules apply,
-so you can define values that are global in the global scope, and only
-define values that are specific to a particular class in the local
-scope. The \fBvendor-option-space\fR declaration tells the DHCP
-server to use options in the SUNW option space to construct the
-.B vendor-encapsulated-options
-option.
-.SH SEE ALSO
-dhclient.conf(5), dhcp-eval(5),
-dhclient(8), RFC2132, RFC2131.
-.SH AUTHOR
-The Internet Systems Consortium DHCP Distribution was written by Ted
-Lemon under a contract with Vixie Labs. Funding for
-this project was provided through Internet Systems Consortium.
-Information about Internet Systems Consortium can be found at
-.B http://www.isc.org.
diff --git a/contrib/isc-dhcp/common/discover.c b/contrib/isc-dhcp/common/discover.c
deleted file mode 100644
index c2f9d47..0000000
--- a/contrib/isc-dhcp/common/discover.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/* dispatch.c
-
- Network input dispatcher... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: discover.c,v 1.42.2.15 2004/06/10 17:59:16 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <sys/ioctl.h>
-
-struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
-int interfaces_invalidated;
-int quiet_interface_discovery;
-u_int16_t local_port;
-u_int16_t remote_port;
-int (*dhcp_interface_setup_hook) (struct interface_info *, struct iaddr *);
-int (*dhcp_interface_discovery_hook) (struct interface_info *);
-isc_result_t (*dhcp_interface_startup_hook) (struct interface_info *);
-int (*dhcp_interface_shutdown_hook) (struct interface_info *);
-
-struct in_addr limited_broadcast;
-struct in_addr local_address;
-
-void (*bootp_packet_handler) PROTO ((struct interface_info *,
- struct dhcp_packet *, unsigned,
- unsigned int,
- struct iaddr, struct hardware *));
-
-omapi_object_type_t *dhcp_type_interface;
-#if defined (TRACING)
-trace_type_t *interface_trace;
-trace_type_t *inpacket_trace;
-trace_type_t *outpacket_trace;
-#endif
-struct interface_info **interface_vector;
-int interface_count;
-int interface_max;
-
-OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface)
-
-isc_result_t interface_setup ()
-{
- isc_result_t status;
- status = omapi_object_type_register (&dhcp_type_interface,
- "interface",
- dhcp_interface_set_value,
- dhcp_interface_get_value,
- dhcp_interface_destroy,
- dhcp_interface_signal_handler,
- dhcp_interface_stuff_values,
- dhcp_interface_lookup,
- dhcp_interface_create,
- dhcp_interface_remove,
- 0, 0, 0,
- sizeof (struct interface_info),
- interface_initialize, RC_MISC);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register interface object type: %s",
- isc_result_totext (status));
-
- return status;
-}
-
-#if defined (TRACING)
-void interface_trace_setup ()
-{
- interface_trace = trace_type_register ("interface", (void *)0,
- trace_interface_input,
- trace_interface_stop, MDL);
- inpacket_trace = trace_type_register ("inpacket", (void *)0,
- trace_inpacket_input,
- trace_inpacket_stop, MDL);
- outpacket_trace = trace_type_register ("outpacket", (void *)0,
- trace_outpacket_input,
- trace_outpacket_stop, MDL);
-}
-#endif
-
-isc_result_t interface_initialize (omapi_object_t *ipo,
- const char *file, int line)
-{
- struct interface_info *ip = (struct interface_info *)ipo;
- ip -> rfdesc = ip -> wfdesc = -1;
- return ISC_R_SUCCESS;
-}
-
-/* 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, *ip;
- struct interface_info *last, *next;
- char buf [2048];
- 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;
- struct ifreq *tif;
-#ifdef ALIAS_NAMES_PERMUTED
- char *s;
-#endif
- isc_result_t status;
- static int setup_fallback = 0;
- int wifcount = 0;
-
- /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
- log_fatal ("Can't create addrlist socket");
-
- /* Get the interface configuration information... */
-
-#ifdef SIOCGIFCONF_ZERO_PROBE
- /* linux will only tell us how long a buffer it wants if we give it
- * a null buffer first. So, do a dry run to figure out the length.
- *
- * XXX this code is duplicated from below because trying to fold
- * the logic into the if statement and goto resulted in excesssive
- * obfuscation. The intent is that unless you run Linux you shouldn't
- * have to deal with this. */
-
- ic.ifc_len = 0;
- ic.ifc_ifcu.ifcu_buf = (caddr_t)NULL;
-#else
- /* otherwise, we just feed it a starting size, and it'll tell us if
- * it needs more */
-
- ic.ifc_len = sizeof buf;
- ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
-#endif
-
- gifconf_again:
- i = ioctl(sock, SIOCGIFCONF, &ic);
-
- if (i < 0)
- log_fatal ("ioctl: SIOCGIFCONF: %m");
-
-#ifdef SIOCGIFCONF_ZERO_PROBE
- /* Workaround for SIOCGIFCONF bug on some Linux versions. */
- if (ic.ifc_ifcu.ifcu_buf == 0 && ic.ifc_len == 0) {
- ic.ifc_len = sizeof buf;
- ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
- goto gifconf_again;
- }
-#endif
-
- /* If the SIOCGIFCONF resulted in more data than would fit in
- a buffer, allocate a bigger buffer. */
- if ((ic.ifc_ifcu.ifcu_buf == buf
-#ifdef SIOCGIFCONF_ZERO_PROBE
- || ic.ifc_ifcu.ifcu_buf == 0
-#endif
- ) && ic.ifc_len > sizeof buf) {
- ic.ifc_ifcu.ifcu_buf = dmalloc ((size_t)ic.ifc_len, MDL);
- if (!ic.ifc_ifcu.ifcu_buf)
- log_fatal ("Can't allocate SIOCGIFCONF buffer.");
- goto gifconf_again;
-#ifdef SIOCGIFCONF_ZERO_PROBE
- } else if (ic.ifc_ifcu.ifcu_buf == 0) {
- ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
- ic.ifc_len = sizeof buf;
- goto gifconf_again;
-#endif
- }
-
-
- /* 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 ||
- state == DISCOVER_REQUESTED))
- ir = 0;
- else if (state == DISCOVER_UNCONFIGURED)
- ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
- else
- ir = INTERFACE_REQUESTED;
-
- /* Cycle through the list of interfaces looking for IP addresses. */
- for (i = 0; i < ic.ifc_len;) {
- struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
-#ifdef HAVE_SA_LEN
- if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
- i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
- else
-#endif
- i += sizeof *ifp;
-
-#ifdef ALIAS_NAMES_PERMUTED
- if ((s = strrchr (ifp -> ifr_name, ':'))) {
- *s = 0;
- }
-#endif
-
-#ifdef SKIP_DUMMY_INTERFACES
- if (!strncmp (ifp -> ifr_name, "dummy", 5))
- continue;
-#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)
- log_fatal ("Can't get interface flags for %s: %m",
- ifr.ifr_name);
-
- /* 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;
-
- /* Skip non broadcast interfaces (plus loopback and
- point-to-point in case an OS incorrectly marks them
- as broadcast). Also skip down interfaces unless we're
- trying to get a list of configurable interfaces. */
- if (((!(ifr.ifr_flags & IFF_BROADCAST) ||
- ifr.ifr_flags & IFF_LOOPBACK ||
- ifr.ifr_flags & IFF_POINTOPOINT) && !tmp) ||
- (!(ifr.ifr_flags & IFF_UP) &&
- state != DISCOVER_UNCONFIGURED))
- continue;
-
- /* If there isn't already an interface by this name,
- allocate one. */
- if (!tmp) {
- tmp = (struct interface_info *)0;
- status = interface_allocate (&tmp, MDL);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Error allocating interface %s: %s",
- ifp -> ifr_name,
- isc_result_totext (status));
- strcpy (tmp -> name, ifp -> ifr_name);
- interface_snorf (tmp, ir);
- interface_dereference (&tmp, MDL);
- tmp = interfaces; /* XXX */
- }
-
- if (dhcp_interface_discovery_hook)
- (*dhcp_interface_discovery_hook) (tmp);
-
- /* If we have the capability, extract link information
- and record it in a linked list. */
-#ifdef HAVE_AF_LINK
- if (ifp -> ifr_addr.sa_family == AF_LINK) {
- struct sockaddr_dl *foo = ((struct sockaddr_dl *)
- (&ifp -> ifr_addr));
-#if defined (HAVE_SIN_LEN)
- tmp -> hw_address.hlen = foo -> sdl_alen;
-#else
- tmp -> hw_address.hlen = 6; /* XXX!!! */
-#endif
- tmp -> hw_address.hbuf [0] = HTYPE_ETHER; /* XXX */
- memcpy (&tmp -> hw_address.hbuf [1],
- LLADDR (foo), tmp -> hw_address.hlen);
- tmp -> hw_address.hlen++; /* for type. */
- } else
-#endif /* AF_LINK */
-
- if (ifp -> ifr_addr.sa_family == AF_INET) {
- struct iaddr addr;
-
- /* 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) &&
- ((tmp -> flags & INTERFACE_AUTOMATIC) &&
- state == DISCOVER_SERVER))
- 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) {
-#ifdef HAVE_SA_LEN
- unsigned len = ((sizeof ifp -> ifr_name) +
- ifp -> ifr_addr.sa_len);
-#else
- unsigned len = sizeof *ifp;
-#endif
- tif = (struct ifreq *)dmalloc (len, MDL);
- if (!tif)
- log_fatal ("no space for ifp.");
- memcpy (tif, ifp, len);
- tmp -> ifp = tif;
- tmp -> primary_address = foo.sin_addr;
- }
-
- /* Grab the address... */
- addr.len = 4;
- memcpy (addr.iabuf, &foo.sin_addr.s_addr,
- addr.len);
- if (dhcp_interface_setup_hook)
- (*dhcp_interface_setup_hook) (tmp, &addr);
- }
- }
-
- /* If we allocated a buffer, free it. */
- if (ic.ifc_ifcu.ifcu_buf != buf)
- dfree (ic.ifc_ifcu.ifcu_buf, MDL);
-
-#if defined (LINUX_SLASHPROC_DISCOVERY)
- /* On Linux, interfaces that don't have IP addresses don't
- show up in the SIOCGIFCONF syscall. This only matters for
- the DHCP client, of course - the relay agent and server
- should only care about interfaces that are configured with
- IP addresses anyway.
-
- The PROCDEV_DEVICE (/proc/net/dev) is a kernel-supplied file
- that, when read, prints a human readable network status. We
- extract the names of the network devices by skipping the first
- two lines (which are header) and then parsing off everything
- up to the colon in each subsequent line - these lines start
- with the interface name, then a colon, then a bunch of
- statistics. */
-
- if (state == DISCOVER_UNCONFIGURED) {
- FILE *proc_dev;
- char buffer [256];
- int skip = 2;
-
- proc_dev = fopen (PROCDEV_DEVICE, "r");
- if (!proc_dev)
- log_fatal ("%s: %m", PROCDEV_DEVICE);
-
- while (fgets (buffer, sizeof buffer, proc_dev)) {
- char *name = buffer;
- char *sep;
-
- /* Skip the first two blocks, which are header
- lines. */
- if (skip) {
- --skip;
- continue;
- }
-
- sep = strrchr (buffer, ':');
- if (sep)
- *sep = '\0';
- while (*name == ' ')
- name++;
-
- /* See if we've seen an interface that matches
- this one. */
- for (tmp = interfaces; tmp; tmp = tmp -> next)
- if (!strcmp (tmp -> name, name))
- break;
-
- /* If we found one, nothing more to do.. */
- if (tmp)
- continue;
-
- /* Otherwise, allocate one. */
- tmp = (struct interface_info *)0;
- status = interface_allocate (&tmp, MDL);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't allocate interface %s: %s",
- name, isc_result_totext (status));
- tmp -> flags = ir;
- strncpy (tmp -> name, name, IFNAMSIZ);
- if (interfaces) {
- interface_reference (&tmp -> next,
- interfaces, MDL);
- interface_dereference (&interfaces, MDL);
- }
- interface_reference (&interfaces, tmp, MDL);
- interface_dereference (&tmp, MDL);
- tmp = interfaces;
-
- if (dhcp_interface_discovery_hook)
- (*dhcp_interface_discovery_hook) (tmp);
-
- }
- fclose (proc_dev);
- }
-#endif
-
- /* Now cycle through all the interfaces we found, looking for
- hardware addresses. */
-#if defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK)
- for (tmp = interfaces; tmp; tmp = tmp -> next) {
- struct ifreq ifr;
- struct sockaddr sa;
- int b, sk;
-
- if (!tmp -> ifp) {
- /* Make up an ifreq structure. */
- tif = (struct ifreq *)dmalloc (sizeof (struct ifreq),
- MDL);
- if (!tif)
- log_fatal ("no space to remember ifp.");
- memset (tif, 0, sizeof (struct ifreq));
- strcpy (tif -> ifr_name, tmp -> name);
- tmp -> ifp = tif;
- }
-
- /* Read the hardware address from this interface. */
- ifr = *tmp -> ifp;
- if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
- continue;
-
- sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
-
- switch (sa.sa_family) {
-#ifdef HAVE_ARPHRD_TUNNEL
- case ARPHRD_TUNNEL:
- /* ignore tunnel interfaces. */
-#endif
-#ifdef HAVE_ARPHRD_ROSE
- case ARPHRD_ROSE:
-#endif
-#ifdef HAVE_ARPHRD_LOOPBACK
- case ARPHRD_LOOPBACK:
- /* ignore loopback interface */
- break;
-#endif
-
- case ARPHRD_ETHER:
- tmp -> hw_address.hlen = 7;
- tmp -> hw_address.hbuf [0] = ARPHRD_ETHER;
- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6);
- break;
-
-#ifndef HAVE_ARPHRD_IEEE802
-# define ARPHRD_IEEE802 HTYPE_IEEE802
-#endif
-#if defined (HAVE_ARPHRD_IEEE802_TR)
- case ARPHRD_IEEE802_TR:
-#endif
- case ARPHRD_IEEE802:
- tmp -> hw_address.hlen = 7;
- tmp -> hw_address.hbuf [0] = ARPHRD_IEEE802;
- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6);
- break;
-
-#ifndef HAVE_ARPHRD_FDDI
-# define ARPHRD_FDDI HTYPE_FDDI
-#endif
- case ARPHRD_FDDI:
- tmp -> hw_address.hlen = 17;
- tmp -> hw_address.hbuf [0] = HTYPE_FDDI; /* XXX */
- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 16);
- break;
-
-#ifdef HAVE_ARPHRD_METRICOM
- case ARPHRD_METRICOM:
- tmp -> hw_address.hlen = 7;
- tmp -> hw_address.hbuf [0] = ARPHRD_METRICOM;
- memcpy (&tmp -> hw_address.hbuf [0], sa.sa_data, 6);
- break;
-#endif
-
-#ifdef HAVE_ARPHRD_AX25
- case ARPHRD_AX25:
- tmp -> hw_address.hlen = 7;
- tmp -> hw_address.hbuf [0] = ARPHRD_AX25;
- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6);
- break;
-#endif
-
-#ifdef HAVE_ARPHRD_NETROM
- case ARPHRD_NETROM:
- tmp -> hw_address.hlen = 7;
- tmp -> hw_address.hbuf [0] = ARPHRD_NETROM;
- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6);
- break;
-#endif
-
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
- break;
- }
- }
-#endif /* defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK) */
-
- /* If we're just trying to get a list of interfaces that we might
- be able to configure, we can quit now. */
- if (state == DISCOVER_UNCONFIGURED) {
- close (sock);
- return;
- }
-
- /* Weed out the interfaces that did not have IP addresses. */
- tmp = last = next = (struct interface_info *)0;
- if (interfaces)
- interface_reference (&tmp, interfaces, MDL);
- while (tmp) {
- if (next)
- interface_dereference (&next, MDL);
- if (tmp -> next)
- interface_reference (&next, tmp -> next, MDL);
- /* skip interfaces that are running already */
- if (tmp -> flags & INTERFACE_RUNNING) {
- interface_dereference(&tmp, MDL);
- if(next)
- interface_reference(&tmp, next, MDL);
- continue;
- }
- if ((tmp -> flags & INTERFACE_AUTOMATIC) &&
- state == DISCOVER_REQUESTED)
- tmp -> flags &= ~(INTERFACE_AUTOMATIC |
- INTERFACE_REQUESTED);
- if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
- if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
- log_fatal ("%s: not found", tmp -> name);
- if (!last) {
- if (interfaces)
- interface_dereference (&interfaces,
- MDL);
- if (next)
- interface_reference (&interfaces, next, MDL);
- } else {
- interface_dereference (&last -> next, MDL);
- if (next)
- interface_reference (&last -> next,
- next, MDL);
- }
- if (tmp -> next)
- interface_dereference (&tmp -> next, MDL);
-
- /* Remember the interface in case we need to know
- about it later. */
- if (dummy_interfaces) {
- interface_reference (&tmp -> next,
- dummy_interfaces, MDL);
- interface_dereference (&dummy_interfaces, MDL);
- }
- interface_reference (&dummy_interfaces, tmp, MDL);
- interface_dereference (&tmp, MDL);
- if (next)
- interface_reference (&tmp, next, MDL);
- 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)) {
- log_error ("%s", "");
- log_error ("No subnet declaration for %s (%s).",
- tmp -> name, inet_ntoa (foo.sin_addr));
- if (supports_multiple_interfaces (tmp)) {
- log_error ("** Ignoring requests on %s. %s",
- tmp -> name, "If this is not what");
- log_error (" you want, please write %s",
- "a subnet declaration");
- log_error (" in your dhcpd.conf file %s",
- "for the network segment");
- log_error (" to %s %s %s",
- "which interface",
- tmp -> name, "is attached. **");
- log_error ("%s", "");
- goto next;
- } else {
- log_error ("You must write a subnet %s",
- " declaration for this");
- log_error ("subnet. You cannot prevent %s",
- "the DHCP server");
- log_error ("from listening on this subnet %s",
- "because your");
- log_fatal ("operating system does not %s.",
- "support this capability");
- }
- }
-
- /* 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);
- }
- }
-
- /* Flag the index as not having been set, so that the
- interface registerer can set it or not as it chooses. */
- tmp -> index = -1;
-
- /* Register the interface... */
- if_register_receive (tmp);
- if_register_send (tmp);
-
- interface_stash (tmp);
- wifcount++;
-#if defined (HAVE_SETFD)
- if (fcntl (tmp -> rfdesc, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on %s: %m",
- tmp -> name);
- if (tmp -> rfdesc != tmp -> wfdesc) {
- if (fcntl (tmp -> wfdesc, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on %s: %m",
- tmp -> name);
- }
-#endif
- next:
- interface_dereference (&tmp, MDL);
- if (next)
- interface_reference (&tmp, next, MDL);
- }
-
- /* Now register all the remaining interfaces as protocols. */
- for (tmp = interfaces; tmp; tmp = tmp -> next) {
- /* not if it's been registered before */
- if (tmp -> flags & INTERFACE_RUNNING)
- continue;
- if (tmp -> rfdesc == -1)
- continue;
- status = omapi_register_io_object ((omapi_object_t *)tmp,
- if_readsocket, 0,
- got_one, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- tmp -> name, isc_result_totext (status));
- }
-
- close (sock);
-
- if (state == DISCOVER_SERVER && wifcount == 0) {
- log_info ("%s", "");
- log_fatal ("Not configured to listen on any interfaces!");
- }
-
- if (!setup_fallback) {
- setup_fallback = 1;
- maybe_setup_fallback ();
- }
-
-#if defined (HAVE_SETFD)
- if (fallback_interface) {
- if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on fallback: %m");
- if (fallback_interface -> rfdesc != fallback_interface -> wfdesc) {
- if (fcntl (fallback_interface -> wfdesc, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on fallback: %m");
- }
- }
-#endif
-}
-
-int if_readsocket (h)
- omapi_object_t *h;
-{
- struct interface_info *ip;
-
- if (h -> type != dhcp_type_interface)
- return -1;
- ip = (struct interface_info *)h;
- return ip -> rfdesc;
-}
-
-int setup_fallback (struct interface_info **fp, const char *file, int line)
-{
- isc_result_t status;
-
- status = interface_allocate (&fallback_interface, file, line);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Error allocating fallback interface: %s",
- isc_result_totext (status));
- strcpy (fallback_interface -> name, "fallback");
- if (dhcp_interface_setup_hook)
- (*dhcp_interface_setup_hook) (fallback_interface,
- (struct iaddr *)0);
- status = interface_reference (fp, fallback_interface, file, line);
-
- fallback_interface -> index = -1;
- interface_stash (fallback_interface);
- return status == ISC_R_SUCCESS;
-}
-
-void reinitialize_interfaces ()
-{
- struct interface_info *ip;
-
- for (ip = interfaces; ip; ip = ip -> next) {
- if_reinitialize_receive (ip);
- if_reinitialize_send (ip);
- }
-
- if (fallback_interface)
- if_reinitialize_send (fallback_interface);
-
- interfaces_invalidated = 1;
-}
-
-isc_result_t got_one (h)
- omapi_object_t *h;
-{
- struct sockaddr_in from;
- struct hardware hfrom;
- struct iaddr ifrom;
- int result;
- union {
- unsigned char packbuf [4095]; /* Packet input buffer.
- Must be as large as largest
- possible MTU. */
- struct dhcp_packet packet;
- } u;
- struct interface_info *ip;
-
- if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- ip = (struct interface_info *)h;
-
- again:
- if ((result =
- receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) {
- log_error ("receive_packet failed on %s: %m", ip -> name);
- return ISC_R_UNEXPECTED;
- }
- if (result == 0)
- return ISC_R_UNEXPECTED;
-
- /* If we didn't at least get the fixed portion of the BOOTP
- packet, drop the packet. We're allowing packets with no
- sname or filename, because we're aware of at least one
- client that sends such packets, but this definitely falls
- into the category of being forgiving. */
- if (result < DHCP_FIXED_NON_UDP - DHCP_SNAME_LEN - DHCP_FILE_LEN)
- return ISC_R_UNEXPECTED;
-
- if (bootp_packet_handler) {
- ifrom.len = 4;
- memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
-
- (*bootp_packet_handler) (ip, &u.packet, (unsigned)result,
- from.sin_port, ifrom, &hfrom);
- }
-
- /* If there is buffered data, read again. This is for, e.g.,
- bpf, which may return two packets at once. */
- if (ip -> rbuf_offset != ip -> rbuf_len)
- goto again;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_interface_set_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_typed_data_t *value)
-{
- struct interface_info *interface;
- isc_result_t status;
- int foo;
-
- if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- interface = (struct interface_info *)h;
-
- if (!omapi_ds_strcmp (name, "name")) {
- if ((value -> type == omapi_datatype_data ||
- value -> type == omapi_datatype_string) &&
- value -> u.buffer.len < sizeof interface -> name) {
- memcpy (interface -> name,
- value -> u.buffer.value,
- value -> u.buffer.len);
- interface -> name [value -> u.buffer.len] = 0;
- } else
- return ISC_R_INVALIDARG;
- return ISC_R_SUCCESS;
- }
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> set_value) {
- status = ((*(h -> inner -> type -> set_value))
- (h -> inner, id, name, value));
- if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
- return status;
- }
-
- return ISC_R_NOTFOUND;
-}
-
-
-isc_result_t dhcp_interface_get_value (omapi_object_t *h,
- omapi_object_t *id,
- omapi_data_string_t *name,
- omapi_value_t **value)
-{
- return ISC_R_NOTIMPLEMENTED;
-}
-
-isc_result_t dhcp_interface_destroy (omapi_object_t *h,
- const char *file, int line)
-{
- struct interface_info *interface;
- isc_result_t status;
-
- if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- interface = (struct interface_info *)h;
-
- if (interface -> ifp) {
- dfree (interface -> ifp, file, line);
- interface -> ifp = 0;
- }
- if (interface -> next)
- interface_dereference (&interface -> next, file, line);
- if (interface -> rbuf) {
- dfree (interface -> rbuf, file, line);
- interface -> rbuf = (unsigned char *)0;
- }
- if (interface -> client)
- interface -> client = (struct client_state *)0;
-
- if (interface -> shared_network)
- omapi_object_dereference ((omapi_object_t **)
- &interface -> shared_network, MDL);
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_interface_signal_handler (omapi_object_t *h,
- const char *name, va_list ap)
-{
- struct interface_info *ip, *interface;
- struct client_config *config;
- struct client_state *client;
- isc_result_t status;
-
- if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- interface = (struct interface_info *)h;
-
- /* If it's an update signal, see if the interface is dead right
- now, or isn't known at all, and if that's the case, revive it. */
- if (!strcmp (name, "update")) {
- for (ip = dummy_interfaces; ip; ip = ip -> next)
- if (ip == interface)
- break;
- if (ip && dhcp_interface_startup_hook)
- return (*dhcp_interface_startup_hook) (ip);
-
- for (ip = interfaces; ip; ip = ip -> next)
- if (ip == interface)
- break;
- if (!ip && dhcp_interface_startup_hook)
- return (*dhcp_interface_startup_hook) (ip);
- }
-
- /* Try to find some inner object that can take the value. */
- if (h -> inner && h -> inner -> type -> get_value) {
- status = ((*(h -> inner -> type -> signal_handler))
- (h -> inner, name, ap));
- if (status == ISC_R_SUCCESS)
- return status;
- }
- return ISC_R_NOTFOUND;
-}
-
-isc_result_t dhcp_interface_stuff_values (omapi_object_t *c,
- omapi_object_t *id,
- omapi_object_t *h)
-{
- struct interface_info *interface;
- isc_result_t status;
-
- if (h -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- interface = (struct interface_info *)h;
-
- /* Write out all the values. */
-
- status = omapi_connection_put_name (c, "state");
- if (status != ISC_R_SUCCESS)
- return status;
- if (interface -> flags && INTERFACE_REQUESTED)
- status = omapi_connection_put_string (c, "up");
- else
- status = omapi_connection_put_string (c, "down");
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Write out the inner object, if any. */
- if (h -> inner && h -> inner -> type -> stuff_values) {
- status = ((*(h -> inner -> type -> stuff_values))
- (c, id, h -> inner));
- if (status == ISC_R_SUCCESS)
- return status;
- }
-
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dhcp_interface_lookup (omapi_object_t **ip,
- omapi_object_t *id,
- omapi_object_t *ref)
-{
- omapi_value_t *tv = (omapi_value_t *)0;
- isc_result_t status;
- struct interface_info *interface;
-
- if (!ref)
- return ISC_R_NOKEYS;
-
- /* First see if we were sent a handle. */
- status = omapi_get_value_str (ref, id, "handle", &tv);
- if (status == ISC_R_SUCCESS) {
- status = omapi_handle_td_lookup (ip, tv -> value);
-
- omapi_value_dereference (&tv, MDL);
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Don't return the object if the type is wrong. */
- if ((*ip) -> type != dhcp_type_interface) {
- omapi_object_dereference (ip, MDL);
- return ISC_R_INVALIDARG;
- }
- }
-
- /* Now look for an interface name. */
- status = omapi_get_value_str (ref, id, "name", &tv);
- if (status == ISC_R_SUCCESS) {
- char *s;
- unsigned len;
- for (interface = interfaces; interface;
- interface = interface -> next) {
- s = memchr (interface -> name, 0, IFNAMSIZ);
- if (s)
- len = s - &interface -> name [0];
- else
- len = IFNAMSIZ;
- if ((tv -> value -> u.buffer.len == len &&
- !memcmp (interface -> name,
- (char *)tv -> value -> u.buffer.value,
- len)))
- break;
- }
- if (!interface) {
- for (interface = dummy_interfaces;
- interface; interface = interface -> next) {
- s = memchr (interface -> name, 0, IFNAMSIZ);
- if (s)
- len = s - &interface -> name [0];
- else
- len = IFNAMSIZ;
- if ((tv -> value -> u.buffer.len == len &&
- !memcmp (interface -> name,
- (char *)
- tv -> value -> u.buffer.value,
- len)))
- break;
- }
- }
-
- omapi_value_dereference (&tv, MDL);
- if (*ip && *ip != (omapi_object_t *)interface) {
- omapi_object_dereference (ip, MDL);
- return ISC_R_KEYCONFLICT;
- } else if (!interface) {
- if (*ip)
- omapi_object_dereference (ip, MDL);
- return ISC_R_NOTFOUND;
- } else if (!*ip)
- omapi_object_reference (ip,
- (omapi_object_t *)interface,
- MDL);
- }
-
- /* If we get to here without finding an interface, no valid key was
- specified. */
- if (!*ip)
- return ISC_R_NOKEYS;
- return ISC_R_SUCCESS;
-}
-
-/* actually just go discover the interface */
-isc_result_t dhcp_interface_create (omapi_object_t **lp,
- omapi_object_t *id)
-{
- struct interface_info *hp;
- isc_result_t status;
-
- hp = (struct interface_info *)0;
- status = interface_allocate (&hp, MDL);
- if (status != ISC_R_SUCCESS)
- return status;
- hp -> flags = INTERFACE_REQUESTED;
- status = interface_reference ((struct interface_info **)lp, hp, MDL);
- interface_dereference (&hp, MDL);
- return status;
-}
-
-isc_result_t dhcp_interface_remove (omapi_object_t *lp,
- omapi_object_t *id)
-{
- struct interface_info *interface, *ip, *last;
-
- interface = (struct interface_info *)lp;
-
- /* remove from interfaces */
- last = 0;
- for (ip = interfaces; ip; ip = ip -> next) {
- if (ip == interface) {
- if (last) {
- interface_dereference (&last -> next, MDL);
- if (ip -> next)
- interface_reference (&last -> next,
- ip -> next, MDL);
- } else {
- interface_dereference (&interfaces, MDL);
- if (ip -> next)
- interface_reference (&interfaces,
- ip -> next, MDL);
- }
- if (ip -> next)
- interface_dereference (&ip -> next, MDL);
- break;
- }
- last = ip;
- }
- if (!ip)
- return ISC_R_NOTFOUND;
-
- /* add the interface to the dummy_interface list */
- if (dummy_interfaces) {
- interface_reference (&interface -> next,
- dummy_interfaces, MDL);
- interface_dereference (&dummy_interfaces, MDL);
- }
- interface_reference (&dummy_interfaces, interface, MDL);
-
- /* do a DHCPRELEASE */
- if (dhcp_interface_shutdown_hook)
- (*dhcp_interface_shutdown_hook) (interface);
-
- /* remove the io object */
- omapi_unregister_io_object ((omapi_object_t *)interface);
-
- if_deregister_send (interface);
- if_deregister_receive (interface);
-
- return ISC_R_SUCCESS;
-}
-
-void interface_stash (struct interface_info *tptr)
-{
- struct interface_info **vec;
- int delta;
-
- /* If the registerer didn't assign an index, assign one now. */
- if (tptr -> index == -1) {
- tptr -> index = interface_count++;
- while (tptr -> index < interface_max &&
- interface_vector [tptr -> index])
- tptr -> index = interface_count++;
- }
-
- if (interface_max <= tptr -> index) {
- delta = tptr -> index - interface_max + 10;
- vec = dmalloc ((interface_max + delta) *
- sizeof (struct interface_info *), MDL);
- if (!vec)
- return;
- memset (&vec [interface_max], 0,
- (sizeof (struct interface_info *)) * delta);
- interface_max += delta;
- if (interface_vector) {
- memcpy (vec, interface_vector,
- (interface_count *
- sizeof (struct interface_info *)));
- dfree (interface_vector, MDL);
- }
- interface_vector = vec;
- }
- interface_reference (&interface_vector [tptr -> index], tptr, MDL);
- if (tptr -> index >= interface_count)
- interface_count = tptr -> index + 1;
-#if defined (TRACING)
- trace_interface_register (interface_trace, tptr);
-#endif
-}
-
-void interface_snorf (struct interface_info *tmp, int ir)
-{
- tmp -> circuit_id = (u_int8_t *)tmp -> name;
- tmp -> circuit_id_len = strlen (tmp -> name);
- tmp -> remote_id = 0;
- tmp -> remote_id_len = 0;
- tmp -> flags = ir;
- if (interfaces) {
- interface_reference (&tmp -> next,
- interfaces, MDL);
- interface_dereference (&interfaces, MDL);
- }
- interface_reference (&interfaces, tmp, MDL);
-}
diff --git a/contrib/isc-dhcp/common/dispatch.c b/contrib/isc-dhcp/common/dispatch.c
deleted file mode 100644
index 326ed1f..0000000
--- a/contrib/isc-dhcp/common/dispatch.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* dispatch.c
-
- Network input dispatcher... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dispatch.c,v 1.63.2.4 2004/06/10 17:59:16 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"
-"$FreeBSD$\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-struct timeout *timeouts;
-static struct timeout *free_timeouts;
-
-#ifdef ENABLE_POLLING_MODE
-extern int polling_interval;
-#endif
-
-void set_time (TIME t)
-{
- /* Do any outstanding timeouts. */
- if (cur_time != t) {
- cur_time = t;
- process_outstanding_timeouts ((struct timeval *)0);
- }
-}
-
-struct timeval *process_outstanding_timeouts (struct timeval *tvp)
-{
- /* 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 -> what);
- if (t -> unref)
- (*t -> unref) (&t -> what, MDL);
- t -> next = free_timeouts;
- free_timeouts = t;
- goto another;
- }
- if (tvp) {
- tvp -> tv_sec = timeouts -> when;
- tvp -> tv_usec = 0;
- }
- return tvp;
- } else
- return (struct timeval *)0;
-}
-
-/* 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 through the
- bootp_packet_handler hook to try to do something with it. */
-
-void dispatch ()
-{
- struct timeval tv, *tvp;
-#ifdef ENABLE_POLLING_MODE
- struct timeval *tvp_new;
-#endif
- isc_result_t status;
-
- tvp = NULL;
-#ifdef ENABLE_POLLING_MODE
- tvp_new = NULL;
-#endif
- /* Wait for a packet or a timeout... XXX */
- do {
- tvp = process_outstanding_timeouts (&tv);
-#ifdef ENABLE_POLLING_MODE
- GET_TIME (&cur_time);
- add_timeout(cur_time + polling_interval, state_polling, 0, 0, 0);
- tvp_new = process_outstanding_timeouts(&tv);
- if (tvp != NULL && (tvp -> tv_sec > tvp_new -> tv_sec))
- tvp = tvp_new;
-#endif /* ENABLE_POLLING_MODE */
- status = omapi_one_dispatch (0, tvp);
- } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
- log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
- isc_result_totext (status));
-}
-
-void add_timeout (when, where, what, ref, unref)
- TIME when;
- void (*where) PROTO ((void *));
- void *what;
- tvref_t ref;
- tvunref_t unref;
-{
- struct timeout *t, *q;
-
- /* See if this timeout supersedes an existing timeout. */
- t = (struct timeout *)0;
- for (q = timeouts; q; q = q -> next) {
- if ((where == NULL || q -> func == where) &&
- q -> what == 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;
- } else {
- q = ((struct timeout *)
- dmalloc (sizeof (struct timeout), MDL));
- if (!q)
- log_fatal ("add_timeout: no memory!");
- }
- memset (q, 0, sizeof *q);
- q -> func = where;
- q -> ref = ref;
- q -> unref = unref;
- if (q -> ref)
- (*q -> ref)(&q -> what, what, MDL);
- else
- q -> what = 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) PROTO ((void *));
- void *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 -> what == 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) {
- if (q -> unref)
- (*q -> unref) (&q -> what, MDL);
- q -> next = free_timeouts;
- free_timeouts = q;
- }
-}
-
-#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
-void cancel_all_timeouts ()
-{
- struct timeout *t, *n;
- for (t = timeouts; t; t = n) {
- n = t -> next;
- if (t -> unref && t -> what)
- (*t -> unref) (&t -> what, MDL);
- t -> next = free_timeouts;
- free_timeouts = t;
- }
-}
-
-void relinquish_timeouts ()
-{
- struct timeout *t, *n;
- for (t = free_timeouts; t; t = n) {
- n = t -> next;
- dfree (t, MDL);
- }
-}
-#endif
diff --git a/contrib/isc-dhcp/common/dlpi.c b/contrib/isc-dhcp/common/dlpi.c
deleted file mode 100644
index 08e9764..0000000
--- a/contrib/isc-dhcp/common/dlpi.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* dlpi.c
-
- Data Link Provider Interface (DLPI) network interface code. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software was written for Internet Systems Consortium
- * by Eric James Negaard, <lmdejn@lmd.ericsson.se>. To learn more about
- * Internet Systems Consortium, see ``http://www.isc.org''.
- *
- * Joost Mulders has also done considerable work in debugging the DLPI API
- * support on Solaris and getting this code to work properly on a variety
- * of different Solaris platforms.
- */
-
-/*
- * Based largely in part to the existing NIT code in nit.c.
- *
- * This code has been developed and tested on sparc-based machines running
- * SunOS 5.5.1, with le and hme network interfaces. It should be pretty
- * generic, though.
- */
-
-/*
- * Implementation notes:
- *
- * I first tried to write this code to the "vanilla" DLPI 2.0 API.
- * It worked on a Sun Ultra-1 with a hme interface, but didn't work
- * on Sun SparcStation 5's with "le" interfaces (the packets sent out
- * via dlpiunitdatareq contained an Ethernet type of 0x0000 instead
- * of the expected 0x0800).
- *
- * Therefore I added the "DLPI_RAW" code which is a Sun extension to
- * the DLPI standard. This code works on both of the above machines.
- * This is configurable in the OS-dependent include file by defining
- * USE_DLPI_RAW.
- *
- * It quickly became apparant that I should also use the "pfmod"
- * STREAMS module to cut down on the amount of user level packet
- * processing. I don't know how widely available "pfmod" is, so it's
- * use is conditionally included. This is configurable in the
- * OS-dependent include file by defining USE_DLPI_PFMOD.
- *
- * A major quirk on the Sun's at least, is that no packets seem to get
- * sent out the interface until six seconds after the interface is
- * first "attached" to [per system reboot] (it's actually from when
- * the interface is attached, not when it is plumbed, so putting a
- * sleep into the dhclient-script at PREINIT time doesn't help). I
- * HAVE tried, without success to poll the fd to see when it is ready
- * for writing. This doesn't help at all. If the sleeps are not done,
- * the initial DHCPREQUEST or DHCPDISCOVER never gets sent out, so
- * I've put them here, when register_send and register_receive are
- * called (split up into two three-second sleeps between the notices,
- * so that it doesn't seem like so long when you're watching :-). The
- * amount of time to sleep is configurable in the OS-dependent include
- * file by defining DLPI_FIRST_SEND_WAIT to be the number of seconds
- * to sleep.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dlpi.c,v 1.28.2.2 2004/06/10 17:59:17 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (USE_DLPI_SEND) || defined (USE_DLPI_RECEIVE)
-
-# include <sys/ioctl.h>
-# include <sys/time.h>
-# include <sys/dlpi.h>
-# include <stropts.h>
-# ifdef USE_DLPI_PFMOD
-# include <sys/pfmod.h>
-# endif
-# ifdef USE_POLL
-# include <poll.h>
-# endif
-
-# include <netinet/in_systm.h>
-# include "includes/netinet/ip.h"
-# include "includes/netinet/udp.h"
-# include "includes/netinet/if_ether.h"
-
-# ifdef USE_DLPI_PFMOD
-# ifdef USE_DLPI_RAW
-# define DLPI_MODNAME "DLPI+RAW+PFMOD"
-# else
-# define DLPI_MODNAME "DLPI+PFMOD"
-# endif
-# else
-# ifdef USE_DLPI_RAW
-# define DLPI_MODNAME "DLPI+RAW"
-# else
-# define DLPI_MODNAME "DLPI"
-# endif
-# endif
-
-# ifndef ABS
-# define ABS(x) ((x) >= 0 ? (x) : 0-(x))
-# endif
-
-static int strioctl PROTO ((int fd, int cmd, int timeout, int len, char *dp));
-
-#define DLPI_MAXDLBUF 8192 /* Buffer size */
-#define DLPI_MAXDLADDR 1024 /* Max address size */
-#define DLPI_DEVDIR "/dev/" /* Device directory */
-
-static int dlpiopen PROTO ((char *ifname));
-static int dlpiunit PROTO ((char *ifname));
-static int dlpiinforeq PROTO ((int fd));
-static int dlpiphysaddrreq PROTO ((int fd, unsigned long addrtype));
-static int dlpiattachreq PROTO ((int fd, unsigned long ppa));
-static int dlpibindreq PROTO ((int fd, unsigned long sap, unsigned long max_conind,
- unsigned long service_mode, unsigned long conn_mgmt,
- unsigned long xidtest));
-static int dlpidetachreq PROTO ((int fd));
-static int dlpiunbindreq PROTO ((int fd));
-static int dlpiokack PROTO ((int fd, char *bufp));
-static int dlpiinfoack PROTO ((int fd, char *bufp));
-static int dlpiphysaddrack PROTO ((int fd, char *bufp));
-static int dlpibindack PROTO ((int fd, char *bufp));
-static int dlpiunitdatareq PROTO ((int fd, unsigned char *addr,
- int addrlen, unsigned long minpri,
- unsigned long maxpri, unsigned char *data,
- int datalen));
-static int dlpiunitdataind PROTO ((int fd,
- unsigned char *dstaddr,
- unsigned long *dstaddrlen,
- unsigned char *srcaddr,
- unsigned long *srcaddrlen,
- unsigned long *grpaddr,
- unsigned char *data,
- int datalen));
-
-# ifndef USE_POLL
-static void sigalrm PROTO ((int sig));
-# endif
-static int expected PROTO ((unsigned long prim, union DL_primitives *dlp,
- int msgflags));
-static int strgetmsg PROTO ((int fd, struct strbuf *ctlp,
- struct strbuf *datap, int *flagsp,
- char *caller));
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#ifdef USE_DLPI_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_DLPI_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_dlpi (info)
- struct interface_info *info;
-{
- int sock;
- int unit;
- long buf [DLPI_MAXDLBUF];
- union DL_primitives *dlp;
-
- dlp = (union DL_primitives *)buf;
-
- /* Open a DLPI device */
- if ((sock = dlpiopen (info -> name)) < 0) {
- log_fatal ("Can't open DLPI device for %s: %m", info -> name);
- }
-
-
- /*
- * Submit a DL_INFO_REQ request, to find the dl_mac_type and
- * dl_provider_style
- */
- if (dlpiinforeq(sock) < 0 || dlpiinfoack(sock, (char *)buf) < 0) {
- log_fatal ("Can't get DLPI MAC type for %s: %m", info -> name);
- } else {
- switch (dlp -> info_ack.dl_mac_type) {
- case DL_CSMACD: /* IEEE 802.3 */
- case DL_ETHER:
- info -> hw_address.hbuf [0] = HTYPE_ETHER;
- break;
- /* adding token ring 5/1999 - mayer@ping.at */
- case DL_TPR:
- info -> hw_address.hbuf [0] = HTYPE_IEEE802;
- break;
- case DL_FDDI:
- info -> hw_address.hbuf [0] = HTYPE_FDDI;
- break;
- default:
- log_fatal ("%s: unsupported DLPI MAC type %ld",
- info -> name, dlp -> info_ack.dl_mac_type);
- break;
- }
- /*
- * copy the sap length and broadcast address of this interface
- * to interface_info. This fixes nothing but seemed nicer than to
- * assume -2 and ffffff.
- */
- info -> dlpi_sap_length = dlp -> info_ack.dl_sap_length;
- info -> dlpi_broadcast_addr.hlen =
- dlp -> info_ack.dl_brdcst_addr_length;
- memcpy (info -> dlpi_broadcast_addr.hbuf,
- (char *)dlp + dlp -> info_ack.dl_brdcst_addr_offset,
- dlp -> info_ack.dl_brdcst_addr_length);
- }
-
- if (dlp -> info_ack.dl_provider_style == DL_STYLE2) {
- /*
- * Attach to the device. If this fails, the device
- * does not exist.
- */
- unit = dlpiunit (info -> name);
-
- if (dlpiattachreq (sock, unit) < 0
- || dlpiokack (sock, (char *)buf) < 0) {
- log_fatal ("Can't attach DLPI device for %s: %m", info -> name);
- }
- }
-
- /*
- * Bind to the IP service access point (SAP), connectionless (CLDLS).
- */
- if (dlpibindreq (sock, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0) < 0
- || dlpibindack (sock, (char *)buf) < 0) {
- log_fatal ("Can't bind DLPI device for %s: %m", info -> name);
- }
-
- /*
- * Submit a DL_PHYS_ADDR_REQ request, to find
- * the hardware address
- */
- if (dlpiphysaddrreq (sock, DL_CURR_PHYS_ADDR) < 0
- || dlpiphysaddrack (sock, (char *)buf) < 0) {
- log_fatal ("Can't get DLPI hardware address for %s: %m",
- info -> name);
- }
-
- info -> hw_address.hlen = dlp -> physaddr_ack.dl_addr_length + 1;
- memcpy (&info -> hw_address.hbuf [1],
- (char *)buf + dlp -> physaddr_ack.dl_addr_offset,
- dlp -> physaddr_ack.dl_addr_length);
-
-#ifdef USE_DLPI_RAW
- if (strioctl (sock, DLIOCRAW, INFTIM, 0, 0) < 0) {
- log_fatal ("Can't set DLPI RAW mode for %s: %m",
- info -> name);
- }
-#endif
-
-#ifdef USE_DLPI_PFMOD
- if (ioctl (sock, I_PUSH, "pfmod") < 0) {
- log_fatal ("Can't push packet filter onto DLPI for %s: %m",
- info -> name);
- }
-#endif
-
- return sock;
-}
-
-static int
-strioctl (fd, cmd, timeout, len, dp)
-int fd;
-int cmd;
-int timeout;
-int len;
-char *dp;
-{
- struct strioctl sio;
- int rslt;
-
- sio.ic_cmd = cmd;
- sio.ic_timout = timeout;
- sio.ic_len = len;
- sio.ic_dp = dp;
-
- if ((rslt = ioctl (fd, I_STR, &sio)) < 0) {
- return rslt;
- } else {
- return sio.ic_len;
- }
-}
-
-#ifdef USE_DLPI_SEND
-void if_register_send (info)
- struct interface_info *info;
-{
- /* If we're using the DLPI API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_DLPI_RECEIVE
-# ifdef USE_DLPI_PFMOD
- struct packetfilt pf;
-# endif
-
- info -> wfdesc = if_register_dlpi (info);
-
-# ifdef USE_DLPI_PFMOD
- /* Set up an PFMOD filter that rejects everything... */
- pf.Pf_Priority = 0;
- pf.Pf_FilterLen = 1;
- pf.Pf_Filter [0] = ENF_PUSHZERO;
-
- /* Install the filter */
- if (strioctl (info -> wfdesc, PFIOCSETF, INFTIM,
- sizeof (pf), (char *)&pf) < 0) {
- log_fatal ("Can't set PFMOD send filter on %s: %m", info -> name);
- }
-
-# endif /* USE_DLPI_PFMOD */
-#else /* !defined (USE_DLPI_RECEIVE) */
- /*
- * If using DLPI for both send and receive, simply re-use
- * the read file descriptor that was set up earlier.
- */
- info -> wfdesc = info -> rfdesc;
-#endif
-
- if (!quiet_interface_discovery)
- log_info ("Sending on DLPI/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-
-#ifdef DLPI_FIRST_SEND_WAIT
-/* See the implementation notes at the beginning of this file */
-# ifdef USE_DLPI_RECEIVE
- sleep (DLPI_FIRST_SEND_WAIT - (DLPI_FIRST_SEND_WAIT / 2));
-# else
- sleep (DLPI_FIRST_SEND_WAIT);
-# endif
-#endif
-}
-
-void if_deregister_send (info)
- struct interface_info *info;
-{
- /* If we're using the DLPI API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_DLPI_RECEIVE
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling output on DLPI/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_DLPI_SEND */
-
-#ifdef USE_DLPI_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;
-{
-#ifdef USE_DLPI_PFMOD
- struct packetfilt pf;
- struct ip iphdr;
- u_int16_t offset;
-#endif
-
- /* Open a DLPI device and hang it on this interface... */
- info -> rfdesc = if_register_dlpi (info);
-
-#ifdef USE_DLPI_PFMOD
- /* Set up the PFMOD 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;
-
-#if defined (USE_DLPI_RAW)
-# define ETHER_H_PREFIX (14) /* sizeof (ethernet_header) */
- /*
- * ethertype == ETHERTYPE_IP
- */
- offset = 12;
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + (offset / 2);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (ETHERTYPE_IP);
-# else
-# define ETHER_H_PREFIX (0)
-# endif /* USE_DLPI_RAW */
- /*
- * The packets that will be received on this file descriptor
- * will be IP packets (due to the SAP that was specified in
- * the dlbind call). There will be no ethernet header.
- * Therefore, setup the packet filter to check the protocol
- * field for UDP, and the destination port number equal
- * to the local port. All offsets are relative to the start
- * of an IP packet.
- */
-
- /*
- * BOOTPS destination port
- */
- offset = ETHER_H_PREFIX + sizeof (iphdr) + sizeof (u_int16_t);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + (offset / 2);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = local_port;
-
- /*
- * protocol should be udp. this is a byte compare, test for
- * endianess.
- */
- offset = ETHER_H_PREFIX + ((u_int8_t *)&(iphdr.ip_p) - (u_int8_t *)&iphdr);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + (offset / 2);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_AND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0x00FF);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
-
- /* Install the filter... */
- if (strioctl (info -> rfdesc, PFIOCSETF, INFTIM,
- sizeof (pf), (char *)&pf) < 0) {
- log_fatal ("Can't set PFMOD receive filter on %s: %m", info -> name);
- }
-#endif /* USE_DLPI_PFMOD */
-
- if (!quiet_interface_discovery)
- log_info ("Listening on DLPI/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-
-#ifdef DLPI_FIRST_SEND_WAIT
-/* See the implementation notes at the beginning of this file */
-# ifdef USE_DLPI_SEND
- sleep (DLPI_FIRST_SEND_WAIT / 2);
-# else
- sleep (DLPI_FIRST_SEND_WAIT);
-# endif
-#endif
-}
-
-void if_deregister_receive (info)
- struct interface_info *info;
-{
- /* If we're using the DLPI API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_DLPI_SEND
- close (info -> rfdesc);
-#endif
- info -> rfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling input on DLPI/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_DLPI_RECEIVE */
-
-#ifdef USE_DLPI_SEND
-ssize_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 hbufp = 0;
- double hh [32];
- double ih [1536 / sizeof (double)];
- unsigned char *dbuf = (unsigned char *)ih;
- unsigned dbuflen;
- unsigned char dstaddr [DLPI_MAXDLADDR];
- unsigned addrlen;
- int result;
- int fudge;
-
- if (!strcmp (interface -> name, "fallback"))
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
- dbuflen = 0;
-
- /* Assemble the headers... */
-#ifdef USE_DLPI_RAW
- assemble_hw_header (interface, (unsigned char *)hh, &dbuflen, hto);
- if (dbuflen > sizeof hh)
- log_fatal ("send_packet: hh buffer too small.\n");
- fudge = dbuflen % 4; /* IP header must be word-aligned. */
- memcpy (dbuf + fudge, (unsigned char *)hh, dbuflen);
- dbuflen += fudge;
-#else
- fudge = 0;
-#endif
- assemble_udp_ip_header (interface, dbuf, &dbuflen, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- (unsigned char *)raw, len);
-
- /* Copy the data into the buffer (yuk). */
- memcpy (dbuf + dbuflen, raw, len);
- dbuflen += len;
-
-#ifdef USE_DLPI_RAW
- result = write (interface -> wfdesc, dbuf + fudge, dbuflen - fudge);
-#else
-
- /*
- * Setup the destination address (DLSAP) in dstaddr
- *
- * If sap_length < 0 we must deliver the DLSAP as phys+sap.
- * If sap_length > 0 we must deliver the DLSAP as sap+phys.
- *
- * sap = Service Access Point == ETHERTYPE_IP
- * sap + datalink address is called DLSAP in dlpi speak.
- */
- { /* ENCODE DLSAP */
- unsigned char phys [DLPI_MAXDLADDR];
- unsigned char sap [4];
- int sap_len = interface -> dlpi_sap_length;
- int phys_len = interface -> hw_address.hlen - 1;
-
- /* sap = htons (ETHERTYPE_IP) kludge */
- memset (sap, 0, sizeof (sap));
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- sap [0] = 0x00;
- sap [1] = 0x08;
-# else
- sap [0] = 0x08;
- sap [1] = 0x00;
-# endif
-
- if (hto && hto -> hlen == interface -> hw_address.hlen)
- memcpy ( phys, (char *) &hto -> hbuf [1], phys_len);
- else
- memcpy ( phys, interface -> dlpi_broadcast_addr.hbuf,
- interface -> dlpi_broadcast_addr.hlen);
-
- if (sap_len < 0) {
- memcpy ( dstaddr, phys, phys_len);
- memcpy ( (char *) &dstaddr [phys_len], sap, ABS (sap_len));
- }
- else {
- memcpy ( dstaddr, (void *) sap, sap_len);
- memcpy ( (char *) &dstaddr [sap_len], phys, phys_len);
- }
- addrlen = phys_len + ABS (sap_len);
- } /* ENCODE DLSAP */
-
- result = dlpiunitdatareq (interface -> wfdesc, dstaddr, addrlen,
- 0, 0, dbuf, dbuflen);
-#endif /* USE_DLPI_RAW */
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_DLPI_SEND */
-
-#ifdef USE_DLPI_RECEIVE
-ssize_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;
-{
- unsigned char dbuf [1536];
- unsigned char srcaddr [DLPI_MAXDLADDR];
- unsigned long srcaddrlen;
- int flags = 0;
- int length = 0;
- int offset = 0;
- int rslt;
- int bufix = 0;
-
-#ifdef USE_DLPI_RAW
- length = read (interface -> rfdesc, dbuf, sizeof (dbuf));
-#else
- length = dlpiunitdataind (interface -> rfdesc, (unsigned char *)NULL,
- (unsigned long *)NULL, srcaddr, &srcaddrlen,
- (unsigned long *)NULL, dbuf, sizeof (dbuf));
-#endif
-
- if (length <= 0) {
- return length;
- }
-
-# if !defined (USE_DLPI_RAW)
- /*
- * Copy the sender's hw address into hfrom
- * If sap_len < 0 the DLSAP is as phys+sap.
- * If sap_len > 0 the DLSAP is as sap+phys.
- *
- * sap is discarded here.
- */
- { /* DECODE DLSAP */
- int sap_len = interface -> dlpi_sap_length;
- int phys_len = interface -> hw_address.hlen - 1;
-
- if (hfrom && (srcaddrlen == ABS (sap_len) + phys_len )) {
- hfrom -> hbuf [0] = interface -> hw_address.hbuf [0];
- hfrom -> hlen = interface -> hw_address.hlen;
-
- if (sap_len < 0) {
- memcpy ((char *) &hfrom -> hbuf [1], srcaddr, phys_len);
- }
- else {
- memcpy ((char *) &hfrom -> hbuf [1], (char *) &srcaddr [phys_len],
- phys_len);
- }
- }
- else if (hfrom) {
- memset (hfrom, '\0', sizeof *hfrom);
- }
- } /* DECODE_DLSAP */
-
-# endif /* !defined (USE_DLPI_RAW) */
-
- /* Decode the IP and UDP headers... */
- bufix = 0;
-#ifdef USE_DLPI_RAW
- /* Decode the physical header... */
- offset = decode_hw_header (interface, dbuf, 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;
-#endif
- offset = decode_udp_ip_header (interface, dbuf, 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, &dbuf [bufix], length);
- return length;
-}
-#endif
-
-/* Common DLPI routines ...
- *
- * Written by Eric James Negaard, <lmdejn@lmd.ericsson.se>
- *
- * Based largely in part to the example code contained in the document
- * "How to Use the STREAMS Data Link Provider Interface (DLPI)", written
- * by Neal Nuckolls of SunSoft Internet Engineering.
- *
- * This code has been developed and tested on sparc-based machines running
- * SunOS 5.5.1, with le and hme network interfaces. It should be pretty
- * generic, though.
- *
- * The usual disclaimers apply. This code works for me. Don't blame me
- * if it makes your machine or network go down in flames. That taken
- * into consideration, use this code as you wish. If you make usefull
- * modifications I'd appreciate hearing about it.
- */
-
-#define DLPI_MAXWAIT 15 /* Max timeout */
-
-
-/*
- * Parse an interface name and extract the unit number
- */
-
-static int dlpiunit (ifname)
- char *ifname;
-{
- int fd;
- char *cp, *dp, *ep;
- int unit;
-
- if (!ifname) {
- return 0;
- }
-
- /* Advance to the end of the name */
- cp = ifname;
- while (*cp) cp++;
- /* Back up to the start of the first digit */
- while ((*(cp-1) >= '0' && *(cp-1) <= '9') || *(cp - 1) == ':') cp--;
-
- /* Convert the unit number */
- unit = 0;
- while (*cp >= '0' && *cp <= '9') {
- unit *= 10;
- unit += (*cp++ - '0');
- }
-
- return unit;
-}
-
-/*
- * dlpiopen - open the DLPI device for a given interface name
- */
-static int dlpiopen (ifname)
- char *ifname;
-{
- char devname [50];
- char *cp, *dp, *ep;
-
- if (!ifname) {
- return -1;
- }
-
- /* Open a DLPI device */
- if (*ifname == '/') {
- dp = devname;
- } else {
- /* Prepend the device directory */
- memcpy (devname, DLPI_DEVDIR, strlen (DLPI_DEVDIR));
- dp = &devname [strlen (DLPI_DEVDIR)];
- }
-
- /* Find the end of the interface name */
- ep = cp = ifname;
- while (*ep)
- ep++;
- /* And back up to the first digit (unit number) */
- while ((*(ep - 1) >= '0' && *(ep - 1) <= '9') || *(ep - 1) == ':')
- ep--;
-
- /* Copy everything up to the unit number */
- while (cp < ep) {
- *dp++ = *cp++;
- }
- *dp = '\0';
-
- return open (devname, O_RDWR, 0);
-}
-
-/*
- * dlpiinforeq - request information about the data link provider.
- */
-
-static int dlpiinforeq (fd)
- int fd;
-{
- dl_info_req_t info_req;
- struct strbuf ctl;
- int flags;
-
- info_req.dl_primitive = DL_INFO_REQ;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (info_req);
- ctl.buf = (char *)&info_req;
-
- flags = RS_HIPRI;
-
- return putmsg (fd, &ctl, (struct strbuf *)NULL, flags);
-}
-
-/*
- * dlpiphysaddrreq - request the current physical address.
- */
-static int dlpiphysaddrreq (fd, addrtype)
- int fd;
- unsigned long addrtype;
-{
- dl_phys_addr_req_t physaddr_req;
- struct strbuf ctl;
- int flags;
-
- physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
- physaddr_req.dl_addr_type = addrtype;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (physaddr_req);
- ctl.buf = (char *)&physaddr_req;
-
- flags = RS_HIPRI;
-
- return putmsg (fd, &ctl, (struct strbuf *)NULL, flags);
-}
-
-/*
- * dlpiattachreq - send a request to attach to a specific unit.
- */
-static int dlpiattachreq (fd, ppa)
- unsigned long ppa;
- int fd;
-{
- dl_attach_req_t attach_req;
- struct strbuf ctl;
- int flags;
-
- attach_req.dl_primitive = DL_ATTACH_REQ;
- attach_req.dl_ppa = ppa;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (attach_req);
- ctl.buf = (char *)&attach_req;
-
- flags = 0;
-
- return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);
-}
-
-/*
- * dlpibindreq - send a request to bind to a specific SAP address.
- */
-static int dlpibindreq (fd, sap, max_conind, service_mode, conn_mgmt, xidtest)
- unsigned long sap;
- unsigned long max_conind;
- unsigned long service_mode;
- unsigned long conn_mgmt;
- unsigned long xidtest;
- int fd;
-{
- dl_bind_req_t bind_req;
- struct strbuf ctl;
- int flags;
-
- bind_req.dl_primitive = DL_BIND_REQ;
- bind_req.dl_sap = sap;
- bind_req.dl_max_conind = max_conind;
- bind_req.dl_service_mode = service_mode;
- bind_req.dl_conn_mgmt = conn_mgmt;
- bind_req.dl_xidtest_flg = xidtest;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (bind_req);
- ctl.buf = (char *)&bind_req;
-
- flags = 0;
-
- return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);
-}
-
-/*
- * dlpiunbindreq - send a request to unbind.
- */
-static int dlpiunbindreq (fd)
- int fd;
-{
- dl_unbind_req_t unbind_req;
- struct strbuf ctl;
- int flags;
-
- unbind_req.dl_primitive = DL_UNBIND_REQ;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (unbind_req);
- ctl.buf = (char *)&unbind_req;
-
- flags = 0;
-
- return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);
-}
-
-
-/*
- * dlpidetachreq - send a request to detach.
- */
-static int dlpidetachreq (fd)
- int fd;
-{
- dl_detach_req_t detach_req;
- struct strbuf ctl;
- int flags;
-
- detach_req.dl_primitive = DL_DETACH_REQ;
-
- ctl.maxlen = 0;
- ctl.len = sizeof (detach_req);
- ctl.buf = (char *)&detach_req;
-
- flags = 0;
-
- return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);
-}
-
-
-/*
- * dlpibindack - receive an ack to a dlbindreq.
- */
-static int dlpibindack (fd, bufp)
- char *bufp;
- int fd;
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = DLPI_MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- if (strgetmsg (fd, &ctl,
- (struct strbuf*)NULL, &flags, "dlpibindack") < 0) {
- return -1;
- }
-
- dlp = (union DL_primitives *)ctl.buf;
-
- if (!expected (DL_BIND_ACK, dlp, flags) < 0) {
- return -1;
- }
-
- if (ctl.len < sizeof (dl_bind_ack_t)) {
- /* Returned structure is too short */
- return -1;
- }
-
- return 0;
-}
-
-/*
- * dlpiokack - general acknowledgement reception.
- */
-static int dlpiokack (fd, bufp)
- char *bufp;
- int fd;
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = DLPI_MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- if (strgetmsg (fd, &ctl,
- (struct strbuf*)NULL, &flags, "dlpiokack") < 0) {
- return -1;
- }
-
- dlp = (union DL_primitives *)ctl.buf;
-
- if (!expected (DL_OK_ACK, dlp, flags) < 0) {
- return -1;
- }
-
- if (ctl.len < sizeof (dl_ok_ack_t)) {
- /* Returned structure is too short */
- return -1;
- }
-
- return 0;
-}
-
-/*
- * dlpiinfoack - receive an ack to a dlinforeq.
- */
-static int dlpiinfoack (fd, bufp)
- char *bufp;
- int fd;
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = DLPI_MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- if (strgetmsg (fd, &ctl, (struct strbuf *)NULL, &flags,
- "dlpiinfoack") < 0) {
- return -1;
- }
-
- dlp = (union DL_primitives *) ctl.buf;
-
- if (!expected (DL_INFO_ACK, dlp, flags) < 0) {
- return -1;
- }
-
- if (ctl.len < sizeof (dl_info_ack_t)) {
- /* Returned structure is too short */
- return -1;
- }
-
- return 0;
-}
-
-/*
- * dlpiphysaddrack - receive an ack to a dlpiphysaddrreq.
- */
-int dlpiphysaddrack (fd, bufp)
- char *bufp;
- int fd;
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = DLPI_MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- if (strgetmsg (fd, &ctl, (struct strbuf *)NULL, &flags,
- "dlpiphysaddrack") < 0) {
- return -1;
- }
-
- dlp = (union DL_primitives *)ctl.buf;
-
- if (!expected (DL_PHYS_ADDR_ACK, dlp, flags) < 0) {
- return -1;
- }
-
- if (ctl.len < sizeof (dl_phys_addr_ack_t)) {
- /* Returned structure is too short */
- return -1;
- }
-
- return 0;
-}
-
-int dlpiunitdatareq (fd, addr, addrlen, minpri, maxpri, dbuf, dbuflen)
- int fd;
- unsigned char *addr;
- int addrlen;
- unsigned long minpri;
- unsigned long maxpri;
- unsigned char *dbuf;
- int dbuflen;
-{
- long buf [DLPI_MAXDLBUF];
- union DL_primitives *dlp;
- struct strbuf ctl, data;
-
- /* Set up the control information... */
- dlp = (union DL_primitives *)buf;
- dlp -> unitdata_req.dl_primitive = DL_UNITDATA_REQ;
- dlp -> unitdata_req.dl_dest_addr_length = addrlen;
- dlp -> unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
- dlp -> unitdata_req.dl_priority.dl_min = minpri;
- dlp -> unitdata_req.dl_priority.dl_max = maxpri;
-
- /* Append the destination address */
- memcpy ((char *)buf + dlp -> unitdata_req.dl_dest_addr_offset,
- addr, addrlen);
-
- ctl.maxlen = 0;
- ctl.len = dlp -> unitdata_req.dl_dest_addr_offset + addrlen;
- ctl.buf = (char *)buf;
-
- data.maxlen = 0;
- data.buf = (char *)dbuf;
- data.len = dbuflen;
-
- /* Send the packet down the wire... */
- return putmsg (fd, &ctl, &data, 0);
-}
-
-static int dlpiunitdataind (fd, daddr, daddrlen,
- saddr, saddrlen, grpaddr, dbuf, dlen)
- int fd;
- unsigned char *daddr;
- unsigned long *daddrlen;
- unsigned char *saddr;
- unsigned long *saddrlen;
- unsigned long *grpaddr;
- unsigned char *dbuf;
- int dlen;
-{
- long buf [DLPI_MAXDLBUF];
- union DL_primitives *dlp;
- struct strbuf ctl, data;
- int flags = 0;
- int result;
-
- /* Set up the msg_buf structure... */
- dlp = (union DL_primitives *)buf;
- dlp -> unitdata_ind.dl_primitive = DL_UNITDATA_IND;
-
- ctl.maxlen = DLPI_MAXDLBUF;
- ctl.len = 0;
- ctl.buf = (char *)buf;
-
- data.maxlen = dlen;
- data.len = 0;
- data.buf = (char *)dbuf;
-
- result = getmsg (fd, &ctl, &data, &flags);
-
- if (result != 0) {
- return -1;
- }
-
- if (ctl.len < sizeof (dl_unitdata_ind_t) ||
- dlp -> unitdata_ind.dl_primitive != DL_UNITDATA_IND) {
- return -1;
- }
-
- if (data.len <= 0) {
- return data.len;
- }
-
- /* Copy sender info */
- if (saddr) {
- memcpy (saddr,
- (char *)buf + dlp -> unitdata_ind.dl_src_addr_offset,
- dlp -> unitdata_ind.dl_src_addr_length);
- }
- if (saddrlen) {
- *saddrlen = dlp -> unitdata_ind.dl_src_addr_length;
- }
-
- /* Copy destination info */
- if (daddr) {
- memcpy (daddr,
- (char *)buf + dlp -> unitdata_ind.dl_dest_addr_offset,
- dlp -> unitdata_ind.dl_dest_addr_length);
- }
- if (daddrlen) {
- *daddrlen = dlp -> unitdata_ind.dl_dest_addr_length;
- }
-
- if (grpaddr) {
- *grpaddr = dlp -> unitdata_ind.dl_group_address;
- }
-
- return data.len;
-}
-
-/*
- * expected - see if we got what we wanted.
- */
-static int expected (prim, dlp, msgflags)
- unsigned long prim;
- union DL_primitives *dlp;
- int msgflags;
-{
- if (msgflags != RS_HIPRI) {
- /* Message was not M_PCPROTO */
- return 0;
- }
-
- if (dlp -> dl_primitive != prim) {
- /* Incorrect/unexpected return message */
- return 0;
- }
-
- return 1;
-}
-
-/*
- * strgetmsg - get a message from a stream, with timeout.
- */
-static int strgetmsg (fd, ctlp, datap, flagsp, caller)
- struct strbuf *ctlp, *datap;
- char *caller;
- int *flagsp;
- int fd;
-{
- int result;
-#ifdef USE_POLL
- struct pollfd pfd;
- int count;
- time_t now;
- time_t starttime;
- int to_msec;
-#endif
-
-#ifdef USE_POLL
- pfd.fd = fd;
- pfd.events = POLLPRI; /* We're only interested in knowing
- * when we can receive the next high
- * priority message.
- */
- pfd.revents = 0;
-
- now = time (&starttime);
- while (now <= starttime + DLPI_MAXWAIT) {
- to_msec = ((starttime + DLPI_MAXWAIT) - now) * 1000;
- count = poll (&pfd, 1, to_msec);
-
- if (count == 0) {
- /* log_fatal ("strgetmsg: timeout"); */
- return -1;
- } else if (count < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- time (&now);
- continue;
- } else {
- /* log_fatal ("poll: %m"); */
- return -1;
- }
- } else {
- break;
- }
- }
-#else /* defined (USE_POLL) */
- /*
- * Start timer. Can't use select, since it might return true if there
- * were non High-Priority data available on the stream.
- */
- (void) sigset (SIGALRM, sigalrm);
-
- if (alarm (DLPI_MAXWAIT) < 0) {
- /* log_fatal ("alarm: %m"); */
- return -1;
- }
-#endif /* !defined (USE_POLL) */
-
- /*
- * Set flags argument and issue getmsg ().
- */
- *flagsp = 0;
- if ((result = getmsg (fd, ctlp, datap, flagsp)) < 0) {
- return result;
- }
-
-#ifndef USE_POLL
- /*
- * Stop timer.
- */
- if (alarm (0) < 0) {
- /* log_fatal ("alarm: %m"); */
- return -1;
- }
-#endif
-
- /*
- * Check for MOREDATA and/or MORECTL.
- */
- if (result & (MORECTL|MOREDATA)) {
- return -1;
- }
-
- /*
- * Check for at least sizeof (long) control data portion.
- */
- if (ctlp -> len < sizeof (long)) {
- return -1;
- }
-
- return 0;
-}
-
-#ifndef USE_POLL
-/*
- * sigalrm - handle alarms.
- */
-static void sigalrm (sig)
- int sig;
-{
- fprintf (stderr, "strgetmsg: timeout");
- exit (1);
-}
-#endif /* !defined (USE_POLL) */
-
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-void maybe_setup_fallback ()
-{
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- if_register_fallback (fbi);
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-}
-#endif /* USE_DLPI */
diff --git a/contrib/isc-dhcp/common/dns.c b/contrib/isc-dhcp/common/dns.c
deleted file mode 100644
index e80df9a..0000000
--- a/contrib/isc-dhcp/common/dns.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/* dns.c
-
- Domain Name Service subroutines. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 2001-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dns.c,v 1.35.2.16 2004/06/17 20:54:38 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "arpa/nameser.h"
-#include "dst/md5.h"
-
-/* This file is kind of a crutch for the BIND 8 nsupdate code, which has
- * itself been cruelly hacked from its original state. What this code
- * does is twofold: first, it maintains a database of zone cuts that can
- * be used to figure out which server should be contacted to update any
- * given domain name. Secondly, it maintains a set of named TSIG keys,
- * and associates those keys with zones. When an update is requested for
- * a particular zone, the key associated with that zone is used for the
- * update.
- *
- * The way this works is that you define the domain name to which an
- * SOA corresponds, and the addresses of some primaries for that domain name:
- *
- * zone FOO.COM {
- * primary 10.0.17.1;
- * secondary 10.0.22.1, 10.0.23.1;
- * key "FOO.COM Key";
- * }
- *
- * If an update is requested for GAZANGA.TOPANGA.FOO.COM, then the name
- * server looks in its database for a zone record for "GAZANGA.TOPANGA.FOO.COM",
- * doesn't find it, looks for one for "TOPANGA.FOO.COM", doesn't find *that*,
- * looks for "FOO.COM", finds it. So it
- * attempts the update to the primary for FOO.COM. If that times out, it
- * tries the secondaries. You can list multiple primaries if you have some
- * kind of magic name server that supports that. You shouldn't list
- * secondaries that don't know how to forward updates (e.g., BIND 8 doesn't
- * support update forwarding, AFAIK). If no TSIG key is listed, the update
- * is attempted without TSIG.
- *
- * The DHCP server tries to find an existing zone for any given name by
- * trying to look up a local zone structure for each domain containing
- * that name, all the way up to '.'. If it finds one cached, it tries
- * to use that one to do the update. That's why it tries to update
- * "FOO.COM" above, even though theoretically it should try GAZANGA...
- * and TOPANGA... first.
- *
- * If the update fails with a predefined or cached zone (we'll get to
- * those in a second), then it tries to find a more specific zone. This
- * is done by looking first for an SOA for GAZANGA.TOPANGA.FOO.COM. Then
- * an SOA for TOPANGA.FOO.COM is sought. If during this search a predefined
- * or cached zone is found, the update fails - there's something wrong
- * somewhere.
- *
- * If a more specific zone _is_ found, that zone is cached for the length of
- * its TTL in the same database as that described above. TSIG updates are
- * never done for cached zones - if you want TSIG updates you _must_
- * write a zone definition linking the key to the zone. In cases where you
- * know for sure what the key is but do not want to hardcode the IP addresses
- * of the primary or secondaries, a zone declaration can be made that doesn't
- * include any primary or secondary declarations. When the DHCP server
- * encounters this while hunting up a matching zone for a name, it looks up
- * the SOA, fills in the IP addresses, and uses that record for the update.
- * If the SOA lookup returns NXRRSET, a warning is printed and the zone is
- * discarded, TSIG key and all. The search for the zone then continues as if
- * the zone record hadn't been found. Zones without IP addresses don't
- * match when initially hunting for a predefined or cached zone to update.
- *
- * When an update is attempted and no predefined or cached zone is found
- * that matches any enclosing domain of the domain being updated, the DHCP
- * server goes through the same process that is done when the update to a
- * predefined or cached zone fails - starting with the most specific domain
- * name (GAZANGA.TOPANGA.FOO.COM) and moving to the least specific (the root),
- * it tries to look up an SOA record. When it finds one, it creates a cached
- * zone and attempts an update, and gives up if the update fails.
- *
- * TSIG keys are defined like this:
- *
- * key "FOO.COM Key" {
- * algorithm HMAC-MD5.SIG-ALG.REG.INT;
- * secret <Base64>;
- * }
- *
- * <Base64> is a number expressed in base64 that represents the key.
- * It's also permissible to use a quoted string here - this will be
- * translated as the ASCII bytes making up the string, and will not
- * include any NUL termination. The key name can be any text string,
- * and the key type must be one of the key types defined in the draft
- * or by the IANA. Currently only the HMAC-MD5... key type is
- * supported.
- */
-
-dns_zone_hash_t *dns_zone_hash;
-
-#if defined (NSUPDATE)
-isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
- struct dns_zone *zone)
-{
- isc_result_t status;
- ns_tsig_key *tkey;
-
- if (!zone)
- return ISC_R_NOTFOUND;
-
- if (!zone -> key) {
- return ISC_R_KEY_UNKNOWN;
- }
-
- if ((!zone -> key -> name ||
- strlen (zone -> key -> name) > NS_MAXDNAME) ||
- (!zone -> key -> algorithm ||
- strlen (zone -> key -> algorithm) > NS_MAXDNAME) ||
- (!zone -> key) ||
- (!zone -> key -> key) ||
- (zone -> key -> key -> len == 0)) {
- return ISC_R_INVALIDKEY;
- }
- tkey = dmalloc (sizeof *tkey, MDL);
- if (!tkey) {
- nomem:
- return ISC_R_NOMEMORY;
- }
- memset (tkey, 0, sizeof *tkey);
- tkey -> data = dmalloc (zone -> key -> key -> len, MDL);
- if (!tkey -> data) {
- dfree (tkey, MDL);
- goto nomem;
- }
- strcpy (tkey -> name, zone -> key -> name);
- strcpy (tkey -> alg, zone -> key -> algorithm);
- memcpy (tkey -> data,
- zone -> key -> key -> value, zone -> key -> key -> len);
- tkey -> len = zone -> key -> key -> len;
- *key = tkey;
- return ISC_R_SUCCESS;
-}
-
-void tkey_free (ns_tsig_key **key)
-{
- if ((*key) -> data)
- dfree ((*key) -> data, MDL);
- dfree ((*key), MDL);
- *key = (ns_tsig_key *)0;
-}
-#endif
-
-isc_result_t enter_dns_zone (struct dns_zone *zone)
-{
- struct dns_zone *tz = (struct dns_zone *)0;
-
- if (dns_zone_hash) {
- dns_zone_hash_lookup (&tz,
- dns_zone_hash, zone -> name, 0, MDL);
- if (tz == zone) {
- dns_zone_dereference (&tz, MDL);
- return ISC_R_SUCCESS;
- }
- if (tz) {
- dns_zone_hash_delete (dns_zone_hash,
- zone -> name, 0, MDL);
- dns_zone_dereference (&tz, MDL);
- }
- } else {
- if (!dns_zone_new_hash (&dns_zone_hash, 1, MDL))
- return ISC_R_NOMEMORY;
- }
- dns_zone_hash_add (dns_zone_hash, zone -> name, 0, zone, MDL);
- return ISC_R_SUCCESS;
-}
-
-isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
-{
- struct dns_zone *tz = (struct dns_zone *)0;
- int len;
- char *tname = (char *)0;
- isc_result_t status;
-
- if (!dns_zone_hash)
- return ISC_R_NOTFOUND;
-
- len = strlen (name);
- if (name [len - 1] != '.') {
- tname = dmalloc ((unsigned)len + 2, MDL);
- if (!tname)
- return ISC_R_NOMEMORY;;
- strcpy (tname, name);
- tname [len] = '.';
- tname [len + 1] = 0;
- name = tname;
- }
- if (!dns_zone_hash_lookup (zone, dns_zone_hash, name, 0, MDL))
- status = ISC_R_NOTFOUND;
- else
- status = ISC_R_SUCCESS;
-
- if (tname)
- dfree (tname, MDL);
- return status;
-}
-
-int dns_zone_dereference (ptr, file, line)
- struct dns_zone **ptr;
- const char *file;
- int line;
-{
- int i;
- struct dns_zone *dns_zone;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- dns_zone = *ptr;
- *ptr = (struct dns_zone *)0;
- --dns_zone -> refcnt;
- rc_register (file, line, ptr, dns_zone, dns_zone -> refcnt, 1, RC_MISC);
- if (dns_zone -> refcnt > 0)
- return 1;
-
- if (dns_zone -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (dns_zone);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (dns_zone -> name)
- dfree (dns_zone -> name, file, line);
- if (dns_zone -> key)
- omapi_auth_key_dereference (&dns_zone -> key, file, line);
- if (dns_zone -> primary)
- option_cache_dereference (&dns_zone -> primary, file, line);
- if (dns_zone -> secondary)
- option_cache_dereference (&dns_zone -> secondary, file, line);
- dfree (dns_zone, file, line);
- return 1;
-}
-
-#if defined (NSUPDATE)
-isc_result_t find_cached_zone (const char *dname, ns_class class,
- char *zname, size_t zsize,
- struct in_addr *addrs,
- int naddrs, int *naddrout,
- struct dns_zone **zcookie)
-{
- isc_result_t status = ISC_R_NOTFOUND;
- const char *np;
- struct dns_zone *zone = (struct dns_zone *)0;
- struct data_string nsaddrs;
- int ix;
-
- /* The absence of the zcookie pointer indicates that we
- succeeded previously, but the update itself failed, meaning
- that we shouldn't use the cached zone. */
- if (!zcookie)
- return ISC_R_NOTFOUND;
-
- /* We can't look up a null zone. */
- if (!dname || !*dname)
- return ISC_R_INVALIDARG;
-
- /* For each subzone, try to find a cached zone. */
- for (np = dname; np; np = strchr (np, '.')) {
- np++;
- status = dns_zone_lookup (&zone, np);
- if (status == ISC_R_SUCCESS)
- break;
- }
-
- if (status != ISC_R_SUCCESS)
- return status;
-
- /* Make sure the zone is valid. */
- if (zone -> timeout && zone -> timeout < cur_time) {
- dns_zone_dereference (&zone, MDL);
- return ISC_R_CANCELED;
- }
-
- /* Make sure the zone name will fit. */
- if (strlen (zone -> name) > zsize) {
- dns_zone_dereference (&zone, MDL);
- return ISC_R_NOSPACE;
- }
- strcpy (zname, zone -> name);
-
- memset (&nsaddrs, 0, sizeof nsaddrs);
- ix = 0;
-
- if (zone -> primary) {
- if (evaluate_option_cache (&nsaddrs, (struct packet *)0,
- (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0,
- &global_scope,
- zone -> primary, MDL)) {
- int ip = 0;
- while (ix < naddrs) {
- if (ip + 4 > nsaddrs.len)
- break;
- memcpy (&addrs [ix], &nsaddrs.data [ip], 4);
- ip += 4;
- ix++;
- }
- data_string_forget (&nsaddrs, MDL);
- }
- }
- if (zone -> secondary) {
- if (evaluate_option_cache (&nsaddrs, (struct packet *)0,
- (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0,
- &global_scope,
- zone -> secondary, MDL)) {
- int ip = 0;
- while (ix < naddrs) {
- if (ip + 4 > nsaddrs.len)
- break;
- memcpy (&addrs [ix], &nsaddrs.data [ip], 4);
- ip += 4;
- ix++;
- }
- data_string_forget (&nsaddrs, MDL);
- }
- }
-
- /* It's not an error for zcookie to have a value here - actually,
- it's quite likely, because res_nupdate cycles through all the
- names in the update looking for their zones. */
- if (!*zcookie)
- dns_zone_reference (zcookie, zone, MDL);
- dns_zone_dereference (&zone, MDL);
- if (naddrout)
- *naddrout = ix;
- return ISC_R_SUCCESS;
-}
-
-void forget_zone (struct dns_zone **zone)
-{
- dns_zone_dereference (zone, MDL);
-}
-
-void repudiate_zone (struct dns_zone **zone)
-{
- /* XXX Currently we're not differentiating between a cached
- XXX zone and a zone that's been repudiated, which means
- XXX that if we reap cached zones, we blow away repudiated
- XXX zones. This isn't a big problem since we're not yet
- XXX caching zones... :'} */
-
- (*zone) -> timeout = cur_time - 1;
- dns_zone_dereference (zone, MDL);
-}
-
-void cache_found_zone (ns_class class,
- char *zname, struct in_addr *addrs, int naddrs)
-{
- isc_result_t status = ISC_R_NOTFOUND;
- struct dns_zone *zone = (struct dns_zone *)0;
- struct data_string nsaddrs;
- int ix = strlen (zname);
-
- if (zname [ix - 1] == '.')
- ix = 0;
-
- /* See if there's already such a zone. */
- if (dns_zone_lookup (&zone, zname) == ISC_R_SUCCESS) {
- /* If it's not a dynamic zone, leave it alone. */
- if (!zone -> timeout)
- return;
- /* Address may have changed, so just blow it away. */
- if (zone -> primary)
- option_cache_dereference (&zone -> primary, MDL);
- if (zone -> secondary)
- option_cache_dereference (&zone -> secondary, MDL);
- } else if (!dns_zone_allocate (&zone, MDL))
- return;
-
- if (!zone -> name) {
- zone -> name =
- dmalloc (strlen (zname) + 1 + (ix != 0), MDL);
- if (!zone -> name) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- strcpy (zone -> name, zname);
- /* Add a trailing '.' if it was missing. */
- if (ix) {
- zone -> name [ix] = '.';
- zone -> name [ix + 1] = 0;
- }
- }
-
- /* XXX Need to get the lower-level code to push the actual zone
- XXX TTL up to us. */
- zone -> timeout = cur_time + 1800;
-
- if (!option_cache_allocate (&zone -> primary, MDL)) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- if (!buffer_allocate (&zone -> primary -> data.buffer,
- naddrs * sizeof (struct in_addr), MDL)) {
- dns_zone_dereference (&zone, MDL);
- return;
- }
- memcpy (zone -> primary -> data.buffer -> data,
- addrs, naddrs * sizeof *addrs);
- zone -> primary -> data.data =
- &zone -> primary -> data.buffer -> data [0];
- zone -> primary -> data.len = naddrs * sizeof *addrs;
-
- enter_dns_zone (zone);
-}
-
-/* Have to use TXT records for now. */
-#define T_DHCID T_TXT
-
-int get_dhcid (struct data_string *id,
- int type, const u_int8_t *data, unsigned len)
-{
- unsigned char buf[MD5_DIGEST_LENGTH];
- MD5_CTX md5;
- int i;
-
- /* Types can only be 0..(2^16)-1. */
- if (type < 0 || type > 65535)
- return 0;
-
- /* Hexadecimal MD5 digest plus two byte type and NUL. */
- if (!buffer_allocate (&id -> buffer,
- (MD5_DIGEST_LENGTH * 2) + 3, MDL))
- return 0;
- id -> data = id -> buffer -> data;
-
- /*
- * DHCP clients and servers should use the following forms of client
- * identification, starting with the most preferable, and finishing
- * with the least preferable. If the client does not send any of these
- * forms of identification, the DHCP/DDNS interaction is not defined by
- * this specification. The most preferable form of identification is
- * the Globally Unique Identifier Option [TBD]. Next is the DHCP
- * Client Identifier option. Last is the client's link-layer address,
- * as conveyed in its DHCPREQUEST message. Implementors should note
- * that the link-layer address cannot be used if there are no
- * significant bytes in the chaddr field of the DHCP client's request,
- * because this does not constitute a unique identifier.
- * -- "Interaction between DHCP and DNS"
- * <draft-ietf-dhc-dhcp-dns-12.txt>
- * M. Stapp, Y. Rekhter
- */
-
- /* Put the type in the first two bytes. */
- id -> buffer -> data [0] = "0123456789abcdef" [type >> 4];
- id -> buffer -> data [1] = "0123456789abcdef" [type % 15];
-
- /* Mash together an MD5 hash of the identifier. */
- MD5_Init (&md5);
- MD5_Update (&md5, data, len);
- MD5_Final (buf, &md5);
-
- /* Convert into ASCII. */
- for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
- id -> buffer -> data [i * 2 + 2] =
- "0123456789abcdef" [(buf [i] >> 4) & 0xf];
- id -> buffer -> data [i * 2 + 3] =
- "0123456789abcdef" [buf [i] & 0xf];
- }
- id -> len = MD5_DIGEST_LENGTH * 2 + 2;
- id -> buffer -> data [id -> len] = 0;
- id -> terminated = 1;
-
- return 1;
-}
-
-/* Now for the DDNS update code that is shared between client and
- server... */
-
-isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
- struct iaddr ddns_addr,
- struct data_string *ddns_dhcid,
- unsigned long ttl, int rrsetp)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result;
- char ddns_address [16];
-
- if (ddns_addr.len != 4)
- return ISC_R_INVALIDARG;
-
- /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe% */
- sprintf (ddns_address, "%u.%u.%u.%u",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-
- /*
- * When a DHCP client or server intends to update an A RR, it first
- * prepares a DNS UPDATE query which includes as a prerequisite the
- * assertion that the name does not exist. The update section of the
- * query attempts to add the new name and its IP address mapping (an A
- * RR), and the DHCID RR with its unique client-identity.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * A RR does not exist.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = rrsetp ? NXRRSET : NXDOMAIN;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add DHCID RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-
-#ifdef DEBUG_DNS_UPDATES
- print_dns_status ((int)result, &updqueue);
-#endif
-
- /*
- * If this update operation succeeds, the updater can conclude that it
- * has added a new name whose only RRs are the A and DHCID RR records.
- * The A RR update is now complete (and a client updater is finished,
- * while a server might proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result == ISC_R_SUCCESS) {
- log_info ("Added new forward map from %.*s to %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address);
- goto error;
- }
-
-
- /*
- * If the first update operation fails with YXDOMAIN, the updater can
- * conclude that the intended name is in use. The updater then
- * attempts to confirm that the DNS name is not being used by some
- * other host. The updater prepares a second UPDATE query in which the
- * prerequisite is that the desired name has attached to it a DHCID RR
- * whose contents match the client identity. The update section of
- * this query deletes the existing A records on the name, and adds the
- * A record that matches the DHCP binding and the DHCID RR with the
- * client identity.
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result != (rrsetp ? ISC_R_YXRRSET : ISC_R_YXDOMAIN)) {
- log_error ("Unable to add forward map from %.*s to %s: %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address,
- isc_result_totext (result));
- goto error;
- }
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- /*
- * DHCID RR exists, and matches client identity.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Delete A RRset.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Add A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, ttl);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = ADD;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
-
- if (result != ISC_R_SUCCESS) {
- if (result == YXRRSET || result == YXDOMAIN ||
- result == NXRRSET || result == NXDOMAIN)
- log_error ("Forward map from %.*s to %s already in use",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data,
- ddns_address);
- else
- log_error ("Can't update forward map %.*s to %s: %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data,
- ddns_address, isc_result_totext (result));
-
- } else {
- log_info ("Added new forward map from %.*s to %s",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data, ddns_address);
- }
-#if defined (DEBUG_DNS_UPDATES)
- print_dns_status ((int)result, &updqueue);
-#endif
-
- /*
- * If this query succeeds, the updater can conclude that the current
- * client was the last client associated with the domain name, and that
- * the name now contains the updated A RR. The A RR update is now
- * complete (and a client updater is finished, while a server would
- * then proceed to perform a PTR RR update).
- * -- "Interaction between DHCP and DNS"
- */
-
- /*
- * If the second query fails with NXRRSET, the updater must conclude
- * that the client's desired name is in use by another host. At this
- * juncture, the updater can decide (based on some administrative
- * configuration outside of the scope of this document) whether to let
- * the existing owner of the name keep that name, and to (possibly)
- * perform some name disambiguation operation on behalf of the current
- * client, or to replace the RRs on the name with RRs that represent
- * the current client. If the configured policy allows replacement of
- * existing records, the updater submits a query that deletes the
- * existing A RR and the existing DHCID RR, adding A and DHCID RRs that
- * represent the IP address and client-identity of the new client.
- * -- "Interaction between DHCP and DNS"
- */
-
- error:
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
-isc_result_t ddns_remove_a (struct data_string *ddns_fwd_name,
- struct iaddr ddns_addr,
- struct data_string *ddns_dhcid)
-{
- ns_updque updqueue;
- ns_updrec *updrec;
- isc_result_t result = SERVFAIL;
- char ddns_address [16];
-
- if (ddns_addr.len != 4)
- return ISC_R_INVALIDARG;
-
- /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe% */
- sprintf (ddns_address, "%u.%u.%u.%u",
- ddns_addr.iabuf[0], ddns_addr.iabuf[1],
- ddns_addr.iabuf[2], ddns_addr.iabuf[3]);
-
- /*
- * The entity chosen to handle the A record for this client (either the
- * client or the server) SHOULD delete the A record that was added when
- * the lease was made to the client.
- *
- * In order to perform this delete, the updater prepares an UPDATE
- * query which contains two prerequisites. The first prerequisite
- * asserts that the DHCID RR exists whose data is the client identity
- * described in Section 4.3. The second prerequisite asserts that the
- * data in the A RR contains the IP address of the lease that has
- * expired or been released.
- * -- "Interaction between DHCP and DNS"
- */
-
- ISC_LIST_INIT (updqueue);
-
- /*
- * DHCID RR exists, and matches client identity.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID,0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * A RR matches the expiring lease.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = YXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
-
- /*
- * Delete appropriate A RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)ddns_address;
- updrec -> r_size = strlen (ddns_address);
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
-
- /*
- * If the query fails, the updater MUST NOT delete the DNS name. It
- * may be that the host whose lease on the server has expired has moved
- * to another network and obtained a lease from a different server,
- * which has caused the client's A RR to be replaced. It may also be
- * that some other client has been configured with a name that matches
- * the name of the DHCP client, and the policy was that the last client
- * to specify the name would get the name. In this case, the DHCID RR
- * will no longer match the updater's notion of the client-identity of
- * the host pointed to by the DNS name.
- * -- "Interaction between DHCP and DNS"
- */
-
- if (result != ISC_R_SUCCESS) {
- /* If the rrset isn't there, we didn't need to do the
- delete, which is success. */
- if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN)
- result = ISC_R_SUCCESS;
- goto error;
- }
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- /* If the deletion of the A succeeded, and there are no A records
- left for this domain, then we can blow away the DHCID record
- as well. We can't blow away the DHCID record above because
- it's possible that more than one A has been added to this
- domain name. */
- ISC_LIST_INIT (updqueue);
-
- /*
- * A RR does not exist.
- */
- updrec = minires_mkupdrec (S_PREREQ,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_A, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = (unsigned char *)0;
- updrec -> r_size = 0;
- updrec -> r_opcode = NXRRSET;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Delete appropriate DHCID RR.
- */
- updrec = minires_mkupdrec (S_UPDATE,
- (const char *)ddns_fwd_name -> data,
- C_IN, T_DHCID, 0);
- if (!updrec) {
- result = ISC_R_NOMEMORY;
- goto error;
- }
-
- updrec -> r_data = ddns_dhcid -> data;
- updrec -> r_size = ddns_dhcid -> len;
- updrec -> r_opcode = DELETE;
-
- ISC_LIST_APPEND (updqueue, updrec, r_link);
-
- /*
- * Attempt to perform the update.
- */
- result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- print_dns_status ((int)result, &updqueue);
-
- /* Fall through. */
- error:
-
- while (!ISC_LIST_EMPTY (updqueue)) {
- updrec = ISC_LIST_HEAD (updqueue);
- ISC_LIST_UNLINK (updqueue, updrec, r_link);
- minires_freeupdrec (updrec);
- }
-
- return result;
-}
-
-
-#endif /* NSUPDATE */
-
-HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone, dns_zone_hash_t,
- dns_zone_reference, dns_zone_dereference)
diff --git a/contrib/isc-dhcp/common/ethernet.c b/contrib/isc-dhcp/common/ethernet.c
deleted file mode 100644
index dd7af2b..0000000
--- a/contrib/isc-dhcp/common/ethernet.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ethernet.c
-
- Packet assembly code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: ethernet.c,v 1.6.2.3 2004/06/10 17:59:17 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
-#include "includes/netinet/if_ether.h"
-#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
-
-#if defined (PACKET_ASSEMBLY)
-/* Assemble an hardware header... */
-
-void assemble_ethernet_header (interface, buf, bufix, to)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned *bufix;
- struct hardware *to;
-{
- struct isc_ether_header eh;
-
- if (to && to -> hlen == 7) /* XXX */
- memcpy (eh.ether_dhost, &to -> hbuf [1],
- sizeof eh.ether_dhost);
- else
- memset (eh.ether_dhost, 0xff, sizeof (eh.ether_dhost));
- if (interface -> hw_address.hlen - 1 == sizeof (eh.ether_shost))
- memcpy (eh.ether_shost, &interface -> hw_address.hbuf [1],
- sizeof (eh.ether_shost));
- else
- memset (eh.ether_shost, 0x00, sizeof (eh.ether_shost));
-
- eh.ether_type = htons (ETHERTYPE_IP);
-
- memcpy (&buf [*bufix], &eh, ETHER_HEADER_SIZE);
- *bufix += ETHER_HEADER_SIZE;
-}
-#endif /* PACKET_ASSEMBLY */
-
-#ifdef PACKET_DECODING
-/* Decode a hardware header... */
-
-ssize_t decode_ethernet_header (interface, buf, bufix, from)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned bufix;
- struct hardware *from;
-{
- struct isc_ether_header eh;
-
- memcpy (&eh, buf + bufix, ETHER_HEADER_SIZE);
-
-#ifdef USERLAND_FILTER
- if (ntohs (eh.ether_type) != ETHERTYPE_IP)
- return -1;
-#endif
- memcpy (&from -> hbuf [1], eh.ether_shost, sizeof (eh.ether_shost));
- from -> hbuf [0] = ARPHRD_ETHER;
- from -> hlen = (sizeof eh.ether_shost) + 1;
-
- return ETHER_HEADER_SIZE;
-}
-#endif /* PACKET_DECODING */
diff --git a/contrib/isc-dhcp/common/execute.c b/contrib/isc-dhcp/common/execute.c
deleted file mode 100644
index 46b2580..0000000
--- a/contrib/isc-dhcp/common/execute.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/* execute.c
-
- Support for executable statements. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1998-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: execute.c,v 1.44.2.10 2004/06/10 17:59:17 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <omapip/omapip_p.h>
-
-int execute_statements (result, packet, lease, client_state,
- in_options, out_options, scope, statements)
- struct binding_value **result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *out_options;
- struct binding_scope **scope;
- struct executable_statement *statements;
-{
- struct executable_statement *r, *e, *next;
- int rc;
- int status;
- unsigned long num;
- struct binding_scope *outer;
- struct binding *binding;
- struct data_string ds;
- struct binding_scope *ns;
-
- if (!statements)
- return 1;
-
- r = (struct executable_statement *)0;
- next = (struct executable_statement *)0;
- e = (struct executable_statement *)0;
- executable_statement_reference (&r, statements, MDL);
- while (r && !(result && *result)) {
- if (r -> next)
- executable_statement_reference (&next, r -> next, MDL);
- switch (r -> op) {
- case statements_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: statements");
-#endif
- status = execute_statements (result, packet, lease,
- client_state, in_options,
- out_options, scope,
- r -> data.statements);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: statements returns %d", status);
-#endif
- if (!status)
- return 0;
- break;
-
- case on_statement:
- if (lease) {
- if (r -> data.on.evtypes & ON_EXPIRY) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: on expiry");
-#endif
- if (lease -> on_expiry)
- executable_statement_dereference
- (&lease -> on_expiry, MDL);
- if (r -> data.on.statements)
- executable_statement_reference
- (&lease -> on_expiry,
- r -> data.on.statements, MDL);
- }
- if (r -> data.on.evtypes & ON_RELEASE) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: on release");
-#endif
- if (lease -> on_release)
- executable_statement_dereference
- (&lease -> on_release, MDL);
- if (r -> data.on.statements)
- executable_statement_reference
- (&lease -> on_release,
- r -> data.on.statements, MDL);
- }
- if (r -> data.on.evtypes & ON_COMMIT) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: on commit");
-#endif
- if (lease -> on_commit)
- executable_statement_dereference
- (&lease -> on_commit, MDL);
- if (r -> data.on.statements)
- executable_statement_reference
- (&lease -> on_commit,
- r -> data.on.statements, MDL);
- }
- }
- break;
-
- case switch_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: switch");
-#endif
- status = (find_matching_case
- (&e, packet, lease, client_state,
- in_options, out_options, scope,
- r -> data.s_switch.expr,
- r -> data.s_switch.statements));
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: switch: case %lx", (unsigned long)e);
-#endif
- if (status) {
- if (!(execute_statements
- (result, packet, lease, client_state,
- in_options, out_options, scope, e))) {
- executable_statement_dereference
- (&e, MDL);
- return 0;
- }
- executable_statement_dereference (&e, MDL);
- }
- break;
-
- /* These have no effect when executed. */
- case case_statement:
- case default_statement:
- break;
-
- case if_statement:
- status = (evaluate_boolean_expression
- (&rc, packet,
- lease, client_state, in_options,
- out_options, scope, r -> data.ie.expr));
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: if %s", (status
- ? (rc ? "true" : "false")
- : "NULL"));
-#endif
- /* XXX Treat NULL as false */
- if (!status)
- rc = 0;
- if (!execute_statements
- (result, packet, lease, client_state,
- in_options, out_options, scope,
- rc ? r -> data.ie.tc : r -> data.ie.fc))
- return 0;
- break;
-
- case eval_statement:
- status = evaluate_expression
- ((struct binding_value **)0,
- packet, lease, client_state, in_options,
- out_options, scope, r -> data.eval, MDL);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: evaluate: %s",
- (status ? "succeeded" : "failed"));
-#endif
- break;
-
- case return_statement:
- status = evaluate_expression
- (result, packet,
- lease, client_state, in_options,
- out_options, scope, r -> data.retval, MDL);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: return: %s",
- (status ? "succeeded" : "failed"));
-#endif
- break;
-
- case add_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: add %s", (r -> data.add -> name
- ? r -> data.add -> name
- : "<unnamed class>"));
-#endif
- classify (packet, r -> data.add);
- break;
-
- case break_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: break");
-#endif
- return 1;
-
- case supersede_option_statement:
- case send_option_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: %s option %s.%s",
- (r -> op == supersede_option_statement
- ? "supersede" : "send"),
- r -> data.option -> option -> universe -> name,
- r -> data.option -> option -> name);
- goto option_statement;
-#endif
- case default_option_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: default option %s.%s",
- r -> data.option -> option -> universe -> name,
- r -> data.option -> option -> name);
- goto option_statement;
-#endif
- case append_option_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: append option %s.%s",
- r -> data.option -> option -> universe -> name,
- r -> data.option -> option -> name);
- goto option_statement;
-#endif
- case prepend_option_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: prepend option %s.%s",
- r -> data.option -> option -> universe -> name,
- r -> data.option -> option -> name);
- option_statement:
-#endif
- set_option (r -> data.option -> option -> universe,
- out_options, r -> data.option, r -> op);
- break;
-
- case set_statement:
- case define_statement:
- if (!scope) {
- log_error ("set %s: no scope",
- r -> data.set.name);
- status = 0;
- break;
- }
- if (!*scope) {
- if (!binding_scope_allocate (scope, MDL)) {
- log_error ("set %s: can't allocate scope",
- r -> data.set.name);
- status = 0;
- break;
- }
- }
- binding = find_binding (*scope, r -> data.set.name);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: set %s", r -> data.set.name);
-#endif
- if (!binding) {
- binding = dmalloc (sizeof *binding, MDL);
- if (binding) {
- memset (binding, 0, sizeof *binding);
- binding -> name =
- dmalloc (strlen
- (r -> data.set.name) + 1,
- MDL);
- if (binding -> name) {
- strcpy (binding -> name,
- r -> data.set.name);
- binding -> next = (*scope) -> bindings;
- (*scope) -> bindings = binding;
- } else {
- badalloc:
- dfree (binding, MDL);
- binding = (struct binding *)0;
- }
- }
- }
- if (binding) {
- if (binding -> value)
- binding_value_dereference
- (&binding -> value, MDL);
- if (r -> op == set_statement) {
- status = (evaluate_expression
- (&binding -> value, packet,
- lease, client_state,
- in_options, out_options,
- scope, r -> data.set.expr,
- MDL));
- } else {
- if (!(binding_value_allocate
- (&binding -> value, MDL))) {
- dfree (binding, MDL);
- binding = (struct binding *)0;
- }
- if (binding -> value) {
- binding -> value -> type =
- binding_function;
- (fundef_reference
- (&binding -> value -> value.fundef,
- r -> data.set.expr -> data.func,
- MDL));
- }
- }
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: set %s%s", r -> data.set.name,
- (binding && status ? "" : " (failed)"));
-#endif
- break;
-
- case unset_statement:
- if (!scope || !*scope) {
- status = 0;
- break;
- }
- binding = find_binding (*scope, r -> data.unset);
- if (binding) {
- if (binding -> value)
- binding_value_dereference
- (&binding -> value, MDL);
- status = 1;
- } else
- status = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: unset %s: %s", r -> data.unset,
- (status ? "found" : "not found"));
-#endif
- break;
-
- case let_statement:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: let %s", r -> data.let.name);
-#endif
- ns = (struct binding_scope *)0;
- binding_scope_allocate (&ns, MDL);
- e = r;
-
- next_let:
- if (ns) {
- binding = dmalloc (sizeof *binding, MDL);
- memset (binding, 0, sizeof *binding);
- if (!binding) {
- blb:
- binding_scope_dereference (&ns, MDL);
- } else {
- binding -> name =
- dmalloc (strlen
- (e -> data.let.name + 1),
- MDL);
- if (binding -> name)
- strcpy (binding -> name,
- e -> data.let.name);
- else {
- dfree (binding, MDL);
- binding = (struct binding *)0;
- goto blb;
- }
- }
- }
- if (ns && binding) {
- status = (evaluate_expression
- (&binding -> value, packet, lease,
- client_state,
- in_options, out_options,
- scope, e -> data.set.expr, MDL));
- binding -> next = ns -> bindings;
- ns -> bindings = binding;
- }
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: let %s%s", e -> data.let.name,
- (binding && status ? "" : "failed"));
-#endif
- if (!e -> data.let.statements) {
- } else if (e -> data.let.statements -> op ==
- let_statement) {
- e = e -> data.let.statements;
- goto next_let;
- } else if (ns) {
- if (scope && *scope)
- binding_scope_reference (&ns -> outer,
- *scope, MDL);
- execute_statements
- (result, packet, lease,
- client_state,
- in_options, out_options,
- &ns, e -> data.let.statements);
- }
- if (ns)
- binding_scope_dereference (&ns, MDL);
- break;
-
- case log_statement:
- memset (&ds, 0, sizeof ds);
- status = (evaluate_data_expression
- (&ds, packet,
- lease, client_state, in_options,
- out_options, scope, r -> data.log.expr,
- MDL));
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("exec: log");
-#endif
-
- if (status) {
- switch (r -> data.log.priority) {
- case log_priority_fatal:
- log_fatal ("%.*s", (int)ds.len,
- ds.buffer -> data);
- break;
- case log_priority_error:
- log_error ("%.*s", (int)ds.len,
- ds.buffer -> data);
- break;
- case log_priority_debug:
- log_debug ("%.*s", (int)ds.len,
- ds.buffer -> data);
- break;
- case log_priority_info:
- log_info ("%.*s", (int)ds.len,
- ds.buffer -> data);
- break;
- }
- data_string_forget (&ds, MDL);
- }
-
- break;
-
- default:
- log_error ("bogus statement type %d", r -> op);
- break;
- }
- executable_statement_dereference (&r, MDL);
- if (next) {
- executable_statement_reference (&r, next, MDL);
- executable_statement_dereference (&next, MDL);
- }
- }
-
- return 1;
-}
-
-/* Execute all the statements in a particular scope, and all statements in
- scopes outer from that scope, but if a particular limiting scope is
- reached, do not execute statements in that scope or in scopes outer
- from it. More specific scopes need to take precedence over less
- specific scopes, so we recursively traverse the scope list, executing
- the most outer scope first. */
-
-void execute_statements_in_scope (result, packet,
- lease, client_state, in_options, out_options,
- scope, group, limiting_group)
- struct binding_value **result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *out_options;
- struct binding_scope **scope;
- struct group *group;
- struct group *limiting_group;
-{
- struct group *limit;
-
- /* If we've recursed as far as we can, return. */
- if (!group)
- return;
-
- /* As soon as we get to a scope that is outer than the limiting
- scope, we are done. This is so that if somebody does something
- like this, it does the expected thing:
-
- domain-name "fugue.com";
- shared-network FOO {
- host bar {
- domain-name "othello.fugue.com";
- fixed-address 10.20.30.40;
- }
- subnet 10.20.30.0 netmask 255.255.255.0 {
- domain-name "manhattan.fugue.com";
- }
- }
-
- The problem with the above arrangement is that the host's
- group nesting will be host -> shared-network -> top-level,
- and the limiting scope when we evaluate the host's scope
- will be the subnet -> shared-network -> top-level, so we need
- to know when we evaluate the host's scope to stop before we
- evaluate the shared-networks scope, because it's outer than
- the limiting scope, which means we've already evaluated it. */
-
- for (limit = limiting_group; limit; limit = limit -> next) {
- if (group == limit)
- return;
- }
-
- if (group -> next)
- execute_statements_in_scope (result, packet,
- lease, client_state,
- in_options, out_options, scope,
- group -> next, limiting_group);
- execute_statements (result, packet, lease, client_state, in_options,
- out_options, scope, group -> statements);
-}
-
-/* Dereference or free any subexpressions of a statement being freed. */
-
-int executable_statement_dereference (ptr, file, line)
- struct executable_statement **ptr;
- const char *file;
- int line;
-{
- struct executable_statement *bp;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- (*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
- if ((*ptr) -> refcnt > 0) {
- *ptr = (struct executable_statement *)0;
- return 1;
- }
-
- if ((*ptr) -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (*ptr);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if ((*ptr) -> next)
- executable_statement_dereference (&(*ptr) -> next, file, line);
-
- switch ((*ptr) -> op) {
- case statements_statement:
- if ((*ptr) -> data.statements)
- executable_statement_dereference
- (&(*ptr) -> data.statements, file, line);
- break;
-
- case on_statement:
- if ((*ptr) -> data.on.statements)
- executable_statement_dereference
- (&(*ptr) -> data.on.statements, file, line);
- break;
-
- case switch_statement:
- if ((*ptr) -> data.s_switch.statements)
- executable_statement_dereference
- (&(*ptr) -> data.on.statements, file, line);
- if ((*ptr) -> data.s_switch.expr)
- expression_dereference (&(*ptr) -> data.s_switch.expr,
- file, line);
- break;
-
- case case_statement:
- if ((*ptr) -> data.s_switch.expr)
- expression_dereference (&(*ptr) -> data.c_case,
- file, line);
- break;
-
- case if_statement:
- if ((*ptr) -> data.ie.expr)
- expression_dereference (&(*ptr) -> data.ie.expr,
- file, line);
- if ((*ptr) -> data.ie.tc)
- executable_statement_dereference
- (&(*ptr) -> data.ie.tc, file, line);
- if ((*ptr) -> data.ie.fc)
- executable_statement_dereference
- (&(*ptr) -> data.ie.fc, file, line);
- break;
-
- case eval_statement:
- if ((*ptr) -> data.eval)
- expression_dereference (&(*ptr) -> data.eval,
- file, line);
- break;
-
- case return_statement:
- if ((*ptr) -> data.eval)
- expression_dereference (&(*ptr) -> data.eval,
- file, line);
- break;
-
- case set_statement:
- if ((*ptr)->data.set.name)
- dfree ((*ptr)->data.set.name, file, line);
- if ((*ptr)->data.set.expr)
- expression_dereference (&(*ptr) -> data.set.expr,
- file, line);
- break;
-
- case unset_statement:
- if ((*ptr)->data.unset)
- dfree ((*ptr)->data.unset, file, line);
- break;
-
- case supersede_option_statement:
- case send_option_statement:
- case default_option_statement:
- case append_option_statement:
- case prepend_option_statement:
- if ((*ptr) -> data.option)
- option_cache_dereference (&(*ptr) -> data.option,
- file, line);
- break;
-
- default:
- /* Nothing to do. */
- break;
- }
-
- dfree ((*ptr), file, line);
- *ptr = (struct executable_statement *)0;
- return 1;
-}
-
-void write_statements (file, statements, indent)
- FILE *file;
- struct executable_statement *statements;
- int indent;
-{
- struct executable_statement *r, *x;
- int result;
- int status;
- const char *s, *t, *dot;
- int col;
-
- if (!statements)
- return;
-
- for (r = statements; r; r = r -> next) {
- switch (r -> op) {
- case statements_statement:
- write_statements (file, r -> data.statements, indent);
- break;
-
- case on_statement:
- indent_spaces (file, indent);
- fprintf (file, "on ");
- s = "";
- if (r -> data.on.evtypes & ON_EXPIRY) {
- fprintf (file, "%sexpiry", s);
- s = " or ";
- }
- if (r -> data.on.evtypes & ON_COMMIT) {
- fprintf (file, "%scommit", s);
- s = "or";
- }
- if (r -> data.on.evtypes & ON_RELEASE) {
- fprintf (file, "%srelease", s);
- s = "or";
- }
- if (r -> data.on.statements) {
- fprintf (file, " {");
- write_statements (file,
- r -> data.on.statements,
- indent + 2);
- indent_spaces (file, indent);
- fprintf (file, "}");
- } else {
- fprintf (file, ";");
- }
- break;
-
- case switch_statement:
- indent_spaces (file, indent);
- fprintf (file, "switch (");
- col = write_expression (file,
- r -> data.s_switch.expr,
- indent + 7, indent + 7, 1);
- col = token_print_indent (file, col, indent + 7,
- "", "", ")");
- token_print_indent (file,
- col, indent, " ", "", "{");
- write_statements (file, r -> data.s_switch.statements,
- indent + 2);
- indent_spaces (file, indent);
- fprintf (file, "}");
- break;
-
- case case_statement:
- indent_spaces (file, indent - 1);
- fprintf (file, "case ");
- col = write_expression (file,
- r -> data.s_switch.expr,
- indent + 5, indent + 5, 1);
- token_print_indent (file, col, indent + 5,
- "", "", ":");
- break;
-
- case default_statement:
- indent_spaces (file, indent - 1);
- fprintf (file, "default: ");
- break;
-
- case if_statement:
- indent_spaces (file, indent);
- fprintf (file, "if ");
- x = r;
- col = write_expression (file,
- x -> data.ie.expr,
- indent + 3, indent + 3, 1);
- else_if:
- token_print_indent (file, col, indent, " ", "", "{");
- write_statements (file, x -> data.ie.tc, indent + 2);
- if (x -> data.ie.fc &&
- x -> data.ie.fc -> op == if_statement &&
- !x -> data.ie.fc -> next) {
- indent_spaces (file, indent);
- fprintf (file, "} elsif ");
- x = x -> data.ie.fc;
- col = write_expression (file,
- x -> data.ie.expr,
- indent + 6,
- indent + 6, 1);
- goto else_if;
- }
- if (x -> data.ie.fc) {
- indent_spaces (file, indent);
- fprintf (file, "} else {");
- write_statements (file, x -> data.ie.fc,
- indent + 2);
- }
- indent_spaces (file, indent);
- fprintf (file, "}");
- break;
-
- case eval_statement:
- indent_spaces (file, indent);
- fprintf (file, "eval ");
- col = write_expression (file, r -> data.eval,
- indent + 5, indent + 5, 1);
- fprintf (file, ";");
- break;
-
- case return_statement:
- indent_spaces (file, indent);
- fprintf (file, "return;");
- break;
-
- case add_statement:
- indent_spaces (file, indent);
- fprintf (file, "add \"%s\"", r -> data.add -> name);
- break;
-
- case break_statement:
- indent_spaces (file, indent);
- fprintf (file, "break;");
- break;
-
- case supersede_option_statement:
- case send_option_statement:
- s = "supersede";
- goto option_statement;
-
- case default_option_statement:
- s = "default";
- goto option_statement;
-
- case append_option_statement:
- s = "append";
- goto option_statement;
-
- case prepend_option_statement:
- s = "prepend";
- option_statement:
- /* Note: the reason we don't try to pretty print
- the option here is that the format of the option
- may change in dhcpd.conf, and then when this
- statement was read back, it would cause a syntax
- error. */
- if (r -> data.option -> option -> universe ==
- &dhcp_universe) {
- t = "";
- dot = "";
- } else {
- t = (r -> data.option -> option ->
- universe -> name);
- dot = ".";
- }
- indent_spaces (file, indent);
- fprintf (file, "%s %s%s%s = ", s, t, dot,
- r -> data.option -> option -> name);
- col = (indent + strlen (s) + strlen (t) +
- strlen (dot) + strlen (r -> data.option ->
- option -> name) + 4);
- if (r -> data.option -> expression)
- write_expression
- (file,
- r -> data.option -> expression,
- col, indent + 8, 1);
- else
- token_indent_data_string
- (file, col, indent + 8, "", "",
- &r -> data.option -> data);
-
- fprintf (file, ";"); /* XXX */
- break;
-
- case set_statement:
- indent_spaces (file, indent);
- fprintf (file, "set ");
- col = token_print_indent (file, indent + 4, indent + 4,
- "", "", r -> data.set.name);
- col = token_print_indent (file, col, indent + 4,
- " ", " ", "=");
- col = write_expression (file, r -> data.set.expr,
- indent + 3, indent + 3, 0);
- col = token_print_indent (file, col, indent + 4,
- " ", "", ";");
- break;
-
- case unset_statement:
- indent_spaces (file, indent);
- fprintf (file, "unset ");
- col = token_print_indent (file, indent + 6, indent + 6,
- "", "", r -> data.set.name);
- col = token_print_indent (file, col, indent + 6,
- " ", "", ";");
- break;
-
- case log_statement:
- indent_spaces (file, indent);
- fprintf (file, "log ");
- col = token_print_indent (file, col, indent + 4,
- "", "", "(");
- switch (r -> data.log.priority) {
- case log_priority_fatal:
- col = token_print_indent
- (file, col, indent + 4, "",
- " ", "fatal,");
- break;
- case log_priority_error:
- col = token_print_indent
- (file, col, indent + 4, "",
- " ", "error,");
- break;
- case log_priority_debug:
- col = token_print_indent
- (file, col, indent + 4, "",
- " ", "debug,");
- break;
- case log_priority_info:
- col = token_print_indent
- (file, col, indent + 4, "",
- " ", "info,");
- break;
- }
- col = write_expression (file, r -> data.log.expr,
- indent + 4, indent + 4, 0);
- col = token_print_indent (file, col, indent + 4,
- "", "", ");");
-
- break;
-
- default:
- log_fatal ("bogus statement type %d\n", r -> op);
- }
- }
-}
-
-/* Find a case statement in the sequence of executable statements that
- matches the expression, and if found, return the following statement.
- If no case statement matches, try to find a default statement and
- return that (the default statement can precede all the case statements).
- Otherwise, return the null statement. */
-
-int find_matching_case (struct executable_statement **ep,
- struct packet *packet, struct lease *lease,
- struct client_state *client_state,
- struct option_state *in_options,
- struct option_state *out_options,
- struct binding_scope **scope,
- struct expression *expr,
- struct executable_statement *stmt)
-{
- int status, sub;
- struct executable_statement *s;
- unsigned long foo;
-
- if (is_data_expression (expr)) {
- struct executable_statement *e;
- struct data_string cd, ds;
- memset (&ds, 0, sizeof ds);
- memset (&cd, 0, sizeof cd);
-
- status = (evaluate_data_expression (&ds, packet, lease,
- client_state, in_options,
- out_options, scope, expr,
- MDL));
- if (status) {
- for (s = stmt; s; s = s -> next) {
- if (s -> op == case_statement) {
- sub = (evaluate_data_expression
- (&cd, packet, lease, client_state,
- in_options, out_options,
- scope, s -> data.c_case, MDL));
- if (sub && cd.len == ds.len &&
- !memcmp (cd.data, ds.data, cd.len))
- {
- data_string_forget (&cd, MDL);
- data_string_forget (&ds, MDL);
- executable_statement_reference
- (ep, s -> next, MDL);
- return 1;
- }
- data_string_forget (&cd, MDL);
- }
- }
- data_string_forget (&ds, MDL);
- }
- } else {
- unsigned long n, c;
- status = evaluate_numeric_expression (&n, packet, lease,
- client_state,
- in_options, out_options,
- scope, expr);
-
- if (status) {
- for (s = stmt; s; s = s -> next) {
- if (s -> op == case_statement) {
- sub = (evaluate_numeric_expression
- (&c, packet, lease, client_state,
- in_options, out_options,
- scope, s -> data.c_case));
- if (sub && n == c) {
- executable_statement_reference
- (ep, s -> next, MDL);
- return 1;
- }
- }
- }
- }
- }
-
- /* If we didn't find a matching case statement, look for a default
- statement and return the statement following it. */
- for (s = stmt; s; s = s -> next)
- if (s -> op == default_statement)
- break;
- if (s) {
- executable_statement_reference (ep, s -> next, MDL);
- return 1;
- }
- return 0;
-}
-
-int executable_statement_foreach (struct executable_statement *stmt,
- int (*callback) (struct
- executable_statement *,
- void *, int),
- void *vp, int condp)
-{
- struct executable_statement *foo;
- int ok = 0;
- int result;
-
- for (foo = stmt; foo; foo = foo -> next) {
- if ((*callback) (foo, vp, condp) != 0)
- ok = 1;
- switch (foo -> op) {
- case null_statement:
- break;
- case if_statement:
- if (executable_statement_foreach (foo -> data.ie.tc,
- callback, vp, 1))
- ok = 1;
- if (executable_statement_foreach (foo -> data.ie.fc,
- callback, vp, 1))
- ok = 1;
- break;
- case add_statement:
- break;
- case eval_statement:
- break;
- case break_statement:
- break;
- case default_option_statement:
- break;
- case supersede_option_statement:
- break;
- case append_option_statement:
- break;
- case prepend_option_statement:
- break;
- case send_option_statement:
- break;
- case statements_statement:
- if ((executable_statement_foreach
- (foo -> data.statements, callback, vp, condp)))
- ok = 1;
- break;
- case on_statement:
- if ((executable_statement_foreach
- (foo -> data.on.statements, callback, vp, 1)))
- ok = 1;
- break;
- case switch_statement:
- if ((executable_statement_foreach
- (foo -> data.s_switch.statements, callback, vp, 1)))
- ok = 1;
- break;
- case case_statement:
- break;
- case default_statement:
- break;
- case set_statement:
- break;
- case unset_statement:
- break;
- case let_statement:
- if ((executable_statement_foreach
- (foo -> data.let.statements, callback, vp, 0)))
- ok = 1;
- break;
- case define_statement:
- break;
- case log_statement:
- case return_statement:
- break;
- }
- }
- return ok;
-}
diff --git a/contrib/isc-dhcp/common/fddi.c b/contrib/isc-dhcp/common/fddi.c
deleted file mode 100644
index 9fdbb94..0000000
--- a/contrib/isc-dhcp/common/fddi.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* fddi.c
-
- Packet assembly code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: fddi.c,v 1.3.2.2 2004/06/10 17:59:18 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (DEC_FDDI)
-#include <netinet/if_fddi.h>
-#include <net/if_llc.h>
-
-#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
-#include "includes/netinet/if_ether.h"
-#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
-
-#if defined (PACKET_ASSEMBLY)
-/* Assemble an hardware header... */
-
-void assemble_fddi_header (interface, buf, bufix, to)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned *bufix;
- struct hardware *to;
-{
- struct fddi_header fh;
- struct llc lh;
-
- if (to && to -> hlen == 7)
- memcpy (fh.fddi_dhost, &to -> hbuf [1],
- sizeof (fh.fddi_dhost));
- memcpy (fh.fddi_shost,
- &interface -> hw_address.hbuf [1], sizeof (fh.fddi_shost));
- fh.fddi_fc = FDDIFC_LLC_ASYNC;
- memcpy (&buf [*bufix], &fh, sizeof fh);
- *bufix += sizeof fh;
-
- lh.llc_dsap = LLC_SNAP_LSAP;
- lh.llc_ssap = LLC_SNAP_LSAP;
- lh.llc_un.type_snap.control = LLC_UI;
- lh.llc_un.type_snap.ether_type = htons (ETHERTYPE_IP);
- memcpy (&buf [*bufix], &lh, LLC_SNAP_LEN);
- *bufix += LLC_SNAP_LEN;
-}
-#endif /* PACKET_ASSEMBLY */
-
-#ifdef PACKET_DECODING
-/* Decode a hardware header... */
-
-ssize_t decode_fddi_header (interface, buf, bufix, from)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned bufix;
- struct hardware *from;
-{
- struct fddi_header fh;
- struct llc lh;
-
- from -> hbuf [0] = HTYPE_FDDI;
- memcpy (&from -> hbuf [1], fh.fddi_shost, sizeof fh.fddi_shost);
- return FDDI_HEADER_SIZE + LLC_SNAP_LEN;
-}
-#endif /* PACKET_DECODING */
-#endif /* DEC_FDDI */
diff --git a/contrib/isc-dhcp/common/icmp.c b/contrib/isc-dhcp/common/icmp.c
deleted file mode 100644
index 8ef2283..0000000
--- a/contrib/isc-dhcp/common/icmp.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* dhcp.c
-
- ICMP Protocol engine - for sending out pings and receiving
- responses. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: icmp.c,v 1.30.2.6 2004/06/10 17:59:18 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "netinet/ip.h"
-#include "netinet/ip_icmp.h"
-
-struct icmp_state *icmp_state;
-static omapi_object_type_t *dhcp_type_icmp;
-static int no_icmp;
-
-OMAPI_OBJECT_ALLOC (icmp_state, struct icmp_state, dhcp_type_icmp)
-
-#if defined (TRACING)
-trace_type_t *trace_icmp_input;
-trace_type_t *trace_icmp_output;
-#endif
-
-/* Initialize the ICMP protocol. */
-
-void icmp_startup (routep, handler)
- int routep;
- void (*handler) PROTO ((struct iaddr, u_int8_t *, int));
-{
- struct protoent *proto;
- int protocol = 1;
- struct sockaddr_in from;
- int fd;
- int state;
- struct icmp_state *new;
- omapi_object_t *h;
- isc_result_t result;
-
- /* Only initialize icmp once. */
- if (dhcp_type_icmp)
- log_fatal ("attempted to reinitialize icmp protocol");
-
- result = omapi_object_type_register (&dhcp_type_icmp, "icmp",
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- sizeof (struct icmp_state),
- 0, RC_MISC);
-
- if (result != ISC_R_SUCCESS)
- log_fatal ("Can't register icmp object type: %s",
- isc_result_totext (result));
-
- icmp_state_allocate (&icmp_state, MDL);
- icmp_state -> icmp_handler = handler;
-
-#if defined (TRACING)
- trace_icmp_input = trace_type_register ("icmp-input", (void *)0,
- trace_icmp_input_input,
- trace_icmp_input_stop, MDL);
- trace_icmp_output = trace_type_register ("icmp-output", (void *)0,
- trace_icmp_output_input,
- trace_icmp_output_stop, MDL);
-
- /* If we're playing back a trace file, don't create the socket
- or set up the callback. */
- if (!trace_playback ()) {
-#endif
- /* Get the protocol number (should be 1). */
- proto = getprotobyname ("icmp");
- if (proto)
- protocol = proto -> p_proto;
-
- /* Get a raw socket for the ICMP protocol. */
- icmp_state -> socket = socket (AF_INET, SOCK_RAW, protocol);
- if (icmp_state -> socket < 0) {
- no_icmp = 1;
- log_error ("unable to create icmp socket: %m");
- return;
- }
-
-#if defined (HAVE_SETFD)
- if (fcntl (icmp_state -> socket, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on icmp: %m");
-#endif
-
- /* Make sure it does routing... */
- state = 0;
- if (setsockopt (icmp_state -> socket, SOL_SOCKET, SO_DONTROUTE,
- (char *)&state, sizeof state) < 0)
- log_fatal ("Can't disable SO_DONTROUTE on ICMP: %m");
-
- result = (omapi_register_io_object
- ((omapi_object_t *)icmp_state,
- icmp_readsocket, 0, icmp_echoreply, 0, 0));
- if (result != ISC_R_SUCCESS)
- log_fatal ("Can't register icmp handle: %s",
- isc_result_totext (result));
-#if defined (TRACING)
- }
-#endif
-}
-
-int icmp_readsocket (h)
- omapi_object_t *h;
-{
- struct icmp_state *state;
-
- state = (struct icmp_state *)h;
- return state -> socket;
-}
-
-int icmp_echorequest (addr)
- struct iaddr *addr;
-{
- struct sockaddr_in to;
- struct icmp icmp;
- int status;
-#if defined (TRACING)
- trace_iov_t iov [2];
-#endif
-
- if (no_icmp)
- return 1;
- if (!icmp_state)
- log_fatal ("ICMP protocol used before initialization.");
-
- memset (&to, 0, sizeof(to));
-#ifdef HAVE_SA_LEN
- to.sin_len = sizeof to;
-#endif
- to.sin_family = AF_INET;
- to.sin_port = 0; /* unused. */
- memcpy (&to.sin_addr, addr -> iabuf, sizeof to.sin_addr); /* XXX */
-
- icmp.icmp_type = ICMP_ECHO;
- icmp.icmp_code = 0;
- icmp.icmp_cksum = 0;
- icmp.icmp_seq = 0;
-#ifdef PTRSIZE_64BIT
- icmp.icmp_id = (((u_int32_t)(u_int64_t)addr) ^
- (u_int32_t)(((u_int64_t)addr) >> 32));
-#else
- icmp.icmp_id = (u_int32_t)addr;
-#endif
- memset (&icmp.icmp_dun, 0, sizeof icmp.icmp_dun);
-
- icmp.icmp_cksum = wrapsum (checksum ((unsigned char *)&icmp,
- sizeof icmp, 0));
-
-#if defined (TRACING)
- if (trace_playback ()) {
- char *buf = (char *)0;
- unsigned buflen = 0;
-
- /* Consume the ICMP event. */
- status = trace_get_packet (&trace_icmp_output, &buflen, &buf);
- if (status != ISC_R_SUCCESS)
- log_error ("icmp_echorequest: %s",
- isc_result_totext (status));
- if (buf)
- dfree (buf, MDL);
- } else {
- if (trace_record ()) {
- iov [0].buf = (char *)addr;
- iov [0].len = sizeof *addr;
- iov [1].buf = (char *)&icmp;
- iov [1].len = sizeof icmp;
- trace_write_packet_iov (trace_icmp_output,
- 2, iov, MDL);
- }
-#endif
- /* Send the ICMP packet... */
- status = sendto (icmp_state -> socket,
- (char *)&icmp, sizeof icmp, 0,
- (struct sockaddr *)&to, sizeof to);
- if (status < 0)
- log_error ("icmp_echorequest %s: %m",
- inet_ntoa(to.sin_addr));
-
- if (status != sizeof icmp)
- return 0;
-#if defined (TRACING)
- }
-#endif
- return 1;
-}
-
-isc_result_t icmp_echoreply (h)
- omapi_object_t *h;
-{
- struct icmp *icfrom;
- struct ip *ip;
- struct sockaddr_in from;
- u_int8_t icbuf [1500];
- int status;
- SOCKLEN_T sl;
- int hlen, len;
- struct iaddr ia;
- struct icmp_state *state;
-#if defined (TRACING)
- trace_iov_t iov [2];
-#endif
-
- state = (struct icmp_state *)h;
-
- sl = sizeof from;
- status = recvfrom (state -> socket, (char *)icbuf, sizeof icbuf, 0,
- (struct sockaddr *)&from, &sl);
- if (status < 0) {
- log_error ("icmp_echoreply: %m");
- return ISC_R_UNEXPECTED;
- }
-
- /* Find the IP header length... */
- ip = (struct ip *)icbuf;
- hlen = IP_HL (ip);
-
- /* Short packet? */
- if (status < hlen + (sizeof *icfrom)) {
- return ISC_R_SUCCESS;
- }
-
- len = status - hlen;
- icfrom = (struct icmp *)(icbuf + hlen);
-
- /* Silently discard ICMP packets that aren't echoreplies. */
- if (icfrom -> icmp_type != ICMP_ECHOREPLY) {
- return ISC_R_SUCCESS;
- }
-
- /* If we were given a second-stage handler, call it. */
- if (state -> icmp_handler) {
- memcpy (ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
- ia.len = sizeof from.sin_addr;
-
-#if defined (TRACING)
- if (trace_record ()) {
- ia.len = htonl(ia.len);
- iov [0].buf = (char *)&ia;
- iov [0].len = sizeof ia;
- iov [1].buf = (char *)icbuf;
- iov [1].len = len;
- trace_write_packet_iov (trace_icmp_input, 2, iov, MDL);
- ia.len = ntohl(ia.len);
- }
-#endif
- (*state -> icmp_handler) (ia, icbuf, len);
- }
- return ISC_R_SUCCESS;
-}
-
-#if defined (TRACING)
-void trace_icmp_input_input (trace_type_t *ttype, unsigned length, char *buf)
-{
- struct iaddr *ia;
- unsigned len;
- u_int8_t *icbuf;
- ia = (struct iaddr *)buf;
- ia->len = ntohl(ia->len);
- icbuf = (u_int8_t *)(ia + 1);
- if (icmp_state -> icmp_handler)
- (*icmp_state -> icmp_handler) (*ia, icbuf,
- (int)(length - sizeof ia));
-}
-
-void trace_icmp_input_stop (trace_type_t *ttype) { }
-
-void trace_icmp_output_input (trace_type_t *ttype, unsigned length, char *buf)
-{
- struct icmp *icmp;
- struct iaddr ia;
-
- if (length != (sizeof (*icmp) + (sizeof ia))) {
- log_error ("trace_icmp_output_input: data size mismatch %d:%d",
- length, (int)((sizeof (*icmp)) + (sizeof ia)));
- return;
- }
- ia.len = 4;
- memcpy (ia.iabuf, buf, 4);
- icmp = (struct icmp *)(buf + 1);
-
- log_error ("trace_icmp_output_input: unsent ping to %s", piaddr (ia));
-}
-
-void trace_icmp_output_stop (trace_type_t *ttype) { }
-#endif /* TRACING */
diff --git a/contrib/isc-dhcp/common/inet.c b/contrib/isc-dhcp/common/inet.c
deleted file mode 100644
index 53f5869..0000000
--- a/contrib/isc-dhcp/common/inet.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* inet.c
-
- Subroutines to manipulate internet addresses in a safely portable
- way... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: inet.c,v 1.8.2.5 2004/06/10 17:59:18 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#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;
-}
-
-/* Given a subnet number and netmask, return the address on that subnet
- for which the host portion of the address is all ones (the standard
- broadcast address). */
-
-struct iaddr broadcast_addr (subnet, mask)
- struct iaddr subnet;
- struct iaddr mask;
-{
- int i, j, k;
- struct iaddr rv;
-
- if (subnet.len != mask.len) {
- rv.len = 0;
- return rv;
- }
-
- for (i = 0; i < subnet.len; i++) {
- rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
- }
- rv.len = subnet.len;
-
- 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;
-}
-
-char *piaddr1 (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;
-}
-
-char *piaddrmask (struct iaddr addr, struct iaddr mask,
- const char *file, int line)
-{
- char *s, *t;
- int i, mw;
- unsigned len;
-
- for (i = 0; i < 32; i++) {
- if (!mask.iabuf [3 - i / 8])
- i += 7;
- else if (mask.iabuf [3 - i / 8] & (1 << (i % 8)))
- break;
- }
- mw = 32 - i;
- len = mw > 9 ? 2 : 1;
- len += 4; /* three dots and a slash. */
- for (i = 0; i < (mw / 8) + 1; i++) {
- if (addr.iabuf [i] > 99)
- len += 3;
- else if (addr.iabuf [i] > 9)
- len += 2;
- else
- len++;
- }
- s = dmalloc (len + 1, file, line);
- if (!s)
- return s;
- t = s;
- sprintf (t, "%d", addr.iabuf [0]);
- t += strlen (t);
- for (i = 1; i < (mw / 8) + 1; i++) {
- sprintf (t, ".%d", addr.iabuf [i]);
- t += strlen (t);
- }
- *t++ = '/';
- sprintf (t, "%d", mw);
- return s;
-}
-
diff --git a/contrib/isc-dhcp/common/iscprint.c b/contrib/isc-dhcp/common/iscprint.c
deleted file mode 100644
index d26896e..0000000
--- a/contrib/isc-dhcp/common/iscprint.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: iscprint.c,v 1.1.2.1 2004/06/14 21:09:22 dhankins Exp $ */
-
-#include "dhcpd.h"
-
-#ifdef NO_SNPRINTF
-
-#ifndef LINT
-static char copyright[] =
-"$Id: iscprint.c,v 1.1.2.1 2004/06/14 21:09:22 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium, Inc. All rights reserved.";
-#endif
-
-#define INSIST(cond) REQUIRE(cond)
-#define REQUIRE(cond) if (!(cond)) { return 0; }
-
-/*
- * Return length of string that would have been written if not truncated.
- */
-
-int
-isc_print_snprintf(char *str, size_t size, const char *format, ...) {
- va_list ap;
- int ret;
-
- va_start(ap, format);
- ret = vsnprintf(str, size, format, ap);
- va_end(ap);
- return (ret);
-}
-
-/*
- * Return length of string that would have been written if not truncated.
- */
-
-int
-isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
- int h;
- int l;
- int q;
- int alt;
- int zero;
- int left;
- int plus;
- int space;
- int neg;
- isc_int64_t tmpi;
- isc_uint64_t tmpui;
- unsigned long width;
- unsigned long precision;
- unsigned int length;
- char buf[1024];
- char c;
- void *v;
- char *save = str;
- const char *cp;
- const char *head;
- int count = 0;
- int pad;
- int zeropad;
- int dot;
- double dbl;
-#ifdef HAVE_LONG_DOUBLE
- long double ldbl;
-#endif
- char fmt[32];
-
- INSIST(str != NULL);
- INSIST(format != NULL);
-
- while (*format != '\0') {
- if (*format != '%') {
- if (size > 1) {
- *str++ = *format;
- size--;
- }
- count++;
- format++;
- continue;
- }
- format++;
-
- /*
- * Reset flags.
- */
- dot = neg = space = plus = left = zero = alt = h = l = q = 0;
- width = precision = 0;
- head = "";
- length = pad = zeropad = 0;
-
- do {
- if (*format == '#') {
- alt = 1;
- format++;
- } else if (*format == '-') {
- left = 1;
- zero = 0;
- format++;
- } else if (*format == ' ') {
- if (!plus)
- space = 1;
- format++;
- } else if (*format == '+') {
- plus = 1;
- space = 0;
- format++;
- } else if (*format == '0') {
- if (!left)
- zero = 1;
- format++;
- } else
- break;
- } while (1);
-
- /*
- * Width.
- */
- if (*format == '*') {
- width = va_arg(ap, int);
- format++;
- } else if (isdigit((unsigned char)*format)) {
- char *e;
- width = strtoul(format, &e, 10);
- format = e;
- }
-
- /*
- * Precision.
- */
- if (*format == '.') {
- format++;
- dot = 1;
- if (*format == '*') {
- precision = va_arg(ap, int);
- format++;
- } else if (isdigit((unsigned char)*format)) {
- char *e;
- precision = strtoul(format, &e, 10);
- format = e;
- }
- }
-
- switch (*format) {
- case '\0':
- continue;
- case '%':
- if (size > 1) {
- *str++ = *format;
- size--;
- }
- count++;
- break;
- case 'q':
- q = 1;
- format++;
- goto doint;
- case 'h':
- h = 1;
- format++;
- goto doint;
- case 'l':
- l = 1;
- format++;
- if (*format == 'l') {
- q = 1;
- format++;
- }
- goto doint;
- case 'n':
- case 'i':
- case 'd':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- doint:
- if (precision != 0)
- zero = 0;
- switch (*format) {
- case 'n':
- if (h) {
- short int *p;
- p = va_arg(ap, short *);
- REQUIRE(p != NULL);
- *p = str - save;
- } else if (l) {
- long int *p;
- p = va_arg(ap, long *);
- REQUIRE(p != NULL);
- *p = str - save;
- } else {
- int *p;
- p = va_arg(ap, int *);
- REQUIRE(p != NULL);
- *p = str - save;
- }
- break;
- case 'i':
- case 'd':
- if (q)
- tmpi = va_arg(ap, isc_int64_t);
- else if (l)
- tmpi = va_arg(ap, long int);
- else
- tmpi = va_arg(ap, int);
- if (tmpi < 0) {
- head = "-";
- tmpui = -tmpi;
- } else {
- if (plus)
- head = "+";
- else if (space)
- head = " ";
- else
- head = "";
- tmpui = tmpi;
- }
- sprintf(buf, "%u", tmpui);
- goto printint;
- case 'o':
- if (q)
- tmpui = va_arg(ap, isc_uint64_t);
- else if (l)
- tmpui = va_arg(ap, long int);
- else
- tmpui = va_arg(ap, int);
- sprintf(buf, alt ? "%#o"
- : "%o", tmpui);
- goto printint;
- case 'u':
- if (q)
- tmpui = va_arg(ap, isc_uint64_t);
- else if (l)
- tmpui = va_arg(ap, unsigned long int);
- else
- tmpui = va_arg(ap, unsigned int);
- sprintf(buf, "%u", tmpui);
- goto printint;
- case 'x':
- if (q)
- tmpui = va_arg(ap, isc_uint64_t);
- else if (l)
- tmpui = va_arg(ap, unsigned long int);
- else
- tmpui = va_arg(ap, unsigned int);
- if (alt) {
- head = "0x";
- if (precision > 2)
- precision -= 2;
- }
- sprintf(buf, "%x", tmpui);
- goto printint;
- case 'X':
- if (q)
- tmpui = va_arg(ap, isc_uint64_t);
- else if (l)
- tmpui = va_arg(ap, unsigned long int);
- else
- tmpui = va_arg(ap, unsigned int);
- if (alt) {
- head = "0X";
- if (precision > 2)
- precision -= 2;
- }
- sprintf(buf, "%X", tmpui);
- goto printint;
- printint:
- if (precision != 0 || width != 0) {
- length = strlen(buf);
- if (length < precision)
- zeropad = precision - length;
- else if (length < width && zero)
- zeropad = width - length;
- if (width != 0) {
- pad = width - length -
- zeropad - strlen(head);
- if (pad < 0)
- pad = 0;
- }
- }
- count += strlen(head) + strlen(buf) + pad +
- zeropad;
- if (!left) {
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- }
- cp = head;
- while (*cp != '\0' && size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (zeropad > 0 && size > 1) {
- *str++ = '0';
- size--;
- zeropad--;
- }
- cp = buf;
- while (*cp != '\0' && size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- break;
- default:
- break;
- }
- break;
- case 's':
- cp = va_arg(ap, char *);
- REQUIRE(cp != NULL);
-
- if (precision != 0) {
- /*
- * cp need not be NULL terminated.
- */
- const char *tp;
- unsigned long n;
-
- n = precision;
- tp = cp;
- while (n != 0 && *tp != '\0')
- n--, tp++;
- length = precision - n;
- } else {
- length = strlen(cp);
- }
- if (width != 0) {
- pad = width - length;
- if (pad < 0)
- pad = 0;
- }
- count += pad + length;
- if (!left)
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- if (precision != 0)
- while (precision > 0 && *cp != '\0' &&
- size > 1) {
- *str++ = *cp++;
- size--;
- precision--;
- }
- else
- while (*cp != '\0' && size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- break;
- case 'c':
- c = va_arg(ap, int);
- if (width > 0) {
- count += width;
- width--;
- if (left) {
- *str++ = c;
- size--;
- }
- while (width-- > 0 && size > 1) {
- *str++ = ' ';
- size--;
- }
- if (!left && size > 1) {
- *str++ = c;
- size--;
- }
- } else {
- count++;
- if (size > 1) {
- *str++ = c;
- size--;
- }
- }
- break;
- case 'p':
- v = va_arg(ap, void *);
- sprintf(buf, "%p", v);
- length = strlen(buf);
- if (precision > length)
- zeropad = precision - length;
- if (width > 0) {
- pad = width - length - zeropad;
- if (pad < 0)
- pad = 0;
- }
- count += length + pad + zeropad;
- if (!left)
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- cp = buf;
- if (zeropad > 0 && buf[0] == '0' &&
- (buf[1] == 'x' || buf[1] == 'X')) {
- if (size > 1) {
- *str++ = *cp++;
- size--;
- }
- if (size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (zeropad > 0 && size > 1) {
- *str++ = '0';
- size--;
- zeropad--;
- }
- }
- while (*cp != '\0' && size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- break;
- case 'D': /*deprecated*/
- INSIST("use %ld instead of %D" == NULL);
- case 'O': /*deprecated*/
- INSIST("use %lo instead of %O" == NULL);
- case 'U': /*deprecated*/
- INSIST("use %lu instead of %U" == NULL);
-
- case 'L':
-#ifdef HAVE_LONG_DOUBLE
- l = 1;
-#else
- INSIST("long doubles are not supported" == NULL);
-#endif
- /*FALLTHROUGH*/
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- if (!dot)
- precision = 6;
- /*
- * IEEE floating point.
- * MIN 2.2250738585072014E-308
- * MAX 1.7976931348623157E+308
- * VAX floating point has a smaller range than IEEE.
- *
- * precisions > 324 don't make much sense.
- * if we cap the precision at 512 we will not
- * overflow buf.
- */
- if (precision > 512)
- precision = 512;
- sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "",
- plus ? "+" : space ? " " : "",
- precision, l ? "L" : "", *format);
- switch (*format) {
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
-#ifdef HAVE_LONG_DOUBLE
- if (l) {
- ldbl = va_arg(ap, long double);
- sprintf(buf, fmt, ldbl);
- } else
-#endif
- {
- dbl = va_arg(ap, double);
- sprintf(buf, fmt, dbl);
- }
- length = strlen(buf);
- if (width > 0) {
- pad = width - length;
- if (pad < 0)
- pad = 0;
- }
- count += length + pad;
- if (!left)
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- cp = buf;
- while (*cp != ' ' && size > 1) {
- *str++ = *cp++;
- size--;
- }
- while (pad > 0 && size > 1) {
- *str++ = ' ';
- size--;
- pad--;
- }
- break;
- default:
- continue;
- }
- break;
- default:
- continue;
- }
- format++;
- }
- if (size > 0)
- *str = '\0';
- return (count);
-}
-
-#endif
diff --git a/contrib/isc-dhcp/common/lpf.c b/contrib/isc-dhcp/common/lpf.c
deleted file mode 100644
index 87ba8fe..0000000
--- a/contrib/isc-dhcp/common/lpf.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* lpf.c
-
- Linux packet filter code, contributed by Brian Murrel at Interlinx
- Support Services in Vancouver, B.C. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: lpf.c,v 1.29.2.2 2004/06/10 17:59:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <asm/types.h>
-#include <linux/filter.h>
-#include <linux/if_ether.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_LPF_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_LPF_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_lpf (info)
- struct interface_info *info;
-{
- int sock;
- char filename[50];
- int b;
- struct sockaddr sa;
-
- /* Make an LPF socket. */
- if ((sock = socket(PF_PACKET, SOCK_PACKET,
- htons((short)ETH_P_ALL))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
- log_error ("socket: %m - make sure");
- log_error ("CONFIG_PACKET (Packet socket) %s",
- "and CONFIG_FILTER");
- log_error ("(Socket Filtering) are enabled %s",
- "in your kernel");
- log_fatal ("configuration!");
- }
- log_fatal ("Open a socket for LPF: %m");
- }
-
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
- sa.sa_family = AF_PACKET;
- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);
- if (bind (sock, &sa, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
- log_error ("socket: %m - make sure");
- log_error ("CONFIG_PACKET (Packet socket) %s",
- "and CONFIG_FILTER");
- log_error ("(Socket Filtering) are enabled %s",
- "in your kernel");
- log_fatal ("configuration!");
- }
- log_fatal ("Bind socket to interface: %m");
- }
-
- return sock;
-}
-#endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
-
-#ifdef USE_LPF_SEND
-void if_register_send (info)
- struct interface_info *info;
-{
- /* If we're using the lpf API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_LPF_RECEIVE
- info -> wfdesc = if_register_lpf (info);
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- log_info ("Sending on LPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_send (info)
- struct interface_info *info;
-{
- /* don't need to close twice if we are using lpf for sending and
- receiving */
-#ifndef USE_LPF_RECEIVE
- /* for LPF this is simple, packet filters are removed when sockets
- are closed */
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
- if (!quiet_interface_discovery)
- log_info ("Disabling output on LPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_LPF_SEND */
-
-#ifdef USE_LPF_RECEIVE
-/* Defined in bpf.c. We can't extern these in dhcpd.h without pulling
- in bpf includes... */
-extern struct sock_filter dhcp_bpf_filter [];
-extern int dhcp_bpf_filter_len;
-
-#if defined (HAVE_TR_SUPPORT)
-extern struct sock_filter dhcp_bpf_tr_filter [];
-extern int dhcp_bpf_tr_filter_len;
-static void lpf_tr_filter_setup (struct interface_info *);
-#endif
-
-static void lpf_gen_filter_setup (struct interface_info *);
-
-void if_register_receive (info)
- struct interface_info *info;
-{
- /* Open a LPF device and hang it on this interface... */
- info -> rfdesc = if_register_lpf (info);
-
-#if defined (HAVE_TR_SUPPORT)
- if (info -> hw_address.hbuf [0] == HTYPE_IEEE802)
- lpf_tr_filter_setup (info);
- else
-#endif
- lpf_gen_filter_setup (info);
-
- if (!quiet_interface_discovery)
- log_info ("Listening on LPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_receive (info)
- struct interface_info *info;
-{
- /* for LPF this is simple, packet filters are removed when sockets
- are closed */
- close (info -> rfdesc);
- info -> rfdesc = -1;
- if (!quiet_interface_discovery)
- log_info ("Disabling input on LPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-static void lpf_gen_filter_setup (info)
- struct interface_info *info;
-{
- struct sock_fprog p;
-
- /* Set up the bpf filter program structure. This is defined in
- bpf.c */
- p.len = dhcp_bpf_filter_len;
- p.filter = dhcp_bpf_filter;
-
- /* Patch the server port into the LPF program...
- XXX changes to filter program may require changes
- to the insn number(s) used below! XXX */
- dhcp_bpf_filter [8].k = ntohs ((short)local_port);
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT) {
- log_error ("socket: %m - make sure");
- log_error ("CONFIG_PACKET (Packet socket) %s",
- "and CONFIG_FILTER");
- log_error ("(Socket Filtering) are enabled %s",
- "in your kernel");
- log_fatal ("configuration!");
- }
- log_fatal ("Can't install packet filter program: %m");
- }
-}
-
-#if defined (HAVE_TR_SUPPORT)
-static void lpf_tr_filter_setup (info)
- struct interface_info *info;
-{
- struct sock_fprog p;
-
- /* Set up the bpf filter program structure. This is defined in
- bpf.c */
- p.len = dhcp_bpf_tr_filter_len;
- p.filter = dhcp_bpf_tr_filter;
-
- /* Patch the server port into the LPF program...
- XXX changes to filter program may require changes
- XXX to the insn number(s) used below!
- XXX Token ring filter is null - when/if we have a filter
- XXX that's not, we'll need this code.
- XXX dhcp_bpf_filter [?].k = ntohs (local_port); */
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT) {
- log_error ("socket: %m - make sure");
- log_error ("CONFIG_PACKET (Packet socket) %s",
- "and CONFIG_FILTER");
- log_error ("(Socket Filtering) are enabled %s",
- "in your kernel");
- log_fatal ("configuration!");
- }
- log_fatal ("Can't install packet filter program: %m");
- }
-}
-#endif /* HAVE_TR_SUPPORT */
-#endif /* USE_LPF_RECEIVE */
-
-#ifdef USE_LPF_SEND
-ssize_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 hbufp = 0, ibufp = 0;
- double hh [16];
- double ih [1536 / sizeof (double)];
- unsigned char *buf = (unsigned char *)ih;
- struct sockaddr sa;
- int result;
- int fudge;
-
- if (!strcmp (interface -> name, "fallback"))
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
- fudge = hbufp % 4; /* IP header must be word-aligned. */
- memcpy (buf + fudge, (unsigned char *)hh, hbufp);
- ibufp = hbufp + fudge;
- assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- (unsigned char *)raw, len);
- memcpy (buf + ibufp, raw, len);
-
- /* For some reason, SOCK_PACKET sockets can't be connected,
- so we have to do a sentdo every time. */
- memset (&sa, 0, sizeof sa);
- sa.sa_family = AF_PACKET;
- strncpy (sa.sa_data,
- (const char *)interface -> ifp, sizeof sa.sa_data);
-
- result = sendto (interface -> wfdesc,
- buf + fudge, ibufp + len - fudge, 0, &sa, sizeof sa);
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_LPF_SEND */
-
-#ifdef USE_LPF_RECEIVE
-ssize_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];
- unsigned bufix = 0;
-
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-
- bufix = 0;
- /* 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, (unsigned)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;
-}
-
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-void maybe_setup_fallback ()
-{
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- if_register_fallback (fbi);
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-}
-#endif
diff --git a/contrib/isc-dhcp/common/memory.c b/contrib/isc-dhcp/common/memory.c
deleted file mode 100644
index 4a444e2..0000000
--- a/contrib/isc-dhcp/common/memory.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* memory.c
-
- Memory-resident database... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: memory.c,v 1.66.2.5 2004/06/10 17:59:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-struct group *root_group;
-group_hash_t *group_name_hash;
-int (*group_write_hook) (struct group_object *);
-
-isc_result_t delete_group (struct group_object *group, int writep)
-{
- struct group_object *d;
-
- /* The group should exist and be hashed - if not, it's invalid. */
- if (group_name_hash) {
- d = (struct group_object *)0;
- group_hash_lookup (&d, group_name_hash, group -> name,
- strlen (group -> name), MDL);
- } else
- return ISC_R_INVALIDARG;
- if (!d)
- return ISC_R_INVALIDARG;
-
- /* Also not okay to delete a group that's not the one in
- the hash table. */
- if (d != group)
- return ISC_R_INVALIDARG;
-
- /* If it's dynamic, and we're deleting it, we can just blow away the
- hash table entry. */
- if ((group -> flags & GROUP_OBJECT_DYNAMIC) &&
- !(group -> flags & GROUP_OBJECT_STATIC)) {
- group_hash_delete (group_name_hash,
- group -> name, strlen (group -> name), MDL);
- } else {
- group -> flags |= GROUP_OBJECT_DELETED;
- if (group -> group)
- group_dereference (&group -> group, MDL);
- }
-
- /* Store the group declaration in the lease file. */
- if (writep && group_write_hook) {
- if (!(*group_write_hook) (group))
- return ISC_R_IOERROR;
- }
- return ISC_R_SUCCESS;
-}
-
-isc_result_t supersede_group (struct group_object *group, int writep)
-{
- struct group_object *t, *u;
- isc_result_t status;
-
- /* Register the group in the group name hash table,
- so we can look it up later. */
- if (group_name_hash) {
- t = (struct group_object *)0;
- group_hash_lookup (&t, group_name_hash,
- group -> name,
- strlen (group -> name), MDL);
- if (t && t != group) {
- /* If this isn't a dynamic entry, then we need to flag
- the replacement as not dynamic either - otherwise,
- if the dynamic entry is deleted later, the static
- entry will come back next time the server is stopped
- and restarted. */
- if (!(t -> flags & GROUP_OBJECT_DYNAMIC))
- group -> flags |= GROUP_OBJECT_STATIC;
-
- /* Delete the old object if it hasn't already been
- deleted. If it has already been deleted, get rid of
- the hash table entry. This is a legitimate
- situation - a deleted static object needs to be kept
- around so we remember it's deleted. */
- if (!(t -> flags & GROUP_OBJECT_DELETED))
- delete_group (t, 0);
- else {
- group_hash_delete (group_name_hash,
- group -> name,
- strlen (group -> name),
- MDL);
- group_object_dereference (&t, MDL);
- }
- }
- } else {
- group_new_hash (&group_name_hash, 0, MDL);
- t = (struct group_object *)0;
- }
-
- /* Add the group to the group name hash if it's not
- already there, and also thread it into the list of
- dynamic groups if appropriate. */
- if (!t) {
- group_hash_add (group_name_hash, group -> name,
- strlen (group -> name), group, MDL);
- }
-
- /* Store the group declaration in the lease file. */
- if (writep && group_write_hook) {
- if (!(*group_write_hook) (group))
- return ISC_R_IOERROR;
- }
- return ISC_R_SUCCESS;
-}
-
-int clone_group (struct group **gp, struct group *group,
- const char *file, int line)
-{
- isc_result_t status;
- struct group *g = (struct group *)0;
-
- /* Normally gp should contain the null pointer, but for convenience
- it's permissible to clone a group into itself. */
- if (*gp && *gp != group)
- return 0;
- if (!group_allocate (&g, file, line))
- return 0;
- if (group == *gp)
- *gp = (struct group *)0;
- group_reference (gp, g, file, line);
- g -> authoritative = group -> authoritative;
- group_reference (&g -> next, group, file, line);
- group_dereference (&g, file, line);
- return 1;
-}
diff --git a/contrib/isc-dhcp/common/nit.c b/contrib/isc-dhcp/common/nit.c
deleted file mode 100644
index ea1f5dc..0000000
--- a/contrib/isc-dhcp/common/nit.c
+++ /dev/null
@@ -1,420 +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) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: nit.c,v 1.34.2.2 2004/06/10 17:59:19 dhankins Exp $ Copyright (c) 2004 Internet Systems 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)
- log_fatal ("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)
- log_fatal ("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 *)&ifr;
- sio.ic_timout = INFTIM;
- if (ioctl (sock, I_STR, &sio) < 0)
- log_fatal ("Can't get physical layer address for %s: %m",
- info -> name);
-
- /* XXX code below assumes ethernet interface! */
- info -> hw_address.hlen = 7;
- info -> hw_address.hbuf [0] = ARPHRD_ETHER;
- memcpy (&info -> hw_address.hbuf [1],
- ifr.ifr_ifru.ifru_addr.sa_data, 6);
-
- if (ioctl (sock, I_PUSH, "pf") < 0)
- log_fatal ("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)
- log_fatal ("Can't set NIT filter: %m");
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- log_info ("Sending on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_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
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
- if (!quiet_interface_discovery)
- log_info ("Disabling output on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#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)
- log_fatal ("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)
- log_info ("I_SRDOPT failed on %s: %m", info -> name);
-
-#if 0
- /* Push on the chunker... */
- if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0)
- log_fatal ("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)
- log_fatal ("Can't set chunk timeout: %m");
-#endif
-
- /* Ask for no header... */
- x = 0;
- if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
- log_fatal ("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)
- log_fatal ("Can't set NIT filter on %s: %m", info -> name);
-
- if (!quiet_interface_discovery)
- log_info ("Listening on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_receive (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. */
- close (info -> rfdesc);
- info -> rfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling input on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_NIT_RECEIVE */
-
-#ifdef USE_NIT_SEND
-ssize_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 hbufp, ibufp;
- double hh [16];
- double ih [1536 / sizeof (double)];
- unsigned char *buf = (unsigned char *)ih;
- struct sockaddr *junk;
- struct strbuf ctl, data;
- struct sockaddr_in foo;
- int result;
-
- if (!strcmp (interface -> name, "fallback"))
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
- /* Start with the sockaddr struct... */
- junk = (struct sockaddr *)&hh [0];
- hbufp = (((unsigned char *)&junk -> sa_data [0]) -
- (unsigned char *)&hh[0]);
- ibufp = 0;
-
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)junk, &hbufp, hto);
- assemble_udp_ip_header (interface, buf, &ibufp,
- from.s_addr, to -> sin_addr.s_addr,
- to -> sin_port, (unsigned char *)raw, len);
-
- /* Copy the data into the buffer (yuk). */
- memcpy (buf + ibufp, raw, len);
-
- /* Set up the sockaddr structure... */
-#if USE_SIN_LEN
- junk -> sa_len = hbufp - 2; /* XXX */
-#endif
- junk -> sa_family = AF_UNSPEC;
-
- /* Set up the msg_buf structure... */
- ctl.buf = (char *)&hh [0];
- ctl.maxlen = ctl.len = hbufp;
- data.buf = (char *)&ih [0];
- data.maxlen = data.len = ibufp + len;
-
- result = putmsg (interface -> wfdesc, &ctl, &data, 0);
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_NIT_SEND */
-
-#ifdef USE_NIT_RECEIVE
-ssize_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;
-}
-
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-void maybe_setup_fallback ()
-{
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- if_register_fallback (fbi);
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-}
-#endif
diff --git a/contrib/isc-dhcp/common/options.c b/contrib/isc-dhcp/common/options.c
deleted file mode 100644
index 9b67b23..0000000
--- a/contrib/isc-dhcp/common/options.c
+++ /dev/null
@@ -1,2248 +0,0 @@
-/* options.c
-
- DHCP options parsing and reassembly. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: options.c,v 1.85.2.13 2004/06/10 17:59:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#define DHCP_OPTION_DATA
-#include "dhcpd.h"
-#include <omapip/omapip_p.h>
-
-struct option *vendor_cfg_option;
-
-static void do_option_set PROTO ((pair *,
- struct option_cache *,
- enum statement_op));
-
-/* Parse all available options out of the specified packet. */
-
-int parse_options (packet)
- struct packet *packet;
-{
- int i;
- struct option_cache *op = (struct option_cache *)0;
-
- /* Allocate a new option state. */
- if (!option_state_allocate (&packet -> options, MDL)) {
- packet -> options_valid = 0;
- return 0;
- }
-
- /* 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 1;
- }
-
- /* Go through the options field, up to the end of the packet
- or the End field. */
- if (!parse_option_buffer (packet -> options,
- &packet -> raw -> options [4],
- (packet -> packet_length -
- DHCP_FIXED_NON_UDP - 4),
- &dhcp_universe))
- return 0;
-
- /* If we parsed a DHCP Option Overload option, parse more
- options out of the buffer(s) containing them. */
- if (packet -> options_valid &&
- (op = lookup_option (&dhcp_universe, packet -> options,
- DHO_DHCP_OPTION_OVERLOAD))) {
- if (op -> data.data [0] & 1) {
- if (!parse_option_buffer
- (packet -> options,
- (unsigned char *)packet -> raw -> file,
- sizeof packet -> raw -> file,
- &dhcp_universe))
- return 0;
- }
- if (op -> data.data [0] & 2) {
- if (!parse_option_buffer
- (packet -> options,
- (unsigned char *)packet -> raw -> sname,
- sizeof packet -> raw -> sname,
- &dhcp_universe))
- return 0;
- }
- }
- packet -> options_valid = 1;
- return 1;
-}
-
-/* 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. */
-
-int parse_option_buffer (options, buffer, length, universe)
- struct option_state *options;
- const unsigned char *buffer;
- unsigned length;
- struct universe *universe;
-{
- unsigned char *t;
- const unsigned char *end = buffer + length;
- unsigned len, offset;
- int code;
- struct option_cache *op = (struct option_cache *)0;
- struct buffer *bp = (struct buffer *)0;
-
- if (!buffer_allocate (&bp, length, MDL)) {
- log_error ("no memory for option buffer.");
- return 0;
- }
- memcpy (bp -> data, buffer, length);
-
- for (offset = 0; buffer [offset] != DHO_END && offset < length; ) {
- code = buffer [offset];
- /* Pad options don't have a length - just skip them. */
- if (code == DHO_PAD) {
- ++offset;
- continue;
- }
-
- /* Don't look for length if the buffer isn't that big. */
- if (offset + 2 > length) {
- len = 65536;
- goto bogus;
- }
-
- /* All other fields (except end, see above) have a
- one-byte length. */
- len = buffer [offset + 1];
-
- /* If the length is outrageous, the options are bad. */
- if (offset + len + 2 > length) {
- bogus:
- log_error ("parse_option_buffer: option %s (%d) %s.",
- dhcp_options [code].name, len,
- "larger than buffer");
- buffer_dereference (&bp, MDL);
- return 0;
- }
-
- /* If the option contains an encapsulation, parse it. If
- the parse fails, or the option isn't an encapsulation (by
- far the most common case), or the option isn't entirely
- an encapsulation, keep the raw data as well. */
- if (universe -> options [code] &&
- !((universe -> options [code] -> format [0] == 'e' ||
- universe -> options [code] -> format [0] == 'E') &&
- (parse_encapsulated_suboptions
- (options, universe -> options [code],
- buffer + offset + 2, len,
- universe, (const char *)0)))) {
- op = lookup_option (universe, options, code);
- if (op) {
- struct data_string new;
- memset (&new, 0, sizeof new);
- if (!buffer_allocate (&new.buffer, op -> data.len + len,
- MDL)) {
- log_error ("parse_option_buffer: No memory.");
- return 0;
- }
- memcpy (new.buffer -> data, op -> data.data,
- op -> data.len);
- memcpy (&new.buffer -> data [op -> data.len],
- &bp -> data [offset + 2], len);
- new.len = op -> data.len + len;
- new.data = new.buffer -> data;
- data_string_forget (&op -> data, MDL);
- data_string_copy (&op -> data, &new, MDL);
- data_string_forget (&new, MDL);
- } else {
- save_option_buffer (universe, options, bp,
- &bp -> data [offset + 2], len,
- universe -> options [code], 1);
- }
- }
- offset += len + 2;
- }
- buffer_dereference (&bp, MDL);
- return 1;
-}
-
-/* If an option in an option buffer turns out to be an encapsulation,
- figure out what to do. If we don't know how to de-encapsulate it,
- or it's not well-formed, return zero; otherwise, return 1, indicating
- that we succeeded in de-encapsulating it. */
-
-struct universe *find_option_universe (struct option *eopt, const char *uname)
-{
- int i;
- char *s, *t;
- struct universe *universe = (struct universe *)0;
-
- /* Look for the E option in the option format. */
- s = strchr (eopt -> format, 'E');
- if (!s) {
- log_error ("internal encapsulation format error 1.");
- return 0;
- }
- /* Look for the universe name in the option format. */
- t = strchr (++s, '.');
- /* If there was no trailing '.', or there's something after the
- trailing '.', the option is bogus and we can't use it. */
- if (!t || t [1]) {
- log_error ("internal encapsulation format error 2.");
- return 0;
- }
- if (t == s && uname) {
- for (i = 0; i < universe_count; i++) {
- if (!strcmp (universes [i] -> name, uname)) {
- universe = universes [i];
- break;
- }
- }
- } else if (t != s) {
- for (i = 0; i < universe_count; i++) {
- if (strlen (universes [i] -> name) == t - s &&
- !memcmp (universes [i] -> name,
- s, (unsigned)(t - s))) {
- universe = universes [i];
- break;
- }
- }
- }
- return universe;
-}
-
-/* If an option in an option buffer turns out to be an encapsulation,
- figure out what to do. If we don't know how to de-encapsulate it,
- or it's not well-formed, return zero; otherwise, return 1, indicating
- that we succeeded in de-encapsulating it. */
-
-int parse_encapsulated_suboptions (struct option_state *options,
- struct option *eopt,
- const unsigned char *buffer,
- unsigned len, struct universe *eu,
- const char *uname)
-{
- int i;
- struct universe *universe = find_option_universe (eopt, uname);
-
- /* If we didn't find the universe, we can't do anything with it
- right now (e.g., we can't decode vendor options until we've
- decoded the packet and executed the scopes that it matches). */
- if (!universe)
- return 0;
-
- /* If we don't have a decoding function for it, we can't decode
- it. */
- if (!universe -> decode)
- return 0;
-
- i = (*universe -> decode) (options, buffer, len, universe);
-
- /* If there is stuff before the suboptions, we have to keep it. */
- if (eopt -> format [0] != 'E')
- return 0;
- /* Otherwise, return the status of the decode function. */
- return i;
-}
-
-int fqdn_universe_decode (struct option_state *options,
- const unsigned char *buffer,
- unsigned length, struct universe *u)
-{
- char *name;
- struct buffer *bp = (struct buffer *)0;
-
- /* FQDN options have to be at least four bytes long. */
- if (length < 3)
- return 0;
-
- /* Save the contents of the option in a buffer. */
- if (!buffer_allocate (&bp, length + 4, MDL)) {
- log_error ("no memory for option buffer.");
- return 0;
- }
- memcpy (&bp -> data [3], buffer + 1, length - 1);
-
- if (buffer [0] & 4) /* encoded */
- bp -> data [0] = 1;
- else
- bp -> data [0] = 0;
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [0], 1,
- &fqdn_options [FQDN_ENCODED], 0)) {
- bad:
- buffer_dereference (&bp, MDL);
- return 0;
- }
-
- if (buffer [0] & 1) /* server-update */
- bp -> data [2] = 1;
- else
- bp -> data [2] = 0;
- if (buffer [0] & 2) /* no-client-update */
- bp -> data [1] = 1;
- else
- bp -> data [1] = 0;
-
- /* XXX Ideally we should store the name in DNS format, so if the
- XXX label isn't in DNS format, we convert it to DNS format,
- XXX rather than converting labels specified in DNS format to
- XXX the plain ASCII representation. But that's hard, so
- XXX not now. */
-
- /* Not encoded using DNS format? */
- if (!bp -> data [0]) {
- unsigned i;
-
- /* Some broken clients NUL-terminate this option. */
- if (buffer [length - 1] == 0) {
- --length;
- bp -> data [1] = 1;
- }
-
- /* Determine the length of the hostname component of the
- name. If the name contains no '.' character, it
- represents a non-qualified label. */
- for (i = 3; i < length && buffer [i] != '.'; i++);
- i -= 3;
-
- /* Note: If the client sends a FQDN, the first '.' will
- be used as a NUL terminator for the hostname. */
- if (i)
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data[5], i,
- &fqdn_options [FQDN_HOSTNAME],
- 0))
- goto bad;
- /* Note: If the client sends a single label, the
- FQDN_DOMAINNAME option won't be set. */
- if (length > 4 + i &&
- !save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data[6 + i], length - 4 - i,
- &fqdn_options [FQDN_DOMAINNAME], 1))
- goto bad;
- /* Also save the whole name. */
- if (length > 3)
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [5], length - 3,
- &fqdn_options [FQDN_FQDN], 1))
- goto bad;
- } else {
- unsigned len;
- unsigned total_len = 0;
- unsigned first_len = 0;
- int terminated = 0;
- unsigned char *s;
-
- s = &bp -> data[5];
-
- while (s < &bp -> data[0] + length + 2) {
- len = *s;
- if (len > 63) {
- log_info ("fancy bits in fqdn option");
- return 0;
- }
- if (len == 0) {
- terminated = 1;
- break;
- }
- if (s + len > &bp -> data [0] + length + 3) {
- log_info ("fqdn tag longer than buffer");
- return 0;
- }
-
- if (first_len == 0) {
- first_len = len;
- }
-
- *s = '.';
- s += len + 1;
- total_len += len + 1;
- }
-
- /* We wind up with a length that's one too many because
- we shouldn't increment for the last label, but there's
- no way to tell we're at the last label until we exit
- the loop. :'*/
- if (total_len > 0)
- total_len--;
-
- if (!terminated) {
- first_len = total_len;
- }
-
- if (first_len > 0 &&
- !save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data[6], first_len,
- &fqdn_options [FQDN_HOSTNAME], 0))
- goto bad;
- if (total_len > 0 && first_len != total_len) {
- if (!save_option_buffer
- (&fqdn_universe, options, bp,
- &bp -> data[6 + first_len], total_len - first_len,
- &fqdn_options [FQDN_DOMAINNAME], 1))
- goto bad;
- }
- if (total_len > 0)
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [6], total_len,
- &fqdn_options [FQDN_FQDN], 1))
- goto bad;
- }
-
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [1], 1,
- &fqdn_options [FQDN_NO_CLIENT_UPDATE], 0))
- goto bad;
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [2], 1,
- &fqdn_options [FQDN_SERVER_UPDATE], 0))
- goto bad;
-
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [3], 1,
- &fqdn_options [FQDN_RCODE1], 0))
- goto bad;
- if (!save_option_buffer (&fqdn_universe, options, bp,
- &bp -> data [4], 1,
- &fqdn_options [FQDN_RCODE2], 0))
- goto bad;
-
- buffer_dereference (&bp, MDL);
- return 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, lease, client_state,
- mms, in_options, cfg_options,
- scope, overload, terminate, bootpp, prl, vuname)
- struct packet *inpacket;
- struct dhcp_packet *outpacket;
- struct lease *lease;
- struct client_state *client_state;
- int mms;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- int overload; /* Overload flags that may be set. */
- int terminate;
- int bootpp;
- struct data_string *prl;
- const char *vuname;
-{
-#define PRIORITY_COUNT 300
- unsigned priority_list [PRIORITY_COUNT];
- int priority_len;
- unsigned char buffer [4096]; /* Really big buffer... */
- unsigned main_buffer_size;
- unsigned mainbufix, bufix, agentix;
- unsigned option_size;
- unsigned length;
- int i;
- struct option_cache *op;
- struct data_string ds;
- pair pp, *hash;
- int need_endopt = 0;
- int have_sso = 0;
-
- memset (&ds, 0, sizeof ds);
-
- /* If there's a Maximum Message Size option in the incoming packet
- and no alternate maximum message size has been specified, take the
- one in the packet. */
-
- if (inpacket &&
- (op = lookup_option (&dhcp_universe, inpacket -> options,
- DHO_DHCP_MAX_MESSAGE_SIZE))) {
- evaluate_option_cache (&ds, inpacket,
- lease, client_state, in_options,
- cfg_options, scope, op, MDL);
- if (ds.len >= sizeof (u_int16_t)) {
- i = getUShort (ds.data);
-
- if(!mms || (i < mms))
- mms = i;
- }
- data_string_forget (&ds, MDL);
- }
-
- /* If the client has provided a maximum DHCP message size,
- use that; otherwise, if it's BOOTP, only 64 bytes; otherwise
- use up to the minimum IP MTU size (576 bytes). */
- /* XXX if a BOOTP client specifies a max message size, we will
- honor it. */
-
- if (mms) {
- main_buffer_size = mms - DHCP_FIXED_LEN;
-
- /* Enforce a minimum packet size... */
- if (main_buffer_size < (576 - DHCP_FIXED_LEN))
- main_buffer_size = 576 - DHCP_FIXED_LEN;
- } else if (bootpp) {
- if (inpacket) {
- main_buffer_size =
- inpacket -> packet_length - DHCP_FIXED_LEN;
- if (main_buffer_size < 64)
- main_buffer_size = 64;
- } else
- main_buffer_size = 64;
- } else
- main_buffer_size = 576 - DHCP_FIXED_LEN;
-
- /* Set a hard limit at the size of the output buffer. */
- if (main_buffer_size > sizeof buffer)
- main_buffer_size = sizeof buffer;
-
- /* 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;
- priority_list [priority_len++] = DHO_DHCP_REQUESTED_ADDRESS;
- priority_list [priority_len++] = DHO_FQDN;
-
- if (prl && prl -> len > 0) {
- if ((op = lookup_option (&dhcp_universe, cfg_options,
- DHO_SUBNET_SELECTION))) {
- if (priority_len < PRIORITY_COUNT)
- priority_list [priority_len++] =
- DHO_SUBNET_SELECTION;
- }
-
- data_string_truncate (prl, (PRIORITY_COUNT - priority_len));
-
- for (i = 0; i < prl -> len; i++) {
- /* Prevent client from changing order of delivery
- of relay agent information option. */
- if (prl -> data [i] != DHO_DHCP_AGENT_OPTIONS)
- priority_list [priority_len++] =
- prl -> data [i];
- }
- } else {
- /* First, hardcode some more options that ought to be
- sent first... */
- priority_list [priority_len++] = DHO_SUBNET_MASK;
- priority_list [priority_len++] = DHO_ROUTERS;
- priority_list [priority_len++] = DHO_DOMAIN_NAME_SERVERS;
- priority_list [priority_len++] = DHO_HOST_NAME;
-
- /* Append a list of the standard DHCP options from the
- standard DHCP option space. Actually, if a site
- option space hasn't been specified, we wind up
- treating the dhcp option space as the site option
- space, and the first for loop is skipped, because
- it's slightly more general to do it this way,
- taking the 1Q99 DHCP futures work into account. */
- if (cfg_options -> site_code_min) {
- for (i = 0; i < OPTION_HASH_SIZE; i++) {
- hash = cfg_options -> universes [dhcp_universe.index];
- if (hash) {
- for (pp = hash [i]; pp; pp = pp -> cdr) {
- op = (struct option_cache *)(pp -> car);
- if (op -> option -> code <
- cfg_options -> site_code_min &&
- priority_len < PRIORITY_COUNT &&
- (op -> option -> code !=
- DHO_DHCP_AGENT_OPTIONS))
- priority_list [priority_len++] =
- op -> option -> code;
- }
- }
- }
- }
-
- /* Now cycle through the site option space, or if there
- is no site option space, we'll be cycling through the
- dhcp option space. */
- for (i = 0; i < OPTION_HASH_SIZE; i++) {
- hash = (cfg_options -> universes
- [cfg_options -> site_universe]);
- if (hash)
- for (pp = hash [i]; pp; pp = pp -> cdr) {
- op = (struct option_cache *)(pp -> car);
- if (op -> option -> code >=
- cfg_options -> site_code_min &&
- priority_len < PRIORITY_COUNT &&
- (op -> option -> code !=
- DHO_DHCP_AGENT_OPTIONS))
- priority_list [priority_len++] =
- op -> option -> code;
- }
- }
-
- /* Now go through all the universes for which options
- were set and see if there are encapsulations for
- them; if there are, put the encapsulation options
- on the priority list as well. */
- for (i = 0; i < cfg_options -> universe_count; i++) {
- if (cfg_options -> universes [i] &&
- universes [i] -> enc_opt &&
- priority_len < PRIORITY_COUNT &&
- universes [i] -> enc_opt -> universe == &dhcp_universe)
- {
- if (universes [i] -> enc_opt -> code !=
- DHO_DHCP_AGENT_OPTIONS)
- priority_list [priority_len++] =
- universes [i] -> enc_opt -> code;
- }
- }
-
- /* The vendor option space can't stand on its own, so always
- add it to the list. */
- if (priority_len < PRIORITY_COUNT)
- priority_list [priority_len++] =
- DHO_VENDOR_ENCAPSULATED_OPTIONS;
- }
-
- /* 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)),
- inpacket, lease, client_state,
- in_options, cfg_options, scope,
- priority_list, priority_len,
- main_buffer_size,
- (main_buffer_size +
- ((overload & 1) ? DHCP_FILE_LEN : 0)),
- terminate, vuname);
-
- /* 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;
- agentix = mainbufix;
- if (mainbufix < main_buffer_size)
- need_endopt = 1;
- 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);
- length = DHCP_FIXED_NON_UDP + main_buffer_size;
- agentix = main_buffer_size;
-
- bufix = main_buffer_size - 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;
- }
- }
-
- /* Now hack in the agent options if there are any. */
- priority_list [0] = DHO_DHCP_AGENT_OPTIONS;
- priority_len = 1;
- agentix +=
- store_options (&outpacket -> options [agentix],
- 1500 - DHCP_FIXED_LEN - agentix,
- inpacket, lease, client_state,
- in_options, cfg_options, scope,
- priority_list, priority_len,
- 1500 - DHCP_FIXED_LEN - agentix,
- 1500 - DHCP_FIXED_LEN - agentix, 0, (char *)0);
-
- /* Tack a DHO_END option onto the packet if we need to. */
- if (agentix < 1500 - DHCP_FIXED_LEN && need_endopt)
- outpacket -> options [agentix++] = DHO_END;
-
- /* Figure out the length. */
- length = DHCP_FIXED_NON_UDP + agentix;
- return length;
-}
-
-/* Store all the requested options into the requested buffer. */
-
-int store_options (buffer, buflen, packet, lease, client_state,
- in_options, cfg_options, scope, priority_list, priority_len,
- first_cutoff, second_cutoff, terminate, vuname)
- unsigned char *buffer;
- unsigned buflen;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- unsigned *priority_list;
- int priority_len;
- unsigned first_cutoff, second_cutoff;
- int terminate;
- const char *vuname;
-{
- int bufix = 0;
- int i;
- int ix;
- int tto;
- struct data_string od;
- struct option_cache *oc;
- unsigned code;
- int optstart;
-
- memset (&od, 0, sizeof od);
-
- /* Eliminate duplicate options in the parameter request list.
- There's got to be some clever knuthian way to do this:
- Eliminate all but the first occurance of a value in an array
- of values without otherwise disturbing the order of the array. */
- for (i = 0; i < priority_len - 1; i++) {
- tto = 0;
- for (ix = i + 1; ix < priority_len + tto; ix++) {
- if (tto)
- priority_list [ix - tto] =
- priority_list [ix];
- if (priority_list [i] == priority_list [ix]) {
- tto++;
- priority_len--;
- }
- }
- }
-
- /* Copy out the options in the order that they appear in the
- priority list... */
- for (i = 0; i < priority_len; i++) {
- /* Number of bytes left to store (some may already
- have been stored by a previous pass). */
- unsigned length;
- int optstart;
- struct universe *u;
- int have_encapsulation = 0;
- struct data_string encapsulation;
-
- memset (&encapsulation, 0, sizeof encapsulation);
-
- /* Code for next option to try to store. */
- code = priority_list [i];
-
- /* Look up the option in the site option space if the code
- is above the cutoff, otherwise in the DHCP option space. */
- if (code >= cfg_options -> site_code_min)
- u = universes [cfg_options -> site_universe];
- else
- u = &dhcp_universe;
-
- oc = lookup_option (u, cfg_options, code);
-
- /* It's an encapsulation, try to find the universe
- to be encapsulated first, except that if it's a straight
- encapsulation and the user has provided a value for the
- encapsulation option, use the user-provided value. */
- if (u -> options [code] &&
- ((u -> options [code] -> format [0] == 'E' && !oc) ||
- u -> options [code] -> format [0] == 'e')) {
- int uix;
- static char *s, *t;
- struct option_cache *tmp;
- struct data_string name;
-
- s = strchr (u -> options [code] -> format, 'E');
- if (s)
- t = strchr (++s, '.');
- if (s && t) {
- memset (&name, 0, sizeof name);
-
- /* A zero-length universe name means the vendor
- option space, if one is defined. */
- if (t == s) {
- if (vendor_cfg_option) {
- tmp = lookup_option (vendor_cfg_option -> universe,
- cfg_options,
- vendor_cfg_option -> code);
- if (tmp)
- evaluate_option_cache (&name, packet, lease,
- client_state,
- in_options,
- cfg_options,
- scope, tmp, MDL);
- } else if (vuname) {
- name.data = (unsigned char *)s;
- name.len = strlen (s);
- }
- } else {
- name.data = (unsigned char *)s;
- name.len = t - s;
- }
-
- /* If we found a universe, and there are options configured
- for that universe, try to encapsulate it. */
- if (name.len) {
- have_encapsulation =
- (option_space_encapsulate
- (&encapsulation, packet, lease, client_state,
- in_options, cfg_options, scope, &name));
- data_string_forget (&name, MDL);
- }
- }
- }
-
- /* In order to avoid memory leaks, we have to get to here
- with any option cache that we allocated in tmp not being
- referenced by tmp, and whatever option cache is referenced
- by oc being an actual reference. lookup_option doesn't
- generate a reference (this needs to be fixed), so the
- preceding goop ensures that if we *didn't* generate a new
- option cache, oc still winds up holding an actual reference. */
-
- /* If no data is available for this option, skip it. */
- if (!oc && !have_encapsulation) {
- continue;
- }
-
- /* Find the value of the option... */
- if (oc) {
- evaluate_option_cache (&od, packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, MDL);
- if (!od.len) {
- data_string_forget (&encapsulation, MDL);
- data_string_forget (&od, MDL);
- have_encapsulation = 0;
- continue;
- }
- }
-
- /* We should now have a constant length for the option. */
- length = od.len;
- if (have_encapsulation) {
- length += encapsulation.len;
- if (!od.len) {
- data_string_copy (&od, &encapsulation, MDL);
- data_string_forget (&encapsulation, MDL);
- } else {
- struct buffer *bp = (struct buffer *)0;
- if (!buffer_allocate (&bp, length, MDL)) {
- option_cache_dereference (&oc, MDL);
- data_string_forget (&od, MDL);
- data_string_forget (&encapsulation, MDL);
- continue;
- }
- memcpy (&bp -> data [0], od.data, od.len);
- memcpy (&bp -> data [od.len], encapsulation.data,
- encapsulation.len);
- data_string_forget (&od, MDL);
- data_string_forget (&encapsulation, MDL);
- od.data = &bp -> data [0];
- buffer_reference (&od.buffer, bp, MDL);
- buffer_dereference (&bp, MDL);
- od.len = length;
- od.terminated = 0;
- }
- }
-
- /* 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;
- int consumed = 0;
-
- /* 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,
- od.data + ix, (unsigned)(incr - 1));
- buffer [bufix + 2 + incr - 1] = 0;
- } else {
- memcpy (buffer + bufix + 2,
- od.data + ix, (unsigned)incr);
- }
- length -= incr;
- ix += incr;
- bufix += 2 + incr;
- }
- data_string_forget (&od, MDL);
- }
-
- return bufix;
-}
-
-/* Format the specified option so that a human can easily read it. */
-
-const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
- struct option *option;
- const unsigned char *data;
- unsigned len;
- int emit_commas;
- int emit_quotes;
-{
- static char optbuf [32768]; /* XXX */
- int hunksize = 0;
- int opthunk = 0;
- int hunkinc = 0;
- int numhunk = -1;
- int numelem = 0;
- char fmtbuf [32];
- struct enumeration *enumbuf [32];
- int i, j, k, l;
- char *op = optbuf;
- const unsigned char *dp = data;
- struct in_addr foo;
- char comma;
- unsigned long tval;
-
- if (emit_commas)
- comma = ',';
- else
- comma = ' ';
-
- memset (enumbuf, 0, sizeof enumbuf);
-
- /* Figure out the size of the data. */
- for (l = i = 0; option -> format [i]; i++, l++) {
- if (!numhunk) {
- log_error ("%s: Extra codes in format string: %s",
- option -> name,
- &(option -> format [i]));
- break;
- }
- numelem++;
- fmtbuf [l] = option -> format [i];
- switch (option -> format [i]) {
- case 'a':
- --numelem;
- fmtbuf [l] = 0;
- numhunk = 0;
- break;
- case 'A':
- --numelem;
- fmtbuf [l] = 0;
- numhunk = 0;
- break;
- case 'E':
- /* Skip the universe name. */
- while (option -> format [i] &&
- option -> format [i] != '.')
- i++;
- case 'X':
- for (k = 0; k < len; k++) {
- if (!isascii (data [k]) ||
- !isprint (data [k]))
- break;
- }
- /* If we found no bogus characters, or the bogus
- character we found is a trailing NUL, it's
- okay to print this option as text. */
- if (k == len || (k + 1 == len && data [k] == 0)) {
- fmtbuf [l] = 't';
- numhunk = -2;
- } else {
- fmtbuf [l] = 'x';
- hunksize++;
- comma = ':';
- numhunk = 0;
- }
- fmtbuf [l + 1] = 0;
- break;
- case 'd':
- case 't':
- fmtbuf [l] = 't';
- fmtbuf [l + 1] = 0;
- numhunk = -2;
- break;
- case 'N':
- k = i;
- while (option -> format [i] &&
- option -> format [i] != '.')
- i++;
- enumbuf [l] =
- find_enumeration (&option -> format [k] + 1,
- i - k - 1);
- hunksize += 1;
- hunkinc = 1;
- break;
- case 'I':
- case 'l':
- case 'L':
- case 'T':
- hunksize += 4;
- hunkinc = 4;
- break;
- case 's':
- case 'S':
- hunksize += 2;
- hunkinc = 2;
- break;
- case 'b':
- case 'B':
- case 'f':
- hunksize++;
- hunkinc = 1;
- break;
- case 'e':
- break;
- case 'o':
- opthunk += hunkinc;
- break;
- default:
- log_error ("%s: garbage in format string: %s",
- option -> name,
- &(option -> format [i]));
- break;
- }
- }
-
- /* Check for too few bytes... */
- if (hunksize - opthunk > len) {
- log_error ("%s: expecting at least %d bytes; got %d",
- option -> name,
- hunksize, len);
- return "<error>";
- }
- /* Check for too many bytes... */
- if (numhunk == -1 && hunksize < len)
- log_error ("%s: %d extra bytes",
- option -> 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)
- log_error ("%s: %d extra bytes at end of array\n",
- option -> 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':
- if (emit_quotes)
- *op++ = '"';
- for (; dp < data + len; dp++) {
- if (!isascii (*dp) ||
- !isprint (*dp)) {
- /* Skip trailing NUL. */
- if (dp + 1 != data + len ||
- *dp != 0) {
- sprintf (op, "\\%03o",
- *dp);
- op += 4;
- }
- } else if (*dp == '"' ||
- *dp == '\'' ||
- *dp == '$' ||
- *dp == '`' ||
- *dp == '\\') {
- *op++ = '\\';
- *op++ = *dp;
- } else
- *op++ = *dp;
- }
- if (emit_quotes)
- *op++ = '"';
- *op = 0;
- break;
- /* pretty-printing an array of enums is
- going to get ugly. */
- case 'N':
- if (!enumbuf [j])
- goto enum_as_num;
- for (i = 0; ;i++) {
- if (!enumbuf [j] -> values [i].name)
- goto enum_as_num;
- if (enumbuf [j] -> values [i].value ==
- *dp)
- break;
- }
- strcpy (op, enumbuf [j] -> values [i].name);
- op += strlen (op);
- 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 'T':
- tval = getULong (dp);
- if (tval == -1)
- sprintf (op, "%s", "infinite");
- else
- sprintf (op, "%ld", tval);
- break;
- case 'L':
- sprintf (op, "%ld",
- (unsigned long)getULong (dp));
- dp += 4;
- break;
- case 's':
- sprintf (op, "%d", (int)getShort (dp));
- dp += 2;
- break;
- case 'S':
- sprintf (op, "%d", (unsigned)getUShort (dp));
- dp += 2;
- break;
- case 'b':
- sprintf (op, "%d", *(const char *)dp++);
- break;
- case 'B':
- enum_as_num:
- sprintf (op, "%d", *dp++);
- break;
- case 'x':
- sprintf (op, "%x", *dp++);
- break;
- case 'f':
- strcpy (op, *dp++ ? "true" : "false");
- break;
- default:
- log_error ("Unexpected format code %c",
- fmtbuf [j]);
- }
- op += strlen (op);
- if (dp == data + len)
- break;
- if (j + 1 < numelem && comma != ':')
- *op++ = ' ';
- }
- if (i + 1 < numhunk) {
- *op++ = comma;
- }
- if (dp == data + len)
- break;
- }
- return optbuf;
-}
-
-int get_option (result, universe, packet, lease, client_state,
- in_options, cfg_options, options, scope, code, file, line)
- struct data_string *result;
- struct universe *universe;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct option_state *options;
- struct binding_scope **scope;
- unsigned code;
- const char *file;
- int line;
-{
- struct option_cache *oc;
-
- if (!universe -> lookup_func)
- return 0;
- oc = ((*universe -> lookup_func) (universe, options, code));
- if (!oc)
- return 0;
- if (!evaluate_option_cache (result, packet, lease, client_state,
- in_options, cfg_options, scope, oc,
- file, line))
- return 0;
- return 1;
-}
-
-void set_option (universe, options, option, op)
- struct universe *universe;
- struct option_state *options;
- struct option_cache *option;
- enum statement_op op;
-{
- struct option_cache *oc, *noc;
-
- switch (op) {
- case if_statement:
- case add_statement:
- case eval_statement:
- case break_statement:
- default:
- log_error ("bogus statement type in do_option_set.");
- break;
-
- case default_option_statement:
- oc = lookup_option (universe, options,
- option -> option -> code);
- if (oc)
- break;
- save_option (universe, options, option);
- break;
-
- case supersede_option_statement:
- case send_option_statement:
- /* Install the option, replacing any existing version. */
- save_option (universe, options, option);
- break;
-
- case append_option_statement:
- case prepend_option_statement:
- oc = lookup_option (universe, options,
- option -> option -> code);
- if (!oc) {
- save_option (universe, options, option);
- break;
- }
- /* If it's not an expression, make it into one. */
- if (!oc -> expression && oc -> data.len) {
- if (!expression_allocate (&oc -> expression, MDL)) {
- log_error ("Can't allocate const expression.");
- break;
- }
- oc -> expression -> op = expr_const_data;
- data_string_copy
- (&oc -> expression -> data.const_data,
- &oc -> data, MDL);
- data_string_forget (&oc -> data, MDL);
- }
- noc = (struct option_cache *)0;
- if (!option_cache_allocate (&noc, MDL))
- break;
- if (op == append_option_statement) {
- if (!make_concat (&noc -> expression,
- oc -> expression,
- option -> expression)) {
- option_cache_dereference (&noc, MDL);
- break;
- }
- } else {
- if (!make_concat (&noc -> expression,
- option -> expression,
- oc -> expression)) {
- option_cache_dereference (&noc, MDL);
- break;
- }
- }
- noc -> option = oc -> option;
- save_option (universe, options, noc);
- option_cache_dereference (&noc, MDL);
- break;
- }
-}
-
-struct option_cache *lookup_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- unsigned code;
-{
- if (!options)
- return (struct option_cache *)0;
- if (universe -> lookup_func)
- return (*universe -> lookup_func) (universe, options, code);
- else
- log_error ("can't look up options in %s space.",
- universe -> name);
- return (struct option_cache *)0;
-}
-
-struct option_cache *lookup_hashed_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- unsigned code;
-{
- int hashix;
- pair bptr;
- pair *hash;
-
- /* Make sure there's a hash table. */
- if (universe -> index >= options -> universe_count ||
- !(options -> universes [universe -> index]))
- return (struct option_cache *)0;
-
- hash = options -> universes [universe -> index];
-
- hashix = compute_option_hash (code);
- for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
- if (((struct option_cache *)(bptr -> car)) -> option -> code ==
- code)
- return (struct option_cache *)(bptr -> car);
- }
- return (struct option_cache *)0;
-}
-
-int save_option_buffer (struct universe *universe,
- struct option_state *options,
- struct buffer *bp,
- unsigned char *buffer, unsigned length,
- struct option *option, int tp)
-{
- struct buffer *lbp = (struct buffer *)0;
- struct option_cache *op = (struct option_cache *)0;
-
- if (!option_cache_allocate (&op, MDL)) {
- log_error ("No memory for option %s.%s.",
- universe -> name,
- option -> name);
- return 0;
- }
-
- /* If we weren't passed a buffer in which the data are saved and
- refcounted, allocate one now. */
- if (!bp) {
- if (!buffer_allocate (&lbp, length, MDL)) {
- log_error ("no memory for option buffer.");
-
- option_cache_dereference (&op, MDL);
- return 0;
- }
- memcpy (lbp -> data, buffer, length + tp);
- bp = lbp;
- buffer = &bp -> data [0]; /* Refer to saved buffer. */
- }
-
- /* Reference buffer copy to option cache. */
- op -> data.buffer = (struct buffer *)0;
- buffer_reference (&op -> data.buffer, bp, MDL);
-
- /* Point option cache into buffer. */
- op -> data.data = buffer;
- op -> data.len = length;
-
- if (tp) {
- /* NUL terminate (we can get away with this because we (or
- the caller!) allocated one more than the buffer size, and
- because the byte following the end of an option is always
- the code of the next option, which the caller is getting
- out of the *original* buffer. */
- buffer [length] = 0;
- op -> data.terminated = 1;
- } else
- op -> data.terminated = 0;
-
- op -> option = option;
-
- /* Now store the option. */
- save_option (universe, options, op);
-
- /* And let go of our reference. */
- option_cache_dereference (&op, MDL);
-
- return 1;
-}
-
-void save_option (struct universe *universe,
- struct option_state *options, struct option_cache *oc)
-{
- if (universe -> save_func)
- (*universe -> save_func) (universe, options, oc);
- else
- log_error ("can't store options in %s space.",
- universe -> name);
-}
-
-void save_hashed_option (universe, options, oc)
- struct universe *universe;
- struct option_state *options;
- struct option_cache *oc;
-{
- int hashix;
- pair bptr;
- pair *hash = options -> universes [universe -> index];
-
- if (oc -> refcnt == 0)
- abort ();
-
- /* Compute the hash. */
- hashix = compute_option_hash (oc -> option -> code);
-
- /* If there's no hash table, make one. */
- if (!hash) {
- hash = (pair *)dmalloc (OPTION_HASH_SIZE * sizeof *hash, MDL);
- if (!hash) {
- log_error ("no memory to store %s.%s",
- universe -> name, oc -> option -> name);
- return;
- }
- memset (hash, 0, OPTION_HASH_SIZE * sizeof *hash);
- options -> universes [universe -> index] = (VOIDPTR)hash;
- } else {
- /* Try to find an existing option matching the new one. */
- for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
- if (((struct option_cache *)
- (bptr -> car)) -> option -> code ==
- oc -> option -> code)
- break;
- }
-
- /* If we find one, dereference it and put the new one
- in its place. */
- if (bptr) {
- option_cache_dereference
- ((struct option_cache **)&bptr -> car, MDL);
- option_cache_reference
- ((struct option_cache **)&bptr -> car,
- oc, MDL);
- return;
- }
- }
-
- /* Otherwise, just put the new one at the head of the list. */
- bptr = new_pair (MDL);
- if (!bptr) {
- log_error ("No memory for option_cache reference.");
- return;
- }
- bptr -> cdr = hash [hashix];
- bptr -> car = 0;
- option_cache_reference ((struct option_cache **)&bptr -> car, oc, MDL);
- hash [hashix] = bptr;
-}
-
-void delete_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- int code;
-{
- if (universe -> delete_func)
- (*universe -> delete_func) (universe, options, code);
- else
- log_error ("can't delete options from %s space.",
- universe -> name);
-}
-
-void delete_hashed_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- int code;
-{
- int hashix;
- pair bptr, prev = (pair)0;
- pair *hash = options -> universes [universe -> index];
-
- /* There may not be any options in this space. */
- if (!hash)
- return;
-
- /* Try to find an existing option matching the new one. */
- hashix = compute_option_hash (code);
- for (bptr = hash [hashix]; bptr; bptr = bptr -> cdr) {
- if (((struct option_cache *)(bptr -> car)) -> option -> code
- == code)
- break;
- prev = bptr;
- }
- /* If we found one, wipe it out... */
- if (bptr) {
- if (prev)
- prev -> cdr = bptr -> cdr;
- else
- hash [hashix] = bptr -> cdr;
- option_cache_dereference
- ((struct option_cache **)(&bptr -> car), MDL);
- free_pair (bptr, MDL);
- }
-}
-
-extern struct option_cache *free_option_caches; /* XXX */
-
-int option_cache_dereference (ptr, file, line)
- struct option_cache **ptr;
- const char *file;
- int line;
-{
- if (!ptr || !*ptr) {
- log_error ("Null pointer in option_cache_dereference: %s(%d)",
- file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- (*ptr) -> refcnt--;
- rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
- if (!(*ptr) -> refcnt) {
- if ((*ptr) -> data.buffer)
- data_string_forget (&(*ptr) -> data, file, line);
- if ((*ptr) -> expression)
- expression_dereference (&(*ptr) -> expression,
- file, line);
- if ((*ptr) -> next)
- option_cache_dereference (&((*ptr) -> next),
- file, line);
- /* Put it back on the free list... */
- (*ptr) -> expression = (struct expression *)free_option_caches;
- free_option_caches = *ptr;
- dmalloc_reuse (free_option_caches, (char *)0, 0, 0);
- }
- if ((*ptr) -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (*ptr);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct option_cache *)0;
- return 0;
-#endif
- }
- *ptr = (struct option_cache *)0;
- return 1;
-
-}
-
-int hashed_option_state_dereference (universe, state, file, line)
- struct universe *universe;
- struct option_state *state;
- const char *file;
- int line;
-{
- pair *heads;
- pair cp, next;
- int i;
-
- /* Get the pointer to the array of hash table bucket heads. */
- heads = (pair *)(state -> universes [universe -> index]);
- if (!heads)
- return 0;
-
- /* For each non-null head, loop through all the buckets dereferencing
- the attached option cache structures and freeing the buckets. */
- for (i = 0; i < OPTION_HASH_SIZE; i++) {
- for (cp = heads [i]; cp; cp = next) {
- next = cp -> cdr;
- option_cache_dereference
- ((struct option_cache **)&cp -> car,
- file, line);
- free_pair (cp, file, line);
- }
- }
-
- dfree (heads, file, line);
- state -> universes [universe -> index] = (void *)0;
- return 1;
-}
-
-int store_option (result, universe, packet, lease, client_state,
- in_options, cfg_options, scope, oc)
- struct data_string *result;
- struct universe *universe;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct option_cache *oc;
-{
- struct data_string d1, d2;
-
- memset (&d1, 0, sizeof d1);
- memset (&d2, 0, sizeof d2);
-
- if (evaluate_option_cache (&d2, packet, lease, client_state,
- in_options, cfg_options, scope, oc, MDL)) {
- if (!buffer_allocate (&d1.buffer,
- (result -> len +
- universe -> length_size +
- universe -> tag_size + d2.len), MDL)) {
- data_string_forget (result, MDL);
- data_string_forget (&d2, MDL);
- return 0;
- }
- d1.data = &d1.buffer -> data [0];
- if (result -> len)
- memcpy (d1.buffer -> data,
- result -> data, result -> len);
- d1.len = result -> len;
- (*universe -> store_tag) (&d1.buffer -> data [d1.len],
- oc -> option -> code);
- d1.len += universe -> tag_size;
- (*universe -> store_length) (&d1.buffer -> data [d1.len],
- d2.len);
- d1.len += universe -> length_size;
- memcpy (&d1.buffer -> data [d1.len], d2.data, d2.len);
- d1.len += d2.len;
- data_string_forget (&d2, MDL);
- data_string_forget (result, MDL);
- data_string_copy (result, &d1, MDL);
- data_string_forget (&d1, MDL);
- return 1;
- }
- return 0;
-}
-
-int option_space_encapsulate (result, packet, lease, client_state,
- in_options, cfg_options, scope, name)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct data_string *name;
-{
- struct universe *u;
-
- u = (struct universe *)0;
- universe_hash_lookup (&u, universe_hash,
- (const char *)name -> data, name -> len, MDL);
- if (!u)
- return 0;
-
- if (u -> encapsulate)
- return (*u -> encapsulate) (result, packet, lease,
- client_state,
- in_options, cfg_options, scope, u);
- log_error ("encapsulation requested for %s with no support.",
- name -> data);
- return 0;
-}
-
-int hashed_option_space_encapsulate (result, packet, lease, client_state,
- in_options, cfg_options, scope, universe)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct universe *universe;
-{
- pair p, *hash;
- int status;
- int i;
-
- if (universe -> index >= cfg_options -> universe_count)
- return 0;
-
- hash = cfg_options -> universes [universe -> index];
- if (!hash)
- return 0;
-
- status = 0;
- for (i = 0; i < OPTION_HASH_SIZE; i++) {
- for (p = hash [i]; p; p = p -> cdr) {
- if (store_option (result, universe, packet,
- lease, client_state, in_options,
- cfg_options, scope,
- (struct option_cache *)p -> car))
- status = 1;
- }
- }
-
- return status;
-}
-
-int nwip_option_space_encapsulate (result, packet, lease, client_state,
- in_options, cfg_options, scope, universe)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct universe *universe;
-{
- pair ocp;
- int status;
- int i;
- static struct option_cache *no_nwip;
- struct data_string ds;
- struct option_chain_head *head;
-
- if (universe -> index >= cfg_options -> universe_count)
- return 0;
- head = ((struct option_chain_head *)
- cfg_options -> universes [fqdn_universe.index]);
- if (!head)
- return 0;
-
- status = 0;
- for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
- struct option_cache *oc = (struct option_cache *)(ocp -> car);
- if (store_option (result, universe, packet,
- lease, client_state, in_options,
- cfg_options, scope,
- (struct option_cache *)ocp -> car))
- status = 1;
- }
-
- /* If there's no data, the nwip suboption is supposed to contain
- a suboption saying there's no data. */
- if (!status) {
- if (!no_nwip) {
- static unsigned char nni [] = { 1, 0 };
- memset (&ds, 0, sizeof ds);
- ds.data = nni;
- ds.len = 2;
- if (option_cache_allocate (&no_nwip, MDL))
- data_string_copy (&no_nwip -> data, &ds, MDL);
- no_nwip -> option = nwip_universe.options [1];
- }
- if (no_nwip) {
- if (store_option (result, universe, packet, lease,
- client_state, in_options,
- cfg_options, scope, no_nwip))
- status = 1;
- }
- } else {
- memset (&ds, 0, sizeof ds);
-
- /* If we have nwip options, the first one has to be the
- nwip-exists-in-option-area option. */
- if (!buffer_allocate (&ds.buffer, result -> len + 2, MDL)) {
- data_string_forget (result, MDL);
- return 0;
- }
- ds.data = &ds.buffer -> data [0];
- ds.buffer -> data [0] = 2;
- ds.buffer -> data [1] = 0;
- memcpy (&ds.buffer -> data [2], result -> data, result -> len);
- data_string_forget (result, MDL);
- data_string_copy (result, &ds, MDL);
- data_string_forget (&ds, MDL);
- }
-
- return status;
-}
-
-int fqdn_option_space_encapsulate (result, packet, lease, client_state,
- in_options, cfg_options, scope, universe)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct universe *universe;
-{
- pair ocp;
- struct data_string results [FQDN_SUBOPTION_COUNT + 1];
- unsigned i;
- unsigned len;
- struct buffer *bp = (struct buffer *)0;
- struct option_chain_head *head;
-
- /* If there's no FQDN universe, don't encapsulate. */
- if (fqdn_universe.index >= cfg_options -> universe_count)
- return 0;
- head = ((struct option_chain_head *)
- cfg_options -> universes [fqdn_universe.index]);
- if (!head)
- return 0;
-
- /* Figure out the values of all the suboptions. */
- memset (results, 0, sizeof results);
- for (ocp = head -> first; ocp; ocp = ocp -> cdr) {
- struct option_cache *oc = (struct option_cache *)(ocp -> car);
- if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
- continue;
- evaluate_option_cache (&results [oc -> option -> code],
- packet, lease, client_state, in_options,
- cfg_options, scope, oc, MDL);
- }
- len = 4 + results [FQDN_FQDN].len;
- /* Save the contents of the option in a buffer. */
- if (!buffer_allocate (&bp, len, MDL)) {
- log_error ("no memory for option buffer.");
- return 0;
- }
- buffer_reference (&result -> buffer, bp, MDL);
- result -> len = 3;
- result -> data = &bp -> data [0];
-
- memset (&bp -> data [0], 0, len);
- if (results [FQDN_NO_CLIENT_UPDATE].len &&
- results [FQDN_NO_CLIENT_UPDATE].data [0])
- bp -> data [0] |= 2;
- if (results [FQDN_SERVER_UPDATE].len &&
- results [FQDN_SERVER_UPDATE].data [0])
- bp -> data [0] |= 1;
- if (results [FQDN_RCODE1].len)
- bp -> data [1] = results [FQDN_RCODE1].data [0];
- if (results [FQDN_RCODE2].len)
- bp -> data [2] = results [FQDN_RCODE2].data [0];
-
- if (results [FQDN_ENCODED].len &&
- results [FQDN_ENCODED].data [0]) {
- unsigned char *out;
- int i;
- bp -> data [0] |= 4;
- out = &bp -> data [3];
- if (results [FQDN_FQDN].len) {
- i = 0;
- while (i < results [FQDN_FQDN].len) {
- int j;
- for (j = i; ('.' !=
- results [FQDN_FQDN].data [j]) &&
- j < results [FQDN_FQDN].len; j++)
- ;
- *out++ = j - i;
- memcpy (out, &results [FQDN_FQDN].data [i],
- (unsigned)(j - i));
- out += j - i;
- i = j;
- if (results [FQDN_FQDN].data [j] == '.')
- i++;
- }
- if ((results [FQDN_FQDN].data
- [results [FQDN_FQDN].len - 1] == '.'))
- *out++ = 0;
- result -> len = out - result -> data;
- result -> terminated = 0;
- }
- } else {
- if (results [FQDN_FQDN].len) {
- memcpy (&bp -> data [3], results [FQDN_FQDN].data,
- results [FQDN_FQDN].len);
- result -> len += results [FQDN_FQDN].len;
- result -> terminated = 0;
- }
- }
- for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) {
- if (results [i].len)
- data_string_forget (&results [i], MDL);
- }
- buffer_dereference (&bp, MDL);
- return 1;
-}
-
-void option_space_foreach (struct packet *packet, struct lease *lease,
- struct client_state *client_state,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *stuff,
- void (*func) (struct option_cache *,
- struct packet *,
- struct lease *, struct client_state *,
- struct option_state *,
- struct option_state *,
- struct binding_scope **,
- struct universe *, void *))
-{
- if (u -> foreach)
- (*u -> foreach) (packet, lease, client_state, in_options,
- cfg_options, scope, u, stuff, func);
-}
-
-void suboption_foreach (struct packet *packet, struct lease *lease,
- struct client_state *client_state,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *stuff,
- void (*func) (struct option_cache *,
- struct packet *,
- struct lease *, struct client_state *,
- struct option_state *,
- struct option_state *,
- struct binding_scope **,
- struct universe *, void *),
- struct option_cache *oc,
- const char *vsname)
-{
- struct universe *universe = find_option_universe (oc -> option,
- vsname);
- int i;
-
- if (universe -> foreach)
- (*universe -> foreach) (packet, lease, client_state,
- in_options, cfg_options,
- scope, universe, stuff, func);
-}
-
-void hashed_option_space_foreach (struct packet *packet, struct lease *lease,
- struct client_state *client_state,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *stuff,
- void (*func) (struct option_cache *,
- struct packet *,
- struct lease *,
- struct client_state *,
- struct option_state *,
- struct option_state *,
- struct binding_scope **,
- struct universe *, void *))
-{
- pair *hash;
- int i;
- struct option_cache *oc;
-
- if (cfg_options -> universe_count <= u -> index)
- return;
-
- hash = cfg_options -> universes [u -> index];
- if (!hash)
- return;
- for (i = 0; i < OPTION_HASH_SIZE; i++) {
- pair p;
- /* XXX save _all_ options! XXX */
- for (p = hash [i]; p; p = p -> cdr) {
- oc = (struct option_cache *)p -> car;
- (*func) (oc, packet, lease, client_state,
- in_options, cfg_options, scope, u, stuff);
- }
- }
-}
-
-void save_linked_option (universe, options, oc)
- struct universe *universe;
- struct option_state *options;
- struct option_cache *oc;
-{
- pair *tail;
- pair np = (pair )0;
- struct option_chain_head *head;
-
- if (universe -> index >= options -> universe_count)
- return;
- head = ((struct option_chain_head *)
- options -> universes [universe -> index]);
- if (!head) {
- if (!option_chain_head_allocate (((struct option_chain_head **)
- &options -> universes
- [universe -> index]), MDL))
- return;
- head = ((struct option_chain_head *)
- options -> universes [universe -> index]);
- }
-
- /* Find the tail of the list. */
- for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
- if (oc -> option ==
- ((struct option_cache *)((*tail) -> car)) -> option) {
- option_cache_dereference ((struct option_cache **)
- (&(*tail) -> car), MDL);
- option_cache_reference ((struct option_cache **)
- (&(*tail) -> car), oc, MDL);
- return;
- }
- }
-
- *tail = cons (0, 0);
- if (*tail) {
- option_cache_reference ((struct option_cache **)
- (&(*tail) -> car), oc, MDL);
- }
-}
-
-int linked_option_space_encapsulate (result, packet, lease, client_state,
- in_options, cfg_options, scope, universe)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct universe *universe;
-{
- int status;
- pair oc;
- struct option_chain_head *head;
-
- if (universe -> index >= cfg_options -> universe_count)
- return 0;
- head = ((struct option_chain_head *)
- cfg_options -> universes [universe -> index]);
- if (!head)
- return 0;
-
- status = 0;
- for (oc = head -> first; oc; oc = oc -> cdr) {
- if (store_option (result, universe, packet,
- lease, client_state, in_options, cfg_options,
- scope, (struct option_cache *)(oc -> car)))
- status = 1;
- }
-
- return status;
-}
-
-void delete_linked_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- int code;
-{
- pair *tail, tmp = (pair)0;
- struct option_chain_head *head;
-
- if (universe -> index >= options -> universe_count)
- return;
- head = ((struct option_chain_head *)
- options -> universes [universe -> index]);
- if (!head)
- return;
-
- for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {
- if (code ==
- ((struct option_cache *)(*tail) -> car) -> option -> code)
- {
- tmp = (*tail) -> cdr;
- option_cache_dereference ((struct option_cache **)
- (&(*tail) -> car), MDL);
- dfree (*tail, MDL);
- (*tail) = tmp;
- break;
- }
- }
-}
-
-struct option_cache *lookup_linked_option (universe, options, code)
- struct universe *universe;
- struct option_state *options;
- unsigned code;
-{
- pair oc;
- struct option_chain_head *head;
-
- if (universe -> index >= options -> universe_count)
- return 0;
- head = ((struct option_chain_head *)
- options -> universes [universe -> index]);
- if (!head)
- return 0;
-
- for (oc = head -> first; oc; oc = oc -> cdr) {
- if (code ==
- ((struct option_cache *)(oc -> car)) -> option -> code) {
- return (struct option_cache *)(oc -> car);
- }
- }
-
- return (struct option_cache *)0;
-}
-
-int linked_option_state_dereference (universe, state, file, line)
- struct universe *universe;
- struct option_state *state;
- const char *file;
- int line;
-{
- return (option_chain_head_dereference
- ((struct option_chain_head **)
- (&state -> universes [universe -> index]), MDL));
-}
-
-void linked_option_space_foreach (struct packet *packet, struct lease *lease,
- struct client_state *client_state,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *stuff,
- void (*func) (struct option_cache *,
- struct packet *,
- struct lease *,
- struct client_state *,
- struct option_state *,
- struct option_state *,
- struct binding_scope **,
- struct universe *, void *))
-{
- pair car;
- struct option_chain_head *head;
-
- if (u -> index >= cfg_options -> universe_count)
- return;
- head = ((struct option_chain_head *)
- cfg_options -> universes [u -> index]);
- if (!head)
- return;
- for (car = head -> first; car; car = car -> cdr) {
- (*func) ((struct option_cache *)(car -> car),
- packet, lease, client_state,
- in_options, cfg_options, scope, u, stuff);
- }
-}
-
-void do_packet (interface, packet, len, from_port, from, hfrom)
- struct interface_info *interface;
- struct dhcp_packet *packet;
- unsigned len;
- unsigned int from_port;
- struct iaddr from;
- struct hardware *hfrom;
-{
- int i;
- struct option_cache *op;
- struct packet *decoded_packet;
-#if defined (DEBUG_MEMORY_LEAKAGE)
- unsigned long previous_outstanding = dmalloc_outstanding;
-#endif
-
-#if defined (TRACING)
- trace_inpacket_stash (interface, packet, len, from_port, from, hfrom);
-#endif
-
- decoded_packet = (struct packet *)0;
- if (!packet_allocate (&decoded_packet, MDL)) {
- log_error ("do_packet: no memory for incoming packet!");
- return;
- }
- decoded_packet -> raw = packet;
- decoded_packet -> packet_length = len;
- decoded_packet -> client_port = from_port;
- decoded_packet -> client_addr = from;
- interface_reference (&decoded_packet -> interface, interface, MDL);
- decoded_packet -> haddr = hfrom;
-
- if (packet -> hlen > sizeof packet -> chaddr) {
- packet_dereference (&decoded_packet, MDL);
- log_info ("Discarding packet with bogus hlen.");
- return;
- }
-
- /* If there's an option buffer, try to parse it. */
- if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) {
- if (!parse_options (decoded_packet)) {
- if (decoded_packet -> options)
- option_state_dereference
- (&decoded_packet -> options, MDL);
- packet_dereference (&decoded_packet, MDL);
- return;
- }
-
- if (decoded_packet -> options_valid &&
- (op = lookup_option (&dhcp_universe,
- decoded_packet -> options,
- DHO_DHCP_MESSAGE_TYPE))) {
- struct data_string dp;
- memset (&dp, 0, sizeof dp);
- evaluate_option_cache (&dp, decoded_packet,
- (struct lease *)0,
- (struct client_state *)0,
- decoded_packet -> options,
- (struct option_state *)0,
- (struct binding_scope **)0,
- op, MDL);
- if (dp.len > 0)
- decoded_packet -> packet_type = dp.data [0];
- else
- decoded_packet -> packet_type = 0;
- data_string_forget (&dp, MDL);
- }
- }
-
- if (decoded_packet -> packet_type)
- dhcp (decoded_packet);
- else
- bootp (decoded_packet);
-
- /* If the caller kept the packet, they'll have upped the refcnt. */
- packet_dereference (&decoded_packet, MDL);
-
-#if defined (DEBUG_MEMORY_LEAKAGE)
- log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
- dmalloc_generation,
- dmalloc_outstanding - previous_outstanding,
- dmalloc_outstanding, dmalloc_longterm);
-#endif
-#if defined (DEBUG_MEMORY_LEAKAGE)
- dmalloc_dump_outstanding ();
-#endif
-#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
- dump_rc_history (0);
-#endif
-}
-
diff --git a/contrib/isc-dhcp/common/packet.c b/contrib/isc-dhcp/common/packet.c
deleted file mode 100644
index 4038aec..0000000
--- a/contrib/isc-dhcp/common/packet.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* packet.c
-
- Packet assembly code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This code was originally contributed by Archie Cobbs, and is still
- * very similar to that contribution, although the packet checksum code
- * has been hacked significantly with the help of quite a few ISC DHCP
- * users, without whose gracious and thorough help the checksum code would
- * still be disabled.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: packet.c,v 1.40.2.3 2004/06/10 17:59:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
-
-/* Compute the easy part of the checksum on a range of bytes. */
-
-u_int32_t checksum (buf, nbytes, sum)
- unsigned char *buf;
- unsigned nbytes;
- u_int32_t sum;
-{
- unsigned i;
-
-#ifdef DEBUG_CHECKSUM
- log_debug ("checksum (%x %d %x)", buf, nbytes, sum);
-#endif
-
- /* Checksum all the pairs of bytes first... */
- for (i = 0; i < (nbytes & ~1U); i += 2) {
-#ifdef DEBUG_CHECKSUM_VERBOSE
- log_debug ("sum = %x", sum);
-#endif
- sum += (u_int16_t) ntohs(*((u_int16_t *)(buf + i)));
- /* Add carry. */
- if (sum > 0xFFFF)
- sum -= 0xFFFF;
- }
-
- /* 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
- log_debug ("sum = %x", sum);
-#endif
- sum += buf [i] << 8;
- /* Add carry. */
- if (sum > 0xFFFF)
- sum -= 0xFFFF;
- }
-
- return sum;
-}
-
-/* Finish computing the checksum, and then put it into network byte order. */
-
-u_int32_t wrapsum (sum)
- u_int32_t sum;
-{
-#ifdef DEBUG_CHECKSUM
- log_debug ("wrapsum (%x)", sum);
-#endif
-
- sum = ~sum & 0xFFFF;
-#ifdef DEBUG_CHECKSUM_VERBOSE
- log_debug ("sum = %x", sum);
-#endif
-
-#ifdef DEBUG_CHECKSUM
- log_debug ("wrapsum returns %x", htons (sum));
-#endif
- return htons(sum);
-}
-
-#ifdef PACKET_ASSEMBLY
-void assemble_hw_header (interface, buf, bufix, to)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned *bufix;
- struct hardware *to;
-{
-#if defined (HAVE_TR_SUPPORT)
- if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802)
- assemble_tr_header (interface, buf, bufix, to);
- else
-#endif
-#if defined (DEC_FDDI)
- if (interface -> hw_address.hbuf [0] == HTYPE_FDDI)
- assemble_fddi_header (interface, buf, bufix, to);
- else
-#endif
- assemble_ethernet_header (interface, buf, bufix, to);
-
-}
-
-/* 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;
- unsigned *bufix;
- u_int32_t from;
- u_int32_t to;
- u_int32_t port;
- unsigned char *data;
- unsigned len;
-{
- struct ip ip;
- struct udphdr udp;
-
- /* Fill out the IP header */
- IP_V_SET (&ip, 4);
- IP_HL_SET (&ip, 20);
- 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. */
-
- udp.uh_sum =
- wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
- checksum (data, len,
- checksum ((unsigned char *)
- &ip.ip_src,
- 2 * sizeof ip.ip_src,
- IPPROTO_UDP +
- (u_int32_t)
- ntohs (udp.uh_ulen)))));
-
- /* 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. */
-
-ssize_t decode_hw_header (interface, buf, bufix, from)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned bufix;
- struct hardware *from;
-{
-#if defined (HAVE_TR_SUPPORT)
- if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802)
- return decode_tr_header (interface, buf, bufix, from);
- else
-#endif
-#if defined (DEC_FDDI)
- if (interface -> hw_address.hbuf [0] == HTYPE_FDDI)
- return decode_fddi_header (interface, buf, bufix, from);
- else
-#endif
- return decode_ethernet_header (interface, buf, bufix, from);
-}
-
-/* UDP header and IP header decoded together for convenience. */
-
-ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned bufix;
- struct sockaddr_in *from;
- unsigned char *data;
- unsigned buflen;
-{
- struct ip *ip;
- struct udphdr *udp;
- u_int32_t ip_len = (buf [bufix] & 0xf) << 2;
- u_int32_t sum, usum;
- static int ip_packets_seen;
- static int ip_packets_bad_checksum;
- static int udp_packets_seen;
- static int udp_packets_bad_checksum;
- static int udp_packets_length_checked;
- static int udp_packets_length_overflow;
- unsigned len;
- unsigned ulen;
- int ignore = 0;
-
- 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 */
-
- ulen = ntohs (udp -> uh_ulen);
- if (ulen < sizeof *udp ||
- ((unsigned char *)udp) + ulen > buf + bufix + buflen) {
- log_info ("bogus UDP packet length: %d", ulen);
- return -1;
- }
-
- /* Check the IP header checksum - it should be zero. */
- ++ip_packets_seen;
- if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
- ++ip_packets_bad_checksum;
- if (ip_packets_seen > 4 &&
- (ip_packets_seen / ip_packets_bad_checksum) < 2) {
- log_info ("%d bad IP checksums seen in %d packets",
- ip_packets_bad_checksum, ip_packets_seen);
- ip_packets_seen = ip_packets_bad_checksum = 0;
- }
- return -1;
- }
-
- /* Check the IP packet length. */
- if (ntohs (ip -> ip_len) != buflen) {
- if ((ntohs (ip -> ip_len + 2) & ~1) == buflen)
- ignore = 1;
- else
- log_debug ("ip length %d disagrees with bytes received %d.",
- ntohs (ip -> ip_len), buflen);
- }
-
- /* 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 = ulen - sizeof *udp;
- ++udp_packets_length_checked;
- if (len + data > buf + bufix + buflen) {
- ++udp_packets_length_overflow;
- if (udp_packets_length_checked > 4 &&
- (udp_packets_length_checked /
- udp_packets_length_overflow) < 2) {
- log_info ("%d udp packets in %d too long - dropped",
- udp_packets_length_overflow,
- udp_packets_length_checked);
- udp_packets_length_overflow =
- udp_packets_length_checked = 0;
- }
- return -1;
- }
- if (len + data < buf + bufix + buflen &&
- len + data != buf + bufix + buflen && !ignore)
- log_debug ("accepting packet with data after udp payload.");
- if (len + data > buf + bufix + buflen) {
- log_debug ("dropping packet with bogus uh_ulen %ld",
- (long)(len + sizeof *udp));
- return -1;
- }
- }
-
- 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,
- 2 * sizeof ip -> ip_src,
- IPPROTO_UDP +
- (u_int32_t)ulen))));
-
- udp_packets_seen++;
- if (usum && usum != sum) {
- udp_packets_bad_checksum++;
- if (udp_packets_seen > 4 &&
- (udp_packets_seen / udp_packets_bad_checksum) < 2) {
- log_info ("%d bad udp checksums in %d packets",
- udp_packets_bad_checksum, udp_packets_seen);
- udp_packets_seen = udp_packets_bad_checksum = 0;
- }
- return -1;
- }
-
- /* 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/contrib/isc-dhcp/common/parse.c b/contrib/isc-dhcp/common/parse.c
deleted file mode 100644
index 90f01c3..0000000
--- a/contrib/isc-dhcp/common/parse.c
+++ /dev/null
@@ -1,4844 +0,0 @@
-/* parse.c
-
- Common parser code for dhcpd and dhclient. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: parse.c,v 1.104.2.17 2004/06/17 20:54:38 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"
-"$FreeBSD$";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-/* Enumerations can be specified in option formats, and are used for
- parsing, so we define the routines that manage them here. */
-
-struct enumeration *enumerations;
-
-void add_enumeration (struct enumeration *enumeration)
-{
- enumeration -> next = enumerations;
- enumerations = enumeration;
-}
-
-struct enumeration *find_enumeration (const char *name, int length)
-{
- struct enumeration *e;
-
- for (e = enumerations; e; e = e -> next)
- if (strlen (e -> name) == length &&
- !memcmp (e -> name, name, (unsigned)length))
- return e;
- return (struct enumeration *)0;
-}
-
-struct enumeration_value *find_enumeration_value (const char *name,
- int length,
- const char *value)
-{
- struct enumeration *e;
- int i;
-
- e = find_enumeration (name, length);
- if (e) {
- for (i = 0; e -> values [i].name; i++) {
- if (!strcmp (value, e -> values [i].name))
- return &e -> values [i];
- }
- }
- return (struct enumeration_value *)0;
-}
-
-/* Skip to the semicolon ending the current statement. If we encounter
- braces, the matching closing brace terminates the statement. If we
- encounter a right brace but haven't encountered a left brace, return
- leaving the brace in the token buffer for the caller. If we see a
- semicolon and haven't seen a left brace, return. This lets us skip
- over:
-
- statement;
- statement foo bar { }
- statement foo bar { statement { } }
- statement}
-
- ...et cetera. */
-
-void skip_to_semi (cfile)
- struct parse *cfile;
-{
- skip_to_rbrace (cfile, 0);
-}
-
-void skip_to_rbrace (cfile, brace_count)
- struct parse *cfile;
- int brace_count;
-{
- enum dhcp_token token;
- const char *val;
-
-#if defined (DEBUG_TOKEN)
- log_error ("skip_to_rbrace: %d\n", brace_count);
-#endif
- do {
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == RBRACE) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (brace_count) {
- if (!--brace_count)
- return;
- } else
- return;
- } else if (token == LBRACE) {
- brace_count++;
- } else if (token == SEMI && !brace_count) {
- token = next_token (&val, (unsigned *)0, cfile);
- return;
- } else if (token == EOL) {
- /* EOL only happens when parsing /etc/resolv.conf,
- and we treat it like a semicolon because the
- resolv.conf file is line-oriented. */
- token = next_token (&val, (unsigned *)0, cfile);
- return;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- } while (token != END_OF_FILE);
-}
-
-int parse_semi (cfile)
- struct parse *cfile;
-{
- enum dhcp_token token;
- const char *val;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != SEMI) {
- parse_warn (cfile, "semicolon expected.");
- skip_to_semi (cfile);
- return 0;
- }
- return 1;
-}
-
-/* string-parameter :== STRING SEMI */
-
-int parse_string (cfile, sptr, lptr)
- struct parse *cfile;
- char **sptr;
- unsigned *lptr;
-{
- const char *val;
- enum dhcp_token token;
- char *s;
- unsigned len;
-
- token = next_token (&val, &len, cfile);
- if (token != STRING) {
- parse_warn (cfile, "expecting a string");
- skip_to_semi (cfile);
- return 0;
- }
- s = (char *)dmalloc (len + 1, MDL);
- if (!s)
- log_fatal ("no memory for string %s.", val);
- memcpy (s, val, len + 1);
-
- if (!parse_semi (cfile)) {
- dfree (s, MDL);
- return 0;
- }
- if (sptr)
- *sptr = s;
- else
- dfree (s, MDL);
- if (lptr)
- *lptr = len;
- return 1;
-}
-
-/*
- * hostname :== IDENTIFIER
- * | IDENTIFIER DOT
- * | hostname DOT IDENTIFIER
- */
-
-char *parse_host_name (cfile)
- struct parse *cfile;
-{
- const char *val;
- enum dhcp_token token;
- unsigned len = 0;
- char *s;
- char *t;
- pair c = (pair)0;
- int ltid = 0;
-
- /* Read a dotted hostname... */
- do {
- /* Read a token, which should be an identifier. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token) && token != NUMBER)
- break;
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* Store this identifier... */
- if (!(s = (char *)dmalloc (strlen (val) + 1, MDL)))
- log_fatal ("can't allocate temp space for hostname.");
- strcpy (s, val);
- c = cons ((caddr_t)s, c);
- len += strlen (s) + 1;
- /* Look for a dot; if it's there, keep going, otherwise
- we're done. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == DOT) {
- token = next_token (&val, (unsigned *)0, cfile);
- ltid = 1;
- } else
- ltid = 0;
- } while (token == DOT);
-
- /* Should be at least one token. */
- if (!len)
- return (char *)0;
-
- /* Assemble the hostname together into a string. */
- if (!(s = (char *)dmalloc (len + ltid, MDL)))
- log_fatal ("can't allocate space for hostname.");
- t = s + len + ltid;
- *--t = 0;
- if (ltid)
- *--t = '.';
- while (c) {
- pair cdr = c -> cdr;
- unsigned l = strlen ((char *)(c -> car));
- t -= l;
- memcpy (t, (char *)(c -> car), l);
- /* Free up temp space. */
- dfree (c -> car, MDL);
- dfree (c, MDL);
- c = cdr;
- if (t != s)
- *--t = '.';
- }
- return s;
-}
-
-/* ip-addr-or-hostname :== ip-address | hostname
- ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
-
- Parse an ip address or a hostname. If uniform is zero, put in
- an expr_substring node to limit hostnames that evaluate to more
- than one IP address. */
-
-int parse_ip_addr_or_hostname (expr, cfile, uniform)
- struct expression **expr;
- struct parse *cfile;
- int uniform;
-{
- const char *val;
- enum dhcp_token token;
- unsigned char addr [4];
- unsigned len = sizeof addr;
- char *name;
- struct expression *x = (struct expression *)0;
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (is_identifier (token)) {
- name = parse_host_name (cfile);
- if (!name)
- return 0;
- if (!make_host_lookup (expr, name)) {
- dfree(name, MDL);
- return 0;
- }
- dfree(name, MDL);
- if (!uniform) {
- if (!make_limit (&x, *expr, 4))
- return 0;
- expression_dereference (expr, MDL);
- *expr = x;
- }
- } else if (token == NUMBER) {
- if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8))
- return 0;
- return make_const_data (expr, addr, len, 0, 1, MDL);
- } else {
- if (token != RBRACE && token != LBRACE)
- token = next_token (&val, (unsigned *)0, cfile);
- parse_warn (cfile, "%s (%d): expecting IP address or hostname",
- val, token);
- if (token != SEMI)
- skip_to_semi (cfile);
- return 0;
- }
-
- return 1;
-}
-
-/*
- * ip-address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
- */
-
-int parse_ip_addr (cfile, addr)
- struct parse *cfile;
- struct iaddr *addr;
-{
- const char *val;
- enum dhcp_token token;
-
- addr -> len = 4;
- if (parse_numeric_aggregate (cfile, addr -> iabuf,
- &addr -> len, DOT, 10, 8))
- return 1;
- return 0;
-}
-
-/*
- * hardware-parameter :== HARDWARE hardware-type colon-seperated-hex-list SEMI
- * hardware-type :== ETHERNET | TOKEN_RING | FDDI
- */
-
-void parse_hardware_param (cfile, hardware)
- struct parse *cfile;
- struct hardware *hardware;
-{
- const char *val;
- enum dhcp_token token;
- unsigned hlen;
- unsigned char *t;
-
- token = next_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case ETHERNET:
- hardware -> hbuf [0] = HTYPE_ETHER;
- break;
- case TOKEN_RING:
- hardware -> hbuf [0] = HTYPE_IEEE802;
- break;
- case FDDI:
- hardware -> hbuf [0] = HTYPE_FDDI;
- break;
- default:
- if (!strncmp (val, "unknown-", 8)) {
- hardware -> hbuf [0] = atoi (&val [8]);
- } else {
- parse_warn (cfile,
- "expecting a network hardware type");
- skip_to_semi (cfile);
-
- return;
- }
- }
-
- /* Parse the hardware address information. Technically,
- it would make a lot of sense to restrict the length of the
- data we'll accept here to the length of a particular hardware
- address type. Unfortunately, there are some broken clients
- out there that put bogus data in the chaddr buffer, and we accept
- that data in the lease file rather than simply failing on such
- clients. Yuck. */
- hlen = 0;
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == SEMI) {
- hardware -> hlen = 1;
- goto out;
- }
- t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen,
- COLON, 16, 8);
- if (!t) {
- hardware -> hlen = 1;
- return;
- }
- if (hlen + 1 > sizeof hardware -> hbuf) {
- dfree (t, MDL);
- parse_warn (cfile, "hardware address too long");
- } else {
- hardware -> hlen = hlen + 1;
- memcpy ((unsigned char *)&hardware -> hbuf [1], t, hlen);
- if (hlen + 1 < sizeof hardware -> hbuf)
- memset (&hardware -> hbuf [hlen + 1], 0,
- (sizeof hardware -> hbuf) - hlen - 1);
- dfree (t, MDL);
- }
-
- out:
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != SEMI) {
- parse_warn (cfile, "expecting semicolon.");
- skip_to_semi (cfile);
- }
-}
-
-/* lease-time :== NUMBER SEMI */
-
-void parse_lease_time (cfile, timep)
- struct parse *cfile;
- TIME *timep;
-{
- const char *val;
- enum dhcp_token token;
- int32_t num;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "Expecting numeric lease time");
- skip_to_semi (cfile);
- return;
- }
- convert_num (cfile, (unsigned char *)&num, val, 10, 32);
- /* Unswap the number - convert_num returns stuff in NBO. */
- *timep = ntohl (num);
-
- parse_semi (cfile);
-}
-
-/* No BNF for numeric aggregates - that's defined by the caller. What
- this function does is to parse a sequence of numbers seperated by
- the token specified in seperator. If max is zero, any number of
- numbers will be parsed; otherwise, exactly max numbers are
- expected. Base and size tell us how to internalize the numbers
- once they've been tokenized. */
-
-unsigned char *parse_numeric_aggregate (cfile, buf,
- max, seperator, base, size)
- struct parse *cfile;
- unsigned char *buf;
- unsigned *max;
- int seperator;
- int base;
- unsigned size;
-{
- const char *val;
- enum dhcp_token token;
- unsigned char *bufp = buf, *s, *t;
- unsigned count = 0;
- pair c = (pair)0;
-
- if (!bufp && *max) {
- bufp = (unsigned char *)dmalloc (*max * size / 8, MDL);
- if (!bufp)
- log_fatal ("no space for numeric aggregate");
- s = 0;
- } else
- s = bufp;
-
- do {
- if (count) {
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != seperator) {
- if (!*max)
- break;
- if (token != RBRACE && token != LBRACE)
- token = next_token (&val,
- (unsigned *)0,
- cfile);
- parse_warn (cfile, "too few numbers.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (unsigned char *)0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- }
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (token == END_OF_FILE) {
- parse_warn (cfile, "unexpected end of file");
- break;
- }
-
- /* Allow NUMBER_OR_NAME if base is 16. */
- if (token != NUMBER &&
- (base != 16 || token != NUMBER_OR_NAME)) {
- parse_warn (cfile, "expecting numeric value.");
- skip_to_semi (cfile);
- return (unsigned char *)0;
- }
- /* If we can, convert the number now; otherwise, build
- a linked list of all the numbers. */
- if (s) {
- convert_num (cfile, s, val, base, size);
- s += size / 8;
- } else {
- t = (unsigned char *)dmalloc (strlen (val) + 1, MDL);
- if (!t)
- log_fatal ("no temp space for number.");
- strcpy ((char *)t, val);
- c = cons ((caddr_t)t, c);
- }
- } while (++count != *max);
-
- /* If we had to cons up a list, convert it now. */
- if (c) {
- bufp = (unsigned char *)dmalloc (count * size / 8, MDL);
- if (!bufp)
- log_fatal ("no space for numeric aggregate.");
- s = bufp + count - size / 8;
- *max = count;
- }
- while (c) {
- pair cdr = c -> cdr;
- convert_num (cfile, s, (char *)(c -> car), base, size);
- s -= size / 8;
- /* Free up temp space. */
- dfree (c -> car, MDL);
- dfree (c, MDL);
- c = cdr;
- }
- return bufp;
-}
-
-void convert_num (cfile, buf, str, base, size)
- struct parse *cfile;
- unsigned char *buf;
- const char *str;
- int base;
- unsigned size;
-{
- const char *ptr = str;
- int negative = 0;
- u_int32_t val = 0;
- int tval;
- int max;
-
- if (*ptr == '-') {
- negative = 1;
- ++ptr;
- }
-
- /* If base wasn't specified, figure it out from the data. */
- if (!base) {
- if (ptr [0] == '0') {
- if (ptr [1] == 'x') {
- base = 16;
- ptr += 2;
- } else if (isascii (ptr [1]) && isdigit (ptr [1])) {
- base = 8;
- ptr += 1;
- } else {
- base = 10;
- }
- } else {
- base = 10;
- }
- }
-
- do {
- tval = *ptr++;
- /* XXX assumes ASCII... */
- if (tval >= 'a')
- tval = tval - 'a' + 10;
- else if (tval >= 'A')
- tval = tval - 'A' + 10;
- else if (tval >= '0')
- tval -= '0';
- else {
- parse_warn (cfile, "Bogus number: %s.", str);
- break;
- }
- if (tval >= base) {
- parse_warn (cfile,
- "Bogus number %s: digit %d not in base %d",
- str, tval, base);
- break;
- }
- val = val * base + tval;
- } while (*ptr);
-
- if (negative)
- max = (1 << (size - 1));
- else
- max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
- if (val > max) {
- switch (base) {
- case 8:
- parse_warn (cfile,
- "%s%lo exceeds max (%d) for precision.",
- negative ? "-" : "",
- (unsigned long)val, max);
- break;
- case 16:
- parse_warn (cfile,
- "%s%lx exceeds max (%d) for precision.",
- negative ? "-" : "",
- (unsigned long)val, max);
- break;
- default:
- parse_warn (cfile,
- "%s%lu exceeds max (%d) for precision.",
- negative ? "-" : "",
- (unsigned long)val, max);
- break;
- }
- }
-
- if (negative) {
- switch (size) {
- case 8:
- *buf = -(unsigned long)val;
- break;
- case 16:
- putShort (buf, -(long)val);
- break;
- case 32:
- putLong (buf, -(long)val);
- break;
- default:
- parse_warn (cfile,
- "Unexpected integer size: %d\n", size);
- break;
- }
- } else {
- switch (size) {
- case 8:
- *buf = (u_int8_t)val;
- break;
- case 16:
- putUShort (buf, (u_int16_t)val);
- break;
- case 32:
- putULong (buf, val);
- break;
- default:
- parse_warn (cfile,
- "Unexpected integer size: %d\n", size);
- break;
- }
- }
-}
-
-/*
- * date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
- * NUMBER COLON NUMBER COLON NUMBER SEMI |
- * NUMBER NUMBER SLASH NUMBER SLASH NUMBER
- * NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
- * NEVER
- *
- * Dates are stored in GMT or with a timezone offset; first number is day
- * of week; next is year/month/day; next is hours:minutes:seconds on a
- * 24-hour clock, followed by the timezone offset in seconds, which is
- * optional.
- */
-
-TIME parse_date (cfile)
- struct parse *cfile;
-{
- struct tm tm;
- int guess;
- int tzoff, wday, year, mon, mday, hour, min, sec;
- const char *val;
- enum dhcp_token token;
- static int months [11] = { 31, 59, 90, 120, 151, 181,
- 212, 243, 273, 304, 334 };
-
- /* Day of week, or "never"... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == NEVER) {
- if (!parse_semi (cfile))
- return 0;
- return MAX_TIME;
- }
-
- if (token != NUMBER) {
- parse_warn (cfile, "numeric day of week expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- wday = atoi (val);
-
- /* Year... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric year expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
-
- /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
- somebody invents a time machine, I think we can safely disregard
- it. This actually works around a stupid Y2K bug that was present
- in a very early beta release of dhcpd. */
- year = atoi (val);
- if (year > 1900)
- year -= 1900;
-
- /* Slash seperating year from month... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != SLASH) {
- parse_warn (cfile,
- "expected slash seperating year from month.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
-
- /* Month... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric month expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- mon = atoi (val) - 1;
-
- /* Slash seperating month from day... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != SLASH) {
- parse_warn (cfile,
- "expected slash seperating month from day.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
-
- /* Month... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric day of month expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- mday = atoi (val);
-
- /* Hour... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric hour expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- hour = atoi (val);
-
- /* Colon seperating hour from minute... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COLON) {
- parse_warn (cfile,
- "expected colon seperating hour from minute.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
-
- /* Minute... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric minute expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- min = atoi (val);
-
- /* Colon seperating minute from second... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COLON) {
- parse_warn (cfile,
- "expected colon seperating hour from minute.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
-
- /* Minute... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "numeric minute expected.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (TIME)0;
- }
- sec = atoi (val);
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == NUMBER) {
- token = next_token (&val, (unsigned *)0, cfile);
- tzoff = atoi (val);
- } else
- tzoff = 0;
-
- /* Make sure the date ends in a semicolon... */
- if (!parse_semi (cfile))
- return 0;
-
- /* Guess the time value... */
- guess = ((((((365 * (year - 70) + /* Days in years since '70 */
- (year - 69) / 4 + /* Leap days since '70 */
- (mon /* Days in months this year */
- ? months [mon - 1]
- : 0) +
- (mon > 1 && /* Leap day this year */
- !((year - 72) & 3)) +
- mday - 1) * 24) + /* Day of month */
- hour) * 60) +
- min) * 60) + sec + tzoff;
-
- /* This guess could be wrong because of leap seconds or other
- weirdness we don't know about that the system does. For
- now, we're just going to accept the guess, but at some point
- it might be nice to do a successive approximation here to
- get an exact value. Even if the error is small, if the
- server is restarted frequently (and thus the lease database
- is reread), the error could accumulate into something
- significant. */
-
- return guess;
-}
-
-/*
- * option-name :== IDENTIFIER |
- IDENTIFIER . IDENTIFIER
- */
-
-struct option *parse_option_name (cfile, allocate, known)
- struct parse *cfile;
- int allocate;
- int *known;
-{
- const char *val;
- enum dhcp_token token;
- char *uname;
- struct universe *universe;
- struct option *option;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile,
- "expecting identifier after option keyword.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct option *)0;
- }
- uname = dmalloc (strlen (val) + 1, MDL);
- if (!uname)
- log_fatal ("no memory for uname information.");
- strcpy (uname, val);
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == DOT) {
- /* Go ahead and take the DOT token... */
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* The next token should be an identifier... */
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile, "expecting identifier after '.'");
- if (token != SEMI)
- skip_to_semi (cfile);
- return (struct option *)0;
- }
-
- /* Look up the option name hash table for the specified
- uname. */
- universe = (struct universe *)0;
- if (!universe_hash_lookup (&universe, universe_hash,
- uname, 0, MDL)) {
- parse_warn (cfile, "no option space named %s.", uname);
- skip_to_semi (cfile);
- return (struct option *)0;
- }
- } else {
- /* Use the default hash table, which contains all the
- standard dhcp option names. */
- val = uname;
- universe = &dhcp_universe;
- }
-
- /* Look up the actual option info... */
- option = (struct option *)0;
- option_hash_lookup (&option, universe -> hash, val, 0, MDL);
-
- /* If we didn't get an option structure, it's an undefined option. */
- if (option) {
- if (known)
- *known = 1;
- } else {
- /* If we've been told to allocate, that means that this
- (might) be an option code definition, so we'll create
- an option structure just in case. */
- if (allocate) {
- option = new_option (MDL);
- if (val == uname)
- option -> name = val;
- else {
- char *s;
- dfree (uname, MDL);
- s = dmalloc (strlen (val) + 1, MDL);
- if (!s)
- log_fatal ("no memory for option %s.%s",
- universe -> name, val);
- strcpy (s, val);
- option -> name = s;
- }
- option -> universe = universe;
- option -> code = 0;
- return option;
- }
- if (val == uname)
- parse_warn (cfile, "no option named %s", val);
- else
- parse_warn (cfile, "no option named %s in space %s",
- val, uname);
- skip_to_semi (cfile);
- return (struct option *)0;
- }
-
- /* Free the initial identifier token. */
- dfree (uname, MDL);
- return option;
-}
-
-/* IDENTIFIER SEMI */
-
-void parse_option_space_decl (cfile)
- struct parse *cfile;
-{
- int token;
- const char *val;
- struct universe **ua, *nu;
- char *s;
-
- next_token (&val, (unsigned *)0, cfile); /* Discard the SPACE token,
- which was checked by the
- caller. */
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile, "expecting identifier.");
- skip_to_semi (cfile);
- return;
- }
- nu = new_universe (MDL);
- if (!nu)
- log_fatal ("No memory for new option space.");
-
- /* Set up the server option universe... */
- s = dmalloc (strlen (val) + 1, MDL);
- if (!s)
- log_fatal ("No memory for new option space name.");
- strcpy (s, val);
- nu -> name = s;
- nu -> lookup_func = lookup_hashed_option;
- nu -> option_state_dereference =
- hashed_option_state_dereference;
- nu -> foreach = hashed_option_space_foreach;
- nu -> save_func = save_hashed_option;
- nu -> delete_func = delete_hashed_option;
- nu -> encapsulate = hashed_option_space_encapsulate;
- nu -> decode = parse_option_buffer;
- nu -> length_size = 1;
- nu -> tag_size = 1;
- nu -> store_tag = putUChar;
- nu -> store_length = putUChar;
- nu -> index = universe_count++;
- if (nu -> index >= universe_max) {
- ua = dmalloc (universe_max * 2 * sizeof *ua, MDL);
- if (!ua)
- log_fatal ("No memory to expand option space array.");
- memcpy (ua, universes, universe_max * sizeof *ua);
- universe_max *= 2;
- dfree (universes, MDL);
- universes = ua;
- }
- universes [nu -> index] = nu;
- option_new_hash (&nu -> hash, 1, MDL);
- if (!nu -> hash)
- log_fatal ("Can't allocate %s option hash table.", nu -> name);
- universe_hash_add (universe_hash, nu -> name, 0, nu, MDL);
- parse_semi (cfile);
-}
-
-/* This is faked up to look good right now. Ideally, this should do a
- recursive parse and allow arbitrary data structure definitions, but for
- now it just allows you to specify a single type, an array of single types,
- a sequence of types, or an array of sequences of types.
-
- ocd :== NUMBER EQUALS ocsd SEMI
-
- ocsd :== ocsd_type |
- ocsd_type_sequence |
- ARRAY OF ocsd_simple_type_sequence
-
- ocsd_type_sequence :== LBRACE ocsd_types RBRACE
-
- ocsd_simple_type_sequence :== LBRACE ocsd_simple_types RBRACE
-
- ocsd_types :== ocsd_type |
- ocsd_types ocsd_type
-
- ocsd_type :== ocsd_simple_type |
- ARRAY OF ocsd_simple_type
-
- ocsd_simple_types :== ocsd_simple_type |
- ocsd_simple_types ocsd_simple_type
-
- ocsd_simple_type :== BOOLEAN |
- INTEGER NUMBER |
- SIGNED INTEGER NUMBER |
- UNSIGNED INTEGER NUMBER |
- IP-ADDRESS |
- TEXT |
- STRING |
- ENCAPSULATE identifier */
-
-int parse_option_code_definition (cfile, option)
- struct parse *cfile;
- struct option *option;
-{
- const char *val;
- enum dhcp_token token;
- unsigned arrayp = 0;
- int recordp = 0;
- int no_more_in_record = 0;
- char tokbuf [128];
- unsigned tokix = 0;
- char type;
- int code;
- int is_signed;
- char *s;
- int has_encapsulation = 0;
-
- /* Parse the option code. */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "expecting option code number.");
- skip_to_semi (cfile);
- return 0;
- }
- option -> code = atoi (val);
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != EQUAL) {
- parse_warn (cfile, "expecting \"=\"");
- skip_to_semi (cfile);
- return 0;
- }
-
- /* See if this is an array. */
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == ARRAY) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != OF) {
- parse_warn (cfile, "expecting \"of\".");
- skip_to_semi (cfile);
- return 0;
- }
- arrayp = 1;
- token = next_token (&val, (unsigned *)0, cfile);
- }
-
- if (token == LBRACE) {
- recordp = 1;
- token = next_token (&val, (unsigned *)0, cfile);
- }
-
- /* At this point we're expecting a data type. */
- next_type:
- if (has_encapsulation) {
- parse_warn (cfile,
- "encapsulate must always be the last item.");
- skip_to_semi (cfile);
- return 0;
- }
-
- switch (token) {
- case ARRAY:
- if (arrayp) {
- parse_warn (cfile, "no nested arrays.");
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != OF) {
- parse_warn (cfile, "expecting \"of\".");
- skip_to_semi (cfile);
- return 0;
- }
- arrayp = recordp + 1;
- token = next_token (&val, (unsigned *)0, cfile);
- if ((recordp) && (token == LBRACE)) {
- parse_warn (cfile,
- "only uniform array inside record.");
- skip_to_rbrace (cfile, recordp + 1);
- skip_to_semi (cfile);
- return 0;
- }
- goto next_type;
- case BOOLEAN:
- type = 'f';
- break;
- case INTEGER:
- is_signed = 1;
- parse_integer:
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "expecting number.");
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- switch (atoi (val)) {
- case 8:
- type = is_signed ? 'b' : 'B';
- break;
- case 16:
- type = is_signed ? 's' : 'S';
- break;
- case 32:
- type = is_signed ? 'l' : 'L';
- break;
- default:
- parse_warn (cfile,
- "%s bit precision is not supported.", val);
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- break;
- case SIGNED:
- is_signed = 1;
- parse_signed:
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != INTEGER) {
- parse_warn (cfile, "expecting \"integer\" keyword.");
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- goto parse_integer;
- case UNSIGNED:
- is_signed = 0;
- goto parse_signed;
-
- case IP_ADDRESS:
- type = 'I';
- break;
- case DOMAIN_NAME:
- type = 'd';
- goto no_arrays;
- case TEXT:
- type = 't';
- no_arrays:
- if (arrayp) {
- parse_warn (cfile, "arrays of text strings not %s",
- "yet supported.");
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- no_more_in_record = 1;
- break;
- case STRING_TOKEN:
- type = 'X';
- goto no_arrays;
-
- case ENCAPSULATE:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile,
- "expecting option space identifier");
- skip_to_semi (cfile);
- return 0;
- }
- if (strlen (val) + tokix + 2 > sizeof (tokbuf))
- goto toobig;
- tokbuf [tokix++] = 'E';
- strcpy (&tokbuf [tokix], val);
- tokix += strlen (val);
- type = '.';
- has_encapsulation = 1;
- break;
-
- default:
- parse_warn (cfile, "unknown data type %s", val);
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
-
- if (tokix == sizeof tokbuf) {
- toobig:
- parse_warn (cfile, "too many types in record.");
- skip_to_rbrace (cfile, recordp);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- tokbuf [tokix++] = type;
-
- if (recordp) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (arrayp > recordp) {
- if (tokix == sizeof tokbuf) {
- parse_warn (cfile,
- "too many types in record.");
- skip_to_rbrace (cfile, 1);
- skip_to_semi (cfile);
- return 0;
- }
- arrayp = 0;
- tokbuf[tokix++] = 'a';
- }
- if (token == COMMA) {
- if (no_more_in_record) {
- parse_warn (cfile,
- "%s must be at end of record.",
- type == 't' ? "text" : "string");
- skip_to_rbrace (cfile, 1);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- goto next_type;
- }
- if (token != RBRACE) {
- parse_warn (cfile, "expecting right brace.");
- skip_to_rbrace (cfile, 1);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- }
- if (!parse_semi (cfile)) {
- parse_warn (cfile, "semicolon expected.");
- skip_to_semi (cfile);
- if (recordp)
- skip_to_semi (cfile);
- return 0;
- }
- if (has_encapsulation && arrayp) {
- parse_warn (cfile,
- "Arrays of encapsulations don't make sense.");
- return 0;
- }
- if (has_encapsulation && tokbuf [0] == 'E')
- has_encapsulation = 0;
- s = dmalloc (tokix +
- (arrayp ? 1 : 0) +
- (has_encapsulation ? 1 : 0) + 1, MDL);
- if (!s)
- log_fatal ("no memory for option format.");
- if (has_encapsulation)
- s [0] = 'e';
- memcpy (s + has_encapsulation, tokbuf, tokix);
- tokix += has_encapsulation;
- if (arrayp)
- s [tokix++] = (arrayp > recordp) ? 'a' : 'A';
- s [tokix] = 0;
- option -> format = s;
- if (option -> universe -> options [option -> code]) {
- /* XXX Free the option, but we can't do that now because they
- XXX may start out static. */
- }
- option -> universe -> options [option -> code] = option;
- option_hash_add (option -> universe -> hash,
- (const char *)option -> name,
- 0, option, MDL);
- return 1;
-}
-
-/*
- * base64 :== NUMBER_OR_STRING
- */
-
-int parse_base64 (data, cfile)
- struct data_string *data;
- struct parse *cfile;
-{
- enum dhcp_token token;
- const char *val;
- int i, j, k;
- unsigned acc = 0;
- static unsigned char
- from64 [] = {64, 64, 64, 64, 64, 64, 64, 64, /* \"#$%&' */
- 64, 64, 64, 62, 64, 64, 64, 63, /* ()*+,-./ */
- 52, 53, 54, 55, 56, 57, 58, 59, /* 01234567 */
- 60, 61, 64, 64, 64, 64, 64, 64, /* 89:;<=>? */
- 64, 0, 1, 2, 3, 4, 5, 6, /* @ABCDEFG */
- 7, 8, 9, 10, 11, 12, 13, 14, /* HIJKLMNO */
- 15, 16, 17, 18, 19, 20, 21, 22, /* PQRSTUVW */
- 23, 24, 25, 64, 64, 64, 64, 64, /* XYZ[\]^_ */
- 64, 26, 27, 28, 29, 30, 31, 32, /* 'abcdefg */
- 33, 34, 35, 36, 37, 38, 39, 40, /* hijklmno */
- 41, 42, 43, 44, 45, 46, 47, 48, /* pqrstuvw */
- 49, 50, 51, 64, 64, 64, 64, 64}; /* xyz{|}~ */
- struct string_list *bufs = (struct string_list *)0,
- *last = (struct string_list *)0,
- *t;
- int cc = 0;
- int terminated = 0;
-
- /* It's possible for a + or a / to cause a base64 quantity to be
- tokenized into more than one token, so we have to parse them all
- in before decoding. */
- do {
- unsigned l;
-
- token = next_token (&val, &l, cfile);
- t = dmalloc (l + sizeof *t, MDL);
- if (!t)
- log_fatal ("no memory for base64 buffer.");
- memset (t, 0, (sizeof *t) - 1);
- memcpy (t -> string, val, l + 1);
- cc += l;
- if (last)
- last -> next = t;
- else
- bufs = t;
- last = t;
- token = peek_token (&val, (unsigned *)0, cfile);
- } while (token == NUMBER_OR_NAME || token == NAME || token == EQUAL ||
- token == NUMBER || token == PLUS || token == SLASH ||
- token == STRING);
-
- data -> len = cc;
- data -> len = (data -> len * 3) / 4;
- if (!buffer_allocate (&data -> buffer, data -> len, MDL)) {
- parse_warn (cfile, "can't allocate buffer for base64 data.");
- data -> len = 0;
- data -> data = (unsigned char *)0;
- return 0;
- }
-
- j = k = 0;
- for (t = bufs; t; t = t -> next) {
- for (i = 0; t -> string [i]; i++) {
- unsigned foo = t -> string [i];
- if (terminated && foo != '=') {
- parse_warn (cfile,
- "stuff after base64 '=' terminator: %s.",
- &t -> string [i]);
- goto bad;
- }
- if (foo < ' ' || foo > 'z') {
- bad64:
- parse_warn (cfile,
- "invalid base64 character %d.",
- t -> string [i]);
- bad:
- data_string_forget (data, MDL);
- goto out;
- }
- if (foo == '=')
- terminated = 1;
- else {
- foo = from64 [foo - ' '];
- if (foo == 64)
- goto bad64;
- acc = (acc << 6) + foo;
- switch (k % 4) {
- case 0:
- break;
- case 1:
- data -> buffer -> data [j++] = (acc >> 4);
- acc = acc & 0x0f;
- break;
-
- case 2:
- data -> buffer -> data [j++] = (acc >> 2);
- acc = acc & 0x03;
- break;
- case 3:
- data -> buffer -> data [j++] = acc;
- acc = 0;
- break;
- }
- }
- k++;
- }
- }
- if (k % 4) {
- if (acc) {
- parse_warn (cfile,
- "partial base64 value left over: %d.",
- acc);
- }
- }
- data -> len = j;
- data -> data = data -> buffer -> data;
- out:
- for (t = bufs; t; t = last) {
- last = t -> next;
- dfree (t, MDL);
- }
- if (data -> len)
- return 1;
- else
- return 0;
-}
-
-
-/*
- * colon-seperated-hex-list :== NUMBER |
- * NUMBER COLON colon-seperated-hex-list
- */
-
-int parse_cshl (data, cfile)
- struct data_string *data;
- struct parse *cfile;
-{
- u_int8_t ibuf [128];
- unsigned ilen = 0;
- unsigned tlen = 0;
- struct option_tag *sl = (struct option_tag *)0;
- struct option_tag *next, **last = &sl;
- enum dhcp_token token;
- const char *val;
- unsigned char *rvp;
-
- do {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER && token != NUMBER_OR_NAME) {
- parse_warn (cfile, "expecting hexadecimal number.");
- skip_to_semi (cfile);
- for (; sl; sl = next) {
- next = sl -> next;
- dfree (sl, MDL);
- }
- return 0;
- }
- if (ilen == sizeof ibuf) {
- next = (struct option_tag *)
- dmalloc (ilen - 1 +
- sizeof (struct option_tag), MDL);
- if (!next)
- log_fatal ("no memory for string list.");
- memcpy (next -> data, ibuf, ilen);
- *last = next;
- last = &next -> next;
- tlen += ilen;
- ilen = 0;
- }
- convert_num (cfile, &ibuf [ilen++], val, 16, 8);
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != COLON)
- break;
- token = next_token (&val, (unsigned *)0, cfile);
- } while (1);
-
- if (!buffer_allocate (&data -> buffer, tlen + ilen, MDL))
- log_fatal ("no memory to store octet data.");
- data -> data = &data -> buffer -> data [0];
- data -> len = tlen + ilen;
- data -> terminated = 0;
-
- rvp = &data -> buffer -> data [0];
- while (sl) {
- next = sl -> next;
- memcpy (rvp, sl -> data, sizeof ibuf);
- rvp += sizeof ibuf;
- dfree (sl, MDL);
- sl = next;
- }
-
- memcpy (rvp, ibuf, ilen);
- return 1;
-}
-
-/*
- * executable-statements :== executable-statement executable-statements |
- * executable-statement
- *
- * executable-statement :==
- * IF if-statement |
- * ADD class-name SEMI |
- * BREAK SEMI |
- * OPTION option-parameter SEMI |
- * SUPERSEDE option-parameter SEMI |
- * PREPEND option-parameter SEMI |
- * APPEND option-parameter SEMI
- */
-
-int parse_executable_statements (statements, cfile, lose, case_context)
- struct executable_statement **statements;
- struct parse *cfile;
- int *lose;
- enum expression_context case_context;
-{
- struct executable_statement **next;
-
- next = statements;
- while (parse_executable_statement (next, cfile, lose, case_context))
- next = &((*next) -> next);
- if (!*lose)
- return 1;
- return 0;
-}
-
-int parse_executable_statement (result, cfile, lose, case_context)
- struct executable_statement **result;
- struct parse *cfile;
- int *lose;
- enum expression_context case_context;
-{
- enum dhcp_token token;
- const char *val;
- struct executable_statement base;
- struct class *cta;
- struct option *option;
- struct option_cache *cache;
- int known;
- int flag;
- int i;
- struct dns_zone *zone;
- isc_result_t status;
- char *s;
-
- token = peek_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case IF:
- next_token (&val, (unsigned *)0, cfile);
- return parse_if_statement (result, cfile, lose);
-
- case TOKEN_ADD:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != STRING) {
- parse_warn (cfile, "expecting class name.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
- cta = (struct class *)0;
- status = find_class (&cta, val, MDL);
- if (status != ISC_R_SUCCESS) {
- parse_warn (cfile, "class %s: %s",
- val, isc_result_totext (status));
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- return 0;
- }
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = add_statement;
- (*result) -> data.add = cta;
- break;
-
- case BREAK:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_semi (cfile)) {
- *lose = 1;
- return 0;
- }
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = break_statement;
- break;
-
- case SEND:
- token = next_token (&val, (unsigned *)0, cfile);
- known = 0;
- option = parse_option_name (cfile, 0, &known);
- if (!option) {
- *lose = 1;
- return 0;
- }
- return parse_option_statement (result, cfile, 1, option,
- send_option_statement);
-
- case SUPERSEDE:
- case OPTION:
- token = next_token (&val, (unsigned *)0, cfile);
- known = 0;
- option = parse_option_name (cfile, 0, &known);
- if (!option) {
- *lose = 1;
- return 0;
- }
- return parse_option_statement (result, cfile, 1, option,
- supersede_option_statement);
-
- case ALLOW:
- flag = 1;
- goto pad;
- case DENY:
- flag = 0;
- goto pad;
- case IGNORE:
- flag = 2;
- pad:
- token = next_token (&val, (unsigned *)0, cfile);
- cache = (struct option_cache *)0;
- if (!parse_allow_deny (&cache, cfile, flag))
- return 0;
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = supersede_option_statement;
- (*result) -> data.option = cache;
- break;
-
- case DEFAULT:
- token = next_token (&val, (unsigned *)0, cfile);
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == COLON)
- goto switch_default;
- known = 0;
- option = parse_option_name (cfile, 0, &known);
- if (!option) {
- *lose = 1;
- return 0;
- }
- return parse_option_statement (result, cfile, 1, option,
- default_option_statement);
-
- case PREPEND:
- token = next_token (&val, (unsigned *)0, cfile);
- known = 0;
- option = parse_option_name (cfile, 0, &known);
- if (!option) {
- *lose = 1;
- return 0;
- }
- return parse_option_statement (result, cfile, 1, option,
- prepend_option_statement);
-
- case APPEND:
- token = next_token (&val, (unsigned *)0, cfile);
- known = 0;
- option = parse_option_name (cfile, 0, &known);
- if (!option) {
- *lose = 1;
- return 0;
- }
- return parse_option_statement (result, cfile, 1, option,
- append_option_statement);
-
- case ON:
- token = next_token (&val, (unsigned *)0, cfile);
- return parse_on_statement (result, cfile, lose);
-
- case SWITCH:
- token = next_token (&val, (unsigned *)0, cfile);
- return parse_switch_statement (result, cfile, lose);
-
- case CASE:
- token = next_token (&val, (unsigned *)0, cfile);
- if (case_context == context_any) {
- parse_warn (cfile,
- "case statement in inappropriate scope.");
- *lose = 1;
- skip_to_semi (cfile);
- return 0;
- }
- return parse_case_statement (result,
- cfile, lose, case_context);
-
- switch_default:
- token = next_token (&val, (unsigned *)0, cfile);
- if (case_context == context_any) {
- parse_warn (cfile, "switch default statement in %s",
- "inappropriate scope.");
-
- *lose = 1;
- return 0;
- } else {
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for default statement.");
- (*result) -> op = default_statement;
- return 1;
- }
-
- case DEFINE:
- case TOKEN_SET:
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == DEFINE)
- flag = 1;
- else
- flag = 0;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NAME && token != NUMBER_OR_NAME) {
- parse_warn (cfile,
- "%s can't be a variable name", val);
- badset:
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for set statement.");
- (*result) -> op = flag ? define_statement : set_statement;
- (*result) -> data.set.name = dmalloc (strlen (val) + 1, MDL);
- if (!(*result)->data.set.name)
- log_fatal ("can't allocate variable name");
- strcpy ((*result) -> data.set.name, val);
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (token == LPAREN) {
- struct string_list *head, *cur, *new;
- struct expression *expr;
- head = cur = (struct string_list *)0;
- do {
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (token == RPAREN)
- break;
- if (token != NAME && token != NUMBER_OR_NAME) {
- parse_warn (cfile,
- "expecting argument name");
- skip_to_rbrace (cfile, 0);
- *lose = 1;
- executable_statement_dereference
- (result, MDL);
- return 0;
- }
- new = ((struct string_list *)
- dmalloc (sizeof (struct string_list) +
- strlen (val), MDL));
- if (!new)
- log_fatal ("can't allocate string.");
- memset (new, 0, sizeof *new);
- strcpy (new -> string, val);
- if (cur) {
- cur -> next = new;
- cur = new;
- } else {
- head = cur = new;
- }
- token = next_token (&val,
- (unsigned *)0, cfile);
- } while (token == COMMA);
-
- if (token != RPAREN) {
- parse_warn (cfile, "expecting right paren.");
- badx:
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LBRACE) {
- parse_warn (cfile, "expecting left brace.");
- goto badx;
- }
-
- expr = (struct expression *)0;
- if (!(expression_allocate (&expr, MDL)))
- log_fatal ("can't allocate expression.");
- expr -> op = expr_function;
- if (!fundef_allocate (&expr -> data.func, MDL))
- log_fatal ("can't allocate fundef.");
- expr -> data.func -> args = head;
- (*result) -> data.set.expr = expr;
-
- if (!(parse_executable_statements
- (&expr -> data.func -> statements, cfile, lose,
- case_context))) {
- if (*lose)
- goto badx;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "expecting rigt brace.");
- goto badx;
- }
- } else {
- if (token != EQUAL) {
- parse_warn (cfile,
- "expecting '=' in %s statement.",
- flag ? "define" : "set");
- goto badset;
- }
-
- if (!parse_expression (&(*result) -> data.set.expr,
- cfile, lose, context_any,
- (struct expression **)0,
- expr_none)) {
- if (!*lose)
- parse_warn (cfile,
- "expecting expression.");
- else
- *lose = 1;
- skip_to_semi (cfile);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- break;
-
- case UNSET:
- token = next_token (&val, (unsigned *)0, cfile);
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NAME && token != NUMBER_OR_NAME) {
- parse_warn (cfile,
- "%s can't be a variable name", val);
- badunset:
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for set statement.");
- (*result) -> op = unset_statement;
- (*result) -> data.unset = dmalloc (strlen (val) + 1, MDL);
- if (!(*result)->data.unset)
- log_fatal ("can't allocate variable name");
- strcpy ((*result) -> data.unset, val);
- if (!parse_semi (cfile)) {
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- break;
-
- case EVAL:
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for eval statement.");
- (*result) -> op = eval_statement;
-
- if (!parse_expression (&(*result) -> data.eval,
- cfile, lose, context_data, /* XXX */
- (struct expression **)0, expr_none)) {
- if (!*lose)
- parse_warn (cfile,
- "expecting data expression.");
- else
- *lose = 1;
- skip_to_semi (cfile);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- executable_statement_dereference (result, MDL);
- }
- break;
-
- case RETURN:
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for return statement.");
- (*result) -> op = return_statement;
-
- if (!parse_expression (&(*result) -> data.retval,
- cfile, lose, context_data,
- (struct expression **)0, expr_none)) {
- if (!*lose)
- parse_warn (cfile,
- "expecting data expression.");
- else
- *lose = 1;
- skip_to_semi (cfile);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- break;
-
- case LOG:
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for log statement.");
- (*result) -> op = log_statement;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- parse_warn (cfile, "left parenthesis expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- token = peek_token (&val, (unsigned *)0, cfile);
- i = 1;
- if (token == FATAL) {
- (*result) -> data.log.priority = log_priority_fatal;
- } else if (token == ERROR) {
- (*result) -> data.log.priority = log_priority_error;
- } else if (token == TOKEN_DEBUG) {
- (*result) -> data.log.priority = log_priority_debug;
- } else if (token == INFO) {
- (*result) -> data.log.priority = log_priority_info;
- } else {
- (*result) -> data.log.priority = log_priority_debug;
- i = 0;
- }
- if (i) {
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA) {
- parse_warn (cfile, "comma expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
- }
-
- if (!(parse_data_expression
- (&(*result) -> data.log.expr, cfile, lose))) {
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- parse_warn (cfile, "right parenthesis expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != SEMI) {
- parse_warn (cfile, "semicolon expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
- break;
-
- /* Not really a statement, but we parse it here anyway
- because it's appropriate for all DHCP agents with
- parsers. */
- case ZONE:
- token = next_token (&val, (unsigned *)0, cfile);
- zone = (struct dns_zone *)0;
- if (!dns_zone_allocate (&zone, MDL))
- log_fatal ("no memory for new zone.");
- zone -> name = parse_host_name (cfile);
- if (!zone -> name) {
- parse_warn (cfile, "expecting hostname.");
- badzone:
- *lose = 1;
- skip_to_semi (cfile);
- dns_zone_dereference (&zone, MDL);
- return 0;
- }
- i = strlen (zone -> name);
- if (zone -> name [i - 1] != '.') {
- s = dmalloc ((unsigned)i + 2, MDL);
- if (!s) {
- parse_warn (cfile, "no trailing '.' on zone");
- goto badzone;
- }
- strcpy (s, zone -> name);
- s [i] = '.';
- s [i + 1] = 0;
- dfree (zone -> name, MDL);
- zone -> name = s;
- }
- if (!parse_zone (zone, cfile))
- goto badzone;
- status = enter_dns_zone (zone);
- if (status != ISC_R_SUCCESS) {
- parse_warn (cfile, "dns zone key %s: %s",
- zone -> name, isc_result_totext (status));
- dns_zone_dereference (&zone, MDL);
- return 0;
- }
- dns_zone_dereference (&zone, MDL);
- return 1;
-
- /* Also not really a statement, but same idea as above. */
- case KEY:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_key (cfile)) {
- *lose = 1;
- return 0;
- }
- return 1;
-
- default:
- if (config_universe && is_identifier (token)) {
- option = (struct option *)0;
- option_hash_lookup (&option, config_universe -> hash,
- val, 0, MDL);
- if (option) {
- token = next_token (&val,
- (unsigned *)0, cfile);
- return parse_option_statement
- (result, cfile, 1, option,
- supersede_option_statement);
- }
- }
-
- if (token == NUMBER_OR_NAME || token == NAME) {
- /* This is rather ugly. Since function calls are
- data expressions, fake up an eval statement. */
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for eval statement.");
- (*result) -> op = eval_statement;
-
- if (!parse_expression (&(*result) -> data.eval,
- cfile, lose, context_data,
- (struct expression **)0,
- expr_none)) {
- if (!*lose)
- parse_warn (cfile, "expecting "
- "function call.");
- else
- *lose = 1;
- skip_to_semi (cfile);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_semi (cfile)) {
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- break;
- }
-
- *lose = 0;
- return 0;
- }
-
- return 1;
-}
-
-/* zone-statements :== zone-statement |
- zone-statement zone-statements
- zone-statement :==
- PRIMARY ip-addresses SEMI |
- SECONDARY ip-addresses SEMI |
- key-reference SEMI
- ip-addresses :== ip-addr-or-hostname |
- ip-addr-or-hostname COMMA ip-addresses
- key-reference :== KEY STRING |
- KEY identifier */
-
-int parse_zone (struct dns_zone *zone, struct parse *cfile)
-{
- int token;
- const char *val;
- char *key_name;
- struct option_cache *oc;
- int done = 0;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LBRACE) {
- parse_warn (cfile, "expecting left brace");
- return 0;
- }
-
- do {
- token = peek_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case PRIMARY:
- if (zone -> primary) {
- parse_warn (cfile,
- "more than one primary.");
- skip_to_semi (cfile);
- return 0;
- }
- if (!option_cache_allocate (&zone -> primary, MDL))
- log_fatal ("can't allocate primary option cache.");
- oc = zone -> primary;
- goto consemup;
-
- case SECONDARY:
- if (zone -> secondary) {
- parse_warn (cfile, "more than one secondary.");
- skip_to_semi (cfile);
- return 0;
- }
- if (!option_cache_allocate (&zone -> secondary, MDL))
- log_fatal ("can't allocate secondary.");
- oc = zone -> secondary;
- consemup:
- token = next_token (&val, (unsigned *)0, cfile);
- do {
- struct expression *expr = (struct expression *)0;
- if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) {
- parse_warn (cfile,
- "expecting IP addr or hostname.");
- skip_to_semi (cfile);
- return 0;
- }
- if (oc -> expression) {
- struct expression *old =
- (struct expression *)0;
- expression_reference (&old,
- oc -> expression,
- MDL);
- expression_dereference (&oc -> expression,
- MDL);
- if (!make_concat (&oc -> expression,
- old, expr))
- log_fatal ("no memory for concat.");
- expression_dereference (&expr, MDL);
- expression_dereference (&old, MDL);
- } else {
- expression_reference (&oc -> expression,
- expr, MDL);
- expression_dereference (&expr, MDL);
- }
- token = next_token (&val, (unsigned *)0, cfile);
- } while (token == COMMA);
- if (token != SEMI) {
- parse_warn (cfile, "expecting semicolon.");
- skip_to_semi (cfile);
- return 0;
- }
- break;
-
- case KEY:
- token = next_token (&val, (unsigned *)0, cfile);
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == STRING) {
- token = next_token (&val, (unsigned *)0, cfile);
- key_name = (char *)0;
- } else {
- key_name = parse_host_name (cfile);
- if (!key_name) {
- parse_warn (cfile, "expecting key name.");
- skip_to_semi (cfile);
- return 0;
- }
- val = key_name;
- }
- if (omapi_auth_key_lookup_name (&zone -> key, val) !=
- ISC_R_SUCCESS)
- parse_warn (cfile, "unknown key %s", val);
- if (key_name)
- dfree (key_name, MDL);
- if (!parse_semi (cfile))
- return 0;
- break;
-
- default:
- done = 1;
- break;
- }
- } while (!done);
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "expecting right brace.");
- return 0;
- }
- return 1;
-}
-
-/* key-statements :== key-statement |
- key-statement key-statements
- key-statement :==
- ALGORITHM host-name SEMI |
- secret-definition SEMI
- secret-definition :== SECRET base64val |
- SECRET STRING */
-
-int parse_key (struct parse *cfile)
-{
- int token;
- const char *val;
- int done = 0;
- struct auth_key *key;
- struct data_string ds;
- isc_result_t status;
- char *s;
-
- key = (struct auth_key *)0;
- if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS)
- log_fatal ("no memory for key");
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == STRING) {
- token = next_token (&val, (unsigned *)0, cfile);
- key -> name = dmalloc (strlen (val) + 1, MDL);
- if (!key -> name)
- log_fatal ("no memory for key name.");
- strcpy (key -> name, val);
-
- } else {
- key -> name = parse_host_name (cfile);
- if (!key -> name) {
- parse_warn (cfile, "expecting key name.");
- skip_to_semi (cfile);
- goto bad;
- }
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LBRACE) {
- parse_warn (cfile, "expecting left brace");
- goto bad;
- }
-
- do {
- token = next_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case ALGORITHM:
- if (key -> algorithm) {
- parse_warn (cfile,
- "key %s: too many algorithms",
- key -> name);
- goto rbad;
- }
- key -> algorithm = parse_host_name (cfile);
- if (!key -> algorithm) {
- parse_warn (cfile,
- "expecting key algorithm name.");
- goto rbad;
- }
- if (!parse_semi (cfile))
- goto rbad;
- /* If the algorithm name isn't an FQDN, tack on
- the .SIG-ALG.REG.NET. domain. */
- s = strrchr (key -> algorithm, '.');
- if (!s) {
- static char add [] = ".SIG-ALG.REG.INT.";
- s = dmalloc (strlen (key -> algorithm) +
- sizeof (add), MDL);
- if (!s) {
- log_error ("no memory for key %s.",
- "algorithm");
- goto rbad;
- }
- strcpy (s, key -> algorithm);
- strcat (s, add);
- dfree (key -> algorithm, MDL);
- key -> algorithm = s;
- } else if (s [1]) {
- /* If there is no trailing '.', hack one in. */
- s = dmalloc (strlen (key -> algorithm) + 2, MDL);
- if (!s) {
- log_error ("no memory for key %s.",
- key -> algorithm);
- goto rbad;
- }
- strcpy (s, key -> algorithm);
- strcat (s, ".");
- dfree (key -> algorithm, MDL);
- key -> algorithm = s;
- }
- break;
-
- case SECRET:
- if (key -> key) {
- parse_warn (cfile, "key %s: too many secrets",
- key -> name);
- goto rbad;
- }
-
- memset (&ds, 0, sizeof(ds));
- if (!parse_base64 (&ds, cfile))
- goto rbad;
- status = omapi_data_string_new (&key -> key, ds.len,
- MDL);
- if (status != ISC_R_SUCCESS)
- goto rbad;
- memcpy (key -> key -> value,
- ds.buffer -> data, ds.len);
- data_string_forget (&ds, MDL);
-
- if (!parse_semi (cfile))
- goto rbad;
- break;
-
- default:
- done = 1;
- break;
- }
- } while (!done);
- if (token != RBRACE) {
- parse_warn (cfile, "expecting right brace.");
- goto rbad;
- }
- /* Allow the BIND 8 syntax, which has a semicolon after each
- closing brace. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == SEMI)
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* Remember the key. */
- status = omapi_auth_key_enter (key);
- if (status != ISC_R_SUCCESS) {
- parse_warn (cfile, "tsig key %s: %s",
- key -> name, isc_result_totext (status));
- goto bad;
- }
- omapi_auth_key_dereference (&key, MDL);
- return 1;
-
- rbad:
- skip_to_rbrace (cfile, 1);
- bad:
- omapi_auth_key_dereference (&key, MDL);
- return 0;
-}
-
-/*
- * on-statement :== event-types LBRACE executable-statements RBRACE
- * event-types :== event-type OR event-types |
- * event-type
- * event-type :== EXPIRY | COMMIT | RELEASE
- */
-
-int parse_on_statement (result, cfile, lose)
- struct executable_statement **result;
- struct parse *cfile;
- int *lose;
-{
- enum dhcp_token token;
- const char *val;
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = on_statement;
-
- do {
- token = next_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case EXPIRY:
- (*result) -> data.on.evtypes |= ON_EXPIRY;
- break;
-
- case COMMIT:
- (*result) -> data.on.evtypes |= ON_COMMIT;
- break;
-
- case RELEASE:
- (*result) -> data.on.evtypes |= ON_RELEASE;
- break;
-
- case TRANSMISSION:
- (*result) -> data.on.evtypes |= ON_TRANSMISSION;
- break;
-
- default:
- parse_warn (cfile, "expecting a lease event type");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- } while (token == OR);
-
- /* Semicolon means no statements. */
- if (token == SEMI)
- return 1;
-
- if (token != LBRACE) {
- parse_warn (cfile, "left brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_executable_statements (&(*result) -> data.on.statements,
- cfile, lose, context_any)) {
- if (*lose) {
- /* Try to even things up. */
- do {
- token = next_token (&val,
- (unsigned *)0, cfile);
- } while (token != END_OF_FILE && token != RBRACE);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "right brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- return 1;
-}
-
-/*
- * switch-statement :== LPAREN expr RPAREN LBRACE executable-statements RBRACE
- *
- */
-
-int parse_switch_statement (result, cfile, lose)
- struct executable_statement **result;
- struct parse *cfile;
- int *lose;
-{
- enum dhcp_token token;
- const char *val;
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = switch_statement;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- parse_warn (cfile, "expecting left brace.");
- pfui:
- *lose = 1;
- skip_to_semi (cfile);
- gnorf:
- executable_statement_dereference (result, MDL);
- return 0;
- }
-
- if (!parse_expression (&(*result) -> data.s_switch.expr,
- cfile, lose, context_data_or_numeric,
- (struct expression **)0, expr_none)) {
- if (!*lose) {
- parse_warn (cfile,
- "expecting data or numeric expression.");
- goto pfui;
- }
- goto gnorf;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- parse_warn (cfile, "right paren expected.");
- goto pfui;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LBRACE) {
- parse_warn (cfile, "left brace expected.");
- goto pfui;
- }
- if (!(parse_executable_statements
- (&(*result) -> data.s_switch.statements, cfile, lose,
- (is_data_expression ((*result) -> data.s_switch.expr)
- ? context_data : context_numeric)))) {
- if (*lose) {
- skip_to_rbrace (cfile, 1);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "right brace expected.");
- goto pfui;
- }
- return 1;
-}
-
-/*
- * case-statement :== CASE expr COLON
- *
- */
-
-int parse_case_statement (result, cfile, lose, case_context)
- struct executable_statement **result;
- struct parse *cfile;
- int *lose;
- enum expression_context case_context;
-{
- enum dhcp_token token;
- const char *val;
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for new statement.");
- (*result) -> op = case_statement;
-
- if (!parse_expression (&(*result) -> data.c_case,
- cfile, lose, case_context,
- (struct expression **)0, expr_none))
- {
- if (!*lose) {
- parse_warn (cfile, "expecting %s expression.",
- (case_context == context_data
- ? "data" : "numeric"));
- }
- pfui:
- *lose = 1;
- skip_to_semi (cfile);
- executable_statement_dereference (result, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COLON) {
- parse_warn (cfile, "colon expected.");
- goto pfui;
- }
- return 1;
-}
-
-/*
- * if-statement :== boolean-expression LBRACE executable-statements RBRACE
- * else-statement
- *
- * else-statement :== <null> |
- * ELSE LBRACE executable-statements RBRACE |
- * ELSE IF if-statement |
- * ELSIF if-statement
- */
-
-int parse_if_statement (result, cfile, lose)
- struct executable_statement **result;
- struct parse *cfile;
- int *lose;
-{
- enum dhcp_token token;
- const char *val;
- int parenp;
-
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for if statement.");
-
- (*result) -> op = if_statement;
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == LPAREN) {
- parenp = 1;
- next_token (&val, (unsigned *)0, cfile);
- } else
- parenp = 0;
-
-
- if (!parse_boolean_expression (&(*result) -> data.ie.expr,
- cfile, lose)) {
- if (!*lose)
- parse_warn (cfile, "boolean expression expected.");
- executable_statement_dereference (result, MDL);
- *lose = 1;
- return 0;
- }
-#if defined (DEBUG_EXPRESSION_PARSE)
- print_expression ("if condition", (*result) -> data.ie.expr);
-#endif
- if (parenp) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- parse_warn (cfile, "expecting right paren.");
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LBRACE) {
- parse_warn (cfile, "left brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- if (!parse_executable_statements (&(*result) -> data.ie.tc,
- cfile, lose, context_any)) {
- if (*lose) {
- /* Try to even things up. */
- do {
- token = next_token (&val,
- (unsigned *)0, cfile);
- } while (token != END_OF_FILE && token != RBRACE);
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "right brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == ELSE) {
- token = next_token (&val, (unsigned *)0, cfile);
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == IF) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_if_statement (&(*result) -> data.ie.fc,
- cfile, lose)) {
- if (!*lose)
- parse_warn (cfile,
- "expecting if statement");
- executable_statement_dereference (result, MDL);
- *lose = 1;
- return 0;
- }
- } else if (token != LBRACE) {
- parse_warn (cfile, "left brace or if expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- } else {
- token = next_token (&val, (unsigned *)0, cfile);
- if (!(parse_executable_statements
- (&(*result) -> data.ie.fc,
- cfile, lose, context_any))) {
- executable_statement_dereference (result, MDL);
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RBRACE) {
- parse_warn (cfile, "right brace expected.");
- skip_to_semi (cfile);
- *lose = 1;
- executable_statement_dereference (result, MDL);
- return 0;
- }
- }
- } else if (token == ELSIF) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_if_statement (&(*result) -> data.ie.fc,
- cfile, lose)) {
- if (!*lose)
- parse_warn (cfile,
- "expecting conditional.");
- executable_statement_dereference (result, MDL);
- *lose = 1;
- return 0;
- }
- } else
- (*result) -> data.ie.fc = (struct executable_statement *)0;
-
- return 1;
-}
-
-/*
- * boolean_expression :== CHECK STRING |
- * NOT boolean-expression |
- * data-expression EQUAL data-expression |
- * data-expression BANG EQUAL data-expression |
- * boolean-expression AND boolean-expression |
- * boolean-expression OR boolean-expression
- * EXISTS OPTION-NAME
- */
-
-int parse_boolean_expression (expr, cfile, lose)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
-{
- /* Parse an expression... */
- if (!parse_expression (expr, cfile, lose, context_boolean,
- (struct expression **)0, expr_none))
- return 0;
-
- if (!is_boolean_expression (*expr) &&
- (*expr) -> op != expr_variable_reference &&
- (*expr) -> op != expr_funcall) {
- parse_warn (cfile, "Expecting a boolean expression.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- return 1;
-}
-
-/*
- * data_expression :== SUBSTRING LPAREN data-expression COMMA
- * numeric-expression COMMA
- * numeric-expression RPAREN |
- * CONCAT LPAREN data-expression COMMA
- data-expression RPAREN
- * SUFFIX LPAREN data_expression COMMA
- * numeric-expression RPAREN |
- * OPTION option_name |
- * HARDWARE |
- * PACKET LPAREN numeric-expression COMMA
- * numeric-expression RPAREN |
- * STRING |
- * colon_seperated_hex_list
- */
-
-int parse_data_expression (expr, cfile, lose)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
-{
- /* Parse an expression... */
- if (!parse_expression (expr, cfile, lose, context_data,
- (struct expression **)0, expr_none))
- return 0;
-
- if (!is_data_expression (*expr) &&
- (*expr) -> op != expr_variable_reference &&
- (*expr) -> op != expr_funcall) {
- parse_warn (cfile, "Expecting a data expression.");
- *lose = 1;
- return 0;
- }
- return 1;
-}
-
-/*
- * numeric-expression :== EXTRACT_INT LPAREN data-expression
- * COMMA number RPAREN |
- * NUMBER
- */
-
-int parse_numeric_expression (expr, cfile, lose)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
-{
- /* Parse an expression... */
- if (!parse_expression (expr, cfile, lose, context_numeric,
- (struct expression **)0, expr_none))
- return 0;
-
- if (!is_numeric_expression (*expr) &&
- (*expr) -> op != expr_variable_reference &&
- (*expr) -> op != expr_funcall) {
- parse_warn (cfile, "Expecting a numeric expression.");
- *lose = 1;
- return 0;
- }
- return 1;
-}
-
-/*
- * dns-expression :==
- * UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
- * data-expression COMMA numeric-expression RPAREN
- * DELETE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
- * data-expression RPAREN
- * EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
- * data-expression RPAREN
- * NOT EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
- * data-expression RPAREN
- * ns-class :== IN | CHAOS | HS | NUMBER
- * ns-type :== A | PTR | MX | TXT | NUMBER
- */
-
-int parse_dns_expression (expr, cfile, lose)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
-{
- /* Parse an expression... */
- if (!parse_expression (expr, cfile, lose, context_dns,
- (struct expression **)0, expr_none))
- return 0;
-
- if (!is_dns_expression (*expr) &&
- (*expr) -> op != expr_variable_reference &&
- (*expr) -> op != expr_funcall) {
- parse_warn (cfile, "Expecting a dns update subexpression.");
- *lose = 1;
- return 0;
- }
- return 1;
-}
-
-/* Parse a subexpression that does not contain a binary operator. */
-
-int parse_non_binary (expr, cfile, lose, context)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
- enum expression_context context;
-{
- enum dhcp_token token;
- const char *val;
- struct collection *col;
- struct option *option;
- struct expression *nexp, **ep;
- int known;
- enum expr_op opcode;
- const char *s;
- char *cptr;
- struct executable_statement *stmt;
- int i;
- unsigned long u;
- isc_result_t status, code;
- unsigned len;
-
- token = peek_token (&val, (unsigned *)0, cfile);
-
- /* Check for unary operators... */
- switch (token) {
- case CHECK:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != STRING) {
- parse_warn (cfile, "string expected.");
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
- for (col = collections; col; col = col -> next)
- if (!strcmp (col -> name, val))
- break;
- if (!col) {
- parse_warn (cfile, "unknown collection.");
- *lose = 1;
- return 0;
- }
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_check;
- (*expr) -> data.check = col;
- break;
-
- case TOKEN_NOT:
- token = next_token (&val, (unsigned *)0, cfile);
- if (context == context_dns) {
- token = peek_token (&val, (unsigned *)0, cfile);
- goto not_exists;
- }
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_not;
- if (!parse_non_binary (&(*expr) -> data.not,
- cfile, lose, context_boolean)) {
- if (!*lose) {
- parse_warn (cfile, "expression expected");
- skip_to_semi (cfile);
- }
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- if (!is_boolean_expression ((*expr) -> data.not)) {
- *lose = 1;
- parse_warn (cfile, "boolean expression expected");
- skip_to_semi (cfile);
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case LPAREN:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!parse_expression (expr, cfile, lose, context,
- (struct expression **)0, expr_none)) {
- if (!*lose) {
- parse_warn (cfile, "expression expected");
- skip_to_semi (cfile);
- }
- *lose = 1;
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- *lose = 1;
- parse_warn (cfile, "right paren expected");
- skip_to_semi (cfile);
- return 0;
- }
- break;
-
- case EXISTS:
- if (context == context_dns)
- goto ns_exists;
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_exists;
- known = 0;
- (*expr) -> data.option = parse_option_name (cfile, 0, &known);
- if (!(*expr) -> data.option) {
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case STATIC:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_static;
- break;
-
- case KNOWN:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_known;
- break;
-
- case SUBSTRING:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_substring;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- nolparen:
- expression_dereference (expr, MDL);
- parse_warn (cfile, "left parenthesis expected.");
- *lose = 1;
- return 0;
- }
-
- if (!parse_data_expression (&(*expr) -> data.substring.expr,
- cfile, lose)) {
- nodata:
- expression_dereference (expr, MDL);
- if (!*lose) {
- parse_warn (cfile,
- "expecting data expression.");
- skip_to_semi (cfile);
- *lose = 1;
- }
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA) {
- nocomma:
- expression_dereference (expr, MDL);
- parse_warn (cfile, "comma expected.");
- *lose = 1;
-
- return 0;
- }
-
- if (!parse_numeric_expression
- (&(*expr) -> data.substring.offset,cfile, lose)) {
- nonum:
- if (!*lose) {
- parse_warn (cfile,
- "expecting numeric expression.");
- skip_to_semi (cfile);
- *lose = 1;
- }
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_numeric_expression
- (&(*expr) -> data.substring.len, cfile, lose))
- goto nonum;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- norparen:
- parse_warn (cfile, "right parenthesis expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case SUFFIX:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_suffix;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- if (!parse_data_expression (&(*expr) -> data.suffix.expr,
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_numeric_expression (&(*expr) -> data.suffix.len,
- cfile, lose))
- goto nonum;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case CONCAT:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_concat;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- if (!parse_data_expression (&(*expr) -> data.concat [0],
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- concat_another:
- if (!parse_data_expression (&(*expr) -> data.concat [1],
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (token == COMMA) {
- nexp = (struct expression *)0;
- if (!expression_allocate (&nexp, MDL))
- log_fatal ("can't allocate at CONCAT2");
- nexp -> op = expr_concat;
- expression_reference (&nexp -> data.concat [0],
- *expr, MDL);
- expression_dereference (expr, MDL);
- expression_reference (expr, nexp, MDL);
- expression_dereference (&nexp, MDL);
- goto concat_another;
- }
-
- if (token != RPAREN)
- goto norparen;
- break;
-
- case BINARY_TO_ASCII:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_binary_to_ascii;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- if (!parse_numeric_expression (&(*expr) -> data.b2a.base,
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_numeric_expression (&(*expr) -> data.b2a.width,
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_data_expression (&(*expr) -> data.b2a.seperator,
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_data_expression (&(*expr) -> data.b2a.buffer,
- cfile, lose))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case REVERSE:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_reverse;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- if (!(parse_numeric_expression
- (&(*expr) -> data.reverse.width, cfile, lose)))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!(parse_data_expression
- (&(*expr) -> data.reverse.buffer, cfile, lose)))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case PICK:
- /* pick (a, b, c) actually produces an internal representation
- that looks like pick (a, pick (b, pick (c, nil))). */
- token = next_token (&val, (unsigned *)0, cfile);
- if (!(expression_allocate (expr, MDL)))
- log_fatal ("can't allocate expression");
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- nexp = (struct expression *)0;
- expression_reference (&nexp, *expr, MDL);
- do {
- nexp -> op = expr_pick_first_value;
- if (!(parse_data_expression
- (&nexp -> data.pick_first_value.car,
- cfile, lose)))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == COMMA) {
- struct expression *foo = (struct expression *)0;
- if (!expression_allocate (&foo, MDL))
- log_fatal ("can't allocate expr");
- expression_reference
- (&nexp -> data.pick_first_value.cdr, foo, MDL);
- expression_dereference (&nexp, MDL);
- expression_reference (&nexp, foo, MDL);
- expression_dereference (&foo, MDL);
- }
- } while (token == COMMA);
- expression_dereference (&nexp, MDL);
-
- if (token != RPAREN)
- goto norparen;
- break;
-
- /* dns-update and dns-delete are present for historical
- purposes, but are deprecated in favor of ns-update
- in combination with update, delete, exists and not
- exists. */
- case DNS_UPDATE:
- case DNS_DELETE:
-#if !defined (NSUPDATE)
- parse_warn (cfile,
- "Please rebuild dhcpd with --with-nsupdate.");
-#endif
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == DNS_UPDATE)
- opcode = expr_ns_add;
- else
- opcode = expr_ns_delete;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != STRING) {
- parse_warn (cfile,
- "parse_expression: expecting string.");
- badnsupdate:
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- if (!strcasecmp (val, "a"))
- u = T_A;
- else if (!strcasecmp (val, "ptr"))
- u = T_PTR;
- else if (!strcasecmp (val, "mx"))
- u = T_MX;
- else if (!strcasecmp (val, "cname"))
- u = T_CNAME;
- else if (!strcasecmp (val, "TXT"))
- u = T_TXT;
- else {
- parse_warn (cfile, "unexpected rrtype: %s", val);
- goto badnsupdate;
- }
-
- s = (opcode == expr_ns_add
- ? "old-dns-update"
- : "old-dns-delete");
- cptr = dmalloc (strlen (s) + 1, MDL);
- if (!cptr)
- log_fatal ("can't allocate name for %s", s);
- strcpy (cptr, s);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_funcall;
- (*expr) -> data.funcall.name = cptr;
-
- /* Fake up a function call. */
- ep = &(*expr) -> data.funcall.arglist;
- if (!expression_allocate (ep, MDL))
- log_fatal ("can't allocate expression");
- (*ep) -> op = expr_arg;
- if (!make_const_int (&(*ep) -> data.arg.val, u))
- log_fatal ("can't allocate rrtype value.");
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
- ep = &((*ep) -> data.arg.next);
- if (!expression_allocate (ep, MDL))
- log_fatal ("can't allocate expression");
- (*ep) -> op = expr_arg;
- if (!(parse_data_expression (&(*ep) -> data.arg.val,
- cfile, lose)))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- ep = &((*ep) -> data.arg.next);
- if (!expression_allocate (ep, MDL))
- log_fatal ("can't allocate expression");
- (*ep) -> op = expr_arg;
- if (!(parse_data_expression (&(*ep) -> data.arg.val,
- cfile, lose)))
- goto nodata;
-
- if (opcode == expr_ns_add) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- ep = &((*ep) -> data.arg.next);
- if (!expression_allocate (ep, MDL))
- log_fatal ("can't allocate expression");
- (*ep) -> op = expr_arg;
- if (!(parse_numeric_expression (&(*ep) -> data.arg.val,
- cfile, lose))) {
- parse_warn (cfile,
- "expecting numeric expression.");
- goto badnsupdate;
- }
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case NS_UPDATE:
-#if !defined (NSUPDATE)
- parse_warn (cfile,
- "Please rebuild dhcpd with --with-nsupdate.");
-#endif
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- nexp = *expr;
- do {
- nexp -> op = expr_dns_transaction;
- if (!(parse_dns_expression
- (&nexp -> data.dns_transaction.car,
- cfile, lose)))
- {
- if (!*lose)
- parse_warn
- (cfile,
- "expecting dns expression.");
- badnstrans:
- expression_dereference (expr, MDL);
- *lose = 1;
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
-
- if (token == COMMA) {
- if (!(expression_allocate
- (&nexp -> data.dns_transaction.cdr,
- MDL)))
- log_fatal
- ("can't allocate expression");
- nexp = nexp -> data.dns_transaction.cdr;
- }
- } while (token == COMMA);
-
- if (token != RPAREN)
- goto norparen;
- break;
-
- /* NOT EXISTS is special cased above... */
- not_exists:
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != EXISTS) {
- parse_warn (cfile, "expecting DNS prerequisite.");
- *lose = 1;
- return 0;
- }
- opcode = expr_ns_not_exists;
- goto nsupdatecode;
- case TOKEN_ADD:
- opcode = expr_ns_add;
- goto nsupdatecode;
- case TOKEN_DELETE:
- opcode = expr_ns_delete;
- goto nsupdatecode;
- ns_exists:
- opcode = expr_ns_exists;
- nsupdatecode:
- token = next_token (&val, (unsigned *)0, cfile);
-
-#if !defined (NSUPDATE)
- parse_warn (cfile,
- "Please rebuild dhcpd with --with-nsupdate.");
-#endif
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = opcode;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token) && token != NUMBER) {
- parse_warn (cfile, "expecting identifier or number.");
- badnsop:
- expression_dereference (expr, MDL);
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- if (token == NUMBER)
- (*expr) -> data.ns_add.rrclass = atoi (val);
- else if (!strcasecmp (val, "in"))
- (*expr) -> data.ns_add.rrclass = C_IN;
- else if (!strcasecmp (val, "chaos"))
- (*expr) -> data.ns_add.rrclass = C_CHAOS;
- else if (!strcasecmp (val, "hs"))
- (*expr) -> data.ns_add.rrclass = C_HS;
- else {
- parse_warn (cfile, "unexpected rrclass: %s", val);
- goto badnsop;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token) && token != NUMBER) {
- parse_warn (cfile, "expecting identifier or number.");
- goto badnsop;
- }
-
- if (token == NUMBER)
- (*expr) -> data.ns_add.rrtype = atoi (val);
- else if (!strcasecmp (val, "a"))
- (*expr) -> data.ns_add.rrtype = T_A;
- else if (!strcasecmp (val, "ptr"))
- (*expr) -> data.ns_add.rrtype = T_PTR;
- else if (!strcasecmp (val, "mx"))
- (*expr) -> data.ns_add.rrtype = T_MX;
- else if (!strcasecmp (val, "cname"))
- (*expr) -> data.ns_add.rrtype = T_CNAME;
- else if (!strcasecmp (val, "TXT"))
- (*expr) -> data.ns_add.rrtype = T_TXT;
- else {
- parse_warn (cfile, "unexpected rrtype: %s", val);
- goto badnsop;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!(parse_data_expression
- (&(*expr) -> data.ns_add.rrname, cfile, lose)))
- goto nodata;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!(parse_data_expression
- (&(*expr) -> data.ns_add.rrdata, cfile, lose)))
- goto nodata;
-
- if (opcode == expr_ns_add) {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!(parse_numeric_expression
- (&(*expr) -> data.ns_add.ttl, cfile,
- lose))) {
- if (!*lose)
- parse_warn (cfile,
- "expecting numeric expression.");
- goto badnsupdate;
- }
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case OPTION:
- case CONFIG_OPTION:
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = (token == OPTION
- ? expr_option
- : expr_config_option);
- token = next_token (&val, (unsigned *)0, cfile);
- known = 0;
- (*expr) -> data.option = parse_option_name (cfile, 0, &known);
- if (!(*expr) -> data.option) {
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case HARDWARE:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_hardware;
- break;
-
- case LEASED_ADDRESS:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_leased_address;
- break;
-
- case CLIENT_STATE:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_client_state;
- break;
-
- case FILENAME:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_filename;
- break;
-
- case SERVER_NAME:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_sname;
- break;
-
- case LEASE_TIME:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_lease_time;
- break;
-
- case TOKEN_NULL:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_null;
- break;
-
- case HOST_DECL_NAME:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_host_decl_name;
- break;
-
- case UPDATED_DNS_RR:
- token = next_token (&val, (unsigned *)0, cfile);
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != STRING) {
- parse_warn (cfile, "expecting string.");
- bad_rrtype:
- *lose = 1;
- return 0;
- }
- if (!strcasecmp (val, "a"))
- s = "ddns-fwd-name";
- else if (!strcasecmp (val, "ptr"))
- s = "ddns-rev-name";
- else {
- parse_warn (cfile, "invalid DNS rrtype: %s", val);
- goto bad_rrtype;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
-
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_variable_reference;
- (*expr) -> data.variable =
- dmalloc (strlen (s) + 1, MDL);
- if (!(*expr) -> data.variable)
- log_fatal ("can't allocate variable name.");
- strcpy ((*expr) -> data.variable, s);
- break;
-
- case PACKET:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_packet;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- if (!parse_numeric_expression (&(*expr) -> data.packet.offset,
- cfile, lose))
- goto nonum;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA)
- goto nocomma;
-
- if (!parse_numeric_expression (&(*expr) -> data.packet.len,
- cfile, lose))
- goto nonum;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- case STRING:
- token = next_token (&val, &len, cfile);
- if (!make_const_data (expr, (const unsigned char *)val,
- len, 1, 1, MDL))
- log_fatal ("can't make constant string expression.");
- break;
-
- case EXTRACT_INT:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- parse_warn (cfile, "left parenthesis expected.");
- *lose = 1;
- return 0;
- }
-
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
-
- if (!parse_data_expression (&(*expr) -> data.extract_int,
- cfile, lose)) {
- if (!*lose) {
- parse_warn (cfile,
- "expecting data expression.");
- skip_to_semi (cfile);
- *lose = 1;
- }
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA) {
- parse_warn (cfile, "comma expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "number expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- switch (atoi (val)) {
- case 8:
- (*expr) -> op = expr_extract_int8;
- break;
-
- case 16:
- (*expr) -> op = expr_extract_int16;
- break;
-
- case 32:
- (*expr) -> op = expr_extract_int32;
- break;
-
- default:
- parse_warn (cfile,
- "unsupported integer size %d", atoi (val));
- *lose = 1;
- skip_to_semi (cfile);
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- parse_warn (cfile, "right parenthesis expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case ENCODE_INT:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- parse_warn (cfile, "left parenthesis expected.");
- *lose = 1;
- return 0;
- }
-
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
-
- if (!parse_numeric_expression (&(*expr) -> data.encode_int,
- cfile, lose)) {
- parse_warn (cfile, "expecting numeric expression.");
- skip_to_semi (cfile);
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != COMMA) {
- parse_warn (cfile, "comma expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER) {
- parse_warn (cfile, "number expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- switch (atoi (val)) {
- case 8:
- (*expr) -> op = expr_encode_int8;
- break;
-
- case 16:
- (*expr) -> op = expr_encode_int16;
- break;
-
- case 32:
- (*expr) -> op = expr_encode_int32;
- break;
-
- default:
- parse_warn (cfile,
- "unsupported integer size %d", atoi (val));
- *lose = 1;
- skip_to_semi (cfile);
- expression_dereference (expr, MDL);
- return 0;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN) {
- parse_warn (cfile, "right parenthesis expected.");
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case NUMBER:
- /* If we're in a numeric context, this should just be a
- number, by itself. */
- if (context == context_numeric ||
- context == context_data_or_numeric) {
- next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_const_int;
- (*expr) -> data.const_int = atoi (val);
- break;
- }
-
- case NUMBER_OR_NAME:
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
-
- (*expr) -> op = expr_const_data;
- if (!parse_cshl (&(*expr) -> data.const_data, cfile)) {
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
-
- case NS_FORMERR:
- known = FORMERR;
- goto ns_const;
- ns_const:
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_const_int;
- (*expr) -> data.const_int = known;
- break;
-
- case NS_NOERROR:
- known = ISC_R_SUCCESS;
- goto ns_const;
-
- case NS_NOTAUTH:
- known = ISC_R_NOTAUTH;
- goto ns_const;
-
- case NS_NOTIMP:
- known = ISC_R_NOTIMPLEMENTED;
- goto ns_const;
-
- case NS_NOTZONE:
- known = ISC_R_NOTZONE;
- goto ns_const;
-
- case NS_NXDOMAIN:
- known = ISC_R_NXDOMAIN;
- goto ns_const;
-
- case NS_NXRRSET:
- known = ISC_R_NXRRSET;
- goto ns_const;
-
- case NS_REFUSED:
- known = ISC_R_REFUSED;
- goto ns_const;
-
- case NS_SERVFAIL:
- known = ISC_R_SERVFAIL;
- goto ns_const;
-
- case NS_YXDOMAIN:
- known = ISC_R_YXDOMAIN;
- goto ns_const;
-
- case NS_YXRRSET:
- known = ISC_R_YXRRSET;
- goto ns_const;
-
- case BOOTING:
- known = S_INIT;
- goto ns_const;
-
- case REBOOT:
- known = S_REBOOTING;
- goto ns_const;
-
- case SELECT:
- known = S_SELECTING;
- goto ns_const;
-
- case REQUEST:
- known = S_REQUESTING;
- goto ns_const;
-
- case BOUND:
- known = S_BOUND;
- goto ns_const;
-
- case RENEW:
- known = S_RENEWING;
- goto ns_const;
-
- case REBIND:
- known = S_REBINDING;
- goto ns_const;
-
- case DEFINED:
- token = next_token (&val, (unsigned *)0, cfile);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN)
- goto nolparen;
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NAME && token != NUMBER_OR_NAME) {
- parse_warn (cfile, "%s can't be a variable name", val);
- skip_to_semi (cfile);
- *lose = 1;
- return 0;
- }
-
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_variable_exists;
- (*expr) -> data.variable = dmalloc (strlen (val) + 1, MDL);
- if (!(*expr)->data.variable)
- log_fatal ("can't allocate variable name");
- strcpy ((*expr) -> data.variable, val);
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != RPAREN)
- goto norparen;
- break;
-
- /* Not a valid start to an expression... */
- default:
- if (token != NAME && token != NUMBER_OR_NAME)
- return 0;
-
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* Save the name of the variable being referenced. */
- cptr = dmalloc (strlen (val) + 1, MDL);
- if (!cptr)
- log_fatal ("can't allocate variable name");
- strcpy (cptr, val);
-
- /* Simple variable reference, as far as we can tell. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != LPAREN) {
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_variable_reference;
- (*expr) -> data.variable = cptr;
- break;
- }
-
- token = next_token (&val, (unsigned *)0, cfile);
- if (!expression_allocate (expr, MDL))
- log_fatal ("can't allocate expression");
- (*expr) -> op = expr_funcall;
- (*expr) -> data.funcall.name = cptr;
-
- /* Now parse the argument list. */
- ep = &(*expr) -> data.funcall.arglist;
- do {
- if (!expression_allocate (ep, MDL))
- log_fatal ("can't allocate expression");
- (*ep) -> op = expr_arg;
- if (!parse_expression (&(*ep) -> data.arg.val,
- cfile, lose, context_any,
- (struct expression **)0,
- expr_none)) {
- if (!*lose) {
- parse_warn (cfile,
- "expecting expression.");
- *lose = 1;
- }
- skip_to_semi (cfile);
- expression_dereference (expr, MDL);
- return 0;
- }
- ep = &((*ep) -> data.arg.next);
- token = next_token (&val, (unsigned *)0, cfile);
- } while (token == COMMA);
- if (token != RPAREN) {
- parse_warn (cfile, "Right parenthesis expected.");
- skip_to_semi (cfile);
- *lose = 1;
- expression_dereference (expr, MDL);
- return 0;
- }
- break;
- }
- return 1;
-}
-
-/* Parse an expression. */
-
-int parse_expression (expr, cfile, lose, context, plhs, binop)
- struct expression **expr;
- struct parse *cfile;
- int *lose;
- enum expression_context context;
- struct expression **plhs;
- enum expr_op binop;
-{
- enum dhcp_token token;
- const char *val;
- struct expression *rhs = (struct expression *)0, *tmp;
- struct expression *lhs = (struct expression *)0;
- enum expr_op next_op;
- enum expression_context
- lhs_context = context_any,
- rhs_context = context_any;
-
- /* Consume the left hand side we were passed. */
- if (plhs) {
- expression_reference (&lhs, *plhs, MDL);
- expression_dereference (plhs, MDL);
- }
-
- new_rhs:
- if (!parse_non_binary (&rhs, cfile, lose, context)) {
- /* If we already have a left-hand side, then it's not
- okay for there not to be a right-hand side here, so
- we need to flag it as an error. */
- if (lhs) {
- if (!*lose) {
- parse_warn (cfile,
- "expecting right-hand side.");
- *lose = 1;
- skip_to_semi (cfile);
- }
- expression_dereference (&lhs, MDL);
- }
- return 0;
- }
-
- /* At this point, rhs contains either an entire subexpression,
- or at least a left-hand-side. If we do not see a binary token
- as the next token, we're done with the expression. */
-
- token = peek_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case BANG:
- token = next_token (&val, (unsigned *)0, cfile);
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != EQUAL) {
- parse_warn (cfile, "! in boolean context without =");
- *lose = 1;
- skip_to_semi (cfile);
- if (lhs)
- expression_dereference (&lhs, MDL);
- return 0;
- }
- next_op = expr_not_equal;
- context = expression_context (rhs);
- break;
-
- case EQUAL:
- next_op = expr_equal;
- context = expression_context (rhs);
- break;
-
- case AND:
- next_op = expr_and;
- context = expression_context (rhs);
- break;
-
- case OR:
- next_op = expr_or;
- context = expression_context (rhs);
- break;
-
- case PLUS:
- next_op = expr_add;
- context = expression_context (rhs);
- break;
-
- case MINUS:
- next_op = expr_subtract;
- context = expression_context (rhs);
- break;
-
- case SLASH:
- next_op = expr_divide;
- context = expression_context (rhs);
- break;
-
- case ASTERISK:
- next_op = expr_multiply;
- context = expression_context (rhs);
- break;
-
- case PERCENT:
- next_op = expr_remainder;
- context = expression_context (rhs);
- break;
-
- case AMPERSAND:
- next_op = expr_binary_and;
- context = expression_context (rhs);
- break;
-
- case PIPE:
- next_op = expr_binary_or;
- context = expression_context (rhs);
- break;
-
- case CARET:
- next_op = expr_binary_xor;
- context = expression_context (rhs);
- break;
-
- default:
- next_op = expr_none;
- }
-
- /* If we have no lhs yet, we just parsed it. */
- if (!lhs) {
- /* If there was no operator following what we just parsed,
- then we're done - return it. */
- if (next_op == expr_none) {
- *expr = rhs;
- return 1;
- }
- lhs = rhs;
- rhs = (struct expression *)0;
- binop = next_op;
- next_token (&val, (unsigned *)0, cfile);
- goto new_rhs;
- }
-
- if (binop != expr_none) {
- rhs_context = expression_context(rhs);
- lhs_context = expression_context(lhs);
-
- if ((rhs_context != context_any) && (lhs_context != context_any) &&
- (rhs_context != lhs_context)) {
- parse_warn (cfile, "illegal expression relating different types");
- skip_to_semi (cfile);
- expression_dereference (&rhs, MDL);
- expression_dereference (&lhs, MDL);
- *lose = 1;
- return 0;
- }
-
- switch(binop) {
- case expr_not_equal:
- case expr_equal:
- if ((rhs_context != context_data_or_numeric) &&
- (rhs_context != context_data) &&
- (rhs_context != context_numeric) &&
- (rhs_context != context_any)) {
- parse_warn (cfile, "expecting data/numeric expression");
- skip_to_semi (cfile);
- expression_dereference (&rhs, MDL);
- *lose = 1;
- return 0;
- }
- break;
-
- case expr_and:
- case expr_or:
- if ((rhs_context != context_boolean) &&
- (rhs_context != context_any)) {
- parse_warn (cfile, "expecting boolean expressions");
- skip_to_semi (cfile);
- expression_dereference (&rhs, MDL);
- *lose = 1;
- return 0;
- }
- break;
-
- case expr_add:
- case expr_subtract:
- case expr_divide:
- case expr_multiply:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- if ((rhs_context != context_numeric) &&
- (rhs_context != context_any)) {
- parse_warn (cfile, "expecting numeric expressions");
- skip_to_semi (cfile);
- expression_dereference (&rhs, MDL);
- *lose = 1;
- return 0;
- }
- break;
-
- default:
- break;
- }
- }
-
- /* Now, if we didn't find a binary operator, we're done parsing
- this subexpression, so combine it with the preceding binary
- operator and return the result. */
- if (next_op == expr_none) {
- if (!expression_allocate (expr, MDL))
- log_fatal ("Can't allocate expression!");
-
- (*expr) -> op = binop;
- /* All the binary operators' data union members
- are the same, so we'll cheat and use the member
- for the equals operator. */
- (*expr) -> data.equal [0] = lhs;
- (*expr) -> data.equal [1] = rhs;
- return 1;
- }
-
- /* Eat the operator token - we now know it was a binary operator... */
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* If the binary operator we saw previously has a lower precedence
- than the next operator, then the rhs we just parsed for that
- operator is actually the lhs of the operator with the higher
- precedence - to get the real rhs, we need to recurse on the
- new operator. */
- if (binop != expr_none &&
- op_precedence (binop, next_op) < 0) {
- tmp = rhs;
- rhs = (struct expression *)0;
- if (!parse_expression (&rhs, cfile, lose, op_context (next_op),
- &tmp, next_op)) {
- if (!*lose) {
- parse_warn (cfile,
- "expecting a subexpression");
- *lose = 1;
- }
- return 0;
- }
- next_op = expr_none;
- }
-
- /* Now combine the LHS and the RHS using binop. */
- tmp = (struct expression *)0;
- if (!expression_allocate (&tmp, MDL))
- log_fatal ("No memory for equal precedence combination.");
-
- /* Store the LHS and RHS. */
- tmp -> data.equal [0] = lhs;
- tmp -> data.equal [1] = rhs;
- tmp -> op = binop;
-
- lhs = tmp;
- tmp = (struct expression *)0;
- rhs = (struct expression *)0;
-
- /* Recursions don't return until we have parsed the end of the
- expression, so if we recursed earlier, we can now return what
- we got. */
- if (next_op == expr_none) {
- *expr = lhs;
- return 1;
- }
-
- binop = next_op;
- goto new_rhs;
-}
-
-/* option-statement :== identifier DOT identifier <syntax> SEMI
- | identifier <syntax> SEMI
-
- Option syntax is handled specially through format strings, so it
- would be painful to come up with BNF for it. However, it always
- starts as above and ends in a SEMI. */
-
-int parse_option_statement (result, cfile, lookups, option, op)
- struct executable_statement **result;
- struct parse *cfile;
- int lookups;
- struct option *option;
- enum statement_op op;
-{
- const char *val;
- enum dhcp_token token;
- const char *fmt = NULL;
- struct expression *expr = (struct expression *)0;
- struct expression *tmp;
- int lose;
- struct executable_statement *stmt;
- int ftt = 1;
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == SEMI) {
- /* Eat the semicolon... */
- token = next_token (&val, (unsigned *)0, cfile);
- goto done;
- }
-
- if (token == EQUAL) {
- /* Eat the equals sign. */
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* Parse a data expression and use its value for the data. */
- if (!parse_data_expression (&expr, cfile, &lose)) {
- /* In this context, we must have an executable
- statement, so if we found something else, it's
- still an error. */
- if (!lose) {
- parse_warn (cfile,
- "expecting a data expression.");
- skip_to_semi (cfile);
- }
- return 0;
- }
-
- /* We got a valid expression, so use it. */
- goto done;
- }
-
- /* Parse the option data... */
- do {
- /* Set a flag if this is an array of a simple type (i.e.,
- not an array of pairs of IP addresses, or something
- like that. */
- int uniform = option -> format [1] == 'A';
-
- and_again:
- /* Set fmt to start of format for 'A' and one char back
- for 'a' */
- if ((fmt != NULL) &&
- (fmt != option -> format) && (*fmt == 'a'))
- fmt -= 1;
- else
- fmt = ((fmt == NULL) ||
- (*fmt == 'A')) ? option -> format : fmt;
-
- /* 'a' means always uniform */
- uniform |= (fmt [1] == 'a');
-
- for ( ; *fmt; fmt++) {
- if ((*fmt == 'A') || (*fmt == 'a'))
- break;
- if (*fmt == 'o')
- continue;
- tmp = expr;
- expr = (struct expression *)0;
- if (!parse_option_token (&expr, cfile, &fmt,
- tmp, uniform, lookups)) {
- if (fmt [1] != 'o') {
- if (tmp)
- expression_dereference (&tmp,
- MDL);
- return 0;
- }
- expr = tmp;
- tmp = (struct expression *)0;
- }
- if (tmp)
- expression_dereference (&tmp, MDL);
- }
- if ((*fmt == 'A') || (*fmt == 'a')) {
- token = peek_token (&val, (unsigned *)0, cfile);
- /* Comma means: continue with next element in array */
- if (token == COMMA) {
- token = next_token (&val,
- (unsigned *)0, cfile);
- continue;
- }
- /* no comma: end of array.
- 'A' or end of string means: leave the loop */
- if ((*fmt == 'A') || (fmt[1] == '\0'))
- break;
- /* 'a' means: go on with next char */
- if (*fmt == 'a') {
- fmt++;
- goto and_again;
- }
- }
- } while ((*fmt == 'A') || (*fmt == 'a'));
-
- done:
- if (!parse_semi (cfile))
- return 0;
- if (!executable_statement_allocate (result, MDL))
- log_fatal ("no memory for option statement.");
- (*result) -> op = op;
- if (expr && !option_cache (&(*result) -> data.option,
- (struct data_string *)0, expr, option, MDL))
- log_fatal ("no memory for option cache");
- if (expr)
- expression_dereference (&expr, MDL);
- return 1;
-}
-
-int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
- struct expression **rv;
- struct parse *cfile;
- const char **fmt;
- struct expression *expr;
- int uniform;
- int lookups;
-{
- const char *val;
- enum dhcp_token token;
- struct expression *t = (struct expression *)0;
- unsigned char buf [4];
- unsigned len;
- unsigned char *ob;
- struct iaddr addr;
- int num;
- const char *f, *g;
- struct enumeration_value *e;
-
- switch (**fmt) {
- case 'U':
- token = peek_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- if ((*fmt) [1] != 'o') {
- parse_warn (cfile, "expecting identifier.");
- skip_to_semi (cfile);
- }
- return 0;
- }
- token = next_token (&val, &len, cfile);
- if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1, MDL))
- log_fatal ("No memory for %s", val);
- break;
-
- case 'E':
- g = strchr (*fmt, '.');
- if (!g) {
- parse_warn (cfile,
- "malformed encapsulation format (bug!)");
- skip_to_semi (cfile);
- return 0;
- }
- *fmt = g;
- case 'X':
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == NUMBER_OR_NAME || token == NUMBER) {
- if (!expression_allocate (&t, MDL))
- return 0;
- if (!parse_cshl (&t -> data.const_data, cfile)) {
- expression_dereference (&t, MDL);
- return 0;
- }
- t -> op = expr_const_data;
- } else if (token == STRING) {
- token = next_token (&val, &len, cfile);
- if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1, MDL))
- log_fatal ("No memory for \"%s\"", val);
- } else {
- if ((*fmt) [1] != 'o') {
- parse_warn (cfile, "expecting string %s.",
- "or hexadecimal data");
- skip_to_semi (cfile);
- }
- return 0;
- }
- break;
-
- case 'd': /* Domain name... */
- val = parse_host_name (cfile);
- if (!val) {
- parse_warn (cfile, "not a valid domain name.");
- skip_to_semi (cfile);
- return 0;
- }
- len = strlen (val);
- goto make_string;
-
- case 't': /* Text string... */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != STRING && !is_identifier (token)) {
- if ((*fmt) [1] != 'o') {
- parse_warn (cfile, "expecting string.");
- if (token != SEMI)
- skip_to_semi (cfile);
- }
- return 0;
- }
- token = next_token (&val, &len, cfile);
- make_string:
- if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1, MDL))
- log_fatal ("No memory for concatenation");
- break;
-
- case 'N':
- f = (*fmt) + 1;
- g = strchr (*fmt, '.');
- if (!g) {
- parse_warn (cfile, "malformed %s (bug!)",
- "enumeration format");
- foo:
- skip_to_semi (cfile);
- return 0;
- }
- *fmt = g;
- token = next_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile,
- "identifier expected");
- goto foo;
- }
- e = find_enumeration_value (f, (*fmt) - f, val);
- if (!e) {
- parse_warn (cfile, "unknown value");
- goto foo;
- }
- if (!make_const_data (&t, &e -> value, 1, 0, 1, MDL))
- return 0;
- break;
-
- case 'I': /* IP address or hostname. */
- if (lookups) {
- if (!parse_ip_addr_or_hostname (&t, cfile, uniform))
- return 0;
- } else {
- if (!parse_ip_addr (cfile, &addr))
- return 0;
- if (!make_const_data (&t, addr.iabuf, addr.len,
- 0, 1, MDL))
- return 0;
- }
- break;
-
- case 'T': /* Lease interval. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != INFINITE)
- goto check_number;
- token = next_token (&val, (unsigned *)0, cfile);
- putLong (buf, -1);
- if (!make_const_data (&t, buf, 4, 0, 1, MDL))
- return 0;
- break;
-
- case 'L': /* Unsigned 32-bit integer... */
- case 'l': /* Signed 32-bit integer... */
- token = peek_token (&val, (unsigned *)0, cfile);
- check_number:
- if (token != NUMBER) {
- need_number:
- if ((*fmt) [1] != 'o') {
- parse_warn (cfile, "expecting number.");
- if (token != SEMI)
- skip_to_semi (cfile);
- }
- return 0;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- convert_num (cfile, buf, val, 0, 32);
- if (!make_const_data (&t, buf, 4, 0, 1, MDL))
- return 0;
- break;
-
- case 's': /* Signed 16-bit integer. */
- case 'S': /* Unsigned 16-bit integer. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
- token = next_token (&val, (unsigned *)0, cfile);
- convert_num (cfile, buf, val, 0, 16);
- if (!make_const_data (&t, buf, 2, 0, 1, MDL))
- return 0;
- break;
-
- case 'b': /* Signed 8-bit integer. */
- case 'B': /* Unsigned 8-bit integer. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
- token = next_token (&val, (unsigned *)0, cfile);
- convert_num (cfile, buf, val, 0, 8);
- if (!make_const_data (&t, buf, 1, 0, 1, MDL))
- return 0;
- break;
-
- case 'f': /* Boolean flag. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- if ((*fmt) [1] != 'o')
- parse_warn (cfile, "expecting identifier.");
- bad_flag:
- if ((*fmt) [1] != 'o') {
- if (token != SEMI)
- skip_to_semi (cfile);
- }
- return 0;
- }
- if (!strcasecmp (val, "true")
- || !strcasecmp (val, "on"))
- buf [0] = 1;
- else if (!strcasecmp (val, "false")
- || !strcasecmp (val, "off"))
- buf [0] = 0;
- else if (!strcasecmp (val, "ignore"))
- buf [0] = 2;
- else {
- if ((*fmt) [1] != 'o')
- parse_warn (cfile, "expecting boolean.");
- goto bad_flag;
- }
- token = next_token (&val, (unsigned *)0, cfile);
- if (!make_const_data (&t, buf, 1, 0, 1, MDL))
- return 0;
- break;
-
- default:
- parse_warn (cfile, "Bad format %c in parse_option_token.",
- **fmt);
- skip_to_semi (cfile);
- return 0;
- }
- if (expr) {
- if (!make_concat (rv, expr, t))
- return 0;
- } else
- expression_reference (rv, t, MDL);
- expression_dereference (&t, MDL);
- return 1;
-}
-
-int parse_option_decl (oc, cfile)
- struct option_cache **oc;
- struct parse *cfile;
-{
- const char *val;
- int token;
- u_int8_t buf [4];
- u_int8_t hunkbuf [1024];
- unsigned hunkix = 0;
- const char *fmt, *f;
- struct option *option;
- struct iaddr ip_addr;
- u_int8_t *dp;
- unsigned len;
- int nul_term = 0;
- struct buffer *bp;
- int known = 0;
- struct enumeration_value *e;
-
- option = parse_option_name (cfile, 0, &known);
- if (!option)
- return 0;
-
- /* Parse the option data... */
- do {
- /* Set a flag if this is an array of a simple type (i.e.,
- not an array of pairs of IP addresses, or something
- like that. */
- int uniform = option -> format [1] == 'A';
-
- for (fmt = option -> format; *fmt; fmt++) {
- if (*fmt == 'A')
- break;
- switch (*fmt) {
- case 'E':
- fmt = strchr (fmt, '.');
- if (!fmt) {
- parse_warn (cfile,
- "malformed %s (bug!)",
- "encapsulation format");
- skip_to_semi (cfile);
- return 0;
- }
- case 'X':
- len = parse_X (cfile, &hunkbuf [hunkix],
- sizeof hunkbuf - hunkix);
- hunkix += len;
- break;
-
- case 't': /* Text string... */
- token = next_token (&val,
- &len, cfile);
- if (token != STRING) {
- parse_warn (cfile,
- "expecting string.");
- skip_to_semi (cfile);
- return 0;
- }
- if (hunkix + len + 1 > sizeof hunkbuf) {
- parse_warn (cfile,
- "option data buffer %s",
- "overflow");
- skip_to_semi (cfile);
- return 0;
- }
- memcpy (&hunkbuf [hunkix], val, len + 1);
- nul_term = 1;
- hunkix += len;
- break;
-
- case 'N':
- f = fmt;
- fmt = strchr (fmt, '.');
- if (!fmt) {
- parse_warn (cfile,
- "malformed %s (bug!)",
- "enumeration format");
- foo:
- skip_to_semi (cfile);
- return 0;
- }
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile,
- "identifier expected");
- goto foo;
- }
- e = find_enumeration_value (f, fmt - f, val);
- if (!e) {
- parse_warn (cfile,
- "unknown value");
- goto foo;
- }
- len = 1;
- dp = &e -> value;
- goto alloc;
-
- case 'I': /* IP address. */
- if (!parse_ip_addr (cfile, &ip_addr))
- return 0;
- len = ip_addr.len;
- dp = ip_addr.iabuf;
-
- alloc:
- if (hunkix + len > sizeof hunkbuf) {
- parse_warn (cfile,
- "option data buffer %s",
- "overflow");
- skip_to_semi (cfile);
- return 0;
- }
- memcpy (&hunkbuf [hunkix], dp, len);
- hunkix += len;
- break;
-
- case 'L': /* Unsigned 32-bit integer... */
- case 'l': /* Signed 32-bit integer... */
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (token != NUMBER) {
- need_number:
- parse_warn (cfile,
- "expecting number.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return 0;
- }
- convert_num (cfile, buf, val, 0, 32);
- len = 4;
- dp = buf;
- goto alloc;
-
- case 's': /* Signed 16-bit integer. */
- case 'S': /* Unsigned 16-bit integer. */
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (cfile, buf, val, 0, 16);
- len = 2;
- dp = buf;
- goto alloc;
-
- case 'b': /* Signed 8-bit integer. */
- case 'B': /* Unsigned 8-bit integer. */
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (cfile, buf, val, 0, 8);
- len = 1;
- dp = buf;
- goto alloc;
-
- case 'f': /* Boolean flag. */
- token = next_token (&val,
- (unsigned *)0, cfile);
- if (!is_identifier (token)) {
- parse_warn (cfile,
- "expecting identifier.");
- bad_flag:
- if (token != SEMI)
- skip_to_semi (cfile);
- return 0;
- }
- if (!strcasecmp (val, "true")
- || !strcasecmp (val, "on"))
- buf [0] = 1;
- else if (!strcasecmp (val, "false")
- || !strcasecmp (val, "off"))
- buf [0] = 0;
- else {
- parse_warn (cfile,
- "expecting boolean.");
- goto bad_flag;
- }
- len = 1;
- dp = buf;
- goto alloc;
-
- default:
- log_error ("parse_option_param: Bad format %c",
- *fmt);
- skip_to_semi (cfile);
- return 0;
- }
- }
- token = next_token (&val, (unsigned *)0, cfile);
- } while (*fmt == 'A' && token == COMMA);
-
- if (token != SEMI) {
- parse_warn (cfile, "semicolon expected.");
- skip_to_semi (cfile);
- return 0;
- }
-
- bp = (struct buffer *)0;
- if (!buffer_allocate (&bp, hunkix + nul_term, MDL))
- log_fatal ("no memory to store option declaration.");
- if (!bp -> data)
- log_fatal ("out of memory allocating option data.");
- memcpy (bp -> data, hunkbuf, hunkix + nul_term);
-
- if (!option_cache_allocate (oc, MDL))
- log_fatal ("out of memory allocating option cache.");
-
- (*oc) -> data.buffer = bp;
- (*oc) -> data.data = &bp -> data [0];
- (*oc) -> data.terminated = nul_term;
- (*oc) -> data.len = hunkix;
- (*oc) -> option = option;
- return 1;
-}
-
-/* Consider merging parse_cshl into this. */
-
-int parse_X (cfile, buf, max)
- struct parse *cfile;
- u_int8_t *buf;
- unsigned max;
-{
- int token;
- const char *val;
- unsigned len;
- u_int8_t *s;
-
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == NUMBER_OR_NAME || token == NUMBER) {
- len = 0;
- do {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER && token != NUMBER_OR_NAME) {
- parse_warn (cfile,
- "expecting hexadecimal constant.");
- skip_to_semi (cfile);
- return 0;
- }
- convert_num (cfile, &buf [len], val, 16, 8);
- if (len++ > max) {
- parse_warn (cfile,
- "hexadecimal constant too long.");
- skip_to_semi (cfile);
- return 0;
- }
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token == COLON)
- token = next_token (&val,
- (unsigned *)0, cfile);
- } while (token == COLON);
- val = (char *)buf;
- } else if (token == STRING) {
- token = next_token (&val, &len, cfile);
- if (len + 1 > max) {
- parse_warn (cfile, "string constant too long.");
- skip_to_semi (cfile);
- return 0;
- }
- memcpy (buf, val, len + 1);
- } else {
- parse_warn (cfile, "expecting string or hexadecimal data");
- skip_to_semi (cfile);
- return 0;
- }
- return len;
-}
-
-int parse_warn (struct parse *cfile, const char *fmt, ...)
-{
- va_list list;
- char lexbuf [256];
- char mbuf [1024];
- char fbuf [1024];
- unsigned i, lix;
-
- do_percentm (mbuf, fmt);
- /* %Audit% This is log output. %2004.06.17,Safe%
- * If we truncate we hope the user can get a hint from the log.
- */
- snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
- cfile -> tlname, cfile -> lexline, mbuf);
-
- va_start (list, fmt);
- vsnprintf (mbuf, sizeof mbuf, fbuf, list);
- va_end (list);
-
- lix = 0;
- for (i = 0;
- cfile -> token_line [i] && i < (cfile -> lexchar - 1); i++) {
- if (lix < (sizeof lexbuf) - 1)
- lexbuf [lix++] = ' ';
- if (cfile -> token_line [i] == '\t') {
- for (lix;
- lix < (sizeof lexbuf) - 1 && (lix & 7); lix++)
- lexbuf [lix] = ' ';
- }
- }
- lexbuf [lix] = 0;
-
-#ifndef DEBUG
- syslog (log_priority | LOG_ERR, "%s", mbuf);
- syslog (log_priority | LOG_ERR, "%s", cfile -> token_line);
- if (cfile -> lexchar < 81)
- syslog (log_priority | LOG_ERR, "%s^", lexbuf);
-#endif
-
- if (log_perror) {
- write (2, mbuf, strlen (mbuf));
- write (2, "\n", 1);
- write (2, cfile -> token_line, strlen (cfile -> token_line));
- write (2, "\n", 1);
- if (cfile -> lexchar < 81)
- write (2, lexbuf, lix);
- write (2, "^\n", 2);
- }
-
- cfile -> warnings_occurred = 1;
-
- return 0;
-}
diff --git a/contrib/isc-dhcp/common/print.c b/contrib/isc-dhcp/common/print.c
deleted file mode 100644
index dba1170..0000000
--- a/contrib/isc-dhcp/common/print.c
+++ /dev/null
@@ -1,1405 +0,0 @@
-/* print.c
-
- Turn data structures into printable text. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: print.c,v 1.53.2.11 2004/06/17 20:54:39 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-char *quotify_string (const char *s, const char *file, int line)
-{
- unsigned len = 0;
- const char *sp;
- char *buf, *nsp;
-
- for (sp = s; sp && *sp; sp++) {
- if (*sp == ' ')
- len++;
- else if (!isascii (*sp) || !isprint (*sp))
- len += 4;
- else if (*sp == '"' || *sp == '\\')
- len += 2;
- else
- len++;
- }
-
- buf = dmalloc (len + 1, file, line);
- if (buf) {
- nsp = buf;
- for (sp = s; sp && *sp; sp++) {
- if (*sp == ' ')
- *nsp++ = ' ';
- else if (!isascii (*sp) || !isprint (*sp)) {
- sprintf (nsp, "\\%03o",
- *(const unsigned char *)sp);
- nsp += 4;
- } else if (*sp == '"' || *sp == '\\') {
- *nsp++ = '\\';
- *nsp++ = *sp;
- } else
- *nsp++ = *sp;
- }
- *nsp++ = 0;
- }
- return buf;
-}
-
-char *quotify_buf (const unsigned char *s, unsigned len,
- const char *file, int line)
-{
- unsigned nulen = 0;
- char *buf, *nsp;
- int i;
-
- for (i = 0; i < len; i++) {
- if (s [i] == ' ')
- nulen++;
- else if (!isascii (s [i]) || !isprint (s [i]))
- nulen += 4;
- else if (s [i] == '"' || s [i] == '\\')
- nulen += 2;
- else
- nulen++;
- }
-
- buf = dmalloc (nulen + 1, MDL);
- if (buf) {
- nsp = buf;
- for (i = 0; i < len; i++) {
- if (s [i] == ' ')
- *nsp++ = ' ';
- else if (!isascii (s [i]) || !isprint (s [i])) {
- sprintf (nsp, "\\%03o", s [i]);
- nsp += 4;
- } else if (s [i] == '"' || s [i] == '\\') {
- *nsp++ = '\\';
- *nsp++ = s [i];
- } else
- *nsp++ = s [i];
- }
- *nsp++ = 0;
- }
- return buf;
-}
-
-char *print_base64 (const unsigned char *buf, unsigned len,
- const char *file, int line)
-{
- char *s, *b;
- unsigned bl;
- int i;
- unsigned val, extra;
- static char to64 [] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- bl = ((len * 4 + 2) / 3) + 1;
- b = dmalloc (bl + 1, file, line);
- if (!b)
- return (char *)0;
-
- i = 0;
- s = b;
- while (i != len) {
- val = buf [i++];
- extra = val & 3;
- val = val >> 2;
- *s++ = to64 [val];
- if (i == len) {
- *s++ = to64 [extra << 4];
- *s++ = '=';
- break;
- }
- val = (extra << 8) + buf [i++];
- extra = val & 15;
- val = val >> 4;
- *s++ = to64 [val];
- if (i == len) {
- *s++ = to64 [extra << 2];
- *s++ = '=';
- break;
- }
- val = (extra << 8) + buf [i++];
- extra = val & 0x3f;
- val = val >> 6;
- *s++ = to64 [val];
- *s++ = to64 [extra];
- }
- if (!len)
- *s++ = '=';
- *s++ = 0;
- if (s > b + bl + 1)
- abort ();
- return b;
-}
-
-char *print_hw_addr (htype, hlen, data)
- int htype;
- int hlen;
- unsigned char *data;
-{
- static char habuf [49];
- char *s;
- int i;
-
- if (hlen <= 0)
- habuf [0] = 0;
- else {
- s = habuf;
- for (i = 0; i < hlen; i++) {
- sprintf (s, "%02x", data [i]);
- s += strlen (s);
- *s++ = ':';
- }
- *--s = 0;
- }
- return habuf;
-}
-
-void print_lease (lease)
- struct lease *lease;
-{
- struct tm *t;
- char tbuf [32];
-
- log_debug (" Lease %s",
- piaddr (lease -> ip_addr));
-
- t = gmtime (&lease -> starts);
- strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
- log_debug (" start %s", tbuf);
-
- t = gmtime (&lease -> ends);
- strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
- log_debug (" end %s", tbuf);
-
- if (lease -> hardware_addr.hlen)
- log_debug (" hardware addr = %s",
- print_hw_addr (lease -> hardware_addr.hbuf [0],
- lease -> hardware_addr.hlen - 1,
- &lease -> hardware_addr.hbuf [1]));
- log_debug (" host %s ",
- lease -> host ? lease -> host -> name : "<none>");
-}
-
-#if defined (DEBUG_PACKET)
-void dump_packet_option (struct option_cache *oc,
- struct packet *packet,
- struct lease *lease,
- struct client_state *client,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *foo)
-{
- const char *name, *dot;
- struct data_string ds;
- memset (&ds, 0, sizeof ds);
-
- if (u != &dhcp_universe) {
- name = u -> name;
- dot = ".";
- } else {
- name = "";
- dot = "";
- }
- if (evaluate_option_cache (&ds, packet, lease, client,
- in_options, cfg_options, scope, oc, MDL)) {
- log_debug (" option %s%s%s %s;\n",
- name, dot, oc -> option -> name,
- pretty_print_option (oc -> option,
- ds.data, ds.len, 1, 1));
- data_string_forget (&ds, MDL);
- }
-}
-
-void dump_packet (tp)
- struct packet *tp;
-{
- struct dhcp_packet *tdp = tp -> raw;
-
- log_debug ("packet length %d", tp -> packet_length);
- log_debug ("op = %d htype = %d hlen = %d hops = %d",
- tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
- log_debug ("xid = %x secs = %ld flags = %x",
- tdp -> xid, (unsigned long)tdp -> secs, tdp -> flags);
- log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
- log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
- log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
- log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
- log_debug ("chaddr = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.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]);
- log_debug ("filename = %s", tdp -> file);
- log_debug ("server_name = %s", tdp -> sname);
- if (tp -> options_valid) {
- int i;
-
- for (i = 0; i < tp -> options -> universe_count; i++) {
- if (tp -> options -> universes [i]) {
- option_space_foreach (tp, (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- tp -> options,
- &global_scope,
- universes [i], 0,
- dump_packet_option);
- }
- }
- }
- log_debug ("%s", "");
-}
-#endif
-
-void dump_raw (buf, len)
- const unsigned char *buf;
- unsigned len;
-{
- int i;
- char lbuf [80];
- int lbix = 0;
-
-/*
- 1 2 3 4 5 6 7
-01234567890123456789012345678901234567890123456789012345678901234567890123
-280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
-*/
-
- memset(lbuf, ' ', 79);
- lbuf [79] = 0;
-
- for (i = 0; i < len; i++) {
- if ((i & 15) == 0) {
- if (lbix) {
- lbuf[53]=' ';
- lbuf[54]=' ';
- lbuf[55]=' ';
- lbuf[73]='\0';
- log_info (lbuf);
- }
- memset(lbuf, ' ', 79);
- lbuf [79] = 0;
- sprintf (lbuf, "%03x:", i);
- lbix = 4;
- } else if ((i & 7) == 0)
- lbuf [lbix++] = ' ';
-
- if(isprint(buf[i])) {
- lbuf[56+(i%16)]=buf[i];
- } else {
- lbuf[56+(i%16)]='.';
- }
-
- sprintf (&lbuf [lbix], " %02x", buf [i]);
- lbix += 3;
- lbuf[lbix]=' ';
-
- }
- lbuf[53]=' ';
- lbuf[54]=' ';
- lbuf[55]=' ';
- lbuf[73]='\0';
- log_info (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;
- log_info ("hash bucket %d:", i);
- for (bp = table -> buckets [i]; bp; bp = bp -> next) {
- if (bp -> len)
- dump_raw (bp -> name, bp -> len);
- else
- log_info ("%s", (const char *)bp -> name);
- }
- }
-}
-
-#define HBLEN 60
-
-#define DECLARE_HEX_PRINTER(x) \
-char *print_hex##x (len, data, limit) \
- unsigned len; \
- const u_int8_t *data; \
- unsigned limit; \
-{ \
- \
- static char hex_buf##x [HBLEN + 1]; \
- unsigned i; \
- \
- if (limit > HBLEN) \
- limit = HBLEN; \
- \
- for (i = 0; i < (limit - 2) && i < len; i++) { \
- if (!isascii (data [i]) || !isprint (data [i])) { \
- for (i = 0; i < limit / 3 && i < len; i++) { \
- sprintf (&hex_buf##x [i * 3], \
- "%02x:", data [i]); \
- } \
- hex_buf##x [i * 3 - 1] = 0; \
- return hex_buf##x; \
- } \
- } \
- hex_buf##x [0] = '"'; \
- i = len; \
- if (i > limit - 2) \
- i = limit - 2; \
- memcpy (&hex_buf##x [1], data, i); \
- hex_buf##x [i + 1] = '"'; \
- hex_buf##x [i + 2] = 0; \
- return hex_buf##x; \
-}
-
-DECLARE_HEX_PRINTER (_1)
-DECLARE_HEX_PRINTER (_2)
-DECLARE_HEX_PRINTER (_3)
-
-#define DQLEN 80
-
-char *print_dotted_quads (len, data)
- unsigned len;
- const u_int8_t *data;
-{
- static char dq_buf [DQLEN + 1];
- int i;
- char *s, *last;
-
- s = &dq_buf [0];
- last = s;
-
- i = 0;
-
- /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
- * The sprintf can't exceed 18 bytes, and since the loop enforces
- * 21 bytes of space per iteration at no time can we exit the
- * loop without at least 3 bytes spare.
- */
- do {
- sprintf (s, "%u.%u.%u.%u, ",
- data [i], data [i + 1], data [i + 2], data [i + 3]);
- s += strlen (s);
- i += 4;
- } while ((s - &dq_buf [0] > DQLEN - 21) &&
- i + 3 < len);
- if (i == len)
- s [-2] = 0;
- else
- strcpy (s, "...");
- return dq_buf;
-}
-
-char *print_dec_1 (val)
- unsigned long val;
-{
- static char vbuf [32];
- sprintf (vbuf, "%lu", val);
- return vbuf;
-}
-
-char *print_dec_2 (val)
- unsigned long val;
-{
- static char vbuf [32];
- sprintf (vbuf, "%lu", val);
- return vbuf;
-}
-
-static unsigned print_subexpression PROTO ((struct expression *,
- char *, unsigned));
-
-static unsigned print_subexpression (expr, buf, len)
- struct expression *expr;
- char *buf;
- unsigned len;
-{
- unsigned rv, left;
- const char *s;
-
- switch (expr -> op) {
- case expr_none:
- if (len > 3) {
- strcpy (buf, "nil");
- return 3;
- }
- break;
-
- case expr_match:
- if (len > 7) {
- strcpy (buf, "(match)");
- return 7;
- }
- break;
-
- case expr_check:
- rv = 10 + strlen (expr -> data.check -> name);
- if (len > rv) {
- sprintf (buf, "(check %s)",
- expr -> data.check -> name);
- return rv;
- }
- break;
-
- case expr_equal:
- if (len > 6) {
- rv = 4;
- strcpy (buf, "(eq ");
- rv += print_subexpression (expr -> data.equal [0],
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.equal [1],
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_not_equal:
- if (len > 7) {
- rv = 5;
- strcpy (buf, "(neq ");
- rv += print_subexpression (expr -> data.equal [0],
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.equal [1],
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_substring:
- if (len > 11) {
- rv = 8;
- strcpy (buf, "(substr ");
- rv += print_subexpression (expr -> data.substring.expr,
- buf + rv, len - rv - 3);
- buf [rv++] = ' ';
- rv += print_subexpression
- (expr -> data.substring.offset,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.substring.len,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_suffix:
- if (len > 10) {
- rv = 8;
- strcpy (buf, "(suffix ");
- rv += print_subexpression (expr -> data.suffix.expr,
- buf + rv, len - rv - 2);
- if (len > rv)
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.suffix.len,
- buf + rv, len - rv - 1);
- if (len > rv)
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_concat:
- if (len > 10) {
- rv = 8;
- strcpy (buf, "(concat ");
- rv += print_subexpression (expr -> data.concat [0],
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.concat [1],
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_pick_first_value:
- if (len > 8) {
- rv = 6;
- strcpy (buf, "(pick1st ");
- rv += print_subexpression
- (expr -> data.pick_first_value.car,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression
- (expr -> data.pick_first_value.cdr,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_host_lookup:
- rv = 15 + strlen (expr -> data.host_lookup -> hostname);
- if (len > rv) {
- sprintf (buf, "(dns-lookup %s)",
- expr -> data.host_lookup -> hostname);
- return rv;
- }
- break;
-
- case expr_and:
- s = "and";
- binop:
- rv = strlen (s);
- if (len > rv + 4) {
- buf [0] = '(';
- strcpy (&buf [1], s);
- rv += 1;
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.and [0],
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.and [1],
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_or:
- s = "or";
- goto binop;
-
- case expr_add:
- s = "+";
- goto binop;
-
- case expr_subtract:
- s = "-";
- goto binop;
-
- case expr_multiply:
- s = "*";
- goto binop;
-
- case expr_divide:
- s = "/";
- goto binop;
-
- case expr_remainder:
- s = "%";
- goto binop;
-
- case expr_binary_and:
- s = "&";
- goto binop;
-
- case expr_binary_or:
- s = "|";
- goto binop;
-
- case expr_binary_xor:
- s = "^";
- goto binop;
-
- case expr_not:
- if (len > 6) {
- rv = 5;
- strcpy (buf, "(not ");
- rv += print_subexpression (expr -> data.not,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_config_option:
- s = "cfg-option";
- goto dooption;
-
- case expr_option:
- s = "option";
- dooption:
- rv = strlen (s) + 2 + (strlen (expr -> data.option -> name) +
- strlen (expr -> data.option -> universe -> name));
- if (len > rv) {
- sprintf (buf, "(option %s.%s)",
- expr -> data.option -> universe -> name,
- expr -> data.option -> name);
- return rv;
- }
- break;
-
- case expr_hardware:
- if (len > 10) {
- strcpy (buf, "(hardware)");
- return 10;
- }
- break;
-
- case expr_packet:
- if (len > 10) {
- rv = 8;
- strcpy (buf, "(substr ");
- rv += print_subexpression (expr -> data.packet.offset,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.packet.len,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_const_data:
- s = print_hex_1 (expr -> data.const_data.len,
- expr -> data.const_data.data, len);
- rv = strlen (s);
- if (rv >= len)
- rv = len - 1;
- strncpy (buf, s, rv);
- buf [rv] = 0;
- return rv;
-
- case expr_encapsulate:
- rv = 13;
- strcpy (buf, "(encapsulate ");
- rv += expr -> data.encapsulate.len;
- if (rv + 2 > len)
- rv = len - 2;
- strncpy (buf,
- (const char *)expr -> data.encapsulate.data, rv - 13);
- buf [rv++] = ')';
- buf [rv++] = 0;
- break;
-
- case expr_extract_int8:
- if (len > 7) {
- rv = 6;
- strcpy (buf, "(int8 ");
- rv += print_subexpression (expr -> data.extract_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_extract_int16:
- if (len > 8) {
- rv = 7;
- strcpy (buf, "(int16 ");
- rv += print_subexpression (expr -> data.extract_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_extract_int32:
- if (len > 8) {
- rv = 7;
- strcpy (buf, "(int32 ");
- rv += print_subexpression (expr -> data.extract_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_encode_int8:
- if (len > 7) {
- rv = 6;
- strcpy (buf, "(to-int8 ");
- rv += print_subexpression (expr -> data.encode_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_encode_int16:
- if (len > 8) {
- rv = 7;
- strcpy (buf, "(to-int16 ");
- rv += print_subexpression (expr -> data.encode_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_encode_int32:
- if (len > 8) {
- rv = 7;
- strcpy (buf, "(to-int32 ");
- rv += print_subexpression (expr -> data.encode_int,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_const_int:
- s = print_dec_1 (expr -> data.const_int);
- rv = strlen (s);
- if (len > rv) {
- strcpy (buf, s);
- return rv;
- }
- break;
-
- case expr_exists:
- rv = 10 + (strlen (expr -> data.option -> name) +
- strlen (expr -> data.option -> universe -> name));
- if (len > rv) {
- sprintf (buf, "(exists %s.%s)",
- expr -> data.option -> universe -> name,
- expr -> data.option -> name);
- return rv;
- }
- break;
-
- case expr_variable_exists:
- rv = 10 + strlen (expr -> data.variable);
- if (len > rv) {
- sprintf (buf, "(defined %s)", expr -> data.variable);
- return rv;
- }
- break;
-
- case expr_variable_reference:
- rv = strlen (expr -> data.variable);
- if (len > rv) {
- sprintf (buf, "%s", expr -> data.variable);
- return rv;
- }
- break;
-
- case expr_known:
- s = "known";
- astring:
- rv = strlen (s);
- if (len > rv) {
- strcpy (buf, s);
- return rv;
- }
- break;
-
- case expr_leased_address:
- s = "leased-address";
- goto astring;
-
- case expr_client_state:
- s = "client-state";
- goto astring;
-
- case expr_host_decl_name:
- s = "host-decl-name";
- goto astring;
-
- case expr_lease_time:
- s = "lease-time";
- goto astring;
-
- case expr_static:
- s = "static";
- goto astring;
-
- case expr_filename:
- s = "filename";
- goto astring;
-
- case expr_sname:
- s = "server-name";
- goto astring;
-
- case expr_reverse:
- if (len > 11) {
- rv = 13;
- strcpy (buf, "(reverse ");
- rv += print_subexpression (expr -> data.reverse.width,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.reverse.buffer,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_binary_to_ascii:
- if (len > 5) {
- rv = 9;
- strcpy (buf, "(b2a ");
- rv += print_subexpression (expr -> data.b2a.base,
- buf + rv, len - rv - 4);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.b2a.width,
- buf + rv, len - rv - 3);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.b2a.seperator,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.b2a.buffer,
- buf + rv, len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_dns_transaction:
- rv = 10;
- if (len < rv + 2) {
- buf [0] = '(';
- strcpy (&buf [1], "ns-update ");
- while (len < rv + 2) {
- rv += print_subexpression
- (expr -> data.dns_transaction.car,
- buf + rv, len - rv - 2);
- buf [rv++] = ' ';
- expr = expr -> data.dns_transaction.cdr;
- }
- buf [rv - 1] = ')';
- buf [rv] = 0;
- return rv;
- }
- return 0;
-
- case expr_ns_delete:
- s = "delete";
- left = 4;
- goto dodnsupd;
- case expr_ns_exists:
- s = "exists";
- left = 4;
- goto dodnsupd;
- case expr_ns_not_exists:
- s = "not_exists";
- left = 4;
- goto dodnsupd;
- case expr_ns_add:
- s = "update";
- left = 5;
- dodnsupd:
- rv = strlen (s);
- if (len > strlen (s) + 1) {
- buf [0] = '(';
- strcpy (buf + 1, s);
- rv++;
- buf [rv++] = ' ';
- s = print_dec_1 (expr -> data.ns_add.rrclass);
- if (len > rv + strlen (s) + left) {
- strcpy (&buf [rv], s);
- rv += strlen (&buf [rv]);
- }
- buf [rv++] = ' ';
- left--;
- s = print_dec_1 (expr -> data.ns_add.rrtype);
- if (len > rv + strlen (s) + left) {
- strcpy (&buf [rv], s);
- rv += strlen (&buf [rv]);
- }
- buf [rv++] = ' ';
- left--;
- rv += print_subexpression
- (expr -> data.ns_add.rrname,
- buf + rv, len - rv - left);
- buf [rv++] = ' ';
- left--;
- rv += print_subexpression
- (expr -> data.ns_add.rrdata,
- buf + rv, len - rv - left);
- buf [rv++] = ' ';
- left--;
- rv += print_subexpression
- (expr -> data.ns_add.ttl,
- buf + rv, len - rv - left);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_null:
- if (len > 6) {
- strcpy (buf, "(null)");
- return 6;
- }
- break;
- case expr_funcall:
- rv = 12 + strlen (expr -> data.funcall.name);
- if (len > rv + 1) {
- strcpy (buf, "(funcall ");
- strcpy (buf + 9, expr -> data.funcall.name);
- buf [rv++] = ' ';
- rv += print_subexpression
- (expr -> data.funcall.arglist, buf + rv,
- len - rv - 1);
- buf [rv++] = ')';
- buf [rv] = 0;
- return rv;
- }
- break;
-
- case expr_arg:
- rv = print_subexpression (expr -> data.arg.val, buf, len);
- if (expr -> data.arg.next && rv + 2 < len) {
- buf [rv++] = ' ';
- rv += print_subexpression (expr -> data.arg.next,
- buf, len);
- if (rv + 1 < len)
- buf [rv++] = 0;
- return rv;
- }
- break;
- case expr_function:
- rv = 9;
- if (len > rv + 1) {
- struct string_list *foo;
- strcpy (buf, "(function");
- for (foo = expr -> data.func -> args;
- foo; foo = foo -> next) {
- if (len > rv + 2 + strlen (foo -> string)) {
- buf [rv - 1] = ' ';
- strcpy (&buf [rv], foo -> string);
- rv += strlen (foo -> string);
- }
- }
- buf [rv] = ')';
- buf [rv++] = 0;
- return rv;
- }
- }
- return 0;
-}
-
-void print_expression (name, expr)
- const char *name;
- struct expression *expr;
-{
- char buf [1024];
-
- print_subexpression (expr, buf, sizeof buf);
- log_info ("%s: %s", name, buf);
-}
-
-int token_print_indent_concat (FILE *file, int col, int indent,
- const char *prefix,
- const char *suffix, ...)
-{
- va_list list;
- char *buf;
- unsigned len;
- char *s, *t, *u;
-
- va_start (list, suffix);
- s = va_arg (list, char *);
- len = 0;
- while (s) {
- len += strlen (s);
- s = va_arg (list, char *);
- }
- va_end (list);
-
- t = dmalloc (len + 1, MDL);
- if (!t)
- log_fatal ("token_print_indent: no memory for copy buffer");
-
- va_start (list, suffix);
- s = va_arg (list, char *);
- u = t;
- while (s) {
- len = strlen (s);
- strcpy (u, s);
- u += len;
- }
- va_end (list);
-
- len = token_print_indent (file, col, indent,
- prefix, suffix, t);
- dfree (t, MDL);
- return col;
-}
-
-int token_indent_data_string (FILE *file, int col, int indent,
- const char *prefix, const char *suffix,
- struct data_string *data)
-{
- int i;
- char *buf;
- char obuf [3];
-
- /* See if this is just ASCII. */
- for (i = 0; i < data -> len; i++)
- if (!isascii (data -> data [i]) ||
- !isprint (data -> data [i]))
- break;
-
- /* If we have a purely ASCII string, output it as text. */
- if (i == data -> len) {
- char *buf = dmalloc (data -> len + 3, MDL);
- if (buf) {
- buf [0] = '"';
- memcpy (buf + 1, data -> data, data -> len);
- buf [data -> len + 1] = '"';
- buf [data -> len + 2] = 0;
- i = token_print_indent (file, col, indent,
- prefix, suffix, buf);
- dfree (buf, MDL);
- return i;
- }
- }
-
- for (i = 0; i < data -> len; i++) {
- sprintf (obuf, "%2.2x", data -> data [i]);
- col = token_print_indent (file, col, indent,
- i == 0 ? prefix : "",
- (i + 1 == data -> len
- ? suffix
- : ""), obuf);
- if (i + 1 != data -> len)
- col = token_print_indent (file, col, indent,
- prefix, suffix, ":");
- }
- return col;
-}
-
-int token_print_indent (FILE *file, int col, int indent,
- const char *prefix,
- const char *suffix, const char *buf)
-{
- int len = strlen (buf) + strlen (prefix);
- if (col + len > 79) {
- if (indent + len < 79) {
- indent_spaces (file, indent);
- col = indent;
- } else {
- indent_spaces (file, col);
- col = len > 79 ? 0 : 79 - len - 1;
- }
- } else if (prefix && *prefix) {
- fputs (prefix, file);
- col += strlen (prefix);
- }
- fputs (buf, file);
- col += len;
- if (suffix && *suffix) {
- if (col + strlen (suffix) > 79) {
- indent_spaces (file, indent);
- col = indent;
- } else {
- fputs (suffix, file);
- col += strlen (suffix);
- }
- }
- return col;
-}
-
-void indent_spaces (FILE *file, int indent)
-{
- int i;
- fputc ('\n', file);
- for (i = 0; i < indent; i++)
- fputc (' ', file);
-}
-
-#if defined (NSUPDATE)
-void print_dns_status (int status, ns_updque *uq)
-{
- char obuf [1024];
- char *s = &obuf [0], *end = &obuf [1022];
- ns_updrec *u;
- int position;
- int ttlp;
- const char *predicate = "if", *en, *op;
- int errorp;
-
- for (u = ISC_LIST_HEAD (*uq); u; u = ISC_LIST_NEXT (u, r_link)) {
- ttlp = 0;
-
- switch (u -> r_opcode)
- {
- case NXRRSET:
- op = "rrset doesn't exist";
- position = 1;
- break;
- case YXRRSET:
- op = "rrset exists";
- position = 1;
- break;
- case NXDOMAIN:
- op = "domain doesn't exist";
- position = 1;
- break;
- case YXDOMAIN:
- op = "domain exists";
- position = 1;
- break;
- case ADD:
- op = "add";
- position = 0;
- ttlp = 1;
- break;
- case DELETE:
- op = "delete";
- position = 0;
- break;
- default:
- op = "unknown";
- position = 0;
- break;
- }
- if (!position) {
- if (s != &obuf [0] && s + 1 < end)
- *s++ = ' ';
- if (s + strlen (op) < end) {
- strcpy (s, op);
- s += strlen (s);
- }
- } else {
- if (s != &obuf [0] && s + 1 < end)
- *s++ = ' ';
- if (s + strlen (predicate) < end) {
- strcpy (s, predicate);
- s += strlen (s);
- }
- predicate = "and";
- }
- if (u -> r_dname) {
- if (s + 1 < end)
- *s++ = ' ';
- if (s + strlen (u -> r_dname) < end) {
- strcpy (s, u -> r_dname);
- s += strlen (s);
- }
- }
- if (ttlp) {
- if (s + 1 < end)
- *s++ = ' ';
- /* 27 is as big as a ttl can get. */
- if (s + 27 < end) {
- sprintf (s, "%lu",
- (unsigned long)(u -> r_ttl));
- s += strlen (s);
- }
- }
- switch (u -> r_class) {
- case C_IN:
- en = "IN";
- break;
- case C_CHAOS:
- en = "CHAOS";
- break;
- case C_HS:
- en = "HS";
- break;
- default:
- en = "UNKNOWN";
- break;
- }
- if (s + strlen (en) < end) {
- if (s + 1 < end)
- *s++ = ' ';
- strcpy (s, en);
- s += strlen (en);
- }
- switch (u -> r_type) {
- case T_A:
- en = "A";
- break;
- case T_PTR:
- en = "PTR";
- break;
- case T_MX:
- en = "MX";
- break;
- case T_TXT:
- en = "TXT";
- break;
- case T_KEY:
- en = "KEY";
- break;
- case T_CNAME:
- en = "CNAME";
- break;
- default:
- en = "UNKNOWN";
- break;
- }
- if (s + strlen (en) < end) {
- if (s + 1 < end)
- *s++ = ' ';
- strcpy (s, en);
- s += strlen (en);
- }
- if (u -> r_data) {
- if (s + 1 < end)
- *s++ = ' ';
- if (u -> r_type == T_TXT) {
- if (s + 1 < end)
- *s++ = '"';
- }
- if(u->r_type == T_KEY) {
- strcat(s, "<keydata>");
- s+=strlen("<keydata>");
- }
- else {
- if (s + u -> r_size < end) {
- memcpy (s, u -> r_data, u -> r_size);
- s += u -> r_size;
- if (u -> r_type == T_TXT) {
- if (s + 1 < end)
- *s++ = '"';
- }
- }
- }
- }
- if (position) {
- if (s + 1 < end)
- *s++ = ' ';
- if (s + strlen (op) < end) {
- strcpy (s, op);
- s += strlen (s);
- }
- }
- if (u == ISC_LIST_TAIL (*uq))
- break;
- }
- if (s == &obuf [0]) {
- strcpy (s, "empty update");
- s += strlen (s);
- }
- if (status == NOERROR)
- errorp = 0;
- else
- errorp = 1;
- en = isc_result_totext (status);
-#if 0
- switch (status) {
- case -1:
- en = "resolver failed";
- break;
-
- case FORMERR:
- en = "format error";
- break;
-
- case NOERROR:
- en = "succeeded";
- errorp = 0;
- break;
-
- case NOTAUTH:
- en = "not authorized";
- break;
-
- case NOTIMP:
- en = "not implemented";
- break;
-
- case NOTZONE:
- en = "not a single valid zone";
- break;
-
- case NXDOMAIN:
- en = "no such domain";
- break;
-
- case NXRRSET:
- en = "no such record";
- break;
-
- case REFUSED:
- en = "refused";
- break;
-
- case SERVFAIL:
- en = "server failed";
- break;
-
- case YXDOMAIN:
- en = "domain exists";
- break;
-
- case YXRRSET:
- en = "record exists";
- break;
-
- default:
- en = "unknown error";
- break;
- }
-#endif
-
- if (s + 2 < end) {
- *s++ = ':';
- *s++ = ' ';
- }
- if (s + strlen (en) < end) {
- strcpy (s, en);
- s += strlen (en);
- }
- if (s + 1 < end)
- *s++ = '.';
- *s++ = 0;
- if (errorp)
- log_error ("%s", obuf);
- else
- log_info ("%s", obuf);
-}
-#endif /* NSUPDATE */
diff --git a/contrib/isc-dhcp/common/raw.c b/contrib/isc-dhcp/common/raw.c
deleted file mode 100644
index 1194ffc..0000000
--- a/contrib/isc-dhcp/common/raw.c
+++ /dev/null
@@ -1,144 +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) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: raw.c,v 1.17.2.2 2004/06/10 17:59:20 dhankins Exp $ Copyright (c) 2004 Internet Systems 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. */
- if (!quiet_interface_discovery)
- log_info ("Sending on %s, port %d",
- piaddr (info -> address), htons (local_port));
- if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
- log_fatal ("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)
- log_fatal ("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)
- log_fatal ("Can't set IP_HDRINCL flag: %m");
-
- info -> wfdesc = sock;
- if (!quiet_interface_discovery)
- log_info ("Sending on Raw/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_send (info)
- struct interface_info *info;
-{
- close (info -> wfdesc);
- info -> wfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling output on Raw/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-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];
- int result;
-
- /* 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;
-
- result = writev(interface -> wfdesc, iov, 2);
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_SOCKET_SEND */
diff --git a/contrib/isc-dhcp/common/resolv.c b/contrib/isc-dhcp/common/resolv.c
deleted file mode 100644
index b84de02..0000000
--- a/contrib/isc-dhcp/common/resolv.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* resolv.c
-
- Parser for /etc/resolv.conf file. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: resolv.c,v 1.16.2.2 2004/06/10 17:59:20 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-struct name_server *name_servers;
-struct domain_search_list *domains;
-char path_resolv_conf [] = _PATH_RESOLV_CONF;
-
-void read_resolv_conf (parse_time)
- TIME parse_time;
-{
- int file;
- struct parse *cfile;
- const char *val;
- int token;
- int declaration = 0;
- struct name_server *sp, *sl, *ns;
- struct domain_search_list *dp, *dl, *nd;
- struct iaddr *iaddr;
-
- if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
- log_error ("Can't open %s: %m", path_resolv_conf);
- return;
- }
-
- cfile = (struct parse *)0;
- new_parse (&cfile, file, (char *)0, 0, path_resolv_conf, 1);
-
- do {
- token = next_token (&val, (unsigned *)0, cfile);
- if (token == END_OF_FILE)
- break;
- else if (token == EOL)
- continue;
- else if (token == DOMAIN || token == SEARCH) {
- do {
- struct domain_search_list *nd, **dp;
- char *dn;
-
- dn = parse_host_name (cfile);
- if (!dn)
- break;
-
- dp = &domains;
- for (nd = domains; nd; nd = nd -> next) {
- dp = &nd -> next;
- if (!strcmp (nd -> domain, dn))
- break;
- }
- if (!nd) {
- nd = new_domain_search_list (MDL);
- if (!nd)
- log_fatal ("No memory for %s",
- dn);
- nd -> next =
- (struct domain_search_list *)0;
- *dp = nd;
- nd -> domain = dn;
- dn = (char *)0;
- }
- nd -> rcdate = parse_time;
- token = peek_token (&val,
- (unsigned *)0, cfile);
- } while (token != EOL);
- if (token != EOL) {
- parse_warn (cfile,
- "junk after domain declaration");
- skip_to_semi (cfile);
- }
- token = next_token (&val, (unsigned *)0, cfile);
- } else if (token == NAMESERVER) {
- struct name_server *ns, **sp;
- struct iaddr iaddr;
-
- parse_ip_addr (cfile, &iaddr);
-
- sp = &name_servers;
- for (ns = name_servers; ns; ns = ns -> next) {
- sp = &ns -> next;
- if (!memcmp (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len))
- break;
- }
- if (!ns) {
- ns = new_name_server (MDL);
- if (!ns)
- log_fatal ("No memory for nameserver %s",
- piaddr (iaddr));
- ns -> next = (struct name_server *)0;
- *sp = ns;
- memcpy (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len);
-#ifdef HAVE_SA_LEN
- ns -> addr.sin_len = sizeof ns -> addr;
-#endif
- ns -> addr.sin_family = AF_INET;
- ns -> addr.sin_port = htons (53);
- memset (ns -> addr.sin_zero, 0,
- sizeof ns -> addr.sin_zero);
- }
- ns -> rcdate = parse_time;
- skip_to_semi (cfile);
- } else
- skip_to_semi (cfile); /* Ignore what we don't grok. */
- } while (1);
- token = next_token (&val, (unsigned *)0, cfile);
-
- /* Lose servers that are no longer in /etc/resolv.conf. */
- sl = (struct name_server *)0;
- for (sp = name_servers; sp; sp = ns) {
- ns = sp -> next;
- if (sp -> rcdate != parse_time) {
- if (sl)
- sl -> next = sp -> next;
- else
- name_servers = sp -> next;
- /* We can't actually free the name server structure,
- because somebody might be hanging on to it. If
- your /etc/resolv.conf file changes a lot, this
- could be a noticable memory leak. */
- } else
- sl = sp;
- }
-
- /* Lose domains that are no longer in /etc/resolv.conf. */
- dl = (struct domain_search_list *)0;
- for (dp = domains; dp; dp = nd) {
- nd = dp -> next;
- if (dp -> rcdate != parse_time) {
- if (dl)
- dl -> next = dp -> next;
- else
- domains = dp -> next;
- free_domain_search_list (dp, MDL);
- } else
- dl = dp;
- }
- close (file);
- end_parse (&cfile);
-}
-
-/* Pick a name server from the /etc/resolv.conf file. */
-
-struct name_server *first_name_server ()
-{
- FILE *rc;
- static TIME rcdate;
- struct stat st;
-
- /* Check /etc/resolv.conf and reload it if it's changed. */
- if (cur_time > rcdate) {
- if (stat (path_resolv_conf, &st) < 0) {
- log_error ("Can't stat %s", path_resolv_conf);
- return (struct name_server *)0;
- }
- if (st.st_mtime > rcdate) {
- char rcbuf [512];
- char *s, *t, *u;
- rcdate = cur_time + 1;
-
- read_resolv_conf (rcdate);
- }
- }
-
- return name_servers;
-}
diff --git a/contrib/isc-dhcp/common/socket.c b/contrib/isc-dhcp/common/socket.c
deleted file mode 100644
index 6aa4507..0000000
--- a/contrib/isc-dhcp/common/socket.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* socket.c
-
- BSD socket interface code... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.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.55.2.4 2004/06/10 17:59:21 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#ifdef USE_SOCKET_FALLBACK
-# if !defined (USE_SOCKET_SEND)
-# define if_register_send if_register_fallback
-# define send_packet send_fallback
-# define if_reinitialize_send if_reinitialize_fallback
-# endif
-#endif
-
-static int once = 0;
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
-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) || \
- defined (USE_SOCKET_FALLBACK)
-/* Generic interface registration routine... */
-int if_register_socket (info)
- struct interface_info *info;
-{
- struct sockaddr_in name;
- int sock;
- int flag;
-
-#if !defined (HAVE_SO_BINDTODEVICE) && !defined (USE_FALLBACK)
- /* Make sure only one interface is registered. */
- if (once)
- log_fatal ("The standard socket API can only support %s",
- "hosts with a single network interface.");
- once = 1;
-#endif
-
- memset (&name, 0, sizeof (name));
- /* Set up the address we're going to bind to. */
- name.sin_family = AF_INET;
- name.sin_port = local_port;
- name.sin_addr = local_address;
-
- /* Make a socket... */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
- log_fatal ("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)
- log_fatal ("Can't set SO_REUSEADDR option on dhcp socket: %m");
-
- /* Set the BROADCAST option so that we can broadcast DHCP responses.
- We shouldn't do this for fallback devices, and we can detect that
- a device is a fallback because it has no ifp structure. */
- if (info -> ifp &&
- (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
- (char *)&flag, sizeof flag) < 0))
- log_fatal ("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) {
- log_error ("Can't bind to dhcp address: %m");
- log_error ("Please make sure there is no other dhcp server");
- log_error ("running and that there's no entry for dhcp or");
- log_error ("bootp in /etc/inetd.conf. Also make sure you");
- log_error ("are not running HP JetAdmin software, which");
- log_fatal ("includes a bootp server.");
- }
-
-#if defined (HAVE_SO_BINDTODEVICE)
- /* Bind this socket to this interface. */
- if (info -> ifp &&
- setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
- (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
- log_fatal ("setsockopt: SO_BINDTODEVICE: %m");
- }
-#endif
-
- return sock;
-}
-#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
-
-#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
-void if_register_send (info)
- struct interface_info *info;
-{
-#ifndef USE_SOCKET_RECEIVE
- info -> wfdesc = if_register_socket (info);
-#if defined (USE_SOCKET_FALLBACK)
- /* Fallback only registers for send, but may need to receive as
- well. */
- info -> rfdesc = info -> wfdesc;
-#endif
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- log_info ("Sending on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-#if defined (USE_SOCKET_SEND)
-void if_deregister_send (info)
- struct interface_info *info;
-{
-#ifndef USE_SOCKET_RECEIVE
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling output on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_SOCKET_SEND */
-#endif /* USE_SOCKET_SEND || USE_SOCKET_FALLBACK */
-
-#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);
- if (!quiet_interface_discovery)
- log_info ("Listening on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_receive (info)
- struct interface_info *info;
-{
- close (info -> rfdesc);
- info -> rfdesc = -1;
-
- if (!quiet_interface_discovery)
- log_info ("Disabling input on Socket/%s%s%s",
- info -> name,
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_SOCKET_RECEIVE */
-
-#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
-ssize_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 result;
-#ifdef IGNORE_HOSTUNREACH
- int retry = 0;
- do {
-#endif
- result = sendto (interface -> wfdesc, (char *)raw, len, 0,
- (struct sockaddr *)to, sizeof *to);
-#ifdef IGNORE_HOSTUNREACH
- } while (to -> sin_addr.s_addr == htonl (INADDR_BROADCAST) &&
- result < 0 &&
- (errno == EHOSTUNREACH ||
- errno == ECONNREFUSED) &&
- retry++ < 10);
-#endif
- if (result < 0) {
- log_error ("send_packet: %m");
- if (errno == ENETUNREACH)
- log_error ("send_packet: please consult README file%s",
- " regarding broadcast address.");
- }
- return result;
-}
-#endif /* USE_SOCKET_SEND || USE_SOCKET_FALLBACK */
-
-#ifdef USE_SOCKET_RECEIVE
-ssize_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;
-{
- SOCKLEN_T flen = sizeof *from;
- int result;
-
-#ifdef IGNORE_HOSTUNREACH
- int retry = 0;
- do {
-#endif
- result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
- (struct sockaddr *)from, &flen);
-#ifdef IGNORE_HOSTUNREACH
- } while (result < 0 &&
- (errno == EHOSTUNREACH ||
- errno == ECONNREFUSED) &&
- retry++ < 10);
-#endif
- return result;
-}
-#endif /* USE_SOCKET_RECEIVE */
-
-#if defined (USE_SOCKET_FALLBACK)
-/* This just reads in a packet and silently discards it. */
-
-isc_result_t fallback_discard (object)
- omapi_object_t *object;
-{
- char buf [1540];
- struct sockaddr_in from;
- SOCKLEN_T flen = sizeof from;
- int status;
- struct interface_info *interface;
-
- if (object -> type != dhcp_type_interface)
- return ISC_R_INVALIDARG;
- interface = (struct interface_info *)object;
-
- status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0,
- (struct sockaddr *)&from, &flen);
-#if defined (DEBUG)
- /* Only report fallback discard errors if we're debugging. */
- if (status < 0) {
- log_error ("fallback_discard: %m");
- return ISC_R_UNEXPECTED;
- }
-#endif
- return ISC_R_SUCCESS;
-}
-#endif /* USE_SOCKET_FALLBACK */
-
-#if defined (USE_SOCKET_SEND)
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 0;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
-#if defined (SOCKET_CAN_RECEIVE_UNICAST_UNCONFIGURED)
- return 1;
-#else
- return 0;
-#endif
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
-#if defined (SO_BINDTODEVICE)
- return 1;
-#else
- return 0;
-#endif
-}
-
-/* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise,
- do not. */
-
-void maybe_setup_fallback ()
-{
-#if defined (USE_SOCKET_FALLBACK)
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- fbi -> wfdesc = if_register_socket (fbi);
- fbi -> rfdesc = fbi -> wfdesc;
- log_info ("Sending on Socket/%s%s%s",
- fbi -> name,
- (fbi -> shared_network ? "/" : ""),
- (fbi -> shared_network ?
- fbi -> shared_network -> name : ""));
-
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-#endif
-}
-#endif /* USE_SOCKET_SEND */
diff --git a/contrib/isc-dhcp/common/tables.c b/contrib/isc-dhcp/common/tables.c
deleted file mode 100644
index 6de6d6f..0000000
--- a/contrib/isc-dhcp/common/tables.c
+++ /dev/null
@@ -1,1241 +0,0 @@
-/* tables.c
-
- Tables of information... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$FreeBSD$"
-"$Id: tables.c,v 1.51.2.8 2004/06/10 17:59:21 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-/* XXXDPN: Moved here from hash.c, when it moved to libomapi. Not sure
- where these really belong. */
-HASH_FUNCTIONS (group, const char *, struct group_object, group_hash_t,
- group_reference, group_dereference)
-HASH_FUNCTIONS (universe, const char *, struct universe, universe_hash_t, 0, 0)
-HASH_FUNCTIONS (option, const char *, struct option, option_hash_t, 0, 0)
-
-/* DHCP Option names, formats and codes, from RFC1533.
-
- Format codes:
-
- 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)
- a - array of the preceding character (e.g., IIa means two or more IP
- addresses)
- U - name of an option space (universe)
- F - implicit flag - the presence of the option indicates that the
- flag is true.
- o - the preceding value is optional.
- E - encapsulation, string or colon-seperated hex list (the latter
- two for parsing). E is followed by a text string containing
- the name of the option space to encapsulate, followed by a '.'.
- If the E is immediately followed by '.', the applicable vendor
- option space is used if one is defined.
- e - If an encapsulation directive is not the first thing in the string,
- the option scanner requires an efficient way to find the encapsulation.
- This is done by placing a 'e' at the beginning of the option. The
- 'e' has no other purpose, and is not required if 'E' is the first
- thing in the option.
- X - either an ASCII string or binary data. On output, the string is
- scanned to see if it's printable ASCII and, if so, output as a
- quoted string. If not, it's output as colon-seperated hex. On
- input, the option can be specified either as a quoted string or as
- a colon-seperated hex list.
- N - enumeration. N is followed by a text string containing
- the name of the set of enumeration values to parse or emit,
- followed by a '.'. The width of the data is specified in the
- named enumeration. Named enumerations are tracked in parse.c.
- d - Domain name (i.e., FOO or FOO.BAR).
-*/
-
-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 },
- { "ien116-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", "X", &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", "E.", &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 },
- { "vendor-class-identifier", "X", &dhcp_universe, 60 },
- { "dhcp-client-identifier", "X", &dhcp_universe, 61 },
- { "nwip-domain", "X", &dhcp_universe, 62 },
- { "nwip-suboptions", "Enwip.", &dhcp_universe, 63 },
- { "nisplus-domain", "t", &dhcp_universe, 64 },
- { "nisplus-servers", "IA", &dhcp_universe, 65 },
- { "tftp-server-name", "t", &dhcp_universe, 66 },
- { "bootfile-name", "t", &dhcp_universe, 67 },
- { "mobile-ip-home-agent", "IA", &dhcp_universe, 68 },
- { "smtp-server", "IA", &dhcp_universe, 69 },
- { "pop-server", "IA", &dhcp_universe, 70 },
- { "nntp-server", "IA", &dhcp_universe, 71 },
- { "www-server", "IA", &dhcp_universe, 72 },
- { "finger-server", "IA", &dhcp_universe, 73 },
- { "irc-server", "IA", &dhcp_universe, 74 },
- { "streettalk-server", "IA", &dhcp_universe, 75 },
- { "streettalk-directory-assistance-server", "IA", &dhcp_universe, 76 },
- { "user-class", "t", &dhcp_universe, 77 },
- { "slp-directory-agent", "fIa", &dhcp_universe, 78 },
- { "slp-service-scope", "fto", &dhcp_universe, 79 },
- { "unknown-80", "X", &dhcp_universe, 80 },
- { "fqdn", "Efqdn.", &dhcp_universe, 81 },
- { "relay-agent-information", "Eagent.", &dhcp_universe, 82 },
- { "unknown-83", "X", &dhcp_universe, 83 },
- { "unknown-84", "X", &dhcp_universe, 84 },
- { "nds-servers", "IA", &dhcp_universe, 85 },
- { "nds-tree-name", "X", &dhcp_universe, 86 },
- { "nds-context", "X", &dhcp_universe, 87 },
- { "unknown-88", "X", &dhcp_universe, 88 },
- { "unknown-89", "X", &dhcp_universe, 89 },
- { "unknown-90", "X", &dhcp_universe, 90 },
- { "unknown-91", "X", &dhcp_universe, 91 },
- { "unknown-92", "X", &dhcp_universe, 92 },
- { "unknown-93", "X", &dhcp_universe, 93 },
- { "unknown-94", "X", &dhcp_universe, 94 },
- { "unknown-95", "X", &dhcp_universe, 95 },
- { "unknown-96", "X", &dhcp_universe, 96 },
- { "unknown-97", "X", &dhcp_universe, 97 },
- { "uap-servers", "t", &dhcp_universe, 98 },
- { "unknown-99", "X", &dhcp_universe, 99 },
- { "unknown-100", "X", &dhcp_universe, 100 },
- { "unknown-101", "X", &dhcp_universe, 101 },
- { "unknown-102", "X", &dhcp_universe, 102 },
- { "unknown-103", "X", &dhcp_universe, 103 },
- { "unknown-104", "X", &dhcp_universe, 104 },
- { "unknown-105", "X", &dhcp_universe, 105 },
- { "unknown-106", "X", &dhcp_universe, 106 },
- { "unknown-107", "X", &dhcp_universe, 107 },
- { "unknown-108", "X", &dhcp_universe, 108 },
- { "unknown-109", "X", &dhcp_universe, 109 },
- { "unknown-110", "X", &dhcp_universe, 110 },
- { "unknown-111", "X", &dhcp_universe, 111 },
- { "unknown-112", "X", &dhcp_universe, 112 },
- { "unknown-113", "X", &dhcp_universe, 113 },
- { "unknown-114", "X", &dhcp_universe, 114 },
- { "unknown-115", "X", &dhcp_universe, 115 },
- { "unknown-116", "X", &dhcp_universe, 116 },
- { "unknown-117", "X", &dhcp_universe, 117 },
- { "subnet-selection", "X", &dhcp_universe, 118 },
- { "unknown-119", "X", &dhcp_universe, 119 },
- { "unknown-120", "X", &dhcp_universe, 120 },
- { "unknown-121", "X", &dhcp_universe, 121 },
- { "unknown-122", "X", &dhcp_universe, 122 },
- { "unknown-123", "X", &dhcp_universe, 123 },
- { "unknown-124", "X", &dhcp_universe, 124 },
- { "unknown-125", "X", &dhcp_universe, 125 },
- { "unknown-126", "X", &dhcp_universe, 126 },
- { "unknown-127", "X", &dhcp_universe, 127 },
- { "unknown-128", "X", &dhcp_universe, 128 },
- { "unknown-129", "X", &dhcp_universe, 129 },
- { "unknown-130", "X", &dhcp_universe, 130 },
- { "unknown-131", "X", &dhcp_universe, 131 },
- { "unknown-132", "X", &dhcp_universe, 132 },
- { "unknown-133", "X", &dhcp_universe, 133 },
- { "unknown-134", "X", &dhcp_universe, 134 },
- { "unknown-135", "X", &dhcp_universe, 135 },
- { "unknown-136", "X", &dhcp_universe, 136 },
- { "unknown-137", "X", &dhcp_universe, 137 },
- { "unknown-138", "X", &dhcp_universe, 138 },
- { "unknown-139", "X", &dhcp_universe, 139 },
- { "unknown-140", "X", &dhcp_universe, 140 },
- { "unknown-141", "X", &dhcp_universe, 141 },
- { "unknown-142", "X", &dhcp_universe, 142 },
- { "unknown-143", "X", &dhcp_universe, 143 },
- { "unknown-144", "X", &dhcp_universe, 144 },
- { "unknown-145", "X", &dhcp_universe, 145 },
- { "unknown-146", "X", &dhcp_universe, 146 },
- { "unknown-147", "X", &dhcp_universe, 147 },
- { "unknown-148", "X", &dhcp_universe, 148 },
- { "unknown-149", "X", &dhcp_universe, 149 },
- { "unknown-150", "X", &dhcp_universe, 150 },
- { "unknown-151", "X", &dhcp_universe, 151 },
- { "unknown-152", "X", &dhcp_universe, 152 },
- { "unknown-153", "X", &dhcp_universe, 153 },
- { "unknown-154", "X", &dhcp_universe, 154 },
- { "unknown-155", "X", &dhcp_universe, 155 },
- { "unknown-156", "X", &dhcp_universe, 156 },
- { "unknown-157", "X", &dhcp_universe, 157 },
- { "unknown-158", "X", &dhcp_universe, 158 },
- { "unknown-159", "X", &dhcp_universe, 159 },
- { "unknown-160", "X", &dhcp_universe, 160 },
- { "unknown-161", "X", &dhcp_universe, 161 },
- { "unknown-162", "X", &dhcp_universe, 162 },
- { "unknown-163", "X", &dhcp_universe, 163 },
- { "unknown-164", "X", &dhcp_universe, 164 },
- { "unknown-165", "X", &dhcp_universe, 165 },
- { "unknown-166", "X", &dhcp_universe, 166 },
- { "unknown-167", "X", &dhcp_universe, 167 },
- { "unknown-168", "X", &dhcp_universe, 168 },
- { "unknown-169", "X", &dhcp_universe, 169 },
- { "unknown-170", "X", &dhcp_universe, 170 },
- { "unknown-171", "X", &dhcp_universe, 171 },
- { "unknown-172", "X", &dhcp_universe, 172 },
- { "unknown-173", "X", &dhcp_universe, 173 },
- { "unknown-174", "X", &dhcp_universe, 174 },
- { "unknown-175", "X", &dhcp_universe, 175 },
- { "unknown-176", "X", &dhcp_universe, 176 },
- { "unknown-177", "X", &dhcp_universe, 177 },
- { "unknown-178", "X", &dhcp_universe, 178 },
- { "unknown-179", "X", &dhcp_universe, 179 },
- { "unknown-180", "X", &dhcp_universe, 180 },
- { "unknown-181", "X", &dhcp_universe, 181 },
- { "unknown-182", "X", &dhcp_universe, 182 },
- { "unknown-183", "X", &dhcp_universe, 183 },
- { "unknown-184", "X", &dhcp_universe, 184 },
- { "unknown-185", "X", &dhcp_universe, 185 },
- { "unknown-186", "X", &dhcp_universe, 186 },
- { "unknown-187", "X", &dhcp_universe, 187 },
- { "unknown-188", "X", &dhcp_universe, 188 },
- { "unknown-189", "X", &dhcp_universe, 189 },
- { "unknown-190", "X", &dhcp_universe, 190 },
- { "unknown-191", "X", &dhcp_universe, 191 },
- { "unknown-192", "X", &dhcp_universe, 192 },
- { "unknown-193", "X", &dhcp_universe, 193 },
- { "unknown-194", "X", &dhcp_universe, 194 },
- { "unknown-195", "X", &dhcp_universe, 195 },
- { "unknown-196", "X", &dhcp_universe, 196 },
- { "unknown-197", "X", &dhcp_universe, 197 },
- { "unknown-198", "X", &dhcp_universe, 198 },
- { "unknown-199", "X", &dhcp_universe, 199 },
- { "unknown-200", "X", &dhcp_universe, 200 },
- { "unknown-201", "X", &dhcp_universe, 201 },
- { "unknown-202", "X", &dhcp_universe, 202 },
- { "unknown-203", "X", &dhcp_universe, 203 },
- { "unknown-204", "X", &dhcp_universe, 204 },
- { "unknown-205", "X", &dhcp_universe, 205 },
- { "unknown-206", "X", &dhcp_universe, 206 },
- { "unknown-207", "X", &dhcp_universe, 207 },
- { "unknown-208", "X", &dhcp_universe, 208 },
- { "unknown-209", "X", &dhcp_universe, 209 },
- { "authenticate", "X", &dhcp_universe, 210 },
- { "unknown-211", "X", &dhcp_universe, 211 },
- { "unknown-212", "X", &dhcp_universe, 212 },
- { "unknown-213", "X", &dhcp_universe, 213 },
- { "unknown-214", "X", &dhcp_universe, 214 },
- { "unknown-215", "X", &dhcp_universe, 215 },
- { "unknown-216", "X", &dhcp_universe, 216 },
- { "unknown-217", "X", &dhcp_universe, 217 },
- { "unknown-218", "X", &dhcp_universe, 218 },
- { "unknown-219", "X", &dhcp_universe, 219 },
- { "unknown-220", "X", &dhcp_universe, 220 },
- { "unknown-221", "X", &dhcp_universe, 221 },
- { "unknown-222", "X", &dhcp_universe, 222 },
- { "unknown-223", "X", &dhcp_universe, 223 },
- { "unknown-224", "X", &dhcp_universe, 224 },
- { "unknown-225", "X", &dhcp_universe, 225 },
- { "unknown-226", "X", &dhcp_universe, 226 },
- { "unknown-227", "X", &dhcp_universe, 227 },
- { "unknown-228", "X", &dhcp_universe, 228 },
- { "unknown-229", "X", &dhcp_universe, 229 },
- { "unknown-230", "X", &dhcp_universe, 230 },
- { "unknown-231", "X", &dhcp_universe, 231 },
- { "unknown-232", "X", &dhcp_universe, 232 },
- { "unknown-233", "X", &dhcp_universe, 233 },
- { "unknown-234", "X", &dhcp_universe, 234 },
- { "unknown-235", "X", &dhcp_universe, 235 },
- { "unknown-236", "X", &dhcp_universe, 236 },
- { "unknown-237", "X", &dhcp_universe, 237 },
- { "unknown-238", "X", &dhcp_universe, 238 },
- { "unknown-239", "X", &dhcp_universe, 239 },
- { "unknown-240", "X", &dhcp_universe, 240 },
- { "unknown-241", "X", &dhcp_universe, 241 },
- { "unknown-242", "X", &dhcp_universe, 242 },
- { "unknown-243", "X", &dhcp_universe, 243 },
- { "unknown-244", "X", &dhcp_universe, 244 },
- { "unknown-245", "X", &dhcp_universe, 245 },
- { "unknown-246", "X", &dhcp_universe, 246 },
- { "unknown-247", "X", &dhcp_universe, 247 },
- { "unknown-248", "X", &dhcp_universe, 248 },
- { "unknown-249", "X", &dhcp_universe, 249 },
- { "unknown-250", "X", &dhcp_universe, 250 },
- { "unknown-251", "X", &dhcp_universe, 251 },
- { "unknown-252", "X", &dhcp_universe, 252 },
- { "unknown-253", "X", &dhcp_universe, 253 },
- { "unknown-254", "X", &dhcp_universe, 254 },
- { "option-end", "e", &dhcp_universe, 255 },
-};
-
-struct universe nwip_universe;
-struct option nwip_options [256] = {
- { "pad", "", &nwip_universe, 0 },
- { "illegal-1", "", &nwip_universe, 1 },
- { "illegal-2", "", &nwip_universe, 2 },
- { "illegal-3", "", &nwip_universe, 3 },
- { "illegal-4", "", &nwip_universe, 4 },
- { "nsq-broadcast", "f", &nwip_universe, 5 },
- { "preferred-dss", "IA", &nwip_universe, 6 },
- { "nearest-nwip-server", "IA", &nwip_universe, 7 },
- { "autoretries", "B", &nwip_universe, 8 },
- { "autoretry-secs", "B", &nwip_universe, 9 },
- { "nwip-1-1", "f", &nwip_universe, 10 },
- { "primary-dss", "I", &nwip_universe, 11 },
- { "unknown-12", "X", &nwip_universe, 12 },
- { "unknown-13", "X", &nwip_universe, 13 },
- { "unknown-14", "X", &nwip_universe, 14 },
- { "unknown-15", "X", &nwip_universe, 15 },
- { "unknown-16", "X", &nwip_universe, 16 },
- { "unknown-17", "X", &nwip_universe, 17 },
- { "unknown-18", "X", &nwip_universe, 18 },
- { "unknown-19", "X", &nwip_universe, 19 },
- { "unknown-20", "X", &nwip_universe, 20 },
- { "unknown-21", "X", &nwip_universe, 21 },
- { "unknown-22", "X", &nwip_universe, 22 },
- { "unknown-23", "X", &nwip_universe, 23 },
- { "unknown-24", "X", &nwip_universe, 24 },
- { "unknown-25", "X", &nwip_universe, 25 },
- { "unknown-26", "X", &nwip_universe, 26 },
- { "unknown-27", "X", &nwip_universe, 27 },
- { "unknown-28", "X", &nwip_universe, 28 },
- { "unknown-29", "X", &nwip_universe, 29 },
- { "unknown-30", "X", &nwip_universe, 30 },
- { "unknown-31", "X", &nwip_universe, 31 },
- { "unknown-32", "X", &nwip_universe, 32 },
- { "unknown-33", "X", &nwip_universe, 33 },
- { "unknown-34", "X", &nwip_universe, 34 },
- { "unknown-35", "X", &nwip_universe, 35 },
- { "unknown-36", "X", &nwip_universe, 36 },
- { "unknown-37", "X", &nwip_universe, 37 },
- { "unknown-38", "X", &nwip_universe, 38 },
- { "unknown-39", "X", &nwip_universe, 39 },
- { "unknown-40", "X", &nwip_universe, 40 },
- { "unknown-41", "X", &nwip_universe, 41 },
- { "unknown-42", "X", &nwip_universe, 42 },
- { "unknown-43", "X", &nwip_universe, 43 },
- { "unknown-44", "X", &nwip_universe, 44 },
- { "unknown-45", "X", &nwip_universe, 45 },
- { "unknown-46", "X", &nwip_universe, 46 },
- { "unknown-47", "X", &nwip_universe, 47 },
- { "unknown-48", "X", &nwip_universe, 48 },
- { "unknown-49", "X", &nwip_universe, 49 },
- { "unknown-50", "X", &nwip_universe, 50 },
- { "unknown-51", "X", &nwip_universe, 51 },
- { "unknown-52", "X", &nwip_universe, 52 },
- { "unknown-53", "X", &nwip_universe, 53 },
- { "unknown-54", "X", &nwip_universe, 54 },
- { "unknown-55", "X", &nwip_universe, 55 },
- { "unknown-56", "X", &nwip_universe, 56 },
- { "unknown-57", "X", &nwip_universe, 57 },
- { "unknown-58", "X", &nwip_universe, 58 },
- { "unknown-59", "X", &nwip_universe, 59 },
- { "unknown-60", "X", &nwip_universe, 60 },
- { "unknown-61", "X", &nwip_universe, 61 },
- { "unknown-62", "X", &nwip_universe, 62 },
- { "unknown-63", "X", &nwip_universe, 63 },
- { "unknown-64", "X", &nwip_universe, 64 },
- { "unknown-65", "X", &nwip_universe, 65 },
- { "unknown-66", "X", &nwip_universe, 66 },
- { "unknown-67", "X", &nwip_universe, 67 },
- { "unknown-68", "X", &nwip_universe, 68 },
- { "unknown-69", "X", &nwip_universe, 69 },
- { "unknown-70", "X", &nwip_universe, 70 },
- { "unknown-71", "X", &nwip_universe, 71 },
- { "unknown-72", "X", &nwip_universe, 72 },
- { "unknown-73", "X", &nwip_universe, 73 },
- { "unknown-74", "X", &nwip_universe, 74 },
- { "unknown-75", "X", &nwip_universe, 75 },
- { "unknown-76", "X", &nwip_universe, 76 },
- { "unknown-77", "X", &nwip_universe, 77 },
- { "unknown-78", "X", &nwip_universe, 78 },
- { "unknown-79", "X", &nwip_universe, 79 },
- { "unknown-80", "X", &nwip_universe, 80 },
- { "unknown-81", "X", &nwip_universe, 81 },
- { "unknown-82", "X", &nwip_universe, 82 },
- { "unknown-83", "X", &nwip_universe, 83 },
- { "unknown-84", "X", &nwip_universe, 84 },
- { "unknown-85", "X", &nwip_universe, 85 },
- { "unknown-86", "X", &nwip_universe, 86 },
- { "unknown-87", "X", &nwip_universe, 87 },
- { "unknown-88", "X", &nwip_universe, 88 },
- { "unknown-89", "X", &nwip_universe, 89 },
- { "unknown-90", "X", &nwip_universe, 90 },
- { "unknown-91", "X", &nwip_universe, 91 },
- { "unknown-92", "X", &nwip_universe, 92 },
- { "unknown-93", "X", &nwip_universe, 93 },
- { "unknown-94", "X", &nwip_universe, 94 },
- { "unknown-95", "X", &nwip_universe, 95 },
- { "unknown-96", "X", &nwip_universe, 96 },
- { "unknown-97", "X", &nwip_universe, 97 },
- { "unknown-98", "X", &nwip_universe, 98 },
- { "unknown-99", "X", &nwip_universe, 99 },
- { "unknown-100", "X", &nwip_universe, 100 },
- { "unknown-101", "X", &nwip_universe, 101 },
- { "unknown-102", "X", &nwip_universe, 102 },
- { "unknown-103", "X", &nwip_universe, 103 },
- { "unknown-104", "X", &nwip_universe, 104 },
- { "unknown-105", "X", &nwip_universe, 105 },
- { "unknown-106", "X", &nwip_universe, 106 },
- { "unknown-107", "X", &nwip_universe, 107 },
- { "unknown-108", "X", &nwip_universe, 108 },
- { "unknown-109", "X", &nwip_universe, 109 },
- { "unknown-110", "X", &nwip_universe, 110 },
- { "unknown-111", "X", &nwip_universe, 111 },
- { "unknown-112", "X", &nwip_universe, 112 },
- { "unknown-113", "X", &nwip_universe, 113 },
- { "unknown-114", "X", &nwip_universe, 114 },
- { "unknown-115", "X", &nwip_universe, 115 },
- { "unknown-116", "X", &nwip_universe, 116 },
- { "unknown-117", "X", &nwip_universe, 117 },
- { "unknown-118", "X", &nwip_universe, 118 },
- { "unknown-119", "X", &nwip_universe, 119 },
- { "unknown-120", "X", &nwip_universe, 120 },
- { "unknown-121", "X", &nwip_universe, 121 },
- { "unknown-122", "X", &nwip_universe, 122 },
- { "unknown-123", "X", &nwip_universe, 123 },
- { "unknown-124", "X", &nwip_universe, 124 },
- { "unknown-125", "X", &nwip_universe, 125 },
- { "unknown-126", "X", &nwip_universe, 126 },
- { "unknown-127", "X", &nwip_universe, 127 },
- { "unknown-128", "X", &nwip_universe, 128 },
- { "unknown-129", "X", &nwip_universe, 129 },
- { "unknown-130", "X", &nwip_universe, 130 },
- { "unknown-131", "X", &nwip_universe, 131 },
- { "unknown-132", "X", &nwip_universe, 132 },
- { "unknown-133", "X", &nwip_universe, 133 },
- { "unknown-134", "X", &nwip_universe, 134 },
- { "unknown-135", "X", &nwip_universe, 135 },
- { "unknown-136", "X", &nwip_universe, 136 },
- { "unknown-137", "X", &nwip_universe, 137 },
- { "unknown-138", "X", &nwip_universe, 138 },
- { "unknown-139", "X", &nwip_universe, 139 },
- { "unknown-140", "X", &nwip_universe, 140 },
- { "unknown-141", "X", &nwip_universe, 141 },
- { "unknown-142", "X", &nwip_universe, 142 },
- { "unknown-143", "X", &nwip_universe, 143 },
- { "unknown-144", "X", &nwip_universe, 144 },
- { "unknown-145", "X", &nwip_universe, 145 },
- { "unknown-146", "X", &nwip_universe, 146 },
- { "unknown-147", "X", &nwip_universe, 147 },
- { "unknown-148", "X", &nwip_universe, 148 },
- { "unknown-149", "X", &nwip_universe, 149 },
- { "unknown-150", "X", &nwip_universe, 150 },
- { "unknown-151", "X", &nwip_universe, 151 },
- { "unknown-152", "X", &nwip_universe, 152 },
- { "unknown-153", "X", &nwip_universe, 153 },
- { "unknown-154", "X", &nwip_universe, 154 },
- { "unknown-155", "X", &nwip_universe, 155 },
- { "unknown-156", "X", &nwip_universe, 156 },
- { "unknown-157", "X", &nwip_universe, 157 },
- { "unknown-158", "X", &nwip_universe, 158 },
- { "unknown-159", "X", &nwip_universe, 159 },
- { "unknown-160", "X", &nwip_universe, 160 },
- { "unknown-161", "X", &nwip_universe, 161 },
- { "unknown-162", "X", &nwip_universe, 162 },
- { "unknown-163", "X", &nwip_universe, 163 },
- { "unknown-164", "X", &nwip_universe, 164 },
- { "unknown-165", "X", &nwip_universe, 165 },
- { "unknown-166", "X", &nwip_universe, 166 },
- { "unknown-167", "X", &nwip_universe, 167 },
- { "unknown-168", "X", &nwip_universe, 168 },
- { "unknown-169", "X", &nwip_universe, 169 },
- { "unknown-170", "X", &nwip_universe, 170 },
- { "unknown-171", "X", &nwip_universe, 171 },
- { "unknown-172", "X", &nwip_universe, 172 },
- { "unknown-173", "X", &nwip_universe, 173 },
- { "unknown-174", "X", &nwip_universe, 174 },
- { "unknown-175", "X", &nwip_universe, 175 },
- { "unknown-176", "X", &nwip_universe, 176 },
- { "unknown-177", "X", &nwip_universe, 177 },
- { "unknown-178", "X", &nwip_universe, 178 },
- { "unknown-179", "X", &nwip_universe, 179 },
- { "unknown-180", "X", &nwip_universe, 180 },
- { "unknown-181", "X", &nwip_universe, 181 },
- { "unknown-182", "X", &nwip_universe, 182 },
- { "unknown-183", "X", &nwip_universe, 183 },
- { "unknown-184", "X", &nwip_universe, 184 },
- { "unknown-185", "X", &nwip_universe, 185 },
- { "unknown-186", "X", &nwip_universe, 186 },
- { "unknown-187", "X", &nwip_universe, 187 },
- { "unknown-188", "X", &nwip_universe, 188 },
- { "unknown-189", "X", &nwip_universe, 189 },
- { "unknown-190", "X", &nwip_universe, 190 },
- { "unknown-191", "X", &nwip_universe, 191 },
- { "unknown-192", "X", &nwip_universe, 192 },
- { "unknown-193", "X", &nwip_universe, 193 },
- { "unknown-194", "X", &nwip_universe, 194 },
- { "unknown-195", "X", &nwip_universe, 195 },
- { "unknown-196", "X", &nwip_universe, 196 },
- { "unknown-197", "X", &nwip_universe, 197 },
- { "unknown-198", "X", &nwip_universe, 198 },
- { "unknown-199", "X", &nwip_universe, 199 },
- { "unknown-200", "X", &nwip_universe, 200 },
- { "unknown-201", "X", &nwip_universe, 201 },
- { "unknown-202", "X", &nwip_universe, 202 },
- { "unknown-203", "X", &nwip_universe, 203 },
- { "unknown-204", "X", &nwip_universe, 204 },
- { "unknown-205", "X", &nwip_universe, 205 },
- { "unknown-206", "X", &nwip_universe, 206 },
- { "unknown-207", "X", &nwip_universe, 207 },
- { "unknown-208", "X", &nwip_universe, 208 },
- { "unknown-209", "X", &nwip_universe, 209 },
- { "unknown-210", "X", &nwip_universe, 210 },
- { "unknown-211", "X", &nwip_universe, 211 },
- { "unknown-212", "X", &nwip_universe, 212 },
- { "unknown-213", "X", &nwip_universe, 213 },
- { "unknown-214", "X", &nwip_universe, 214 },
- { "unknown-215", "X", &nwip_universe, 215 },
- { "unknown-216", "X", &nwip_universe, 216 },
- { "unknown-217", "X", &nwip_universe, 217 },
- { "unknown-218", "X", &nwip_universe, 218 },
- { "unknown-219", "X", &nwip_universe, 219 },
- { "unknown-220", "X", &nwip_universe, 220 },
- { "unknown-221", "X", &nwip_universe, 221 },
- { "unknown-222", "X", &nwip_universe, 222 },
- { "unknown-223", "X", &nwip_universe, 223 },
- { "unknown-224", "X", &nwip_universe, 224 },
- { "unknown-225", "X", &nwip_universe, 225 },
- { "unknown-226", "X", &nwip_universe, 226 },
- { "unknown-227", "X", &nwip_universe, 227 },
- { "unknown-228", "X", &nwip_universe, 228 },
- { "unknown-229", "X", &nwip_universe, 229 },
- { "unknown-230", "X", &nwip_universe, 230 },
- { "unknown-231", "X", &nwip_universe, 231 },
- { "unknown-232", "X", &nwip_universe, 232 },
- { "unknown-233", "X", &nwip_universe, 233 },
- { "unknown-234", "X", &nwip_universe, 234 },
- { "unknown-235", "X", &nwip_universe, 235 },
- { "unknown-236", "X", &nwip_universe, 236 },
- { "unknown-237", "X", &nwip_universe, 237 },
- { "unknown-238", "X", &nwip_universe, 238 },
- { "unknown-239", "X", &nwip_universe, 239 },
- { "unknown-240", "X", &nwip_universe, 240 },
- { "unknown-241", "X", &nwip_universe, 241 },
- { "unknown-242", "X", &nwip_universe, 242 },
- { "unknown-243", "X", &nwip_universe, 243 },
- { "unknown-244", "X", &nwip_universe, 244 },
- { "unknown-245", "X", &nwip_universe, 245 },
- { "unknown-246", "X", &nwip_universe, 246 },
- { "unknown-247", "X", &nwip_universe, 247 },
- { "unknown-248", "X", &nwip_universe, 248 },
- { "unknown-249", "X", &nwip_universe, 249 },
- { "unknown-250", "X", &nwip_universe, 250 },
- { "unknown-251", "X", &nwip_universe, 251 },
- { "unknown-252", "X", &nwip_universe, 252 },
- { "unknown-253", "X", &nwip_universe, 253 },
- { "unknown-254", "X", &nwip_universe, 254 },
- { "unknown-end", "e", &nwip_universe, 255 },
-};
-
-struct universe fqdn_universe;
-struct option fqdn_options [256] = {
- { "pad", "", &fqdn_universe, 0 },
- { "no-client-update", "f", &fqdn_universe, 1 },
- { "server-update", "f", &fqdn_universe, 2 },
- { "encoded", "f", &fqdn_universe, 3 },
- { "rcode1", "B", &fqdn_universe, 4 },
- { "rcode2", "B", &fqdn_universe, 5 },
- { "hostname", "t", &fqdn_universe, 6 },
- { "domainname", "t", &fqdn_universe, 7 },
- { "fqdn", "t", &fqdn_universe, 8 },
- { "unknown-9", "X", &fqdn_universe, 9 },
- { "unknown-10", "X", &fqdn_universe, 10 },
- { "unknown-11", "X", &fqdn_universe, 11 },
- { "unknown-12", "X", &fqdn_universe, 12 },
- { "unknown-13", "X", &fqdn_universe, 13 },
- { "unknown-14", "X", &fqdn_universe, 14 },
- { "unknown-15", "X", &fqdn_universe, 15 },
- { "unknown-16", "X", &fqdn_universe, 16 },
- { "unknown-17", "X", &fqdn_universe, 17 },
- { "unknown-18", "X", &fqdn_universe, 18 },
- { "unknown-19", "X", &fqdn_universe, 19 },
- { "unknown-20", "X", &fqdn_universe, 20 },
- { "unknown-21", "X", &fqdn_universe, 21 },
- { "unknown-22", "X", &fqdn_universe, 22 },
- { "unknown-23", "X", &fqdn_universe, 23 },
- { "unknown-24", "X", &fqdn_universe, 24 },
- { "unknown-25", "X", &fqdn_universe, 25 },
- { "unknown-26", "X", &fqdn_universe, 26 },
- { "unknown-27", "X", &fqdn_universe, 27 },
- { "unknown-28", "X", &fqdn_universe, 28 },
- { "unknown-29", "X", &fqdn_universe, 29 },
- { "unknown-30", "X", &fqdn_universe, 30 },
- { "unknown-31", "X", &fqdn_universe, 31 },
- { "unknown-32", "X", &fqdn_universe, 32 },
- { "unknown-33", "X", &fqdn_universe, 33 },
- { "unknown-34", "X", &fqdn_universe, 34 },
- { "unknown-35", "X", &fqdn_universe, 35 },
- { "unknown-36", "X", &fqdn_universe, 36 },
- { "unknown-37", "X", &fqdn_universe, 37 },
- { "unknown-38", "X", &fqdn_universe, 38 },
- { "unknown-39", "X", &fqdn_universe, 39 },
- { "unknown-40", "X", &fqdn_universe, 40 },
- { "unknown-41", "X", &fqdn_universe, 41 },
- { "unknown-42", "X", &fqdn_universe, 42 },
- { "unknown-43", "X", &fqdn_universe, 43 },
- { "unknown-44", "X", &fqdn_universe, 44 },
- { "unknown-45", "X", &fqdn_universe, 45 },
- { "unknown-46", "X", &fqdn_universe, 46 },
- { "unknown-47", "X", &fqdn_universe, 47 },
- { "unknown-48", "X", &fqdn_universe, 48 },
- { "unknown-49", "X", &fqdn_universe, 49 },
- { "unknown-50", "X", &fqdn_universe, 50 },
- { "unknown-51", "X", &fqdn_universe, 51 },
- { "unknown-52", "X", &fqdn_universe, 52 },
- { "unknown-53", "X", &fqdn_universe, 53 },
- { "unknown-54", "X", &fqdn_universe, 54 },
- { "unknown-55", "X", &fqdn_universe, 55 },
- { "unknown-56", "X", &fqdn_universe, 56 },
- { "unknown-57", "X", &fqdn_universe, 57 },
- { "unknown-58", "X", &fqdn_universe, 58 },
- { "unknown-59", "X", &fqdn_universe, 59 },
- { "unknown-60", "X", &fqdn_universe, 60 },
- { "unknown-61", "X", &fqdn_universe, 61 },
- { "unknown-62", "X", &fqdn_universe, 62 },
- { "unknown-63", "X", &fqdn_universe, 63 },
- { "unknown-64", "X", &fqdn_universe, 64 },
- { "unknown-65", "X", &fqdn_universe, 65 },
- { "unknown-66", "X", &fqdn_universe, 66 },
- { "unknown-67", "X", &fqdn_universe, 67 },
- { "unknown-68", "X", &fqdn_universe, 68 },
- { "unknown-69", "X", &fqdn_universe, 69 },
- { "unknown-70", "X", &fqdn_universe, 70 },
- { "unknown-71", "X", &fqdn_universe, 71 },
- { "unknown-72", "X", &fqdn_universe, 72 },
- { "unknown-73", "X", &fqdn_universe, 73 },
- { "unknown-74", "X", &fqdn_universe, 74 },
- { "unknown-75", "X", &fqdn_universe, 75 },
- { "unknown-76", "X", &fqdn_universe, 76 },
- { "unknown-77", "X", &fqdn_universe, 77 },
- { "unknown-78", "X", &fqdn_universe, 78 },
- { "unknown-79", "X", &fqdn_universe, 79 },
- { "unknown-80", "X", &fqdn_universe, 80 },
- { "unknown-81", "X", &fqdn_universe, 81 },
- { "unknown-82", "X", &fqdn_universe, 82 },
- { "unknown-83", "X", &fqdn_universe, 83 },
- { "unknown-84", "X", &fqdn_universe, 84 },
- { "unknown-85", "X", &fqdn_universe, 85 },
- { "unknown-86", "X", &fqdn_universe, 86 },
- { "unknown-87", "X", &fqdn_universe, 87 },
- { "unknown-88", "X", &fqdn_universe, 88 },
- { "unknown-89", "X", &fqdn_universe, 89 },
- { "unknown-90", "X", &fqdn_universe, 90 },
- { "unknown-91", "X", &fqdn_universe, 91 },
- { "unknown-92", "X", &fqdn_universe, 92 },
- { "unknown-93", "X", &fqdn_universe, 93 },
- { "unknown-94", "X", &fqdn_universe, 94 },
- { "unknown-95", "X", &fqdn_universe, 95 },
- { "unknown-96", "X", &fqdn_universe, 96 },
- { "unknown-97", "X", &fqdn_universe, 97 },
- { "unknown-98", "X", &fqdn_universe, 98 },
- { "unknown-99", "X", &fqdn_universe, 99 },
- { "unknown-100", "X", &fqdn_universe, 100 },
- { "unknown-101", "X", &fqdn_universe, 101 },
- { "unknown-102", "X", &fqdn_universe, 102 },
- { "unknown-103", "X", &fqdn_universe, 103 },
- { "unknown-104", "X", &fqdn_universe, 104 },
- { "unknown-105", "X", &fqdn_universe, 105 },
- { "unknown-106", "X", &fqdn_universe, 106 },
- { "unknown-107", "X", &fqdn_universe, 107 },
- { "unknown-108", "X", &fqdn_universe, 108 },
- { "unknown-109", "X", &fqdn_universe, 109 },
- { "unknown-110", "X", &fqdn_universe, 110 },
- { "unknown-111", "X", &fqdn_universe, 111 },
- { "unknown-112", "X", &fqdn_universe, 112 },
- { "unknown-113", "X", &fqdn_universe, 113 },
- { "unknown-114", "X", &fqdn_universe, 114 },
- { "unknown-115", "X", &fqdn_universe, 115 },
- { "unknown-116", "X", &fqdn_universe, 116 },
- { "unknown-117", "X", &fqdn_universe, 117 },
- { "unknown-118", "X", &fqdn_universe, 118 },
- { "unknown-119", "X", &fqdn_universe, 119 },
- { "unknown-120", "X", &fqdn_universe, 120 },
- { "unknown-121", "X", &fqdn_universe, 121 },
- { "unknown-122", "X", &fqdn_universe, 122 },
- { "unknown-123", "X", &fqdn_universe, 123 },
- { "unknown-124", "X", &fqdn_universe, 124 },
- { "unknown-125", "X", &fqdn_universe, 125 },
- { "unknown-126", "X", &fqdn_universe, 126 },
- { "unknown-127", "X", &fqdn_universe, 127 },
- { "unknown-128", "X", &fqdn_universe, 128 },
- { "unknown-129", "X", &fqdn_universe, 129 },
- { "unknown-130", "X", &fqdn_universe, 130 },
- { "unknown-131", "X", &fqdn_universe, 131 },
- { "unknown-132", "X", &fqdn_universe, 132 },
- { "unknown-133", "X", &fqdn_universe, 133 },
- { "unknown-134", "X", &fqdn_universe, 134 },
- { "unknown-135", "X", &fqdn_universe, 135 },
- { "unknown-136", "X", &fqdn_universe, 136 },
- { "unknown-137", "X", &fqdn_universe, 137 },
- { "unknown-138", "X", &fqdn_universe, 138 },
- { "unknown-139", "X", &fqdn_universe, 139 },
- { "unknown-140", "X", &fqdn_universe, 140 },
- { "unknown-141", "X", &fqdn_universe, 141 },
- { "unknown-142", "X", &fqdn_universe, 142 },
- { "unknown-143", "X", &fqdn_universe, 143 },
- { "unknown-144", "X", &fqdn_universe, 144 },
- { "unknown-145", "X", &fqdn_universe, 145 },
- { "unknown-146", "X", &fqdn_universe, 146 },
- { "unknown-147", "X", &fqdn_universe, 147 },
- { "unknown-148", "X", &fqdn_universe, 148 },
- { "unknown-149", "X", &fqdn_universe, 149 },
- { "unknown-150", "X", &fqdn_universe, 150 },
- { "unknown-151", "X", &fqdn_universe, 151 },
- { "unknown-152", "X", &fqdn_universe, 152 },
- { "unknown-153", "X", &fqdn_universe, 153 },
- { "unknown-154", "X", &fqdn_universe, 154 },
- { "unknown-155", "X", &fqdn_universe, 155 },
- { "unknown-156", "X", &fqdn_universe, 156 },
- { "unknown-157", "X", &fqdn_universe, 157 },
- { "unknown-158", "X", &fqdn_universe, 158 },
- { "unknown-159", "X", &fqdn_universe, 159 },
- { "unknown-160", "X", &fqdn_universe, 160 },
- { "unknown-161", "X", &fqdn_universe, 161 },
- { "unknown-162", "X", &fqdn_universe, 162 },
- { "unknown-163", "X", &fqdn_universe, 163 },
- { "unknown-164", "X", &fqdn_universe, 164 },
- { "unknown-165", "X", &fqdn_universe, 165 },
- { "unknown-166", "X", &fqdn_universe, 166 },
- { "unknown-167", "X", &fqdn_universe, 167 },
- { "unknown-168", "X", &fqdn_universe, 168 },
- { "unknown-169", "X", &fqdn_universe, 169 },
- { "unknown-170", "X", &fqdn_universe, 170 },
- { "unknown-171", "X", &fqdn_universe, 171 },
- { "unknown-172", "X", &fqdn_universe, 172 },
- { "unknown-173", "X", &fqdn_universe, 173 },
- { "unknown-174", "X", &fqdn_universe, 174 },
- { "unknown-175", "X", &fqdn_universe, 175 },
- { "unknown-176", "X", &fqdn_universe, 176 },
- { "unknown-177", "X", &fqdn_universe, 177 },
- { "unknown-178", "X", &fqdn_universe, 178 },
- { "unknown-179", "X", &fqdn_universe, 179 },
- { "unknown-180", "X", &fqdn_universe, 180 },
- { "unknown-181", "X", &fqdn_universe, 181 },
- { "unknown-182", "X", &fqdn_universe, 182 },
- { "unknown-183", "X", &fqdn_universe, 183 },
- { "unknown-184", "X", &fqdn_universe, 184 },
- { "unknown-185", "X", &fqdn_universe, 185 },
- { "unknown-186", "X", &fqdn_universe, 186 },
- { "unknown-187", "X", &fqdn_universe, 187 },
- { "unknown-188", "X", &fqdn_universe, 188 },
- { "unknown-189", "X", &fqdn_universe, 189 },
- { "unknown-190", "X", &fqdn_universe, 190 },
- { "unknown-191", "X", &fqdn_universe, 191 },
- { "unknown-192", "X", &fqdn_universe, 192 },
- { "unknown-193", "X", &fqdn_universe, 193 },
- { "unknown-194", "X", &fqdn_universe, 194 },
- { "unknown-195", "X", &fqdn_universe, 195 },
- { "unknown-196", "X", &fqdn_universe, 196 },
- { "unknown-197", "X", &fqdn_universe, 197 },
- { "unknown-198", "X", &fqdn_universe, 198 },
- { "unknown-199", "X", &fqdn_universe, 199 },
- { "unknown-200", "X", &fqdn_universe, 200 },
- { "unknown-201", "X", &fqdn_universe, 201 },
- { "unknown-202", "X", &fqdn_universe, 202 },
- { "unknown-203", "X", &fqdn_universe, 203 },
- { "unknown-204", "X", &fqdn_universe, 204 },
- { "unknown-205", "X", &fqdn_universe, 205 },
- { "unknown-206", "X", &fqdn_universe, 206 },
- { "unknown-207", "X", &fqdn_universe, 207 },
- { "unknown-208", "X", &fqdn_universe, 208 },
- { "unknown-209", "X", &fqdn_universe, 209 },
- { "unknown-210", "X", &fqdn_universe, 210 },
- { "unknown-211", "X", &fqdn_universe, 211 },
- { "unknown-212", "X", &fqdn_universe, 212 },
- { "unknown-213", "X", &fqdn_universe, 213 },
- { "unknown-214", "X", &fqdn_universe, 214 },
- { "unknown-215", "X", &fqdn_universe, 215 },
- { "unknown-216", "X", &fqdn_universe, 216 },
- { "unknown-217", "X", &fqdn_universe, 217 },
- { "unknown-218", "X", &fqdn_universe, 218 },
- { "unknown-219", "X", &fqdn_universe, 219 },
- { "unknown-220", "X", &fqdn_universe, 220 },
- { "unknown-221", "X", &fqdn_universe, 221 },
- { "unknown-222", "X", &fqdn_universe, 222 },
- { "unknown-223", "X", &fqdn_universe, 223 },
- { "unknown-224", "X", &fqdn_universe, 224 },
- { "unknown-225", "X", &fqdn_universe, 225 },
- { "unknown-226", "X", &fqdn_universe, 226 },
- { "unknown-227", "X", &fqdn_universe, 227 },
- { "unknown-228", "X", &fqdn_universe, 228 },
- { "unknown-229", "X", &fqdn_universe, 229 },
- { "unknown-230", "X", &fqdn_universe, 230 },
- { "unknown-231", "X", &fqdn_universe, 231 },
- { "unknown-232", "X", &fqdn_universe, 232 },
- { "unknown-233", "X", &fqdn_universe, 233 },
- { "unknown-234", "X", &fqdn_universe, 234 },
- { "unknown-235", "X", &fqdn_universe, 235 },
- { "unknown-236", "X", &fqdn_universe, 236 },
- { "unknown-237", "X", &fqdn_universe, 237 },
- { "unknown-238", "X", &fqdn_universe, 238 },
- { "unknown-239", "X", &fqdn_universe, 239 },
- { "unknown-240", "X", &fqdn_universe, 240 },
- { "unknown-241", "X", &fqdn_universe, 241 },
- { "unknown-242", "X", &fqdn_universe, 242 },
- { "unknown-243", "X", &fqdn_universe, 243 },
- { "unknown-244", "X", &fqdn_universe, 244 },
- { "unknown-245", "X", &fqdn_universe, 245 },
- { "unknown-246", "X", &fqdn_universe, 246 },
- { "unknown-247", "X", &fqdn_universe, 247 },
- { "unknown-248", "X", &fqdn_universe, 248 },
- { "unknown-249", "X", &fqdn_universe, 249 },
- { "unknown-250", "X", &fqdn_universe, 250 },
- { "unknown-251", "X", &fqdn_universe, 251 },
- { "unknown-252", "X", &fqdn_universe, 252 },
- { "unknown-253", "X", &fqdn_universe, 253 },
- { "unknown-254", "X", &fqdn_universe, 254 },
- { "unknown-end", "e", &fqdn_universe, 255 },
-};
-
-const char *hardware_types [] = {
- "unknown-0",
- "ethernet",
- "unknown-2",
- "unknown-3",
- "unknown-4",
- "unknown-5",
- "token-ring",
- "unknown-7",
- "fddi",
- "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" };
-
-universe_hash_t *universe_hash;
-struct universe **universes;
-int universe_count, universe_max;
-
-/* Universe containing names of configuration options, which, rather than
- writing "option universe-name.option-name ...;", can be set by writing
- "option-name ...;". */
-
-struct universe *config_universe;
-
-void initialize_common_option_spaces()
-{
- int i;
-
- universe_max = 10;
- universes = ((struct universe **)
- dmalloc (universe_max * sizeof (struct universe *), MDL));
- if (!universes)
- log_fatal ("Can't allocate option space table.");
- memset (universes, 0, universe_max * sizeof (struct universe *));
-
- /* Set up the DHCP option universe... */
- dhcp_universe.name = "dhcp";
- dhcp_universe.lookup_func = lookup_hashed_option;
- dhcp_universe.option_state_dereference =
- hashed_option_state_dereference;
- dhcp_universe.save_func = save_hashed_option;
- dhcp_universe.delete_func = delete_hashed_option;
- dhcp_universe.encapsulate = hashed_option_space_encapsulate;
- dhcp_universe.foreach = hashed_option_space_foreach;
- dhcp_universe.decode = parse_option_buffer;
- dhcp_universe.length_size = 1;
- dhcp_universe.tag_size = 1;
- dhcp_universe.store_tag = putUChar;
- dhcp_universe.store_length = putUChar;
- dhcp_universe.index = universe_count++;
- universes [dhcp_universe.index] = &dhcp_universe;
- if (!option_new_hash (&dhcp_universe.hash, 1, MDL))
- log_fatal ("Can't allocate dhcp option hash table.");
- for (i = 0; i < 256; i++) {
- dhcp_universe.options [i] = &dhcp_options [i];
- option_hash_add (dhcp_universe.hash,
- dhcp_options [i].name, 0,
- &dhcp_options [i], MDL);
- }
-
- /* Set up the Novell option universe (for option 63)... */
- nwip_universe.name = "nwip";
- nwip_universe.lookup_func = lookup_linked_option;
- nwip_universe.option_state_dereference =
- linked_option_state_dereference;
- nwip_universe.save_func = save_linked_option;
- nwip_universe.delete_func = delete_linked_option;
- nwip_universe.encapsulate = nwip_option_space_encapsulate;
- nwip_universe.foreach = linked_option_space_foreach;
- nwip_universe.decode = parse_option_buffer;
- nwip_universe.length_size = 1;
- nwip_universe.tag_size = 1;
- nwip_universe.store_tag = putUChar;
- nwip_universe.store_length = putUChar;
- nwip_universe.enc_opt = &dhcp_options [DHO_NWIP_SUBOPTIONS];
- nwip_universe.index = universe_count++;
- universes [nwip_universe.index] = &nwip_universe;
- option_new_hash (&nwip_universe.hash, 1, MDL);
- if (!nwip_universe.hash)
- log_fatal ("Can't allocate nwip option hash table.");
- for (i = 0; i < 256; i++) {
- nwip_universe.options [i] = &nwip_options [i];
- option_hash_add (nwip_universe.hash,
- nwip_options [i].name, 0,
- &nwip_options [i], MDL);
- }
-
- /* Set up the FQDN option universe... */
- fqdn_universe.name = "fqdn";
- fqdn_universe.lookup_func = lookup_linked_option;
- fqdn_universe.option_state_dereference =
- linked_option_state_dereference;
- fqdn_universe.save_func = save_linked_option;
- fqdn_universe.delete_func = delete_linked_option;
- fqdn_universe.encapsulate = fqdn_option_space_encapsulate;
- fqdn_universe.foreach = linked_option_space_foreach;
- fqdn_universe.decode = fqdn_universe_decode;
- fqdn_universe.length_size = 1;
- fqdn_universe.tag_size = 1;
- fqdn_universe.store_tag = putUChar;
- fqdn_universe.store_length = putUChar;
- fqdn_universe.index = universe_count++;
- fqdn_universe.enc_opt = &dhcp_options [DHO_FQDN];
- universes [fqdn_universe.index] = &fqdn_universe;
- option_new_hash (&fqdn_universe.hash, 1, MDL);
- if (!fqdn_universe.hash)
- log_fatal ("Can't allocate fqdn option hash table.");
- for (i = 0; i < 256; i++) {
- fqdn_universe.options [i] = &fqdn_options [i];
- option_hash_add (fqdn_universe.hash,
- fqdn_options [i].name, 0,
- &fqdn_options [i], MDL);
- }
-
- /* Set up the hash of universes. */
- universe_new_hash (&universe_hash, 1, MDL);
- universe_hash_add (universe_hash,
- dhcp_universe.name, 0,
- &dhcp_universe, MDL);
- universe_hash_add (universe_hash,
- nwip_universe.name, 0,
- &nwip_universe, MDL);
- universe_hash_add (universe_hash,
- fqdn_universe.name, 0,
- &fqdn_universe, MDL);
-}
diff --git a/contrib/isc-dhcp/common/tr.c b/contrib/isc-dhcp/common/tr.c
deleted file mode 100644
index c3f097b..0000000
--- a/contrib/isc-dhcp/common/tr.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* tr.c
-
- token ring interface support
- Contributed in May of 1999 by Andrew Chittenden */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: tr.c,v 1.7.2.2 2004/06/10 17:59:21 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (HAVE_TR_SUPPORT) && \
- (defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING))
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-#include "netinet/if_tr.h"
-#include <sys/time.h>
-
-/*
- * token ring device handling subroutines. These are required as token-ring
- * does not have a simple on-the-wire header but requires the use of
- * source routing
- */
-
-static int insert_source_routing PROTO ((struct trh_hdr *trh, struct interface_info* interface));
-static void save_source_routing PROTO ((struct trh_hdr *trh, struct interface_info* interface));
-static void expire_routes PROTO ((void));
-
-/*
- * As we keep a list of interesting routing information only, a singly
- * linked list is all we need
- */
-struct routing_entry {
- struct routing_entry *next;
- unsigned char addr[TR_ALEN];
- unsigned char iface[5];
- __u16 rcf; /* route control field */
- __u16 rseg[8]; /* routing registers */
- unsigned long access_time; /* time we last used this entry */
-};
-
-static struct routing_entry *routing_info = NULL;
-
-static int routing_timeout = 10;
-static struct timeval routing_timer;
-
-void assemble_tr_header (interface, buf, bufix, to)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned *bufix;
- struct hardware *to;
-{
- struct trh_hdr *trh;
- int hdr_len;
- struct trllc *llc;
-
-
- /* set up the token header */
- trh = (struct trh_hdr *) &buf[*bufix];
- if (interface -> hw_address.hlen - 1 == sizeof (trh->saddr))
- memcpy (trh->saddr, &interface -> hw_address.hbuf [1],
- sizeof (trh->saddr));
- else
- memset (trh->saddr, 0x00, sizeof (trh->saddr));
-
- if (to && to -> hlen == 7) /* XXX */
- memcpy (trh->daddr, &to -> hbuf [1], sizeof trh->daddr);
- else
- memset (trh->daddr, 0xff, sizeof (trh->daddr));
-
- hdr_len = insert_source_routing (trh, interface);
-
- trh->ac = AC;
- trh->fc = LLC_FRAME;
-
- /* set up the llc header for snap encoding after the tr header */
- llc = (struct trllc *)(buf + *bufix + hdr_len);
- llc->dsap = EXTENDED_SAP;
- llc->ssap = EXTENDED_SAP;
- llc->llc = UI_CMD;
- llc->protid[0] = 0;
- llc->protid[1] = 0;
- llc->protid[2] = 0;
- llc->ethertype = htons(ETHERTYPE_IP);
-
- hdr_len += sizeof(struct trllc);
-
- *bufix += hdr_len;
-}
-
-
-static unsigned char tr_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-/*
- * decoding the token header is a bit complex as you can see here. It is
- * further complicated by the linux kernel stripping off some valuable
- * information (see comment below) even though we've asked for the raw
- * packets.
- */
-ssize_t decode_tr_header (interface, buf, bufix, from)
- struct interface_info *interface;
- unsigned char *buf;
- unsigned bufix;
- struct hardware *from;
-{
- struct trh_hdr *trh = (struct trh_hdr *) buf + bufix;
- struct trllc *llc;
- struct ip *ip;
- struct udphdr *udp;
- unsigned int route_len = 0;
- ssize_t hdr_len;
- struct timeval now;
-
- /* see whether any source routing information has expired */
- gettimeofday(&now, NULL);
-
- if (routing_timer.tv_sec == 0)
- routing_timer.tv_sec = now.tv_sec + routing_timeout;
- else if ((now.tv_sec - routing_timer.tv_sec) > 0)
- expire_routes();
-
- /* the kernel might have stripped off the source
- * routing bit. We try a heuristic to determine whether
- * this is the case and put it back on if so
- */
- route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
- llc = (struct trllc *)(buf + bufix + sizeof(struct trh_hdr)-TR_MAXRIFLEN+route_len);
- if (llc->dsap == EXTENDED_SAP
- && llc->ssap == EXTENDED_SAP
- && llc->llc == UI_CMD
- && llc->protid[0] == 0
- && llc->protid[1] == 0
- && llc->protid[2] == 0) {
- /* say there is source routing information present */
- trh->saddr[0] |= TR_RII;
- }
-
- if (trh->saddr[0] & TR_RII)
- route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
- else
- route_len = 0;
-
- hdr_len = sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
-
- /* now filter out unwanted packets: this is based on the packet
- * filter code in bpf.c */
- llc = (struct trllc *)(buf + bufix + hdr_len);
- ip = (struct ip *) (llc + 1);
- udp = (struct udphdr *) ((unsigned char*) ip + IP_HL (ip));
-
- /* make sure it is a snap encoded, IP, UDP, unfragmented packet sent
- * to our port */
- if (llc->dsap != EXTENDED_SAP
- || ntohs(llc->ethertype) != ETHERTYPE_IP
- || ip->ip_p != IPPROTO_UDP
- || (ntohs (ip->ip_off) & IP_OFFMASK) != 0
- || udp->uh_dport != local_port)
- return -1;
-
- /* only save source routing information for packets from valued hosts */
- save_source_routing(trh, interface);
-
- return hdr_len + sizeof (struct trllc);
-}
-
-/* insert_source_routing inserts source route information into the token ring
- * header
- */
-static int insert_source_routing (trh, interface)
- struct trh_hdr *trh;
- struct interface_info* interface;
-{
- struct routing_entry *rover;
- struct timeval now;
- unsigned int route_len = 0;
-
- gettimeofday(&now, NULL);
-
- /* single route broadcasts as per rfc 1042 */
- if (memcmp(trh->daddr, tr_broadcast,TR_ALEN) == 0) {
- trh->saddr[0] |= TR_RII;
- trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
- trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
- trh->rcf = htons(trh->rcf);
- } else {
- /* look for a routing entry */
- for (rover = routing_info; rover != NULL; rover = rover->next) {
- if (memcmp(rover->addr, trh->daddr, TR_ALEN) == 0)
- break;
- }
-
- if (rover != NULL) {
- /* success: route that frame */
- if ((rover->rcf & TR_RCF_LEN_MASK) >> 8) {
- __u16 rcf = rover->rcf;
- memcpy(trh->rseg,rover->rseg,sizeof(trh->rseg));
- rcf ^= TR_RCF_DIR_BIT;
- rcf &= ~TR_RCF_BROADCAST_MASK;
- trh->rcf = htons(rcf);
- trh->saddr[0] |= TR_RII;
- }
- rover->access_time = now.tv_sec;
- } else {
- /* we don't have any routing information so send a
- * limited broadcast */
- trh->saddr[0] |= TR_RII;
- trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
- trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
- trh->rcf = htons(trh->rcf);
- }
- }
-
- /* return how much of the header we've actually used */
- if (trh->saddr[0] & TR_RII)
- route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
- else
- route_len = 0;
-
- return sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
-}
-
-/*
- * save any source routing information
- */
-static void save_source_routing(trh, interface)
- struct trh_hdr *trh;
- struct interface_info *interface;
-{
- struct routing_entry *rover;
- struct timeval now;
- unsigned char saddr[TR_ALEN];
- __u16 rcf = 0;
-
- gettimeofday(&now, NULL);
-
- memcpy(saddr, trh->saddr, sizeof(saddr));
- saddr[0] &= 0x7f; /* strip off source routing present flag */
-
- /* scan our table to see if we've got it */
- for (rover = routing_info; rover != NULL; rover = rover->next) {
- if (memcmp(&rover->addr[0], &saddr[0], TR_ALEN) == 0)
- break;
- }
-
- /* found an entry so update it with fresh information */
- if (rover != NULL) {
- if ((trh->saddr[0] & TR_RII) &&
- ((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
- rcf = ntohs(trh->rcf);
- rcf &= ~TR_RCF_BROADCAST_MASK;
- memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
- }
- rover->rcf = rcf;
- rover->access_time = now.tv_sec;
- return; /* that's all folks */
- }
-
- /* no entry found, so create one */
- rover = dmalloc (sizeof (struct routing_entry), MDL);
- if (rover == NULL) {
- fprintf(stderr,
- "%s: unable to save source routing information\n",
- __FILE__);
- return;
- }
-
- memcpy(rover->addr, saddr, sizeof(rover->addr));
- memcpy(rover->iface, interface->name, 5);
- rover->access_time = now.tv_sec;
- if (trh->saddr[0] & TR_RII) {
- if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
- rcf = ntohs(trh->rcf);
- rcf &= ~TR_RCF_BROADCAST_MASK;
- memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
- }
- rover->rcf = rcf;
- }
-
- /* insert into list */
- rover->next = routing_info;
- routing_info = rover;
-
- return;
-}
-
-/*
- * get rid of old routes
- */
-static void expire_routes()
-{
- struct routing_entry *rover;
- struct routing_entry **prover = &routing_info;
- struct timeval now;
-
- gettimeofday(&now, NULL);
-
- while((rover = *prover) != NULL) {
- if ((now.tv_sec - rover->access_time) > routing_timeout) {
- *prover = rover->next;
- dfree (rover, MDL);
- } else
- prover = &rover->next;
- }
-
- /* Reset the timer */
- routing_timer.tv_sec = now.tv_sec + routing_timeout;
- routing_timer.tv_usec = now.tv_usec;
-}
-
-#endif
diff --git a/contrib/isc-dhcp/common/tree.c b/contrib/isc-dhcp/common/tree.c
deleted file mode 100644
index ab357fb..0000000
--- a/contrib/isc-dhcp/common/tree.c
+++ /dev/null
@@ -1,4095 +0,0 @@
-/* tree.c
-
- Routines for manipulating parse trees... */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1995-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: tree.c,v 1.101.2.9 2004/06/17 20:54:39 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include <omapip/omapip_p.h>
-
-struct binding_scope *global_scope;
-
-static int do_host_lookup PROTO ((struct data_string *,
- struct dns_host_entry *));
-
-#ifdef NSUPDATE
-struct __res_state resolver_state;
-int resolver_inited = 0;
-#endif
-
-pair cons (car, cdr)
- caddr_t car;
- pair cdr;
-{
- pair foo = (pair)dmalloc (sizeof *foo, MDL);
- if (!foo)
- log_fatal ("no memory for cons.");
- foo -> car = car;
- foo -> cdr = cdr;
- return foo;
-}
-
-int make_const_option_cache (oc, buffer, data, len, option, file, line)
- struct option_cache **oc;
- struct buffer **buffer;
- u_int8_t *data;
- unsigned len;
- struct option *option;
- const char *file;
- int line;
-{
- struct buffer *bp;
-
- if (buffer) {
- bp = *buffer;
- *buffer = 0;
- } else {
- bp = (struct buffer *)0;
- if (!buffer_allocate (&bp, len, file, line)) {
- log_error ("%s(%d): can't allocate buffer.",
- file, line);
- return 0;
- }
- }
-
- if (!option_cache_allocate (oc, file, line)) {
- log_error ("%s(%d): can't allocate option cache.", file, line);
- buffer_dereference (&bp, file, line);
- return 0;
- }
-
- (*oc) -> data.len = len;
- (*oc) -> data.buffer = bp;
- (*oc) -> data.data = &bp -> data [0];
- (*oc) -> data.terminated = 0;
- if (data)
- memcpy (&bp -> data [0], data, len);
- (*oc) -> option = option;
- return 1;
-}
-
-int make_host_lookup (expr, name)
- struct expression **expr;
- const char *name;
-{
- if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for host lookup tree node.");
- return 0;
- }
- (*expr) -> op = expr_host_lookup;
- if (!enter_dns_host (&((*expr) -> data.host_lookup), name)) {
- expression_dereference (expr, MDL);
- return 0;
- }
- return 1;
-}
-
-int enter_dns_host (dh, name)
- struct dns_host_entry **dh;
- const char *name;
-{
- /* XXX This should really keep a hash table of hostnames
- XXX and just add a new reference to a hostname that
- XXX already exists, if possible, rather than creating
- XXX a new structure. */
- if (!dns_host_entry_allocate (dh, name, MDL)) {
- log_error ("Can't allocate space for new host.");
- return 0;
- }
- return 1;
-}
-
-int make_const_data (struct expression **expr, const unsigned char *data,
- unsigned len, int terminated, int allocate,
- const char *file, int line)
-{
- struct expression *nt;
-
- if (!expression_allocate (expr, file, line)) {
- log_error ("No memory for make_const_data tree node.");
- return 0;
- }
- nt = *expr;
-
- if (len) {
- if (allocate) {
- if (!buffer_allocate (&nt -> data.const_data.buffer,
- len + terminated, file, line)) {
- log_error ("Can't allocate const_data buffer");
- expression_dereference (expr, file, line);
- return 0;
- }
- nt -> data.const_data.data =
- &nt -> data.const_data.buffer -> data [0];
- memcpy (nt -> data.const_data.buffer -> data,
- data, len + terminated);
- } else
- nt -> data.const_data.data = data;
- nt -> data.const_data.terminated = terminated;
- } else
- nt -> data.const_data.data = 0;
-
- nt -> op = expr_const_data;
- nt -> data.const_data.len = len;
- return 1;
-}
-
-int make_const_int (expr, val)
- struct expression **expr;
- unsigned long val;
-{
- if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for make_const_int tree node.");
- return 0;
- }
-
- (*expr) -> op = expr_const_int;
- (*expr) -> data.const_int = val;
- return 1;
-}
-
-int make_concat (expr, left, right)
- struct expression **expr;
- struct expression *left, *right;
-{
- /* 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) {
- if (!right)
- return 0;
- expression_reference (expr, right, MDL);
- return 1;
- }
- if (!right) {
- expression_reference (expr, left, MDL);
- return 1;
- }
-
- /* Otherwise, allocate a new node to concatenate the two. */
- if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for concatenation expression node.");
- return 0;
- }
-
- (*expr) -> op = expr_concat;
- expression_reference (&(*expr) -> data.concat [0], left, MDL);
- expression_reference (&(*expr) -> data.concat [1], right, MDL);
- return 1;
-}
-
-int make_encapsulation (expr, name)
- struct expression **expr;
- struct data_string *name;
-{
- /* Allocate a new node to store the encapsulation. */
- if (!expression_allocate (expr, MDL)) {
- log_error ("No memory for encapsulation expression node.");
- return 0;
- }
-
- (*expr) -> op = expr_encapsulate;
- data_string_copy (&(*expr) -> data.encapsulate, name, MDL);
- return 1;
-}
-
-int make_substring (new, expr, offset, length)
- struct expression **new;
- struct expression *expr;
- struct expression *offset;
- struct expression *length;
-{
- /* Allocate an expression node to compute the substring. */
- if (!expression_allocate (new, MDL)) {
- log_error ("no memory for substring expression.");
- return 0;
- }
- (*new) -> op = expr_substring;
- expression_reference (&(*new) -> data.substring.expr, expr, MDL);
- expression_reference (&(*new) -> data.substring.offset, offset, MDL);
- expression_reference (&(*new) -> data.substring.len, length, MDL);
- return 1;
-}
-
-int make_limit (new, expr, limit)
- struct expression **new;
- struct expression *expr;
- int limit;
-{
- struct expression *rv;
-
- /* Allocate a node to enforce a limit on evaluation. */
- if (!expression_allocate (new, MDL))
- log_error ("no memory for limit expression");
- (*new) -> op = expr_substring;
- expression_reference (&(*new) -> data.substring.expr, expr, MDL);
-
- /* Offset is a constant 0. */
- if (!expression_allocate (&(*new) -> data.substring.offset, MDL)) {
- log_error ("no memory for limit offset expression");
- expression_dereference (new, MDL);
- return 0;
- }
- (*new) -> data.substring.offset -> op = expr_const_int;
- (*new) -> data.substring.offset -> data.const_int = 0;
-
- /* Length is a constant: the specified limit. */
- if (!expression_allocate (&(*new) -> data.substring.len, MDL)) {
- log_error ("no memory for limit length expression");
- expression_dereference (new, MDL);
- return 0;
- }
- (*new) -> data.substring.len -> op = expr_const_int;
- (*new) -> data.substring.len -> data.const_int = limit;
-
- return 1;
-}
-
-int option_cache (struct option_cache **oc, struct data_string *dp,
- struct expression *expr, struct option *option,
- const char *file, int line)
-{
- if (!option_cache_allocate (oc, file, line))
- return 0;
- if (dp)
- data_string_copy (&(*oc) -> data, dp, file, line);
- if (expr)
- expression_reference (&(*oc) -> expression, expr, file, line);
- (*oc) -> option = option;
- return 1;
-}
-
-int make_let (result, name)
- struct executable_statement **result;
- const char *name;
-{
- if (!(executable_statement_allocate (result, MDL)))
- return 0;
-
- (*result) -> op = let_statement;
- (*result) -> data.let.name = dmalloc (strlen (name) + 1, MDL);
- if (!(*result) -> data.let.name) {
- executable_statement_dereference (result, MDL);
- return 0;
- }
- strcpy ((*result) -> data.let.name, name);
- return 1;
-}
-
-static int do_host_lookup (result, dns)
- struct data_string *result;
- struct dns_host_entry *dns;
-{
- struct hostent *h;
- unsigned i, count;
- unsigned new_len;
-
-#ifdef DEBUG_EVAL
- log_debug ("time: now = %d dns = %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
- log_debug ("easy copy: %d %s",
- dns -> data.len,
- (dns -> data.len > 4
- ? inet_ntoa (*(struct in_addr *)(dns -> data.data))
- : 0));
-#endif
- data_string_copy (result, &dns -> data, MDL);
- return 1;
- }
-#ifdef DEBUG_EVAL
- log_debug ("Looking up %s", dns -> hostname);
-#endif
-
- /* Otherwise, look it up... */
- h = gethostbyname (dns -> hostname);
- if (!h) {
-#ifndef NO_H_ERRNO
- switch (h_errno) {
- case HOST_NOT_FOUND:
-#endif
- log_error ("%s: host unknown.", dns -> hostname);
-#ifndef NO_H_ERRNO
- break;
- case TRY_AGAIN:
- log_error ("%s: temporary name server failure",
- dns -> hostname);
- break;
- case NO_RECOVERY:
- log_error ("%s: name server failed", dns -> hostname);
- break;
- case NO_DATA:
- log_error ("%s: no A record associated with address",
- dns -> hostname);
- }
-#endif /* !NO_H_ERRNO */
-
- /* Okay to try again after a minute. */
- dns -> timeout = cur_time + 60;
- data_string_forget (&dns -> data, MDL);
- return 0;
- }
-
-#ifdef DEBUG_EVAL
- log_debug ("Lookup succeeded; first address is %s",
- inet_ntoa (h -> h_addr_list [0]));
-#endif
-
- /* Count the number of addresses we got... */
- for (count = 0; h -> h_addr_list [count]; count++)
- ;
-
- /* Dereference the old data, if any. */
- data_string_forget (&dns -> data, MDL);
-
- /* Do we need to allocate more memory? */
- new_len = count * h -> h_length;
- if (!buffer_allocate (&dns -> data.buffer, new_len, MDL))
- {
- log_error ("No memory for %s.", dns -> hostname);
- return 0;
- }
-
- dns -> data.data = &dns -> data.buffer -> data [0];
- dns -> data.len = new_len;
- dns -> data.terminated = 0;
-
- /* Addresses are conveniently stored one to the buffer, so we
- have to copy them out one at a time... :'( */
- for (i = 0; i < count; i++) {
- memcpy (&dns -> data.buffer -> data [h -> h_length * i],
- h -> h_addr_list [i], (unsigned)(h -> h_length));
- }
-#ifdef DEBUG_EVAL
- log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
- *(int *)(dns -> buffer), h -> h_addr_list [0]);
-#endif
-
- /* XXX 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
- log_debug ("hard copy: %d %s", dns -> data.len,
- (dns -> data.len > 4
- ? inet_ntoa (*(struct in_addr *)(dns -> data.data)) : 0));
-#endif
- data_string_copy (result, &dns -> data, MDL);
- return 1;
-}
-
-int evaluate_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr, file, line)
- struct binding_value **result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
- const char *file;
- int line;
-{
- struct binding_value *bv;
- int status;
- struct binding *binding;
-
- bv = (struct binding_value *)0;
-
- if (expr -> op == expr_variable_reference) {
- if (!scope || !*scope)
- return 0;
-
- binding = find_binding (*scope, expr -> data.variable);
-
- if (binding && binding -> value) {
- if (result)
- binding_value_reference (result,
- binding -> value,
- file, line);
- return 1;
- } else
- return 0;
- } else if (expr -> op == expr_funcall) {
- struct string_list *s;
- struct expression *arg;
- struct binding_scope *ns;
- struct binding *nb;
-
- if (!scope || !*scope) {
- log_error ("%s: no such function.",
- expr -> data.funcall.name);
- return 0;
- }
-
- binding = find_binding (*scope, expr -> data.funcall.name);
-
- if (!binding || !binding -> value) {
- log_error ("%s: no such function.",
- expr -> data.funcall.name);
- return 0;
- }
- if (binding -> value -> type != binding_function) {
- log_error ("%s: not a function.",
- expr -> data.funcall.name);
- return 0;
- }
-
- /* Create a new binding scope in which to define
- the arguments to the function. */
- ns = (struct binding_scope *)0;
- if (!binding_scope_allocate (&ns, MDL)) {
- log_error ("%s: can't allocate argument scope.",
- expr -> data.funcall.name);
- return 0;
- }
-
- arg = expr -> data.funcall.arglist;
- s = binding -> value -> value.fundef -> args;
- while (arg && s) {
- nb = dmalloc (sizeof *nb, MDL);
- if (!nb) {
- blb:
- binding_scope_dereference (&ns, MDL);
- return 0;
- } else {
- memset (nb, 0, sizeof *nb);
- nb -> name = dmalloc (strlen (s -> string) + 1,
- MDL);
- if (nb -> name)
- strcpy (nb -> name, s -> string);
- else {
- dfree (nb, MDL);
- nb = (struct binding *)0;
- goto blb;
- }
- }
- evaluate_expression (&nb -> value, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- arg -> data.arg.val, file, line);
- nb -> next = ns -> bindings;
- ns -> bindings = nb;
- arg = arg -> data.arg.next;
- s = s -> next;
- }
- if (arg) {
- log_error ("%s: too many arguments.",
- expr -> data.funcall.name);
- binding_scope_dereference (&ns, MDL);
- return 0;
- }
- if (s) {
- log_error ("%s: too few arguments.",
- expr -> data.funcall.name);
- binding_scope_dereference (&ns, MDL);
- return 0;
- }
-
- if (scope && *scope)
- binding_scope_reference (&ns -> outer, *scope, MDL);
-
- status = (execute_statements
- (&bv, packet,
- lease, client_state, in_options, cfg_options, &ns,
- binding -> value -> value.fundef -> statements));
- binding_scope_dereference (&ns, MDL);
-
- if (!bv)
- return 1;
- } else if (is_boolean_expression (expr)) {
- if (!binding_value_allocate (&bv, MDL))
- return 0;
- bv -> type = binding_boolean;
- status = (evaluate_boolean_expression
- (&bv -> value.boolean, packet, lease, client_state,
- in_options, cfg_options, scope, expr));
- } else if (is_numeric_expression (expr)) {
- if (!binding_value_allocate (&bv, MDL))
- return 0;
- bv -> type = binding_numeric;
- status = (evaluate_numeric_expression
- (&bv -> value.intval, packet, lease, client_state,
- in_options, cfg_options, scope, expr));
- } else if (is_data_expression (expr)) {
- if (!binding_value_allocate (&bv, MDL))
- return 0;
- bv -> type = binding_data;
- status = (evaluate_data_expression
- (&bv -> value.data, packet, lease, client_state,
- in_options, cfg_options, scope, expr, MDL));
- } else if (is_dns_expression (expr)) {
-#if defined (NSUPDATE)
- if (!binding_value_allocate (&bv, MDL))
- return 0;
- bv -> type = binding_dns;
- status = (evaluate_dns_expression
- (&bv -> value.dns, packet, lease, client_state,
- in_options, cfg_options, scope, expr));
-#endif
- } else {
- log_error ("%s: invalid expression type: %d",
- "evaluate_expression", expr -> op);
- return 0;
- }
- if (result && status)
- binding_value_reference (result, bv, file, line);
- binding_value_dereference (&bv, MDL);
-
- return status;
-}
-
-int binding_value_dereference (struct binding_value **v,
- const char *file, int line)
-{
- struct binding_value *bv = *v;
-
- *v = (struct binding_value *)0;
-
- /* Decrement the reference count. If it's nonzero, we're
- done. */
- --(bv -> refcnt);
- rc_register (file, line, v, bv, bv -> refcnt, 1, RC_MISC);
- if (bv -> refcnt > 0)
- return 1;
- if (bv -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (bv);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- switch (bv -> type) {
- case binding_boolean:
- case binding_numeric:
- break;
- case binding_data:
- if (bv -> value.data.buffer)
- data_string_forget (&bv -> value.data, file, line);
- break;
- case binding_dns:
-#if defined (NSUPDATE)
- if (bv -> value.dns) {
- if (bv -> value.dns -> r_data) {
- dfree (bv -> value.dns -> r_data_ephem, MDL);
- bv -> value.dns -> r_data = (unsigned char *)0;
- bv -> value.dns -> r_data_ephem =
- (unsigned char *)0;
- }
- minires_freeupdrec (bv -> value.dns);
- }
- break;
-#endif
- default:
- log_error ("%s(%d): invalid binding type: %d",
- file, line, bv -> type);
- return 0;
- }
- dfree (bv, file, line);
- return 1;
-}
-
-#if defined (NSUPDATE)
-int evaluate_dns_expression (result, packet, lease, client_state, in_options,
- cfg_options, scope, expr)
- ns_updrec **result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
-{
- ns_updrec *foo;
- unsigned long ttl = 0;
- char *tname;
- struct data_string name, data;
- int r0, r1, r2, r3;
-
- if (!result || *result) {
- log_error ("evaluate_dns_expression called with non-null %s",
- "result pointer");
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- switch (expr -> op) {
-#if defined (NSUPDATE)
- case expr_ns_add:
- r0 = evaluate_numeric_expression (&ttl, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.ns_add.ttl);
- goto nsfinish;
-
- case expr_ns_exists:
- ttl = 1;
-
- case expr_ns_delete:
- case expr_ns_not_exists:
- r0 = 1;
- nsfinish:
- memset (&name, 0, sizeof name);
- r1 = evaluate_data_expression (&name, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.ns_add.rrname,
- MDL);
- if (r1) {
- /* The result of the evaluation may or may not
- be NUL-terminated, but we need it
- terminated for sure, so we have to allocate
- a buffer and terminate it. */
- tname = dmalloc (name.len + 1, MDL);
- if (!tname) {
- r2 = 0;
- r1 = 0;
- data_string_forget (&name, MDL);
- } else {
- memcpy (tname, name.data, name.len);
- tname [name.len] = 0;
- memset (&data, 0, sizeof data);
- r2 = evaluate_data_expression
- (&data, packet, lease, client_state,
- in_options, cfg_options, scope,
- expr -> data.ns_add.rrdata, MDL);
- }
- } else
- r2 = 0;
- if (r0 && r1 && (r2 || expr -> op != expr_ns_add)) {
- *result = minires_mkupdrec (((expr -> op == expr_ns_add ||
- expr -> op == expr_ns_delete)
- ? S_UPDATE : S_PREREQ),
- tname,
- expr -> data.ns_add.rrclass,
- expr -> data.ns_add.rrtype,
- ttl);
- if (!*result) {
- ngood:
- if (r2) {
- data_string_forget (&data, MDL);
- r2 = 0;
- }
- } else {
- if (data.len) {
- /* As a special case, if we get exactly
- four bytes of data, it's an IP address
- represented as a 32-bit quantity, which
- is actually what we *should* be getting
- here. Because res_mkupdrec is currently
- broken and expects a dotted quad, convert
- it. This should be fixed when the new
- resolver is merged. */
- if (data.len == 4) {
- (*result) -> r_data_ephem =
- dmalloc (16, MDL);
- if (!(*result) -> r_data_ephem)
- goto dpngood;
- (*result) -> r_data =
- (*result) -> r_data_ephem;
- /*%Audit% 16 bytes max. %2004.06.17,Safe%*/
- sprintf ((char *)(*result) -> r_data_ephem,
- "%u.%u.%u.%u",
- data.data [0] & 0xff,
- data.data [1] & 0xff,
- data.data [2] & 0xff,
- data.data [3] & 0xff);
- (*result) -> r_size =
- strlen ((const char *)
- (*result) -> r_data);
- } else {
- (*result) -> r_size = data.len;
- (*result) -> r_data_ephem =
- dmalloc (data.len, MDL);
- if (!(*result) -> r_data_ephem) {
- dpngood: /* double plus ungood. */
- minires_freeupdrec (*result);
- *result = 0;
- goto ngood;
- }
- (*result) -> r_data =
- (*result) -> r_data_ephem;
- memcpy ((*result) -> r_data_ephem,
- data.data, data.len);
- }
- } else {
- (*result) -> r_data = 0;
- (*result) -> r_size = 0;
- }
- switch (expr -> op) {
- case expr_ns_add:
- (*result) -> r_opcode = ADD;
- break;
- case expr_ns_delete:
- (*result) -> r_opcode = DELETE;
- break;
- case expr_ns_exists:
- (*result) -> r_opcode = YXRRSET;
- break;
- case expr_ns_not_exists:
- (*result) -> r_opcode = NXRRSET;
- break;
-
- /* Can't happen, but satisfy gcc. */
- default:
- break;
- }
- }
- }
- if (r1) {
- data_string_forget (&name, MDL);
- dfree (tname, MDL);
- }
- if (r2)
- data_string_forget (&data, MDL);
- /* One flaw in the thinking here: an IP address and an
- ASCII string both look like data expressions, but
- for A records, we want an ASCII string, not a
- binary IP address. Do I need to turn binary IP
- addresses into a seperate type? */
- return (r0 && r1 &&
- (r2 || expr -> op != expr_ns_add) && *result);
-
-#else
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- return 0;
-#endif
- case expr_funcall:
- log_error ("%s: dns values for functions not supported.",
- expr -> data.funcall.name);
- break;
-
- case expr_variable_reference:
- log_error ("%s: dns values for variables not supported.",
- expr -> data.variable);
- break;
-
- case expr_check:
- case expr_equal:
- case expr_not_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- case expr_match:
- case expr_static:
- case expr_known:
- case expr_exists:
- case expr_variable_exists:
- log_error ("Boolean opcode in evaluate_dns_expression: %d",
- expr -> op);
- return 0;
-
- case expr_none:
- case expr_substring:
- case expr_suffix:
- case expr_option:
- case expr_hardware:
- case expr_const_data:
- case expr_packet:
- case expr_concat:
- case expr_encapsulate:
- case expr_host_lookup:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_binary_to_ascii:
- case expr_reverse:
- case expr_filename:
- case expr_sname:
- case expr_pick_first_value:
- case expr_host_decl_name:
- case expr_config_option:
- case expr_leased_address:
- case expr_null:
- log_error ("Data opcode in evaluate_dns_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- log_error ("Numeric opcode in evaluate_dns_expression: %d",
- expr -> op);
- return 0;
-
- case expr_function:
- log_error ("Function opcode in evaluate_dns_expression: %d",
- expr -> op);
- return 0;
-
- case expr_arg:
- break;
- }
-
- log_error ("Bogus opcode in evaluate_dns_expression: %d",
- expr -> op);
- return 0;
-}
-#endif /* defined (NSUPDATE) */
-
-int evaluate_boolean_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
- int *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
-{
- struct data_string left, right;
- struct data_string rrtype, rrname, rrdata;
- unsigned long ttl;
- int srrtype, srrname, srrdata, sttl;
- int bleft, bright;
- int sleft, sright;
- struct binding *binding;
- struct binding_value *bv, *obv;
-
- switch (expr -> op) {
- case expr_check:
- *result = check_collection (packet, lease,
- expr -> data.check);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: check (%s) returns %s",
- expr -> data.check -> name,
- *result ? "true" : "false");
-#endif
- return 1;
-
- case expr_equal:
- case expr_not_equal:
- bv = obv = (struct binding_value *)0;
- sleft = evaluate_expression (&bv, packet, lease, client_state,
- in_options, cfg_options, scope,
- expr -> data.equal [0], MDL);
- sright = evaluate_expression (&obv, packet, lease,
- client_state, in_options,
- cfg_options, scope,
- expr -> data.equal [1], MDL);
- if (sleft && sright) {
- if (bv -> type != obv -> type)
- *result = expr -> op == expr_not_equal;
- else {
- switch (obv -> type) {
- case binding_boolean:
- if (bv -> value.boolean == obv -> value.boolean)
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
- break;
-
- case binding_data:
- if ((bv -> value.data.len ==
- obv -> value.data.len) &&
- !memcmp (bv -> value.data.data,
- obv -> value.data.data,
- obv -> value.data.len))
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
- break;
-
- case binding_numeric:
- if (bv -> value.intval == obv -> value.intval)
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
- break;
-
- case binding_dns:
-#if defined (NSUPDATE)
- /* XXX This should be a comparison for equal
- XXX values, not for identity. */
- if (bv -> value.dns == obv -> value.dns)
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
-#else
- *result = expr -> op == expr_not_equal;
-#endif
- break;
-
- case binding_function:
- if (bv -> value.fundef == obv -> value.fundef)
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
- break;
- default:
- *result = expr -> op == expr_not_equal;
- break;
- }
- }
- } else if (!sleft && !sright)
- *result = expr -> op == expr_equal;
- else
- *result = expr -> op == expr_not_equal;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: %sequal = %s",
- expr -> op == expr_not_equal ? "not" : "",
- (*result ? "true" : "false"));
-#endif
- if (sleft)
- binding_value_dereference (&bv, MDL);
- if (sright)
- binding_value_dereference (&obv, MDL);
- return 1;
-
- case expr_and:
- sleft = evaluate_boolean_expression (&bleft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- if (sleft && bleft)
- sright = evaluate_boolean_expression
- (&bright, packet, lease, client_state,
- in_options, cfg_options,
- scope, expr -> data.and [1]);
- else
- sright = bright = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: and (%s, %s) = %s",
- sleft ? (bleft ? "true" : "false") : "NULL",
- sright ? (bright ? "true" : "false") : "NULL",
- ((sleft && sright)
- ? (bleft && bright ? "true" : "false") : "NULL"));
-#endif
- if (sleft && sright) {
- *result = bleft && bright;
- return 1;
- }
- return 0;
-
- case expr_or:
- bleft = bright = 0;
- sleft = evaluate_boolean_expression (&bleft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.or [0]);
- if (!sleft || !bleft)
- sright = evaluate_boolean_expression
- (&bright, packet, lease, client_state,
- in_options, cfg_options,
- scope, expr -> data.or [1]);
- else
- sright = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: or (%s, %s) = %s",
- sleft ? (bleft ? "true" : "false") : "NULL",
- sright ? (bright ? "true" : "false") : "NULL",
- ((sleft || sright)
- ? (bleft || bright ? "true" : "false") : "NULL"));
-#endif
- if (sleft || sright) {
- *result = bleft || bright;
- return 1;
- }
- return 0;
-
- case expr_not:
- sleft = evaluate_boolean_expression (&bleft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.not);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: not (%s) = %s",
- sleft ? (bleft ? "true" : "false") : "NULL",
- ((sleft && sright)
- ? (!bleft ? "true" : "false") : "NULL"));
-
-#endif
- if (sleft) {
- *result = !bleft;
- return 1;
- }
- return 0;
-
- case expr_exists:
- memset (&left, 0, sizeof left);
- if (!in_options ||
- !get_option (&left, expr -> data.exists -> universe,
- packet, lease, client_state,
- in_options, cfg_options, in_options,
- scope, expr -> data.exists -> code, MDL))
- *result = 0;
- else {
- *result = 1;
- data_string_forget (&left, MDL);
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: exists %s.%s = %s",
- expr -> data.option -> universe -> name,
- expr -> data.option -> name,
- *result ? "true" : "false");
-#endif
- return 1;
-
- case expr_known:
- if (!packet) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: known = NULL");
-#endif
- return 0;
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: known = %s",
- packet -> known ? "true" : "false");
-#endif
- *result = packet -> known;
- return 1;
-
- case expr_static:
- if (!lease || !(lease -> flags & STATIC_LEASE)) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: static = false (%s %s %s %d)",
- lease ? "y" : "n",
- (lease && (lease -> flags & STATIC_LEASE)
- ? "y" : "n"),
- piaddr (lease -> ip_addr),
- lease ? lease -> flags : 0);
-#endif
- *result = 0;
- return 1;
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("bool: static = true");
-#endif
- *result = 1;
- return 1;
-
- case expr_variable_exists:
- if (scope && *scope) {
- binding = find_binding (*scope, expr -> data.variable);
-
- if (binding) {
- if (binding -> value)
- *result = 1;
- else
- *result = 0;
- } else
- *result = 0;
- } else
- *result = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("boolean: %s? = %s", expr -> data.variable,
- *result ? "true" : "false");
-#endif
- return 1;
-
- case expr_variable_reference:
- if (scope && *scope) {
- binding = find_binding (*scope, expr -> data.variable);
-
- if (binding && binding -> value) {
- if (binding -> value -> type ==
- binding_boolean) {
- *result = binding -> value -> value.boolean;
- sleft = 1;
- } else {
- log_error ("binding type %d in %s.",
- binding -> value -> type,
- "evaluate_boolean_expression");
- sleft = 0;
- }
- } else
- sleft = 0;
- } else
- sleft = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("boolean: %s = %s", expr -> data.variable,
- sleft ? (*result ? "true" : "false") : "NULL");
-#endif
- return sleft;
-
- case expr_funcall:
- bv = (struct binding_value *)0;
- sleft = evaluate_expression (&bv, packet, lease, client_state,
- in_options, cfg_options,
- scope, expr, MDL);
- if (sleft) {
- if (bv -> type != binding_boolean)
- log_error ("%s() returned type %d in %s.",
- expr -> data.funcall.name,
- bv -> type,
- "evaluate_boolean_expression");
- else
- *result = bv -> value.boolean;
- binding_value_dereference (&bv, MDL);
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("boolean: %s() = %s", expr -> data.funcall.name,
- sleft ? (*result ? "true" : "false") : "NULL");
-#endif
- break;
-
- case expr_none:
- case expr_match:
- case expr_substring:
- case expr_suffix:
- case expr_option:
- case expr_hardware:
- case expr_const_data:
- case expr_packet:
- case expr_concat:
- case expr_encapsulate:
- case expr_host_lookup:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_binary_to_ascii:
- case expr_reverse:
- case expr_pick_first_value:
- case expr_host_decl_name:
- case expr_config_option:
- case expr_leased_address:
- case expr_null:
- case expr_filename:
- case expr_sname:
- log_error ("Data opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- log_error ("Numeric opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
-
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- log_error ("dns opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
-
- case expr_function:
- log_error ("function definition in evaluate_boolean_expr");
- return 0;
-
- case expr_arg:
- break;
- }
-
- log_error ("Bogus opcode in evaluate_boolean_expression: %d",
- expr -> op);
- return 0;
-}
-
-int evaluate_data_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr, file, line)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
- const char *file;
- int line;
-{
- struct data_string data, other;
- unsigned long offset, len, i;
- int s0, s1, s2, s3;
- int status;
- struct binding *binding;
- char *s;
- struct binding_value *bv;
-
- switch (expr -> op) {
- /* Extract N bytes starting at byte M of a data string. */
- case expr_substring:
- memset (&data, 0, sizeof data);
- s0 = evaluate_data_expression (&data, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.substring.expr,
- MDL);
-
- /* Evaluate the offset and length. */
- s1 = evaluate_numeric_expression
- (&offset, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.substring.offset);
- s2 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.substring.len);
-
- if (s0 && s1 && s2) {
- /* If the offset is after end of the string,
- return an empty string. Otherwise, do the
- adjustments and return what's left. */
- if (data.len > offset) {
- data_string_copy (result, &data, file, line);
- result -> len -= offset;
- if (result -> len > len) {
- result -> len = len;
- result -> terminated = 0;
- }
- result -> data += offset;
- }
- s3 = 1;
- } else
- s3 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: substring (%s, %s, %s) = %s",
- s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
- s1 ? print_dec_1 (offset) : "NULL",
- s2 ? print_dec_2 (len) : "NULL",
- (s3 ? print_hex_2 (result -> len, result -> data, 30)
- : "NULL"));
-#endif
- if (s0)
- data_string_forget (&data, MDL);
- if (s3)
- return 1;
- return 0;
-
-
- /* Extract the last N bytes of a data string. */
- case expr_suffix:
- memset (&data, 0, sizeof data);
- s0 = evaluate_data_expression (&data, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.suffix.expr, MDL);
- /* Evaluate the length. */
- s1 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.suffix.len);
- if (s0 && s1) {
- data_string_copy (result, &data, file, line);
-
- /* If we are returning the last N bytes of a
- string whose length is <= N, just return
- the string - otherwise, compute a new
- starting address and decrease the
- length. */
- if (data.len > len) {
- result -> data += data.len - len;
- result -> len = len;
- }
- data_string_forget (&data, MDL);
- }
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: suffix (%s, %s) = %s",
- s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
- s1 ? print_dec_1 (len) : "NULL",
- ((s0 && s1)
- ? print_hex_2 (result -> len, result -> data, 30)
- : "NULL"));
-#endif
- return s0 && s1;
-
- /* Extract an option. */
- case expr_option:
- if (in_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, in_options,
- scope, expr -> data.option -> code,
- file, line);
- else
- s0 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: option %s.%s = %s",
- expr -> data.option -> universe -> name,
- expr -> data.option -> name,
- s0 ? print_hex_1 (result -> len, result -> data, 60)
- : "NULL");
-#endif
- return s0;
-
- case expr_config_option:
- if (cfg_options)
- s0 = get_option (result,
- expr -> data.option -> universe,
- packet, lease, client_state,
- in_options, cfg_options, cfg_options,
- scope, expr -> data.option -> code,
- file, line);
- else
- s0 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: config-option %s.%s = %s",
- expr -> data.option -> universe -> name,
- expr -> data.option -> name,
- s0 ? print_hex_1 (result -> len, result -> data, 60)
- : "NULL");
-#endif
- return s0;
-
- /* Combine the hardware type and address. */
- case expr_hardware:
- /* On the client, hardware is our hardware. */
- if (client_state) {
- memset (result, 0, sizeof *result);
- result -> data =
- client_state -> interface -> hw_address.hbuf;
- result -> len =
- client_state -> interface -> hw_address.hlen;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: hardware = %s",
- print_hex_1 (result -> len,
- result -> data, 60));
-#endif
- return 1;
- }
-
- /* The server cares about the client's hardware address,
- so only in the case where we are examining a packet can
- we return anything. */
- if (!packet || !packet -> raw) {
- log_error ("data: hardware: raw packet not available");
- return 0;
- }
- if (packet -> raw -> hlen > sizeof packet -> raw -> chaddr) {
- log_error ("data: hardware: invalid hlen (%d)\n",
- packet -> raw -> hlen);
- return 0;
- }
- result -> len = packet -> raw -> hlen + 1;
- if (buffer_allocate (&result -> buffer, result -> len,
- file, line)) {
- result -> data = &result -> buffer -> data [0];
- result -> buffer -> data [0] = packet -> raw -> htype;
- memcpy (&result -> buffer -> data [1],
- packet -> raw -> chaddr,
- packet -> raw -> hlen);
- result -> terminated = 0;
- } else {
- log_error ("data: hardware: no memory for buffer.");
- return 0;
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: hardware = %s",
- print_hex_1 (result -> len, result -> data, 60));
-#endif
- return 1;
-
- /* Extract part of the raw packet. */
- case expr_packet:
- if (!packet || !packet -> raw) {
- log_error ("data: packet: raw packet not available");
- return 0;
- }
-
- s0 = evaluate_numeric_expression (&offset, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.packet.offset);
- s1 = evaluate_numeric_expression (&len,
- packet, lease, client_state,
- in_options, cfg_options,
- scope,
- expr -> data.packet.len);
- if (s0 && s1 && offset < packet -> packet_length) {
- if (offset + len > packet -> packet_length)
- result -> len =
- packet -> packet_length - offset;
- else
- result -> len = len;
- if (buffer_allocate (&result -> buffer,
- result -> len, file, line)) {
- result -> data = &result -> buffer -> data [0];
- memcpy (result -> buffer -> data,
- (((unsigned char *)(packet -> raw))
- + offset), result -> len);
- result -> terminated = 0;
- } else {
- log_error ("data: packet: no buffer memory.");
- return 0;
- }
- s2 = 1;
- } else
- s2 = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: packet (%ld, %ld) = %s",
- offset, len,
- s2 ? print_hex_1 (result -> len,
- result -> data, 60) : NULL);
-#endif
- return s2;
-
- /* The encapsulation of all defined options in an
- option space... */
- case expr_encapsulate:
- if (cfg_options)
- s0 = option_space_encapsulate
- (result, packet, lease, client_state,
- in_options, cfg_options, scope,
- &expr -> data.encapsulate);
- else
- s0 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: encapsulate (%s) = %s",
- expr -> data.encapsulate.data,
- s0 ? print_hex_1 (result -> len,
- result -> data, 60) : "NULL");
-#endif
- return s0;
-
- /* Some constant data... */
- case expr_const_data:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: const = %s",
- print_hex_1 (expr -> data.const_data.len,
- expr -> data.const_data.data, 60));
-#endif
- data_string_copy (result,
- &expr -> data.const_data, file, line);
- return 1;
-
- /* Hostname lookup... */
- case expr_host_lookup:
- s0 = do_host_lookup (result, expr -> data.host_lookup);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: DNS lookup (%s) = %s",
- expr -> data.host_lookup -> hostname,
- (s0
- ? print_dotted_quads (result -> len, result -> data)
- : "NULL"));
-#endif
- return s0;
-
- /* Concatenation... */
- case expr_concat:
- memset (&data, 0, sizeof data);
- s0 = evaluate_data_expression (&data, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.concat [0], MDL);
- memset (&other, 0, sizeof other);
- s1 = evaluate_data_expression (&other, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.concat [1], MDL);
-
- if (s0 && s1) {
- result -> len = data.len + other.len;
- if (!buffer_allocate (&result -> buffer,
- (result -> len + other.terminated),
- file, line)) {
- log_error ("data: concat: no memory");
- result -> len = 0;
- data_string_forget (&data, MDL);
- data_string_forget (&other, MDL);
- return 0;
- }
- result -> data = &result -> buffer -> data [0];
- memcpy (result -> buffer -> data, data.data, data.len);
- memcpy (&result -> buffer -> data [data.len],
- other.data, other.len + other.terminated);
- }
-
- if (s0)
- data_string_forget (&data, MDL);
- if (s1)
- data_string_forget (&other, MDL);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: concat (%s, %s) = %s",
- s0 ? print_hex_1 (data.len, data.data, 20) : "NULL",
- s1 ? print_hex_2 (other.len, other.data, 20) : "NULL",
- ((s0 && s1)
- ? print_hex_3 (result -> len, result -> data, 30)
- : "NULL"));
-#endif
- return s0 && s1;
-
- case expr_encode_int8:
- s0 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.encode_int);
- if (s0) {
- result -> len = 1;
- if (!buffer_allocate (&result -> buffer,
- 1, file, line)) {
- log_error ("data: encode_int8: no memory");
- result -> len = 0;
- s0 = 0;
- } else {
- result -> data = &result -> buffer -> data [0];
- result -> buffer -> data [0] = len;
- }
- } else
- result -> len = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- if (!s0)
- log_debug ("data: encode_int8 (NULL) = NULL");
- else
- log_debug ("data: encode_int8 (%ld) = %s", len,
- print_hex_2 (result -> len,
- result -> data, 20));
-#endif
- return s0;
-
-
- case expr_encode_int16:
- s0 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.encode_int);
- if (s0) {
- result -> len = 2;
- if (!buffer_allocate (&result -> buffer, 2,
- file, line)) {
- log_error ("data: encode_int16: no memory");
- result -> len = 0;
- s0 = 0;
- } else {
- result -> data = &result -> buffer -> data [0];
- putUShort (result -> buffer -> data, len);
- }
- } else
- result -> len = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- if (!s0)
- log_debug ("data: encode_int16 (NULL) = NULL");
- else
- log_debug ("data: encode_int16 (%ld) = %s", len,
- print_hex_2 (result -> len,
- result -> data, 20));
-#endif
- return s0;
-
- case expr_encode_int32:
- s0 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.encode_int);
- if (s0) {
- result -> len = 4;
- if (!buffer_allocate (&result -> buffer, 4,
- file, line)) {
- log_error ("data: encode_int32: no memory");
- result -> len = 0;
- s0 = 0;
- } else {
- result -> data = &result -> buffer -> data [0];
- putULong (result -> buffer -> data, len);
- }
- } else
- result -> len = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- if (!s0)
- log_debug ("data: encode_int32 (NULL) = NULL");
- else
- log_debug ("data: encode_int32 (%ld) = %s", len,
- print_hex_2 (result -> len,
- result -> data, 20));
-#endif
- return s0;
-
- case expr_binary_to_ascii:
- /* Evaluate the base (offset) and width (len): */
- s0 = evaluate_numeric_expression
- (&offset, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.b2a.base);
- s1 = evaluate_numeric_expression (&len, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.b2a.width);
-
- /* Evaluate the seperator string. */
- memset (&data, 0, sizeof data);
- s2 = evaluate_data_expression (&data, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.b2a.seperator,
- MDL);
-
- /* Evaluate the data to be converted. */
- memset (&other, 0, sizeof other);
- s3 = evaluate_data_expression (&other, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.b2a.buffer, MDL);
-
- if (s0 && s1 && s2 && s3) {
- unsigned buflen, i;
-
- if (len != 8 && len != 16 && len != 32) {
- log_info ("binary_to_ascii: %s %ld!",
- "invalid width", len);
- goto b2a_out;
- }
- len /= 8;
-
- /* The buffer must be a multiple of the number's
- width. */
- if (other.len % len) {
- log_info ("binary-to-ascii: %s %d %s %ld!",
- "length of buffer", other.len,
- "not a multiple of width", len);
- status = 0;
- goto b2a_out;
- }
-
- /* Count the width of the output. */
- buflen = 0;
- for (i = 0; i < other.len; i += len) {
- if (len == 1) {
- if (offset == 8) {
- if (other.data [i] < 8)
- buflen++;
- else if (other.data [i] < 64)
- buflen += 2;
- else
- buflen += 3;
- } else if (offset == 10) {
- if (other.data [i] < 10)
- buflen++;
- else if (other.data [i] < 100)
- buflen += 2;
- else
- buflen += 3;
- } else if (offset == 16) {
- if (other.data [i] < 16)
- buflen++;
- else
- buflen += 2;
- } else
- buflen += (converted_length
- (&other.data [i],
- offset, 1));
- } else
- buflen += (converted_length
- (&other.data [i],
- offset, len));
- if (i + len != other.len)
- buflen += data.len;
- }
-
- if (!buffer_allocate (&result -> buffer,
- buflen + 1, file, line)) {
- log_error ("data: binary-to-ascii: no memory");
- status = 0;
- goto b2a_out;
- }
- result -> data = &result -> buffer -> data [0];
- result -> len = buflen;
- result -> terminated = 1;
-
- buflen = 0;
- for (i = 0; i < other.len; i += len) {
- buflen += (binary_to_ascii
- (&result -> buffer -> data [buflen],
- &other.data [i], offset, len));
- if (i + len != other.len) {
- memcpy (&result ->
- buffer -> data [buflen],
- data.data, data.len);
- buflen += data.len;
- }
- }
- /* NUL terminate. */
- result -> buffer -> data [buflen] = 0;
- status = 1;
- } else
- status = 0;
-
- b2a_out:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
- s0 ? print_dec_1 (offset) : "NULL",
- s1 ? print_dec_2 (len) : "NULL",
- s2 ? print_hex_1 (data.len, data.data, 30) : "NULL",
- s3 ? print_hex_2 (other.len, other.data, 30) : "NULL",
- (status ? print_hex_3 (result -> len, result -> data, 30)
- : "NULL"));
-#endif
- if (s2)
- data_string_forget (&data, MDL);
- if (s3)
- data_string_forget (&other, MDL);
- if (status)
- return 1;
- return 0;
-
- case expr_reverse:
- /* Evaluate the width (len): */
- s0 = evaluate_numeric_expression
- (&len, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.reverse.width);
-
- /* Evaluate the data. */
- memset (&data, 0, sizeof data);
- s1 = evaluate_data_expression (&data, packet, lease,
- client_state,
- in_options, cfg_options, scope,
- expr -> data.reverse.buffer,
- MDL);
-
- if (s0 && s1) {
- char *upper;
- int i;
-
- /* The buffer must be a multiple of the number's
- width. */
- if (data.len % len) {
- log_info ("reverse: %s %d %s %ld!",
- "length of buffer", data.len,
- "not a multiple of width", len);
- status = 0;
- goto reverse_out;
- }
-
- /* XXX reverse in place? I don't think we can. */
- if (!buffer_allocate (&result -> buffer,
- data.len, file, line)) {
- log_error ("data: reverse: no memory");
- status = 0;
- goto reverse_out;
- }
- result -> data = &result -> buffer -> data [0];
- result -> len = data.len;
- result -> terminated = 0;
-
- for (i = 0; i < data.len; i += len) {
- memcpy (&result -> buffer -> data [i],
- &data.data [data.len - i - len], len);
- }
- status = 1;
- } else
- status = 0;
-
- reverse_out:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: reverse (%s, %s) = %s",
- s0 ? print_dec_1 (len) : "NULL",
- s1 ? print_hex_1 (data.len, data.data, 30) : "NULL",
- (status ? print_hex_3 (result -> len, result -> data, 30)
- : "NULL"));
-#endif
- if (s0)
- data_string_forget (&data, MDL);
- if (status)
- return 1;
- return 0;
-
- case expr_leased_address:
- if (!lease) {
- log_error ("data: leased_address: not available");
- return 0;
- }
- result -> len = lease -> ip_addr.len;
- if (buffer_allocate (&result -> buffer, result -> len,
- file, line)) {
- result -> data = &result -> buffer -> data [0];
- memcpy (&result -> buffer -> data [0],
- lease -> ip_addr.iabuf, lease -> ip_addr.len);
- result -> terminated = 0;
- } else {
- log_error ("data: leased-address: no memory.");
- return 0;
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: leased-address = %s",
- print_hex_1 (result -> len, result -> data, 60));
-#endif
- return 1;
-
- case expr_pick_first_value:
- memset (&data, 0, sizeof data);
- if ((evaluate_data_expression
- (result, packet,
- lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.car, MDL))) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: pick_first_value (%s, xxx)",
- print_hex_1 (result -> len,
- result -> data, 40));
-#endif
- return 1;
- }
-
- if (expr -> data.pick_first_value.cdr &&
- (evaluate_data_expression
- (result, packet,
- lease, client_state, in_options, cfg_options,
- scope, expr -> data.pick_first_value.cdr, MDL))) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: pick_first_value (NULL, %s)",
- print_hex_1 (result -> len,
- result -> data, 40));
-#endif
- return 1;
- }
-
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: pick_first_value (NULL, NULL) = NULL");
-#endif
- return 0;
-
- case expr_host_decl_name:
- if (!lease || !lease -> host) {
- log_error ("data: host_decl_name: not available");
- return 0;
- }
- result -> len = strlen (lease -> host -> name);
- if (buffer_allocate (&result -> buffer,
- result -> len + 1, file, line)) {
- result -> data = &result -> buffer -> data [0];
- strcpy ((char *)&result -> buffer -> data [0],
- lease -> host -> name);
- result -> terminated = 1;
- } else {
- log_error ("data: host-decl-name: no memory.");
- return 0;
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: host-decl-name = %s", lease -> host -> name);
-#endif
- return 1;
-
- case expr_null:
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: null = NULL");
-#endif
- return 0;
-
- case expr_variable_reference:
- if (scope && *scope) {
- binding = find_binding (*scope, expr -> data.variable);
-
- if (binding && binding -> value) {
- if (binding -> value -> type == binding_data) {
- data_string_copy (result,
- &binding -> value -> value.data,
- file, line);
- s0 = 1;
- } else if (binding -> value -> type != binding_data) {
- log_error ("binding type %d in %s.",
- binding -> value -> type,
- "evaluate_data_expression");
- s0 = 0;
- } else
- s0 = 0;
- } else
- s0 = 0;
- } else
- s0 = 0;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: %s = %s", expr -> data.variable,
- s0 ? print_hex_1 (result -> len,
- result -> data, 50) : "NULL");
-#endif
- return s0;
-
- case expr_funcall:
- bv = (struct binding_value *)0;
- s0 = evaluate_expression (&bv, packet, lease, client_state,
- in_options, cfg_options,
- scope, expr, MDL);
- if (s0) {
- if (bv -> type != binding_data)
- log_error ("%s() returned type %d in %s.",
- expr -> data.funcall.name,
- bv -> type,
- "evaluate_data_expression");
- else
- data_string_copy (result, &bv -> value.data,
- file, line);
- binding_value_dereference (&bv, MDL);
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: %s = %s", expr -> data.funcall.name,
- s0 ? print_hex_1 (result -> len,
- result -> data, 50) : "NULL");
-#endif
- break;
-
- /* Extract the filename. */
- case expr_filename:
- if (packet && packet -> raw -> file [0]) {
- char *fn =
- memchr (packet -> raw -> file, 0,
- sizeof packet -> raw -> file);
- if (!fn)
- fn = ((char *)packet -> raw -> file +
- sizeof packet -> raw -> file);
- result -> len = fn - &(packet -> raw -> file [0]);
- if (buffer_allocate (&result -> buffer,
- result -> len + 1, file, line)) {
- result -> data = &result -> buffer -> data [0];
- memcpy (&result -> buffer -> data [0],
- packet -> raw -> file,
- result -> len);
- result -> buffer -> data [result -> len] = 0;
- result -> terminated = 1;
- s0 = 1;
- } else {
- log_error ("data: filename: no memory.");
- s0 = 0;
- }
- } else
- s0 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_info ("data: filename = \"%s\"",
- s0 ? (const char *)(result -> data) : "NULL");
-#endif
- return s0;
-
- /* Extract the server name. */
- case expr_sname:
- if (packet && packet -> raw -> sname [0]) {
- char *fn =
- memchr (packet -> raw -> sname, 0,
- sizeof packet -> raw -> sname);
- if (!fn)
- fn = ((char *)packet -> raw -> sname +
- sizeof packet -> raw -> sname);
- result -> len = fn - &packet -> raw -> sname [0];
- if (buffer_allocate (&result -> buffer,
- result -> len + 1, file, line)) {
- result -> data = &result -> buffer -> data [0];
- memcpy (&result -> buffer -> data [0],
- packet -> raw -> sname,
- result -> len);
- result -> buffer -> data [result -> len] = 0;
- result -> terminated = 1;
- s0 = 1;
- } else {
- log_error ("data: sname: no memory.");
- s0 = 0;
- }
- } else
- s0 = 0;
-
-#if defined (DEBUG_EXPRESSIONS)
- log_info ("data: sname = \"%s\"",
- s0 ? (const char *)(result -> data) : "NULL");
-#endif
- return s0;
-
- case expr_check:
- case expr_equal:
- case expr_not_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- case expr_match:
- case expr_static:
- case expr_known:
- case expr_none:
- case expr_exists:
- case expr_variable_exists:
- log_error ("Boolean opcode in evaluate_data_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_const_int:
- case expr_lease_time:
- case expr_dns_transaction:
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- log_error ("Numeric opcode in evaluate_data_expression: %d",
- expr -> op);
- return 0;
-
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- log_error ("dns update opcode in evaluate_data_expression: %d",
- expr -> op);
- return 0;
-
- case expr_function:
- log_error ("function definition in evaluate_data_expression");
- return 0;
-
- case expr_arg:
- break;
- }
-
- log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
- return 0;
-}
-
-int evaluate_numeric_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
- unsigned long *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
-{
- struct data_string data;
- int status, sleft, sright;
-#if defined (NSUPDATE)
- ns_updrec *nut;
- ns_updque uq;
-#endif
- struct expression *cur, *next;
- struct binding *binding;
- struct binding_value *bv;
- unsigned long ileft, iright;
-
- switch (expr -> op) {
- case expr_check:
- case expr_equal:
- case expr_not_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- case expr_match:
- case expr_static:
- case expr_known:
- case expr_none:
- case expr_exists:
- case expr_variable_exists:
- log_error ("Boolean opcode in evaluate_numeric_expression: %d",
- expr -> op);
- return 0;
-
- case expr_substring:
- case expr_suffix:
- case expr_option:
- case expr_hardware:
- case expr_const_data:
- case expr_packet:
- case expr_concat:
- case expr_encapsulate:
- case expr_host_lookup:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_binary_to_ascii:
- case expr_reverse:
- case expr_filename:
- case expr_sname:
- case expr_pick_first_value:
- case expr_host_decl_name:
- case expr_config_option:
- case expr_leased_address:
- case expr_null:
- log_error ("Data opcode in evaluate_numeric_expression: %d",
- expr -> op);
- return 0;
-
- case expr_extract_int8:
- memset (&data, 0, sizeof data);
- status = evaluate_data_expression
- (&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int, MDL);
- if (status)
- *result = data.data [0];
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("num: extract_int8 (%s) = %s",
- status ? print_hex_1 (data.len, data.data, 60) : "NULL",
- status ? print_dec_1 (*result) : "NULL" );
-#endif
- if (status) data_string_forget (&data, MDL);
- return status;
-
- case expr_extract_int16:
- memset (&data, 0, sizeof data);
- status = (evaluate_data_expression
- (&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int, MDL));
- if (status && data.len >= 2)
- *result = getUShort (data.data);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("num: extract_int16 (%s) = %ld",
- ((status && data.len >= 2) ?
- print_hex_1 (data.len, data.data, 60) : "NULL"),
- *result);
-#endif
- if (status) data_string_forget (&data, MDL);
- return (status && data.len >= 2);
-
- case expr_extract_int32:
- memset (&data, 0, sizeof data);
- status = (evaluate_data_expression
- (&data, packet, lease, client_state, in_options,
- cfg_options, scope, expr -> data.extract_int, MDL));
- if (status && data.len >= 4)
- *result = getULong (data.data);
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("num: extract_int32 (%s) = %ld",
- ((status && data.len >= 4) ?
- print_hex_1 (data.len, data.data, 60) : "NULL"),
- *result);
-#endif
- if (status) data_string_forget (&data, MDL);
- return (status && data.len >= 4);
-
- case expr_const_int:
- *result = expr -> data.const_int;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("number: CONSTANT = %ld", *result);
-#endif
- return 1;
-
- case expr_lease_time:
- if (!lease) {
- log_error ("data: leased_lease: not available");
- return 0;
- }
- if (lease -> ends < cur_time) {
- log_error ("%s %lu when it is now %lu",
- "data: lease_time: lease ends at",
- (long)(lease -> ends), (long)cur_time);
- return 0;
- }
- *result = lease -> ends - cur_time;
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("number: lease-time = (%lu - %lu) = %ld",
- lease -> ends,
- cur_time, *result);
-#endif
- return 1;
-
- case expr_dns_transaction:
-#if !defined (NSUPDATE)
- return 0;
-#else
- if (!resolver_inited) {
- minires_ninit (&resolver_state);
- resolver_inited = 1;
- resolver_state.retrans = 1;
- resolver_state.retry = 1;
- }
- ISC_LIST_INIT (uq);
- cur = expr;
- do {
- next = cur -> data.dns_transaction.cdr;
- nut = 0;
- status = (evaluate_dns_expression
- (&nut, packet,
- lease, client_state, in_options, cfg_options,
- scope, cur -> data.dns_transaction.car));
- if (!status)
- goto dns_bad;
- ISC_LIST_APPEND (uq, nut, r_link);
- cur = next;
- } while (next);
-
- /* Do the update and record the error code, if there was
- an error; otherwise set it to NOERROR. */
- *result = minires_nupdate (&resolver_state,
- ISC_LIST_HEAD (uq));
- status = 1;
-
- print_dns_status ((int)*result, &uq);
-
- dns_bad:
- while (!ISC_LIST_EMPTY (uq)) {
- ns_updrec *tmp = ISC_LIST_HEAD (uq);
- ISC_LIST_UNLINK (uq, tmp, r_link);
- if (tmp -> r_data_ephem) {
- dfree (tmp -> r_data_ephem, MDL);
- tmp -> r_data = (unsigned char *)0;
- tmp -> r_data_ephem = (unsigned char *)0;
- }
- minires_freeupdrec (tmp);
- }
- return status;
-#endif /* NSUPDATE */
-
- case expr_variable_reference:
- if (scope && *scope) {
- binding = find_binding (*scope, expr -> data.variable);
-
- if (binding && binding -> value) {
- if (binding -> value -> type == binding_numeric) {
- *result = binding -> value -> value.intval;
- status = 1;
- } else {
- log_error ("binding type %d in %s.",
- binding -> value -> type,
- "evaluate_numeric_expression");
- status = 0;
- }
- } else
- status = 0;
- } else
- status = 0;
-#if defined (DEBUG_EXPRESSIONS)
- if (status)
- log_debug ("numeric: %s = %ld",
- expr -> data.variable, *result);
- else
- log_debug ("numeric: %s = NULL",
- expr -> data.variable);
-#endif
- return status;
-
- case expr_funcall:
- bv = (struct binding_value *)0;
- status = evaluate_expression (&bv, packet, lease,
- client_state,
- in_options, cfg_options,
- scope, expr, MDL);
- if (status) {
- if (bv -> type != binding_numeric)
- log_error ("%s() returned type %d in %s.",
- expr -> data.funcall.name,
- bv -> type,
- "evaluate_numeric_expression");
- else
- *result = bv -> value.intval;
- binding_value_dereference (&bv, MDL);
- }
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("data: %s = %ld", expr -> data.funcall.name,
- status ? *result : 0);
-#endif
- break;
-
- case expr_add:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld + %ld = %ld",
- ileft, iright, ileft + iright);
- else if (sleft)
- log_debug ("num: %ld + NULL = NULL", ileft);
- else
- log_debug ("num: NULL + %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft + iright;
- return 1;
- }
- return 0;
-
- case expr_subtract:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld - %ld = %ld",
- ileft, iright, ileft - iright);
- else if (sleft)
- log_debug ("num: %ld - NULL = NULL", ileft);
- else
- log_debug ("num: NULL - %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft - iright;
- return 1;
- }
- return 0;
-
- case expr_multiply:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld * %ld = %ld",
- ileft, iright, ileft * iright);
- else if (sleft)
- log_debug ("num: %ld * NULL = NULL", ileft);
- else
- log_debug ("num: NULL * %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft * iright;
- return 1;
- }
- return 0;
-
- case expr_divide:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright) {
- if (iright != 0)
- log_debug ("num: %ld / %ld = %ld",
- ileft, iright, ileft / iright);
- else
- log_debug ("num: %ld / %ld = NULL",
- ileft, iright);
- } else if (sleft)
- log_debug ("num: %ld / NULL = NULL", ileft);
- else
- log_debug ("num: NULL / %ld = NULL", iright);
-#endif
- if (sleft && sright && iright) {
- *result = ileft / iright;
- return 1;
- }
- return 0;
-
- case expr_remainder:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright) {
- if (iright != 0)
- log_debug ("num: %ld %% %ld = %ld",
- ileft, iright, ileft % iright);
- else
- log_debug ("num: %ld %% %ld = NULL",
- ileft, iright);
- } else if (sleft)
- log_debug ("num: %ld %% NULL = NULL", ileft);
- else
- log_debug ("num: NULL %% %ld = NULL", iright);
-#endif
- if (sleft && sright && iright) {
- *result = ileft % iright;
- return 1;
- }
- return 0;
-
- case expr_binary_and:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld | %ld = %ld",
- ileft, iright, ileft & iright);
- else if (sleft)
- log_debug ("num: %ld & NULL = NULL", ileft);
- else
- log_debug ("num: NULL & %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft & iright;
- return 1;
- }
- return 0;
-
- case expr_binary_or:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld | %ld = %ld",
- ileft, iright, ileft | iright);
- else if (sleft)
- log_debug ("num: %ld | NULL = NULL", ileft);
- else
- log_debug ("num: NULL | %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft | iright;
- return 1;
- }
- return 0;
-
- case expr_binary_xor:
- sleft = evaluate_numeric_expression (&ileft, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [0]);
- sright = evaluate_numeric_expression (&iright, packet, lease,
- client_state,
- in_options, cfg_options,
- scope,
- expr -> data.and [1]);
-
-#if defined (DEBUG_EXPRESSIONS)
- if (sleft && sright)
- log_debug ("num: %ld ^ %ld = %ld",
- ileft, iright, ileft ^ iright);
- else if (sleft)
- log_debug ("num: %ld ^ NULL = NULL", ileft);
- else
- log_debug ("num: NULL ^ %ld = NULL", iright);
-#endif
- if (sleft && sright) {
- *result = ileft ^ iright;
- return 1;
- }
- return 0;
-
- case expr_client_state:
- if (client_state) {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("num: client-state = %d",
- client_state -> state);
-#endif
- *result = client_state -> state;
- return 1;
- } else {
-#if defined (DEBUG_EXPRESSIONS)
- log_debug ("num: client-state = NULL");
-#endif
- return 0;
- }
-
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- log_error ("dns opcode in evaluate_numeric_expression: %d",
- expr -> op);
- return 0;
-
- case expr_function:
- log_error ("function definition in evaluate_numeric_expr");
- return 0;
-
- case expr_arg:
- break;
- }
-
- log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
- return 0;
-}
-
-/* Return data hanging off of an option cache structure, or if there
- isn't any, evaluate the expression hanging off of it and return the
- result of that evaluation. There should never be both an expression
- and a valid data_string. */
-
-int evaluate_option_cache (result, packet, lease, client_state,
- in_options, cfg_options, scope, oc, file, line)
- struct data_string *result;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct option_cache *oc;
- const char *file;
- int line;
-{
- if (oc -> data.len) {
- data_string_copy (result, &oc -> data, file, line);
- return 1;
- }
- if (!oc -> expression)
- return 0;
- return evaluate_data_expression (result, packet, lease, client_state,
- in_options, cfg_options, scope,
- oc -> expression, file, line);
-}
-
-/* Evaluate an option cache and extract a boolean from the result,
- returning the boolean. Return false if there is no data. */
-
-int evaluate_boolean_option_cache (ignorep, packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, file, line)
- int *ignorep;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct option_cache *oc;
- const char *file;
- int line;
-{
- struct data_string ds;
- int result;
-
- /* So that we can be called with option_lookup as an argument. */
- if (!oc || !in_options)
- return 0;
-
- memset (&ds, 0, sizeof ds);
- if (!evaluate_option_cache (&ds, packet,
- lease, client_state, in_options,
- cfg_options, scope, oc, file, line))
- return 0;
-
- if (ds.len) {
- result = ds.data [0];
- if (result == 2) {
- result = 0;
- *ignorep = 1;
- } else
- *ignorep = 0;
- } else
- result = 0;
- data_string_forget (&ds, MDL);
- return result;
-}
-
-
-/* Evaluate a boolean expression and return the result of the evaluation,
- or FALSE if it failed. */
-
-int evaluate_boolean_expression_result (ignorep, packet, lease, client_state,
- in_options, cfg_options, scope, expr)
- int *ignorep;
- struct packet *packet;
- struct lease *lease;
- struct client_state *client_state;
- struct option_state *in_options;
- struct option_state *cfg_options;
- struct binding_scope **scope;
- struct expression *expr;
-{
- int result;
-
- /* So that we can be called with option_lookup as an argument. */
- if (!expr)
- return 0;
-
- if (!evaluate_boolean_expression (&result, packet, lease, client_state,
- in_options, cfg_options,
- scope, expr))
- return 0;
-
- if (result == 2) {
- *ignorep = 1;
- result = 0;
- } else
- *ignorep = 0;
- return result;
-}
-
-
-/* Dereference an expression node, and if the reference count goes to zero,
- dereference any data it refers to, and then free it. */
-void expression_dereference (eptr, file, line)
- struct expression **eptr;
- const char *file;
- int line;
-{
- struct expression *expr = *eptr;
-
- /* Zero the pointer. */
- *eptr = (struct expression *)0;
-
- /* Decrement the reference count. If it's nonzero, we're
- done. */
- --(expr -> refcnt);
- rc_register (file, line, eptr, expr, expr -> refcnt, 1, RC_MISC);
- if (expr -> refcnt > 0)
- return;
- if (expr -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (expr);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return;
-#endif
- }
-
- /* Dereference subexpressions. */
- switch (expr -> op) {
- /* All the binary operators can be handled the same way. */
- case expr_equal:
- case expr_not_equal:
- case expr_concat:
- case expr_and:
- case expr_or:
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- if (expr -> data.equal [0])
- expression_dereference (&expr -> data.equal [0],
- file, line);
- if (expr -> data.equal [1])
- expression_dereference (&expr -> data.equal [1],
- file, line);
- break;
-
- case expr_substring:
- if (expr -> data.substring.expr)
- expression_dereference (&expr -> data.substring.expr,
- file, line);
- if (expr -> data.substring.offset)
- expression_dereference (&expr -> data.substring.offset,
- file, line);
- if (expr -> data.substring.len)
- expression_dereference (&expr -> data.substring.len,
- file, line);
- break;
-
- case expr_suffix:
- if (expr -> data.suffix.expr)
- expression_dereference (&expr -> data.suffix.expr,
- file, line);
- if (expr -> data.suffix.len)
- expression_dereference (&expr -> data.suffix.len,
- file, line);
- break;
-
- case expr_not:
- if (expr -> data.not)
- expression_dereference (&expr -> data.not, file, line);
- break;
-
- case expr_packet:
- if (expr -> data.packet.offset)
- expression_dereference (&expr -> data.packet.offset,
- file, line);
- if (expr -> data.packet.len)
- expression_dereference (&expr -> data.packet.len,
- file, line);
- break;
-
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- if (expr -> data.extract_int)
- expression_dereference (&expr -> data.extract_int,
- file, line);
- break;
-
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- if (expr -> data.encode_int)
- expression_dereference (&expr -> data.encode_int,
- file, line);
- break;
-
- case expr_encapsulate:
- case expr_const_data:
- data_string_forget (&expr -> data.const_data, file, line);
- break;
-
- case expr_host_lookup:
- if (expr -> data.host_lookup)
- dns_host_entry_dereference (&expr -> data.host_lookup,
- file, line);
- break;
-
- case expr_binary_to_ascii:
- if (expr -> data.b2a.base)
- expression_dereference (&expr -> data.b2a.base,
- file, line);
- if (expr -> data.b2a.width)
- expression_dereference (&expr -> data.b2a.width,
- file, line);
- if (expr -> data.b2a.seperator)
- expression_dereference (&expr -> data.b2a.seperator,
- file, line);
- if (expr -> data.b2a.buffer)
- expression_dereference (&expr -> data.b2a.buffer,
- file, line);
- break;
-
- case expr_pick_first_value:
- if (expr -> data.pick_first_value.car)
- expression_dereference (&expr -> data.pick_first_value.car,
- file, line);
- if (expr -> data.pick_first_value.cdr)
- expression_dereference (&expr -> data.pick_first_value.cdr,
- file, line);
- break;
-
- case expr_reverse:
- if (expr -> data.reverse.width)
- expression_dereference (&expr -> data.reverse.width,
- file, line);
- if (expr -> data.reverse.buffer)
- expression_dereference
- (&expr -> data.reverse.buffer, file, line);
- break;
-
- case expr_dns_transaction:
- if (expr -> data.dns_transaction.car)
- expression_dereference (&expr -> data.dns_transaction.car,
- file, line);
- if (expr -> data.dns_transaction.cdr)
- expression_dereference (&expr -> data.dns_transaction.cdr,
- file, line);
- break;
-
- case expr_ns_add:
- if (expr -> data.ns_add.rrname)
- expression_dereference (&expr -> data.ns_add.rrname,
- file, line);
- if (expr -> data.ns_add.rrdata)
- expression_dereference (&expr -> data.ns_add.rrdata,
- file, line);
- if (expr -> data.ns_add.ttl)
- expression_dereference (&expr -> data.ns_add.ttl,
- file, line);
- break;
-
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- if (expr -> data.ns_delete.rrname)
- expression_dereference (&expr -> data.ns_delete.rrname,
- file, line);
- if (expr -> data.ns_delete.rrdata)
- expression_dereference (&expr -> data.ns_delete.rrdata,
- file, line);
- break;
-
- case expr_variable_reference:
- case expr_variable_exists:
- if (expr -> data.variable)
- dfree (expr -> data.variable, file, line);
- break;
-
- case expr_funcall:
- if (expr -> data.funcall.name)
- dfree (expr -> data.funcall.name, file, line);
- if (expr -> data.funcall.arglist)
- expression_dereference (&expr -> data.funcall.arglist,
- file, line);
- break;
-
- case expr_arg:
- if (expr -> data.arg.val)
- expression_dereference (&expr -> data.arg.val,
- file, line);
- if (expr -> data.arg.next)
- expression_dereference (&expr -> data.arg.next,
- file, line);
- break;
-
- case expr_function:
- fundef_dereference (&expr -> data.func, file, line);
- break;
-
- /* No subexpressions. */
- case expr_leased_address:
- case expr_lease_time:
- case expr_filename:
- case expr_sname:
- case expr_const_int:
- case expr_check:
- case expr_option:
- case expr_hardware:
- case expr_exists:
- case expr_known:
- case expr_null:
- break;
-
- default:
- break;
- }
- free_expression (expr, MDL);
-}
-
-int is_dns_expression (expr)
- struct expression *expr;
-{
- return (expr -> op == expr_ns_add ||
- expr -> op == expr_ns_delete ||
- expr -> op == expr_ns_exists ||
- expr -> op == expr_ns_not_exists);
-}
-
-int is_boolean_expression (expr)
- struct expression *expr;
-{
- return (expr -> op == expr_check ||
- expr -> op == expr_exists ||
- expr -> op == expr_variable_exists ||
- expr -> op == expr_equal ||
- expr -> op == expr_not_equal ||
- expr -> op == expr_and ||
- expr -> op == expr_or ||
- expr -> op == expr_not ||
- expr -> op == expr_known ||
- expr -> op == expr_static);
-}
-
-int is_data_expression (expr)
- struct expression *expr;
-{
- return (expr -> op == expr_substring ||
- expr -> op == expr_suffix ||
- expr -> op == expr_option ||
- expr -> op == expr_hardware ||
- expr -> op == expr_const_data ||
- expr -> op == expr_packet ||
- expr -> op == expr_concat ||
- expr -> op == expr_encapsulate ||
- expr -> op == expr_encode_int8 ||
- expr -> op == expr_encode_int16 ||
- expr -> op == expr_encode_int32 ||
- expr -> op == expr_host_lookup ||
- expr -> op == expr_binary_to_ascii ||
- expr -> op == expr_filename ||
- expr -> op == expr_sname ||
- expr -> op == expr_reverse ||
- expr -> op == expr_pick_first_value ||
- expr -> op == expr_host_decl_name ||
- expr -> op == expr_leased_address ||
- expr -> op == expr_config_option ||
- expr -> op == expr_null);
-}
-
-int is_numeric_expression (expr)
- struct expression *expr;
-{
- return (expr -> op == expr_extract_int8 ||
- expr -> op == expr_extract_int16 ||
- expr -> op == expr_extract_int32 ||
- expr -> op == expr_const_int ||
- expr -> op == expr_lease_time ||
- expr -> op == expr_dns_transaction ||
- expr -> op == expr_add ||
- expr -> op == expr_subtract ||
- expr -> op == expr_multiply ||
- expr -> op == expr_divide ||
- expr -> op == expr_remainder ||
- expr -> op == expr_binary_and ||
- expr -> op == expr_binary_or ||
- expr -> op == expr_binary_xor ||
- expr -> op == expr_client_state);
-}
-
-int is_compound_expression (expr)
- struct expression *expr;
-{
- return (expr -> op == expr_ns_add ||
- expr -> op == expr_ns_delete ||
- expr -> op == expr_ns_exists ||
- expr -> op == expr_ns_not_exists ||
- expr -> op == expr_substring ||
- expr -> op == expr_suffix ||
- expr -> op == expr_option ||
- expr -> op == expr_concat ||
- expr -> op == expr_encode_int8 ||
- expr -> op == expr_encode_int16 ||
- expr -> op == expr_encode_int32 ||
- expr -> op == expr_binary_to_ascii ||
- expr -> op == expr_reverse ||
- expr -> op == expr_pick_first_value ||
- expr -> op == expr_config_option ||
- expr -> op == expr_extract_int8 ||
- expr -> op == expr_extract_int16 ||
- expr -> op == expr_extract_int32 ||
- expr -> op == expr_dns_transaction);
-}
-
-static int op_val PROTO ((enum expr_op));
-
-static int op_val (op)
- enum expr_op op;
-{
- switch (op) {
- case expr_none:
- case expr_match:
- case expr_static:
- case expr_check:
- case expr_substring:
- case expr_suffix:
- case expr_concat:
- case expr_encapsulate:
- case expr_host_lookup:
- case expr_not:
- case expr_option:
- case expr_hardware:
- case expr_packet:
- case expr_const_data:
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_const_int:
- case expr_exists:
- case expr_variable_exists:
- case expr_known:
- case expr_binary_to_ascii:
- case expr_reverse:
- case expr_filename:
- case expr_sname:
- case expr_pick_first_value:
- case expr_host_decl_name:
- case expr_config_option:
- case expr_leased_address:
- case expr_lease_time:
- case expr_dns_transaction:
- case expr_null:
- case expr_variable_reference:
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- case expr_arg:
- case expr_funcall:
- case expr_function:
- /* XXXDPN: Need to assign sane precedences to these. */
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- return 100;
-
- case expr_equal:
- case expr_not_equal:
- return 3;
-
- case expr_and:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- return 1;
-
- case expr_or:
- case expr_add:
- case expr_subtract:
- return 2;
- }
- return 100;
-}
-
-int op_precedence (op1, op2)
- enum expr_op op1, op2;
-{
- int ov1, ov2;
-
- return op_val (op1) - op_val (op2);
-}
-
-enum expression_context expression_context (struct expression *expr)
-{
- if (is_data_expression (expr))
- return context_data;
- if (is_numeric_expression (expr))
- return context_numeric;
- if (is_boolean_expression (expr))
- return context_boolean;
- if (is_dns_expression (expr))
- return context_dns;
- return context_any;
-}
-
-enum expression_context op_context (op)
- enum expr_op op;
-{
- switch (op) {
-/* XXX Why aren't these specific? */
- case expr_none:
- case expr_match:
- case expr_static:
- case expr_check:
- case expr_substring:
- case expr_suffix:
- case expr_concat:
- case expr_encapsulate:
- case expr_host_lookup:
- case expr_not:
- case expr_option:
- case expr_hardware:
- case expr_packet:
- case expr_const_data:
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_const_int:
- case expr_exists:
- case expr_variable_exists:
- case expr_known:
- case expr_binary_to_ascii:
- case expr_reverse:
- case expr_filename:
- case expr_sname:
- case expr_pick_first_value:
- case expr_host_decl_name:
- case expr_config_option:
- case expr_leased_address:
- case expr_lease_time:
- case expr_null:
- case expr_variable_reference:
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- case expr_dns_transaction:
- case expr_arg:
- case expr_funcall:
- case expr_function:
- return context_any;
-
- case expr_equal:
- case expr_not_equal:
- return context_data;
-
- case expr_and:
- return context_boolean;
-
- case expr_or:
- return context_boolean;
-
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- return context_numeric;
- }
- return context_any;
-}
-
-int write_expression (file, expr, col, indent, firstp)
- FILE *file;
- struct expression *expr;
- int col;
- int indent;
- int firstp;
-{
- struct expression *e;
- const char *s;
- char obuf [65];
- int scol;
- int width;
-
- /* If this promises to be a fat expression, start a new line. */
- if (!firstp && is_compound_expression (expr)) {
- indent_spaces (file, indent);
- col = indent;
- }
-
- switch (expr -> op) {
- case expr_none:
- col = token_print_indent (file, col, indent, "", "", "null");
- break;
-
- case expr_check:
- col = token_print_indent (file, col, indent, "", "", "check");
- col = token_print_indent_concat (file, col, indent,
- " ", "", "\"",
- expr -> data.check -> name,
- "\"", (char *)0);
- break;
-
- case expr_not_equal:
- s = "!=";
- goto binary;
-
- case expr_equal:
- s = "=";
- binary:
- col = write_expression (file, expr -> data.equal [0],
- col, indent, 1);
- col = token_print_indent (file, col, indent, " ", " ", s);
- col = write_expression (file, expr -> data.equal [1],
- col, indent + 2, 0);
- break;
-
- case expr_substring:
- col = token_print_indent (file, col, indent, "", "",
- "substring");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.substring.expr,
- col, scol, 1);
- col = token_print_indent (file, col, indent, "", " ", ",");
- col = write_expression (file, expr -> data.substring.offset,
- col, indent, 0);
- col = token_print_indent (file, col, scol, "", " ", ",");
- col = write_expression (file, expr -> data.substring.len,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_suffix:
- col = token_print_indent (file, col, indent, "", "", "suffix");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.suffix.expr,
- col, scol, 1);
- col = token_print_indent (file, col, scol, "", " ", ",");
- col = write_expression (file, expr -> data.suffix.len,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_concat:
- e = expr;
- col = token_print_indent (file, col, indent, "", "",
- "concat");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- firstp = 1;
- concat_again:
- col = write_expression (file, e -> data.concat [0],
- col, scol, firstp);
- firstp = 0;
- if (!e -> data.concat [1])
- goto no_concat_cdr;
- col = token_print_indent (file, col, scol, "", " ", ",");
- if (e -> data.concat [1] -> op == expr_concat) {
- e = e -> data.concat [1];
- goto concat_again;
- }
- col = write_expression (file, e -> data.concat [1],
- col, scol, 0);
- no_concat_cdr:
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_host_lookup:
- col = token_print_indent (file, col, indent, "", "",
- "gethostbyname");
- col = token_print_indent (file, col, indent, " ", "", "(");
- col = token_print_indent_concat
- (file, col, indent, "", "",
- "\"", expr -> data.host_lookup -> hostname, "\"",
- (char *)0);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_add:
- s = "+";
- goto binary;
-
- case expr_subtract:
- s = "-";
- goto binary;
-
- case expr_multiply:
- s = "*";
- goto binary;
-
- case expr_divide:
- s = "/";
- goto binary;
-
- case expr_remainder:
- s = "%";
- goto binary;
-
- case expr_binary_and:
- s = "&";
- goto binary;
-
- case expr_binary_or:
- s = "|";
- goto binary;
-
- case expr_binary_xor:
- s = "^";
- goto binary;
-
- case expr_and:
- s = "and";
- goto binary;
-
- case expr_or:
- s = "or";
- goto binary;
-
- case expr_not:
- col = token_print_indent (file, col, indent, "", " ", "not");
- col = write_expression (file,
- expr -> data.not, col, indent + 2, 1);
- break;
-
- case expr_option:
- s = "option";
-
- print_option_name:
- col = token_print_indent (file, col, indent, "", "", s);
-
- if (expr -> data.option -> universe != &dhcp_universe) {
- col = token_print_indent (file, col, indent,
- " ", "",
- (expr -> data.option ->
- universe -> name));
- col = token_print_indent (file, col, indent, "", "",
- ".");
- col = token_print_indent (file, col, indent, "", "",
- expr -> data.option -> name);
- } else {
- col = token_print_indent (file, col, indent, " ", "",
- expr -> data.option -> name);
- }
- break;
-
- case expr_hardware:
- col = token_print_indent (file, col, indent, "", "",
- "hardware");
- break;
-
- case expr_packet:
- col = token_print_indent (file, col, indent, "", "",
- "packet");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.packet.offset,
- col, indent, 1);
- col = token_print_indent (file, col, scol, "", " ", ",");
- col = write_expression (file, expr -> data.packet.len,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_const_data:
- col = token_indent_data_string (file, col, indent, "", "",
- &expr -> data.const_data);
- break;
-
- case expr_extract_int8:
- width = 8;
- extract_int:
- col = token_print_indent (file, col, indent, "", "",
- "extract-int");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.extract_int,
- col, indent, 1);
- col = token_print_indent (file, col, scol, "", " ", ",");
- sprintf (obuf, "%d", width);
- col = token_print_indent (file, col, scol, " ", "", obuf);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_extract_int16:
- width = 16;
- goto extract_int;
-
- case expr_extract_int32:
- width = 32;
- goto extract_int;
-
- case expr_encode_int8:
- width = 8;
- encode_int:
- col = token_print_indent (file, col, indent, "", "",
- "encode-int");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.extract_int,
- col, indent, 1);
- col = token_print_indent (file, col, scol, "", " ", ",");
- sprintf (obuf, "%d", width);
- col = token_print_indent (file, col, scol, " ", "", obuf);
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_encode_int16:
- width = 16;
- goto encode_int;
-
- case expr_encode_int32:
- width = 32;
- goto encode_int;
-
- case expr_const_int:
- sprintf (obuf, "%lu", expr -> data.const_int);
- col = token_print_indent (file, col, indent, "", "", obuf);
- break;
-
- case expr_exists:
- s = "exists";
- goto print_option_name;
-
- case expr_encapsulate:
- col = token_print_indent (file, col, indent, "", "",
- "encapsulate");
- col = token_indent_data_string (file, col, indent, " ", "",
- &expr -> data.encapsulate);
- break;
-
- case expr_known:
- col = token_print_indent (file, col, indent, "", "", "known");
- break;
-
- case expr_reverse:
- col = token_print_indent (file, col, indent, "", "",
- "reverse");
- col = token_print_indent (file, col, indent, " ", "", "(");
- scol = col;
- col = write_expression (file, expr -> data.reverse.width,
- col, scol, 1);
- col = token_print_indent (file, col, scol, "", " ", ",");
- col = write_expression (file, expr -> data.reverse.buffer,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_leased_address:
- col = token_print_indent (file, col, indent, "", "",
- "leased-address");
- break;
-
- case expr_client_state:
- col = token_print_indent (file, col, indent, "", "",
- "client-state");
- break;
-
- case expr_binary_to_ascii:
- col = token_print_indent (file, col, indent, "", "",
- "binary-to-ascii");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- scol = col;
- col = write_expression (file, expr -> data.b2a.base,
- col, scol, 1);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.b2a.width,
- col, scol, 0);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.b2a.seperator,
- col, scol, 0);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.b2a.buffer,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_config_option:
- s = "config-option";
- goto print_option_name;
-
- case expr_host_decl_name:
- col = token_print_indent (file, col, indent, "", "",
- "host-decl-name");
- break;
-
- case expr_pick_first_value:
- e = expr;
- col = token_print_indent (file, col, indent, "", "",
- "concat");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- scol = col;
- firstp = 1;
- pick_again:
- col = write_expression (file,
- e -> data.pick_first_value.car,
- col, scol, firstp);
- firstp = 0;
- /* We're being very lisp-like right now - instead of
- representing this expression as (first middle . last) we're
- representing it as (first middle last), which means that the
- tail cdr is always nil. Apologies to non-wisp-lizards - may
- this obscure way of describing the problem motivate you to
- learn more about the one true computing language. */
- if (!e -> data.pick_first_value.cdr)
- goto no_pick_cdr;
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- if (e -> data.pick_first_value.cdr -> op ==
- expr_pick_first_value) {
- e = e -> data.pick_first_value.cdr;
- goto pick_again;
- }
- col = write_expression (file,
- e -> data.pick_first_value.cdr,
- col, scol, 0);
- no_pick_cdr:
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_lease_time:
- col = token_print_indent (file, col, indent, "", "",
- "lease-time");
- break;
-
- case expr_dns_transaction:
- col = token_print_indent (file, col, indent, "", "",
- "ns-update");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- scol = 0;
- for (e = expr;
- e && e -> op == expr_dns_transaction;
- e = e -> data.dns_transaction.cdr) {
- if (!scol) {
- scol = col;
- firstp = 1;
- } else
- firstp = 0;
- col = write_expression (file,
- e -> data.dns_transaction.car,
- col, scol, firstp);
- if (e -> data.dns_transaction.cdr)
- col = token_print_indent (file, col, scol,
- "", " ", ",");
- }
- if (e)
- col = write_expression (file, e, col, scol, 0);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- case expr_ns_add:
- col = token_print_indent (file, col, indent, "", "",
- "update");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- scol = col;
- sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
- col = token_print_indent (file, col, scol, "", "", obuf);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
- col = token_print_indent (file, col, scol, "", "", obuf);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.ns_add.rrname,
- col, scol, 0);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.ns_add.rrdata,
- col, scol, 0);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.ns_add.ttl,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_ns_delete:
- col = token_print_indent (file, col, indent, "", "",
- "delete");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- finish_ns_small:
- scol = col;
- sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
- col = token_print_indent (file, col, scol, "", "", obuf);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
- col = token_print_indent (file, col, scol, "", "", obuf);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.ns_add.rrname,
- col, scol, 0);
- col = token_print_indent (file, col, scol, "", " ",
- ",");
- col = write_expression (file, expr -> data.ns_add.rrdata,
- col, scol, 0);
- col = token_print_indent (file, col, indent, "", "",
- ")");
- break;
-
- case expr_ns_exists:
- col = token_print_indent (file, col, indent, "", "",
- "exists");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- goto finish_ns_small;
-
- case expr_ns_not_exists:
- col = token_print_indent (file, col, indent, "", "",
- "not exists");
- col = token_print_indent (file, col, indent, " ", "",
- "(");
- goto finish_ns_small;
-
- case expr_static:
- col = token_print_indent (file, col, indent, "", "",
- "static");
- break;
-
- case expr_null:
- col = token_print_indent (file, col, indent, "", "", "null");
- break;
-
- case expr_variable_reference:
- col = token_print_indent (file, indent, indent, "", "",
- expr -> data.variable);
- break;
-
- case expr_variable_exists:
- col = token_print_indent (file, indent, indent, "", "",
- "defined");
- col = token_print_indent (file, col, indent, " ", "", "(");
- col = token_print_indent (file, col, indent, "", "",
- expr -> data.variable);
- col = token_print_indent (file, col, indent, "", "", ")");
- break;
-
- default:
- log_fatal ("invalid expression type in print_expression: %d",
- expr -> op);
- }
- return col;
-}
-
-struct binding *find_binding (struct binding_scope *scope, const char *name)
-{
- struct binding *bp;
- struct binding_scope *s;
-
- for (s = scope; s; s = s -> outer) {
- for (bp = s -> bindings; bp; bp = bp -> next) {
- if (!strcasecmp (name, bp -> name)) {
- return bp;
- }
- }
- }
- return (struct binding *)0;
-}
-
-int free_bindings (struct binding_scope *scope, const char *file, int line)
-{
- struct binding *bp, *next;
-
- for (bp = scope -> bindings; bp; bp = next) {
- next = bp -> next;
- if (bp -> name)
- dfree (bp -> name, file, line);
- if (bp -> value)
- binding_value_dereference (&bp -> value, file, line);
- dfree (bp, file, line);
- }
- scope -> bindings = (struct binding *)0;
- return 1;
-}
-
-int binding_scope_dereference (ptr, file, line)
- struct binding_scope **ptr;
- const char *file;
- int line;
-{
- int i;
- struct binding_scope *binding_scope;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- binding_scope = *ptr;
- *ptr = (struct binding_scope *)0;
- --binding_scope -> refcnt;
- rc_register (file, line, ptr,
- binding_scope, binding_scope -> refcnt, 1, RC_MISC);
- if (binding_scope -> refcnt > 0)
- return 1;
-
- if (binding_scope -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (binding_scope);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- free_bindings (binding_scope, file, line);
- if (binding_scope -> outer)
- binding_scope_dereference (&binding_scope -> outer, MDL);
- dfree (binding_scope, file, line);
- return 1;
-}
-
-int fundef_dereference (ptr, file, line)
- struct fundef **ptr;
- const char *file;
- int line;
-{
- struct fundef *bp = *ptr;
- struct string_list *sp, *next;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (!bp) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- bp -> refcnt--;
- rc_register (file, line, ptr, bp, bp -> refcnt, 1, RC_MISC);
- if (bp -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (bp);
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (!bp -> refcnt) {
- for (sp = bp -> args; sp; sp = next) {
- next = sp -> next;
- dfree (sp, file, line);
- }
- if (bp -> statements)
- executable_statement_dereference (&bp -> statements,
- file, line);
- dfree (bp, file, line);
- }
- *ptr = (struct fundef *)0;
- return 1;
-}
-
-#if defined (NOTYET) /* Post 3.0 final. */
-int data_subexpression_length (int *rv,
- struct expression *expr)
-{
- int crhs, clhs, llhs, lrhs;
- switch (expr -> op) {
- case expr_substring:
- if (expr -> data.substring.len &&
- expr -> data.substring.len -> op == expr_const_int) {
- (*rv =
- (int)expr -> data.substring.len -> data.const_int);
- return 1;
- }
- return 0;
-
- case expr_packet:
- case expr_suffix:
- if (expr -> data.suffix.len &&
- expr -> data.suffix.len -> op == expr_const_int) {
- (*rv =
- (int)expr -> data.suffix.len -> data.const_int);
- return 1;
- }
- return 0;
-
- case expr_concat:
- clhs = data_subexpression_length (&llhs,
- expr -> data.concat [0]);
- crhs = data_subexpression_length (&lrhs,
- expr -> data.concat [1]);
- if (crhs == 0 || clhs == 0)
- return 0;
- *rv = llhs + lrhs;
- return 1;
- break;
-
- case expr_hardware:
- return 0;
-
- case expr_const_data:
- *rv = expr -> data.const_data.len;
- return 2;
-
- case expr_reverse:
- return data_subexpression_length (rv,
- expr -> data.reverse.buffer);
-
- case expr_leased_address:
- case expr_lease_time:
- *rv = 4;
- return 2;
-
- case expr_pick_first_value:
- clhs = data_subexpression_length (&llhs,
- expr -> data.concat [0]);
- crhs = data_subexpression_length (&lrhs,
- expr -> data.concat [1]);
- if (crhs == 0 || clhs == 0)
- return 0;
- if (llhs > lrhs)
- *rv = llhs;
- else
- *rv = lrhs;
- return 1;
-
- case expr_binary_to_ascii:
- case expr_config_option:
- case expr_host_decl_name:
- case expr_encapsulate:
- case expr_filename:
- case expr_sname:
- case expr_host_lookup:
- case expr_option:
- case expr_none:
- case expr_match:
- case expr_check:
- case expr_equal:
- case expr_and:
- case expr_or:
- case expr_not:
- case expr_extract_int8:
- case expr_extract_int16:
- case expr_extract_int32:
- case expr_encode_int8:
- case expr_encode_int16:
- case expr_encode_int32:
- case expr_const_int:
- case expr_exists:
- case expr_known:
- case expr_dns_transaction:
- case expr_static:
- case expr_ns_add:
- case expr_ns_delete:
- case expr_ns_exists:
- case expr_ns_not_exists:
- case expr_not_equal:
- case expr_null:
- case expr_variable_exists:
- case expr_variable_reference:
- case expr_arg:
- case expr_funcall:
- case expr_function:
- case expr_add:
- case expr_subtract:
- case expr_multiply:
- case expr_divide:
- case expr_remainder:
- case expr_binary_and:
- case expr_binary_or:
- case expr_binary_xor:
- case expr_client_state:
- return 0;
- }
- return 0;
-}
-
-int expr_valid_for_context (struct expression *expr,
- enum expression_context context)
-{
- /* We don't know at parse time what type of value a function may
- return, so we can't flag an error on it. */
- if (expr -> op == expr_funcall ||
- expr -> op == expr_variable_reference)
- return 1;
-
- switch (context) {
- case context_any:
- return 1;
-
- case context_boolean:
- if (is_boolean_expression (expr))
- return 1;
- return 0;
-
- case context_data:
- if (is_data_expression (expr))
- return 1;
- return 0;
-
- case context_numeric:
- if (is_numeric_expression (expr))
- return 1;
- return 0;
-
- case context_dns:
- if (is_dns_expression (expr)) {
- return 1;
- }
- return 0;
-
- case context_data_or_numeric:
- if (is_numeric_expression (expr) ||
- is_data_expression (expr)) {
- return 1;
- }
- return 0;
-
- case context_function:
- if (expr -> op == expr_function)
- return 1;
- return 0;
- }
- return 0;
-}
-#endif /* NOTYET */
-
-struct binding *create_binding (struct binding_scope **scope, const char *name)
-{
- struct binding *binding;
-
- if (!*scope) {
- if (!binding_scope_allocate (scope, MDL))
- return (struct binding *)0;
- }
-
- binding = find_binding (*scope, name);
- if (!binding) {
- binding = dmalloc (sizeof *binding, MDL);
- if (!binding)
- return (struct binding *)0;
-
- memset (binding, 0, sizeof *binding);
- binding -> name = dmalloc (strlen (name) + 1, MDL);
- if (!binding -> name) {
- dfree (binding, MDL);
- return (struct binding *)0;
- }
- strcpy (binding -> name, name);
-
- binding -> next = (*scope) -> bindings;
- (*scope) -> bindings = binding;
- }
-
- return binding;
-}
-
-
-int bind_ds_value (struct binding_scope **scope,
- const char *name,
- struct data_string *value)
-{
- struct binding *binding;
-
- binding = create_binding (scope, name);
- if (!binding)
- return 0;
-
- if (binding -> value)
- binding_value_dereference (&binding -> value, MDL);
-
- if (!binding_value_allocate (&binding -> value, MDL))
- return 0;
-
- data_string_copy (&binding -> value -> value.data, value, MDL);
- binding -> value -> type = binding_data;
-
- return 1;
-}
-
-
-int find_bound_string (struct data_string *value,
- struct binding_scope *scope,
- const char *name)
-{
- struct binding *binding;
-
- binding = find_binding (scope, name);
- if (!binding ||
- !binding -> value ||
- binding -> value -> type != binding_data)
- return 0;
-
- if (binding -> value -> value.data.terminated) {
- data_string_copy (value, &binding -> value -> value.data, MDL);
- } else {
- buffer_allocate (&value -> buffer,
- binding -> value -> value.data.len,
- MDL);
- if (!value -> buffer)
- return 0;
-
- memcpy (value -> buffer -> data,
- binding -> value -> value.data.data,
- binding -> value -> value.data.len);
- value -> data = value -> buffer -> data;
- value -> len = binding -> value -> value.data.len;
- }
-
- return 1;
-}
-
-int unset (struct binding_scope *scope, const char *name)
-{
- struct binding *binding;
-
- binding = find_binding (scope, name);
- if (binding) {
- if (binding -> value)
- binding_value_dereference
- (&binding -> value, MDL);
- return 1;
- }
- return 0;
-}
-
-/* vim: set tabstop=8: */
diff --git a/contrib/isc-dhcp/common/upf.c b/contrib/isc-dhcp/common/upf.c
deleted file mode 100644
index 72e1b29..0000000
--- a/contrib/isc-dhcp/common/upf.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* upf.c
-
- Ultrix PacketFilter interface code. */
-
-/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1996-2003 by Internet Software Consortium
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Internet Systems Consortium, Inc.
- * 950 Charter Street
- * Redwood City, CA 94063
- * <info@isc.org>
- * http://www.isc.org/
- *
- * This software has been written for Internet Systems Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about Internet Systems Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: upf.c,v 1.21.2.4 2004/06/17 20:54:39 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_UPF_SEND) || defined (USE_UPF_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <net/pfilt.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_UPF_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_UPF_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_upf (info)
- struct interface_info *info;
-{
- int sock;
- char filename[50];
- int b;
- struct endevp param;
-
- /* Open a UPF device */
- for (b = 0; 1; b++) {
- /* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
- sprintf(filename, "/dev/pf/pfilt%d", b);
-
- sock = open (filename, O_RDWR, 0);
- if (sock < 0) {
- if (errno == EBUSY) {
- continue;
- } else {
- log_fatal ("Can't find free upf: %m");
- }
- } else {
- break;
- }
- }
-
- /* Set the UPF device to point at this interface. */
- if (ioctl (sock, EIOCSETIF, info -> ifp) < 0)
- log_fatal ("Can't attach interface %s to upf device %s: %m",
- info -> name, filename);
-
- /* Get the hardware address. */
- if (ioctl (sock, EIOCDEVP, &param) < 0)
- log_fatal ("Can't get interface %s hardware address: %m",
- info -> name);
-
- /* We only know how to do ethernet. */
- if (param.end_dev_type != ENDT_10MB)
- log_fatal ("Invalid device type on network interface %s: %d",
- info -> name, param.end_dev_type);
-
- if (param.end_addr_len != 6)
- log_fatal ("Invalid hardware address length on %s: %d",
- info -> name, param.end_addr_len);
-
- info -> hw_address.hlen = 7;
- info -> hw_address.hbuf [0] = ARPHRD_ETHER;
- memcpy (&info -> hw_address.hbuf [1], param.end_addr, 6);
-
- return sock;
-}
-#endif /* USE_UPF_SEND || USE_UPF_RECEIVE */
-
-#ifdef USE_UPF_SEND
-void if_register_send (info)
- struct interface_info *info;
-{
- /* If we're using the upf API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_UPF_RECEIVE
- info -> wfdesc = if_register_upf (info, interface);
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- log_info ("Sending on UPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_send (info)
- struct interface_info *info;
-{
-#ifndef USE_UPF_RECEIVE
- close (info -> wfdesc);
-#endif
- info -> wfdesc = -1;
- if (!quiet_interface_discovery)
- log_info ("Disabling output on UPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_UPF_SEND */
-
-#ifdef USE_UPF_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 UPF program! XXX */
-
-
-void if_register_receive (info)
- struct interface_info *info;
-{
- int flag = 1;
- u_int32_t addr;
- struct enfilter pf;
- u_int32_t bits;
-
- /* Open a UPF device and hang it on this interface... */
- info -> rfdesc = if_register_upf (info);
-
- /* Allow the copyall flag to be set... */
- if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
- log_fatal ("Can't set ALLOWCOPYALL: %m");
-
- /* Clear all the packet filter mode bits first... */
- flag = (ENHOLDSIG | ENBATCH | ENTSTAMP | ENPROMISC |
- ENNONEXCL | ENCOPYALL);
- if (ioctl (info -> rfdesc, EIOCMBIC, &flag) < 0)
- log_fatal ("Can't clear pfilt bits: %m");
-
- /* Set the ENBATCH and ENCOPYALL bits... */
- bits = ENBATCH | ENCOPYALL;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- log_fatal ("Can't set ENBATCH|ENCOPYALL: %m");
-
- /* Set up the UPF 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.enf_Priority = 0;
- pf.enf_FilterLen = 0;
-
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 6;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (ETHERTYPE_IP);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (IPPROTO_UDP);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 11;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (0xFF);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 18;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = local_port;
-
- if (ioctl (info -> rfdesc, EIOCSETF, &pf) < 0)
- log_fatal ("Can't install packet filter program: %m");
- if (!quiet_interface_discovery)
- log_info ("Listening on UPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-
-void if_deregister_receive (info)
- struct interface_info *info;
-{
- close (info -> rfdesc);
- info -> rfdesc = -1;
- if (!quiet_interface_discovery)
- log_info ("Disabling input on UPF/%s/%s%s%s",
- info -> name,
- print_hw_addr (info -> hw_address.hbuf [0],
- info -> hw_address.hlen - 1,
- &info -> hw_address.hbuf [1]),
- (info -> shared_network ? "/" : ""),
- (info -> shared_network ?
- info -> shared_network -> name : ""));
-}
-#endif /* USE_UPF_RECEIVE */
-
-#ifdef USE_UPF_SEND
-ssize_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 hbufp = 0, ibufp = 0;
- double hw [4];
- double ip [32];
- struct iovec iov [3];
- int result;
- int fudge;
-
- if (!strcmp (interface -> name, "fallback"))
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
- assemble_udp_ip_header (interface,
- (unsigned char *)ip, &ibufp, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- (unsigned char *)raw, len);
-
- /* Fire it off */
- iov [0].iov_base = ((char *)hw);
- iov [0].iov_len = hbufp;
- iov [1].iov_base = ((char *)ip);
- iov [1].iov_len = ibufp;
- iov [2].iov_base = (char *)raw;
- iov [2].iov_len = len;
-
- result = writev(interface -> wfdesc, iov, 3);
- if (result < 0)
- log_error ("send_packet: %m");
- return result;
-}
-#endif /* USE_UPF_SEND */
-
-#ifdef USE_UPF_RECEIVE
-ssize_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 [1500 + sizeof (struct enstamp)];
- int bufix = 0;
-
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-
- bufix = sizeof (struct enstamp);
- /* 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;
-}
-
-int can_unicast_without_arp (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int can_receive_unicast_unconfigured (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-int supports_multiple_interfaces (ip)
- struct interface_info *ip;
-{
- return 1;
-}
-
-void maybe_setup_fallback ()
-{
- isc_result_t status;
- struct interface_info *fbi = (struct interface_info *)0;
- if (setup_fallback (&fbi, MDL)) {
- if_register_fallback (fbi);
- status = omapi_register_io_object ((omapi_object_t *)fbi,
- if_readsocket, 0,
- fallback_discard, 0, 0);
- if (status != ISC_R_SUCCESS)
- log_fatal ("Can't register I/O handle for %s: %s",
- fbi -> name, isc_result_totext (status));
- interface_dereference (&fbi, MDL);
- }
-}
-#endif
OpenPOWER on IntegriCloud