Index: head/contrib/isc-dhcp/CHANGES =================================================================== --- head/contrib/isc-dhcp/CHANGES (revision 131139) +++ head/contrib/isc-dhcp/CHANGES (nonexistent) @@ -1,104 +0,0 @@ -970609 - -- Don't trust hostnames provided by client - Win95 allows *spaces* in - client-supplied hostnames! - -- Be lenient in parsing client-hostname statement in case a bad hostname - got recorded. - -970607 - -- Change size_t to ssize_t in return values where a negative number - is used to indicate an error. - -- Always write out two digits for single-byte quantities in arrays. - -- When parsing a lease database, correctly transfer the client - hostname and hostname to the memory-resident lease structure. - -- If the lease we want to give the client is different than the - one it's asking for, and we recognize the one it's asking for as - ours, NAK it. - -- Only accept a DHCPRELEASE or DHCPNAK if the client supplies an IP - address and the lease corresponding to that address is available to - that client. - -- Make it a warning rather than an error if resolv.conf is missing. - -970605 - -- Add client-hostname token to lexer so that the parser can use it. - Fixes a serious lease database bug. - -- Disable log message on receipt of short ICMP Echo replies. - -970602 - -- Added DHCP Client scripts for FreeBSD, Solaris, and Linux, but - they're not guaranteed to work. - -- Added some Cygwin32 (Windows NT/Windows 95) support, but this is not - sufficiently complete to be useful yet. - -- Updated README - -- Put something useful in TODO - formerly it mostly listed projects - that were way out on the back burner. - -In DHCP Client: - -- Add default, supersede, prepend and append option support, so that a - client can override or modify server-supplied options, and provide - default values if the server provides no values. - -- Add reject keyword, so that packets from rogue DHCP or BOOTP servers - can be rejected out of hand. - -- Added support for booting from BOOTP servers. - -- Added BOOTP flag to client lease declaration, to indicated that a - particular lease was acquired through a BOOTP server. - -- Don't try to do INIT-REBOOT on leases acquired from BOOTP servers. - -- Print server's IP address instead of its IP address when logging - DHCP/BOOTP messages received by client. - -- Fix some bugs in saved lease activation. - -- Fix some scripting bugs. - -- New sample dhclient.conf script demonstrates new features. - -In common code: - -- Partially implemented asynchronous DNS lookups. - -- Fixed some bugs in dispatch routine. - -- Fix date parsing bug that was setting dates forward one day every - time dhcpd was restarted (this has been fixed for a while in the 1.0 - branch). - -- Change name-server option name to ien116-name-server so as to reduce - the potential for confusion. - -DHCP Relay daemon: - -- Fixed an operator precedence bug having to do with the broadcast - flag. - -DHCP Server: - -- Add support to record the client-supplied hostname in the lease file, - for better readability. - -- Fixed a bug in the renewal code that resulted in the server ignoring - unicast renewals from non-local subnets. This bug caused some - heartburn for Win95 machines. - -- Copy ciaddr from saved ciaddr, not from giaddr. - -- New -t flag tests /etc/dhcpd.conf for syntax errors. - Property changes on: head/contrib/isc-dhcp/CHANGES ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/contrib/isc-dhcp/COPYRIGHT =================================================================== --- head/contrib/isc-dhcp/COPYRIGHT (revision 131139) +++ head/contrib/isc-dhcp/COPYRIGHT (nonexistent) @@ -1,17 +0,0 @@ -/* - * Copyright (c) 1996-2003 Internet Software Consortium. - * Use is subject to license terms which appear in the file named - * ISC-LICENSE that should have accompanied this file when you - * received it. If a file named ISC-LICENSE did not accompany this - * file, or you are not sure the one you have is correct, you may - * obtain an applicable copy of the license at: - * - * http://www.isc.org/isc-license-1.0.html. - * - * This file is part of the ISC DHCP distribution. The documentation - * associated with this file is listed in the file DOCUMENTATION, - * included in the top-level directory of this release. - * - * Support and other services are available for ISC products - see - * http://www.isc.org for more information. - */ Property changes on: head/contrib/isc-dhcp/COPYRIGHT ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/contrib/isc-dhcp/ANONCVS =================================================================== --- head/contrib/isc-dhcp/ANONCVS (revision 131139) +++ head/contrib/isc-dhcp/ANONCVS (nonexistent) @@ -1,129 +0,0 @@ - Anonymous CVS Access for the ISC DHCP Distribution - -The ISC DHCP distribution can be accessed using "anonymous" CVS. -"Anonymous" cvs uses the CVS "pserver" mechanism to allow anybody on -the Internet to access a CVS repository without having to register in -any way. Anonymous CVS allows you to access changes as soon as the -DHCP developers commit them, rather than having to wait for the next -snapshot or patchlevel. Changes that have not yet been released yet -are not guaranteed to work, but they can nonetheless be useful in many -cases. - - TABLE OF CONTENTS - - 1. What is anonymous CVS? - 2. How can i start using it? - 3. Checking out the latest code in a release - 4. Checking out the latest code - 5. Checking out a specific release - 6. When to update - - WHAT IS ANONYMOUS CVS? - -Anonymous CVS also allows you to browse through the history of the -DHCP distribution, and examine the revision history of specific files -to see how they have changed between revisions, to try to figure out -why something that was working before is no longer working, or just to -see when a certain change was made. - - HOW CAN I START USING IT? - -To use anonymous CVS to access the DHCP distribution, you must first -"log in". You should only need to do this once, but it is a -necessary step, even though access is anonymous. Anonymous users log -in as user "nobody", password "nobody". To do this, type: - - cvs -d :pserver:nobody@dhcp.cvs.isc.org:/cvsroot login - -You will be prompted for a password - type "nobody". If you get some -kind of error indicating that cvs doesn't know how to log you in, you -are probably running an old version of cvs, and should upgrade. This -should work with cvs version 1.10. - -Once you have logged in, you can check out a version of the DHCP -distribution, so the next question is, which version? - - CHECKING OUT THE LATEST CODE IN A RELEASE - -There are currently four major versions of the distribution - Release -1, Release 2, Release 3, and the current development tree. Releases -1, 2 and 3 are branches in the CVS repository. To check out the -latest code on any of these branches, you would use a branch tag of -RELEASE_1, RELEASE_2 or RELEASE_3 in the following command: - - (setenv CVSROOT :pserver:nobody@dhcp.cvs.isc.org:/cvsroot; - cvs checkout -d dhcp-2.0 -r RELEASE_2 DHCP) - -Note that the example is for Release 2. - - CHECKING OUT THE LATEST CODE - -To check out the current engineering version, use: - - (setenv CVSROOT :pserver:nobody@dhcp.cvs.isc.org:/cvsroot; - cvs checkout -d dhcp-current DHCP) - -Note that the current engineering version is a work in progress, and -there is no real guarantee that it will work for you. - - CHECKING OUT A SPECIFIC RELEASE - -You can also check out specific versions of the DHCP distribution. -There are three kinds of version tags you may find - alpha tags, beta -tags and release tags. Alpha tags look like this: - - V#-ALPHA-YYYYMMDD - -# is the release number. YYYYMMDD is the date of the release, with a -4-digit year, the month expressed as a number (January=1), and the day -of the month specified as a number, with the first day of the month -being 1. - -Beta tags look like this: - - V#-BETA-%-PATCH-* - -Where # is the release number, % is the Beta number (usually 1) and * -is the patchlevel. In the future there may also be beta tags that -look like this: - - V#-#-BETA-%-PATCH-* - -Where #-# is the major version followed by the minor version - for -example, when the first 3.1 beta comes out, the tag will look like -this: - - V3-1-BETA-1-PATCH-0 - -Release tags look like this: - - V#-%-* - -Where # is the major version, % is the minor version, and * is the -patchlevel. So the tag for 1.0pl2 is V1-0-2, and to check it out, -you'd type: - - (setenv CVSROOT :pserver:nobody@dhcp.cvs.isc.org:/cvsroot; - cvs checkout -d dhcp-1.0pl2 -rV1-0-2 DHCP) - -Whenever changes are checked in to the ISC DHCP repository, or files -are tagged, a notice is sent to the dhcp-source-changes@isc.org -mailing list. You can subscribe to this list by sending mail to -dhcp-source-changes-request@isc.org, and you will then get immediate -notification when changes are made. You may find the volume of mail -on this list annoying, however. - - WHEN TO UPDATE - -We do not recommend that you do an update immediately after you see a -change on the dhcp-source-changes mailing list - instead, it's best to -wait a while to make sure that any changes that change depends on have -also been committed. Also, sometimes when development is being done -on two machines, the developers will check in a tentative change that -hasn't been tested at all so that they can update on a different -machine and test the change. The best way to avoid accidentally -getting one of these changes is to not update aggressively - when a -change is made, wait a while before updating, to make sure that it's -not going to be quickly followed by another change. - - Property changes on: head/contrib/isc-dhcp/ANONCVS ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/contrib/isc-dhcp/FREEBSD-upgrade =================================================================== --- head/contrib/isc-dhcp/FREEBSD-upgrade (revision 131139) +++ head/contrib/isc-dhcp/FREEBSD-upgrade (revision 131140) @@ -1,78 +1,78 @@ # ex:ts=8 $FreeBSD$ -ISC DHCP client 3.0.1rc12 +ISC DHCP client 3.0.1rc14 originals can be found at: ftp://ftp.isc.org/isc/dhcp/ For the import of ISC-dhclient the following files were removed: doc/* relay/* server/* client/scripts/ bsdos linux netbsd nextstep solaris openbsd contrib/ dhcp.spec solaris.init ms2isc/ includes/cf/ aix.h alphaosf.h bsdos.h cygwin32.h hpux.h irix.h linux.h netbsd.h nextstep.h openbsd.h qnx.h rhapsody.h sample.h sco.h sunos4.h sunos5-5.h ultrix.h `find . -name '.cvsignore' -delete` Imported by: - cvs import -m 'Import ISC DHCP 3.0.1 RC11 client.' \ - src/contrib/isc-dhcp ISC isc_dhcp_3_0_1_rc12 + cvs import -m 'Import ISC DHCP 3.0.1 RC14 client.' \ + src/contrib/isc-dhcp ISC isc_dhcp_3_0_1_rc14 To make local changes to isc-dhcp, simply patch and commit to the main branch (aka HEAD). Never make local changes on the vendor (ISC) branch. All local changes should be submitted to the ISC for inclusion in the next vendor release. Local Changes: client/clparse.c r1.6 - prefer strlcpy to strcpy. client/dhclient.8 r1.14 - interface polling r1.6 - document -D option. - remove dhcpd from SEE ALSO section. client/dhclient.c r1.35 - interface polling r1.32 - interface polling r1.31 - interface polling r1.30 - interface polling r1.29 - interface polling r1.28 - interface polling r1.27 - interface polling r1.26 - interface polling r1.19 - connect std{in,out,err}. r1.13 - prefer strlcpy to strcpy. r1.6 - quiet by default. - document -D option. client/dhclient.conf.5 - Remove dhcpd from SEE ALSO section. common/dhcp-options.5 r1.2 - note that hostname is only set if not already set. - Remove dhcpd from SEE ALSO section. common/dispatch.c r1.2 - interface polling includes/dhcpd.h r1.5 - interface polling r1.4 - interface polling r1.3 - interface polling r1.2 - interface polling (see CVS logs for complete details) mbr@FreeBSD.org murray@FreeBSD.org obrien@NUXI.com 15-Jan-2003 Index: head/contrib/isc-dhcp/client/clparse.c =================================================================== --- head/contrib/isc-dhcp/client/clparse.c (revision 131139) +++ head/contrib/isc-dhcp/client/clparse.c (revision 131140) @@ -1,1180 +1,1173 @@ /* clparse.c Parser for dhclient config and lease files... */ /* - * Copyright (c) 1996-2002 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * 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: clparse.c,v 1.62.2.4 2003/02/10 00:39:57 dhankins Exp $ Copyright (c) 1996-2002 The Internet Software Consortium. All rights reserved.\n" +"$Id: clparse.c,v 1.62.2.6 2004/06/10 17:59:11 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n" "$FreeBSD$\n"; #endif /* not lint */ #include "dhcpd.h" static TIME parsed_time; struct client_config top_level_config; char client_script_name [] = _PATH_DHCLIENT_SCRIPT; u_int32_t default_requested_options [] = { DHO_SUBNET_MASK, DHO_BROADCAST_ADDRESS, DHO_TIME_OFFSET, DHO_ROUTERS, DHO_DOMAIN_NAME, DHO_DOMAIN_NAME_SERVERS, DHO_HOST_NAME, 0 }; /* client-conf-file :== client-declarations END_OF_FILE client-declarations :== | client-declaration | client-declarations client-declaration */ isc_result_t read_client_conf () { struct client_config *config; struct client_state *state; struct interface_info *ip; isc_result_t status; /* Set up the initial dhcp option universe. */ initialize_common_option_spaces (); /* Initialize the top level client configuration. */ memset (&top_level_config, 0, sizeof top_level_config); /* Set some defaults... */ top_level_config.timeout = 60; top_level_config.select_interval = 0; top_level_config.reboot_timeout = 10; top_level_config.retry_interval = 300; top_level_config.backoff_cutoff = 15; top_level_config.initial_interval = 3; top_level_config.bootp_policy = P_ACCEPT; top_level_config.script_name = path_dhclient_script; top_level_config.requested_options = default_requested_options; top_level_config.omapi_port = -1; top_level_config.do_forward_update = 1; group_allocate (&top_level_config.on_receipt, MDL); if (!top_level_config.on_receipt) log_fatal ("no memory for top-level on_receipt group"); group_allocate (&top_level_config.on_transmission, MDL); if (!top_level_config.on_transmission) log_fatal ("no memory for top-level on_transmission group"); status = read_client_conf_file (path_dhclient_conf, (struct interface_info *)0, &top_level_config); if (status != ISC_R_SUCCESS) { ; #ifdef LATER /* Set up the standard name service updater routine. */ parse = (struct parse *)0; status = new_parse (&parse, -1, default_client_config, (sizeof default_client_config) - 1, "default client configuration", 0); if (status != ISC_R_SUCCESS) log_fatal ("can't begin default client config!"); do { token = peek_token (&val, (unsigned *)0, cfile); if (token == END_OF_FILE) break; parse_client_statement (cfile, (struct interface_info *)0, &top_level_config); } while (1); end_parse (&parse); #endif } /* Set up state and config structures for clients that don't have per-interface configuration statements. */ config = (struct client_config *)0; for (ip = interfaces; ip; ip = ip -> next) { if (!ip -> client) { ip -> client = (struct client_state *) dmalloc (sizeof (struct client_state), MDL); if (!ip -> client) log_fatal ("no memory for client state."); memset (ip -> client, 0, sizeof *(ip -> client)); ip -> client -> interface = ip; } if (!ip -> client -> config) { if (!config) { config = (struct client_config *) dmalloc (sizeof (struct client_config), MDL); if (!config) log_fatal ("no memory for client config."); memcpy (config, &top_level_config, sizeof top_level_config); } ip -> client -> config = config; } } return status; } int read_client_conf_file (const char *name, struct interface_info *ip, struct client_config *client) { int file; struct parse *cfile; const char *val; int token; isc_result_t status; if ((file = open (name, O_RDONLY)) < 0) return uerr2isc (errno); cfile = (struct parse *)0; new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0); do { token = peek_token (&val, (unsigned *)0, cfile); if (token == END_OF_FILE) break; parse_client_statement (cfile, ip, client); } while (1); token = next_token (&val, (unsigned *)0, cfile); status = (cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS); close (file); end_parse (&cfile); return status; } /* lease-file :== client-lease-statements END_OF_FILE client-lease-statements :== | client-lease-statements LEASE client-lease-statement */ void read_client_leases () { int file; struct parse *cfile; const char *val; int token; /* Open the lease file. If we can't open it, just return - we can safely trust the server to remember our state. */ if ((file = open (path_dhclient_db, O_RDONLY)) < 0) return; cfile = (struct parse *)0; new_parse (&cfile, file, (char *)0, 0, path_dhclient_db, 0); do { token = next_token (&val, (unsigned *)0, cfile); if (token == END_OF_FILE) break; if (token != LEASE) { log_error ("Corrupt lease file - possible data loss!"); skip_to_semi (cfile); break; } else parse_client_lease_statement (cfile, 0); } while (1); close (file); end_parse (&cfile); } /* client-declaration :== SEND option-decl | DEFAULT option-decl | SUPERSEDE option-decl | PREPEND option-decl | APPEND option-decl | hardware-declaration | REQUEST option-list | REQUIRE option-list | TIMEOUT number | RETRY number | REBOOT number | SELECT_TIMEOUT number | SCRIPT string | VENDOR_SPACE string | interface-declaration | LEASE client-lease-statement | ALIAS client-lease-statement | KEY key-definition */ void parse_client_statement (cfile, ip, config) struct parse *cfile; struct interface_info *ip; struct client_config *config; { int token; const char *val; struct option *option; struct executable_statement *stmt, **p; enum statement_op op; int lose; char *name; struct data_string key_id; enum policy policy; int known; int tmp, i; isc_result_t status; switch (peek_token (&val, (unsigned *)0, cfile)) { case INCLUDE: next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile); if (token != STRING) { parse_warn (cfile, "filename string expected."); skip_to_semi (cfile); } else { status = read_client_conf_file (val, ip, config); if (status != ISC_R_SUCCESS) parse_warn (cfile, "%s: bad parse.", val); parse_semi (cfile); } return; case KEY: next_token (&val, (unsigned *)0, cfile); if (ip) { /* This may seem arbitrary, but there's a reason for doing it: the authentication key database is not scoped. If we allow the user to declare a key other than in the outer scope, the user is very likely to believe that the key will only be used in that scope. If the user only wants the key to be used on one interface, because it's known that the other interface may be connected to an insecure net and the secret key is considered sensitive, we don't want to lull them into believing they've gotten their way. This is a bit contrived, but people tend not to be entirely rational about security. */ parse_warn (cfile, "key definition not allowed here."); skip_to_semi (cfile); break; } parse_key (cfile); return; /* REQUIRE can either start a policy statement or a comma-seperated list of names of required options. */ case REQUIRE: next_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile); if (token == AUTHENTICATION) { policy = P_REQUIRE; goto do_policy; } parse_option_list (cfile, &config -> required_options); return; case IGNORE: next_token (&val, (unsigned *)0, cfile); policy = P_IGNORE; goto do_policy; case ACCEPT: next_token (&val, (unsigned *)0, cfile); policy = P_ACCEPT; goto do_policy; case PREFER: next_token (&val, (unsigned *)0, cfile); policy = P_PREFER; goto do_policy; case DONT: next_token (&val, (unsigned *)0, cfile); policy = P_DONT; goto do_policy; do_policy: token = next_token (&val, (unsigned *)0, cfile); if (token == AUTHENTICATION) { if (policy != P_PREFER && policy != P_REQUIRE && policy != P_DONT) { parse_warn (cfile, "invalid authentication policy."); skip_to_semi (cfile); return; } config -> auth_policy = policy; } else if (token != TOKEN_BOOTP) { if (policy != P_PREFER && policy != P_IGNORE && policy != P_ACCEPT) { parse_warn (cfile, "invalid bootp policy."); skip_to_semi (cfile); return; } config -> bootp_policy = policy; } else { parse_warn (cfile, "expecting a policy type."); skip_to_semi (cfile); return; } break; case OPTION: token = next_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile); if (token == SPACE) { if (ip) { parse_warn (cfile, "option space definitions %s", " may not be scoped."); skip_to_semi (cfile); break; } parse_option_space_decl (cfile); return; } option = parse_option_name (cfile, 1, &known); if (!option) return; token = next_token (&val, (unsigned *)0, cfile); if (token != CODE) { parse_warn (cfile, "expecting \"code\" keyword."); skip_to_semi (cfile); free_option (option, MDL); return; } if (ip) { parse_warn (cfile, "option definitions may only appear in %s", "the outermost scope."); skip_to_semi (cfile); free_option (option, MDL); return; } if (!parse_option_code_definition (cfile, option)) free_option (option, MDL); return; case MEDIA: token = next_token (&val, (unsigned *)0, cfile); parse_string_list (cfile, &config -> media, 1); return; case HARDWARE: token = next_token (&val, (unsigned *)0, cfile); if (ip) { parse_hardware_param (cfile, &ip -> hw_address); } else { parse_warn (cfile, "hardware address parameter %s", "not allowed here."); skip_to_semi (cfile); } return; case REQUEST: token = next_token (&val, (unsigned *)0, cfile); if (config -> requested_options == default_requested_options) config -> requested_options = (u_int32_t *)0; parse_option_list (cfile, &config -> requested_options); return; case TIMEOUT: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> timeout); return; case RETRY: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> retry_interval); return; case SELECT_TIMEOUT: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> select_interval); return; case OMAPI: token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile); if (token != PORT) { parse_warn (cfile, "unexpected omapi subtype: %s", val); skip_to_semi (cfile); return; } token = next_token (&val, (unsigned *)0, cfile); if (token != NUMBER) { parse_warn (cfile, "invalid port number: `%s'", val); skip_to_semi (cfile); return; } tmp = atoi (val); if (tmp < 0 || tmp > 65535) parse_warn (cfile, "invalid omapi port %d.", tmp); else if (config != &top_level_config) parse_warn (cfile, "omapi port only works at top level."); else config -> omapi_port = tmp; parse_semi (cfile); return; case DO_FORWARD_UPDATE: token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile); if (!strcasecmp (val, "on") || !strcasecmp (val, "true")) config -> do_forward_update = 1; else if (!strcasecmp (val, "off") || !strcasecmp (val, "false")) config -> do_forward_update = 0; else { parse_warn (cfile, "expecting boolean value."); skip_to_semi (cfile); return; } parse_semi (cfile); return; case REBOOT: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> reboot_timeout); return; case BACKOFF_CUTOFF: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> backoff_cutoff); return; case INITIAL_INTERVAL: token = next_token (&val, (unsigned *)0, cfile); parse_lease_time (cfile, &config -> initial_interval); return; case SCRIPT: token = next_token (&val, (unsigned *)0, cfile); parse_string (cfile, &config -> script_name, (unsigned *)0); return; case VENDOR: token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile); if (token != OPTION) { parse_warn (cfile, "expecting 'vendor option space'"); skip_to_semi (cfile); return; } token = next_token (&val, (unsigned *)0, cfile); if (token != SPACE) { parse_warn (cfile, "expecting 'vendor option space'"); skip_to_semi (cfile); return; } token = next_token (&val, (unsigned *)0, cfile); if (!is_identifier (token)) { parse_warn (cfile, "expecting an identifier."); skip_to_semi (cfile); return; } config -> vendor_space_name = dmalloc (strlen (val) + 1, MDL); if (!config -> vendor_space_name) log_fatal ("no memory for vendor option space name."); strcpy (config -> vendor_space_name, val); for (i = 0; i < universe_count; i++) if (!strcmp (universes [i] -> name, config -> vendor_space_name)) break; if (i == universe_count) { log_error ("vendor option space %s not found.", config -> vendor_space_name); } parse_semi (cfile); return; case INTERFACE: token = next_token (&val, (unsigned *)0, cfile); if (ip) parse_warn (cfile, "nested interface declaration."); parse_interface_declaration (cfile, config, (char *)0); return; case PSEUDO: token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile); name = dmalloc (strlen (val) + 1, MDL); if (!name) log_fatal ("no memory for pseudo interface name"); strcpy (name, val); parse_interface_declaration (cfile, config, name); return; case LEASE: token = next_token (&val, (unsigned *)0, cfile); parse_client_lease_statement (cfile, 1); return; case ALIAS: token = next_token (&val, (unsigned *)0, cfile); parse_client_lease_statement (cfile, 2); return; case REJECT: token = next_token (&val, (unsigned *)0, cfile); parse_reject_statement (cfile, config); return; default: lose = 0; stmt = (struct executable_statement *)0; if (!parse_executable_statement (&stmt, cfile, &lose, context_any)) { if (!lose) { parse_warn (cfile, "expecting a statement."); skip_to_semi (cfile); } } else { struct executable_statement **eptr, *sptr; if (stmt && (stmt -> op == send_option_statement || (stmt -> op == on_statement && (stmt -> data.on.evtypes & ON_TRANSMISSION)))) { eptr = &config -> on_transmission -> statements; if (stmt -> op == on_statement) { sptr = (struct executable_statement *)0; executable_statement_reference (&sptr, stmt -> data.on.statements, MDL); executable_statement_dereference (&stmt, MDL); executable_statement_reference (&stmt, sptr, MDL); executable_statement_dereference (&sptr, MDL); } } else eptr = &config -> on_receipt -> statements; if (stmt) { for (; *eptr; eptr = &(*eptr) -> next) ; executable_statement_reference (eptr, stmt, MDL); } return; } break; } parse_semi (cfile); } /* option-list :== option_name | option_list COMMA option_name */ void parse_option_list (cfile, list) struct parse *cfile; u_int32_t **list; { int ix; int token; const char *val; pair p = (pair)0, q, r; struct option *option; ix = 0; do { token = peek_token (&val, (unsigned *)0, cfile); if (token == SEMI) { token = next_token (&val, (unsigned *)0, cfile); break; } if (!is_identifier (token)) { parse_warn (cfile, "%s: expected option name.", val); token = next_token (&val, (unsigned *)0, cfile); skip_to_semi (cfile); return; } option = parse_option_name (cfile, 0, NULL); if (!option) { parse_warn (cfile, "%s: expected option name.", val); return; } if (option -> universe != &dhcp_universe) { parse_warn (cfile, "%s.%s: Only global options allowed.", option -> universe -> name, option->name ); skip_to_semi (cfile); return; } r = new_pair (MDL); if (!r) log_fatal ("can't allocate pair for option code."); r -> car = (caddr_t)(long)option -> code; r -> cdr = (pair)0; if (p) q -> cdr = r; else p = r; q = r; ++ix; token = next_token (&val, (unsigned *)0, cfile); } while (token == COMMA); if (token != SEMI) { parse_warn (cfile, "expecting semicolon."); skip_to_semi (cfile); return; } /* XXX we can't free the list here, because we may have copied XXX it from an outer config state. */ *list = (u_int32_t *)0; if (ix) { *list = dmalloc ((ix + 1) * sizeof **list, MDL); if (!*list) log_error ("no memory for option list."); else { ix = 0; for (q = p; q; q = q -> cdr) (*list) [ix++] = (u_int32_t)(long)q -> car; (*list) [ix] = 0; } while (p) { q = p -> cdr; free_pair (p, MDL); p = q; } } } /* interface-declaration :== INTERFACE string LBRACE client-declarations RBRACE */ void parse_interface_declaration (cfile, outer_config, name) struct parse *cfile; struct client_config *outer_config; char *name; { int token; const char *val; struct client_state *client, **cp; struct interface_info *ip = (struct interface_info *)0; token = next_token (&val, (unsigned *)0, cfile); if (token != STRING) { parse_warn (cfile, "expecting interface name (in quotes)."); skip_to_semi (cfile); return; } if (!interface_or_dummy (&ip, val)) log_fatal ("Can't allocate interface %s.", val); /* If we were given a name, this is a pseudo-interface. */ if (name) { make_client_state (&client); client -> name = name; client -> interface = ip; for (cp = &ip -> client; *cp; cp = &((*cp) -> next)) ; *cp = client; } else { if (!ip -> client) { make_client_state (&ip -> client); ip -> client -> interface = ip; } client = ip -> client; } if (!client -> config) make_client_config (client, outer_config); ip -> flags &= ~INTERFACE_AUTOMATIC; interfaces_requested = 1; token = next_token (&val, (unsigned *)0, cfile); if (token != LBRACE) { parse_warn (cfile, "expecting left brace."); skip_to_semi (cfile); return; } do { token = peek_token (&val, (unsigned *)0, cfile); if (token == END_OF_FILE) { parse_warn (cfile, "unterminated interface declaration."); return; } if (token == RBRACE) break; parse_client_statement (cfile, ip, client -> config); } while (1); token = next_token (&val, (unsigned *)0, cfile); } int interface_or_dummy (struct interface_info **pi, const char *name) { struct interface_info *i; struct interface_info *ip = (struct interface_info *)0; isc_result_t status; /* Find the interface (if any) that matches the name. */ for (i = interfaces; i; i = i -> next) { if (!strcmp (i -> name, name)) { interface_reference (&ip, i, MDL); break; } } /* If it's not a real interface, see if it's on the dummy list. */ if (!ip) { for (ip = dummy_interfaces; ip; ip = ip -> next) { if (!strcmp (ip -> name, name)) { interface_reference (&ip, i, MDL); break; } } } /* If we didn't find an interface, make a dummy interface as a placeholder. */ if (!ip) { isc_result_t status; status = interface_allocate (&ip, MDL); if (status != ISC_R_SUCCESS) log_fatal ("Can't record interface %s: %s", name, isc_result_totext (status)); strlcpy (ip -> name, name, IFNAMSIZ); if (dummy_interfaces) { interface_reference (&ip -> next, dummy_interfaces, MDL); interface_dereference (&dummy_interfaces, MDL); } interface_reference (&dummy_interfaces, ip, MDL); } if (pi) status = interface_reference (pi, ip, MDL); interface_dereference (&ip, MDL); if (status != ISC_R_SUCCESS) return 0; return 1; } void make_client_state (state) struct client_state **state; { *state = ((struct client_state *)dmalloc (sizeof **state, MDL)); if (!*state) log_fatal ("no memory for client state\n"); memset (*state, 0, sizeof **state); } void make_client_config (client, config) struct client_state *client; struct client_config *config; { client -> config = (((struct client_config *) dmalloc (sizeof (struct client_config), MDL))); if (!client -> config) log_fatal ("no memory for client config\n"); memcpy (client -> config, config, sizeof *config); if (!clone_group (&client -> config -> on_receipt, config -> on_receipt, MDL) || !clone_group (&client -> config -> on_transmission, config -> on_transmission, MDL)) log_fatal ("no memory for client state groups."); } /* client-lease-statement :== RBRACE client-lease-declarations LBRACE client-lease-declarations :== | client-lease-declaration | client-lease-declarations client-lease-declaration */ void parse_client_lease_statement (cfile, is_static) struct parse *cfile; int is_static; { - struct client_lease *lease, *lp, *pl; + struct client_lease *lease, *lp, *pl, *next; struct interface_info *ip = (struct interface_info *)0; int token; const char *val; struct client_state *client = (struct client_state *)0; token = next_token (&val, (unsigned *)0, cfile); if (token != LBRACE) { parse_warn (cfile, "expecting left brace."); skip_to_semi (cfile); return; } lease = ((struct client_lease *) dmalloc (sizeof (struct client_lease), MDL)); if (!lease) log_fatal ("no memory for lease.\n"); memset (lease, 0, sizeof *lease); lease -> is_static = is_static; if (!option_state_allocate (&lease -> options, MDL)) log_fatal ("no memory for lease options.\n"); do { token = peek_token (&val, (unsigned *)0, cfile); if (token == END_OF_FILE) { parse_warn (cfile, "unterminated lease declaration."); return; } if (token == RBRACE) break; parse_client_lease_declaration (cfile, lease, &ip, &client); } while (1); token = next_token (&val, (unsigned *)0, cfile); /* If the lease declaration didn't include an interface declaration that we recognized, it's of no use to us. */ if (!ip) { destroy_client_lease (lease); return; } /* Make sure there's a client state structure... */ if (!ip -> client) { make_client_state (&ip -> client); ip -> client -> interface = ip; } if (!client) client = ip -> client; /* If this is an alias lease, it doesn't need to be sorted in. */ if (is_static == 2) { ip -> client -> alias = lease; return; } /* The new lease may supersede a lease that's not the active lease but is still on the lease list, so scan the lease list looking for a lease with the same address, and if we find it, toss it. */ pl = (struct client_lease *)0; - for (lp = client -> leases; lp; lp = lp -> next) { + for (lp = client -> leases; lp; lp = next) { + next = lp -> next; if (lp -> address.len == lease -> address.len && !memcmp (lp -> address.iabuf, lease -> address.iabuf, lease -> address.len)) { if (pl) - pl -> next = lp -> next; + pl -> next = next; else - client -> leases = lp -> next; + client -> leases = next; destroy_client_lease (lp); break; - } + } else + pl = lp; } /* If this is a preloaded lease, just put it on the list of recorded leases - don't make it the active lease. */ if (is_static) { lease -> next = client -> leases; client -> leases = lease; return; } /* The last lease in the lease file on a particular interface is the active lease for that interface. Of course, we don't know what the last lease in the file is until we've parsed the whole file, so at this point, we assume that the lease we just parsed is the active lease for its interface. If there's already an active lease for the interface, and this lease is for the same ip address, then we just toss the old active lease and replace it with this one. If this lease is for a different address, then if the old active lease has expired, we dump it; if not, we put it on the list of leases for this interface which are still valid but no longer active. */ if (client -> active) { if (client -> active -> expiry < cur_time) destroy_client_lease (client -> active); else if (client -> active -> address.len == lease -> address.len && !memcmp (client -> active -> address.iabuf, lease -> address.iabuf, lease -> address.len)) destroy_client_lease (client -> active); else { client -> active -> next = client -> leases; client -> leases = client -> active; } } client -> active = lease; /* phew. */ } /* client-lease-declaration :== BOOTP | INTERFACE string | FIXED_ADDR ip_address | FILENAME string | SERVER_NAME string | OPTION option-decl | RENEW time-decl | REBIND time-decl | EXPIRE time-decl | KEY id */ void parse_client_lease_declaration (cfile, lease, ipp, clientp) struct parse *cfile; struct client_lease *lease; struct interface_info **ipp; struct client_state **clientp; { int token; const char *val; char *t, *n; struct interface_info *ip; struct option_cache *oc; struct client_state *client = (struct client_state *)0; struct data_string key_id; switch (next_token (&val, (unsigned *)0, cfile)) { case KEY: token = next_token (&val, (unsigned *)0, cfile); if (token != STRING && !is_identifier (token)) { parse_warn (cfile, "expecting key name."); skip_to_semi (cfile); break; } if (omapi_auth_key_lookup_name (&lease -> key, val) != ISC_R_SUCCESS) parse_warn (cfile, "unknown key %s", val); parse_semi (cfile); break; case TOKEN_BOOTP: lease -> is_bootp = 1; break; case INTERFACE: token = next_token (&val, (unsigned *)0, cfile); if (token != STRING) { parse_warn (cfile, "expecting interface name (in quotes)."); skip_to_semi (cfile); break; } interface_or_dummy (ipp, val); break; case NAME: token = next_token (&val, (unsigned *)0, cfile); ip = *ipp; if (!ip) { parse_warn (cfile, "state name precedes interface."); break; } for (client = ip -> client; client; client = client -> next) if (client -> name && !strcmp (client -> name, val)) break; if (!client) parse_warn (cfile, "lease specified for unknown pseudo."); *clientp = client; break; case FIXED_ADDR: if (!parse_ip_addr (cfile, &lease -> address)) return; break; case MEDIUM: parse_string_list (cfile, &lease -> medium, 0); return; case FILENAME: parse_string (cfile, &lease -> filename, (unsigned *)0); return; case SERVER_NAME: parse_string (cfile, &lease -> server_name, (unsigned *)0); return; case RENEW: lease -> renewal = parse_date (cfile); return; case REBIND: lease -> rebind = parse_date (cfile); return; case EXPIRE: lease -> expiry = parse_date (cfile); return; case OPTION: oc = (struct option_cache *)0; if (parse_option_decl (&oc, cfile)) { save_option (oc -> option -> universe, lease -> options, oc); option_cache_dereference (&oc, MDL); } return; default: parse_warn (cfile, "expecting lease declaration."); skip_to_semi (cfile); break; } token = next_token (&val, (unsigned *)0, cfile); if (token != SEMI) { parse_warn (cfile, "expecting semicolon."); skip_to_semi (cfile); } } void parse_string_list (cfile, lp, multiple) struct parse *cfile; struct string_list **lp; int multiple; { int token; const char *val; struct string_list *cur, *tmp; /* Find the last medium in the media list. */ if (*lp) { for (cur = *lp; cur -> next; cur = cur -> next) ; } else { cur = (struct string_list *)0; } do { token = next_token (&val, (unsigned *)0, cfile); if (token != STRING) { parse_warn (cfile, "Expecting media options."); skip_to_semi (cfile); return; } tmp = ((struct string_list *) dmalloc (strlen (val) + sizeof (struct string_list), MDL)); if (!tmp) log_fatal ("no memory for string list entry."); strcpy (tmp -> string, val); tmp -> next = (struct string_list *)0; /* Store this medium at the end of the media list. */ if (cur) cur -> next = tmp; else *lp = tmp; cur = tmp; token = next_token (&val, (unsigned *)0, cfile); } while (multiple && token == COMMA); if (token != SEMI) { parse_warn (cfile, "expecting semicolon."); skip_to_semi (cfile); } } void parse_reject_statement (cfile, config) struct parse *cfile; struct client_config *config; { int token; const char *val; struct iaddr addr; struct iaddrlist *list; do { if (!parse_ip_addr (cfile, &addr)) { parse_warn (cfile, "expecting IP address."); skip_to_semi (cfile); return; } list = (struct iaddrlist *)dmalloc (sizeof (struct iaddrlist), MDL); if (!list) log_fatal ("no memory for reject list!"); list -> addr = addr; list -> next = config -> reject_list; config -> reject_list = list; token = next_token (&val, (unsigned *)0, cfile); } while (token == COMMA); if (token != SEMI) { parse_warn (cfile, "expecting semicolon."); skip_to_semi (cfile); } } /* allow-deny-keyword :== BOOTP | BOOTING | DYNAMIC_BOOTP | UNKNOWN_CLIENTS */ int parse_allow_deny (oc, cfile, flag) struct option_cache **oc; struct parse *cfile; int flag; { enum dhcp_token token; const char *val; unsigned char rf = flag; struct expression *data = (struct expression *)0; int status; parse_warn (cfile, "allow/deny/ignore not permitted here."); skip_to_semi (cfile); return 0; } Index: head/contrib/isc-dhcp/client/dhclient-script.8 =================================================================== --- head/contrib/isc-dhcp/client/dhclient-script.8 (revision 131139) +++ head/contrib/isc-dhcp/client/dhclient-script.8 (revision 131140) @@ -1,228 +1,221 @@ .\" dhclient-script.8 .\" -.\" Copyright (c) 1996-2002 Internet Software Consortium. -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: +.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of The Internet Software Consortium nor the names -.\" of its contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. +.\" 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. .\" -.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND -.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR -.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. +.\" 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. .\" -.\" This software has been written for the Internet Software Consortium +.\" Internet Systems Consortium, Inc. +.\" 950 Charter Street +.\" Redwood City, CA 94063 +.\" +.\" 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 the Internet Software Consortium, see +.\" 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: dhclient-script.8,v 1.8.2.4 2002/11/17 02:25:43 dhankins Exp $ .\" $FreeBSD$ .\" .TH dhclient-script 8 .SH NAME dhclient-script - DHCP client network configuration script .SH DESCRIPTION The DHCP client network configuration script is invoked from time to time by \fBdhclient(8)\fR. This script is used by the dhcp client to set each interface's initial configuration prior to requesting an address, to test the address once it has been offered, and to set the interface's final configuration once a lease has been acquired. If no lease is acquired, the script is used to test predefined leases, if any, and also called once if no valid lease can be identified. .PP This script is not meant to be customized by the end user. If local customizations are needed, they should be possible using the enter and exit hooks provided (see HOOKS for details). These hooks will allow the user to override the default behaviour of the client in creating a .B /etc/resolv.conf file. .PP No standard client script exists for some operating systems, even though the actual client may work, so a pioneering user may well need to create a new script or modify an existing one. In general, customizations specific to a particular computer should be done in the .B ETCDIR/dhclient.conf file. If you find that you can't make such a customization without customizing .B ETCDIR/dhclient.conf or using the enter and exit hooks, please submit a bug report. .SH HOOKS When it starts, the client script first defines a shell function, .B make_resolv_conf , which is later used to create the .B /etc/resolv.conf file. To override the default behaviour, redefine this function in the enter hook script. .PP On after defining the make_resolv_conf function, the client script checks for the presence of an executable .B ETCDIR/dhclient-enter-hooks script, and if present, it invokes the script inline, using the Bourne shell '.' command. The entire environment documented under OPERATION is available to this script, which may modify the environment if needed to change the behaviour of the script. If an error occurs during the execution of the script, it can set the exit_status variable to a nonzero value, and .B CLIENTBINDIR/dhclient-script will exit with that error code immediately after the client script exits. .PP After all processing has completed, .B CLIENTBINDIR/dhclient-script checks for the presence of an executable .B ETCDIR/dhclient-exit-hooks script, which if present is invoked using the '.' command. The exit status of dhclient-script will be passed to dhclient-exit-hooks in the exit_status shell variable, and will always be zero if the script succeeded at the task for which it was invoked. The rest of the environment as described previously for dhclient-enter-hooks is also present. The .B ETCDIR/dhclient-exit-hooks script can modify the valid of exit_status to change the exit status of dhclient-script. .SH OPERATION When dhclient needs to invoke the client configuration script, it defines a set of variables in the environment, and then invokes .B CLIENTBINDIR/dhclient-script. In all cases, $reason is set to the name of the reason why the script has been invoked. The following reasons are currently defined: MEDIUM, PREINIT, BOUND, RENEW, REBIND, REBOOT, EXPIRE, FAIL and TIMEOUT. .PP .SH MEDIUM The DHCP client is requesting that an interface's media type be set. The interface name is passed in $interface, and the media type is passed in $medium. .SH PREINIT The DHCP client is requesting that an interface be configured as required in order to send packets prior to receiving an actual address. For clients which use the BSD socket library, this means configuring the interface with an IP address of 0.0.0.0 and a broadcast address of 255.255.255.255. For other clients, it may be possible to simply configure the interface up without actually giving it an IP address at all. The interface name is passed in $interface, and the media type in $medium. .PP If an IP alias has been declared in dhclient.conf, its address will be passed in $alias_ip_address, and that ip alias should be deleted from the interface, along with any routes to it. .SH BOUND The DHCP client has done an initial binding to a new address. The new ip address is passed in $new_ip_address, and the interface name is passed in $interface. The media type is passed in $medium. Any options acquired from the server are passed using the option name described in \fBdhcp-options\fR, except that dashes ('-') are replaced by underscores ('_') in order to make valid shell variables, and the variable names start with new_. So for example, the new subnet mask would be passed in $new_subnet_mask. .PP Before actually configuring the address, dhclient-script should somehow ARP for it and exit with a nonzero status if it receives a reply. In this case, the client will send a DHCPDECLINE message to the server and acquire a different address. This may also be done in the RENEW, REBIND, or REBOOT states, but is not required, and indeed may not be desirable. .PP When a binding has been completed, a lot of network parameters are likely to need to be set up. A new /etc/resolv.conf needs to be created, using the values of $new_domain_name and $new_domain_name_servers (which may list more than one server, separated by spaces). A default route should be set using $new_routers, and static routes may need to be set up using $new_static_routes. .PP If an IP alias has been declared, it must be set up here. The alias IP address will be written as $alias_ip_address, and other DHCP options that are set for the alias (e.g., subnet mask) will be passed in variables named as described previously except starting with $alias_ instead of $new_. Care should be taken that the alias IP address not be used if it is identical to the bound IP address ($new_ip_address), since the other alias parameters may be incorrect in this case. .SH RENEW When a binding has been renewed, the script is called as in BOUND, except that in addition to all the variables starting with $new_, there is another set of variables starting with $old_. Persistent settings that may have changed need to be deleted - for example, if a local route to the bound address is being configured, the old local route should be deleted. If the default route has changed, the old default route should be deleted. If the static routes have changed, the old ones should be deleted. Otherwise, processing can be done as with BOUND. .SH REBIND The DHCP client has rebound to a new DHCP server. This can be handled as with RENEW, except that if the IP address has changed, the ARP table should be cleared. .SH REBOOT The DHCP client has successfully reacquired its old address after a reboot. This can be processed as with BOUND. .SH EXPIRE The DHCP client has failed to renew its lease or acquire a new one, and the lease has expired. The IP address must be relinquished, and all related parameters should be deleted, as in RENEW and REBIND. .SH FAIL The DHCP client has been unable to contact any DHCP servers, and any leases that have been tested have not proved to be valid. The parameters from the last lease tested should be deconfigured. This can be handled in the same way as EXPIRE. .SH TIMEOUT The DHCP client has been unable to contact any DHCP servers. However, an old lease has been identified, and its parameters have been passed in as with BOUND. The client configuration script should test these parameters and, if it has reason to believe they are valid, should exit with a value of zero. If not, it should exit with a nonzero value. .PP The usual way to test a lease is to set up the network as with REBIND (since this may be called to test more than one lease) and then ping the first router defined in $routers. If a response is received, the lease must be valid for the network to which the interface is currently connected. It would be more complete to try to ping all of the routers listed in $new_routers, as well as those listed in $new_static_routes, but current scripts do not do this. .SH FILES Each operating system should generally have its own script file, although the script files for similar operating systems may be similar -or even identical. The script files included in the Internet -Software Consortium DHCP distribution appear in the distribution tree +or even identical. The script files included in Internet +Systems Consortium DHCP distribution appear in the distribution tree under client/scripts, and bear the names of the operating systems on which they are intended to work. .SH BUGS If more than one interface is being used, there's no obvious way to avoid clashes between server-supplied configuration parameters - for example, the stock dhclient-script rewrites /etc/resolv.conf. If more than one interface is being configured, /etc/resolv.conf will be repeatedly initialized to the values provided by one server, and then the other. Assuming the information provided by both servers is valid, this shouldn't cause any real problems, but it could be confusing. .SH SEE ALSO dhclient.conf(5), dhclient.leases(5), dhclient(8). .SH AUTHOR .B dhclient-script(8) -has been written for the Internet Software Consortium +has been written for Internet Systems Consortium by Ted Lemon in cooperation with Vixie -Enterprises. To learn more about the Internet Software Consortium, +Enterprises. To learn more about Internet Systems Consortium, see .B http://www.isc.org. To learn more about Vixie Enterprises, see .B http://www.vix.com. Index: head/contrib/isc-dhcp/client/dhclient.8 =================================================================== --- head/contrib/isc-dhcp/client/dhclient.8 (revision 131139) +++ head/contrib/isc-dhcp/client/dhclient.8 (revision 131140) @@ -1,346 +1,351 @@ .\" dhclient.8 .\" -.\" Copyright (c) 1996-2002 Internet Software Consortium. -.\" Use is subject to license terms which appear in the file named -.\" ISC-LICENSE that should have accompanied this file when you -.\" received it. If a file named ISC-LICENSE did not accompany this -.\" file, or you are not sure the one you have is correct, you may -.\" obtain an applicable copy of the license at: +.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" -.\" http://www.isc.org/isc-license-1.0.html. +.\" 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. .\" -.\" This file is part of the ISC DHCP distribution. The documentation -.\" associated with this file is listed in the file DOCUMENTATION, -.\" included in the top-level directory of this release. +.\" 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. .\" -.\" Support and other services are available for ISC products - see -.\" http://www.isc.org for more information. +.\" Internet Systems Consortium, Inc. +.\" 950 Charter Street +.\" Redwood City, CA 94063 +.\" +.\" http://www.isc.org/ .\" -.\" $Id: dhclient.8,v 1.12.2.7 2002/11/17 02:25:43 dhankins Exp $ +.\" $Id: dhclient.8,v 1.12.2.8 2004/06/10 17:59:12 dhankins Exp $ .\" .\" Portions copyright (c) 2000 David E. O'Brien. .\" All rights reserved. .\" $FreeBSD$ .\" .TH dhclient 8 .SH NAME dhclient - Dynamic Host Configuration Protocol Client .SH SYNOPSIS .B dhclient [ .B -p .I port ] [ .B -D ] [ .B -d ] [ .B -q ] [ .B -v ] [ .B -1 ] [ .B -r ] [ .B -lf .I lease-file ] [ .B -pf .I pid-file ] [ .B -cf .I config-file ] [ .B -sf .I script-file ] [ .B -s server ] [ .B -g relay ] [ .B -i interval ] [ .B -n ] [ .B -nw ] [ .B -w ] [ .I if0 [ .I ...ifN ] ] .SH DESCRIPTION -The Internet Software Consortium DHCP Client, dhclient, provides a +The Internet Systems Consortium DHCP Client, dhclient, provides a means for configuring one or more network interfaces using the Dynamic Host Configuration Protocol, BOOTP protocol, or if these protocols fail, by statically assigning an address. .SH OPERATION .PP The DHCP protocol allows a host to contact a central server which maintains a list of IP addresses which may be assigned on one or more subnets. A DHCP client may request an address from this pool, and then use it on a temporary basis for communication on network. The DHCP protocol also provides a mechanism whereby a client can learn important details about the network to which it is attached, such as the location of a default router, the location of a name server, and so on. .PP On startup, dhclient reads the .IR dhclient.conf for configuration instructions. It then gets a list of all the network interfaces that are configured in the current system. For each interface, it attempts to configure the interface using the DHCP protocol. .PP In order to keep track of leases across system reboots and server restarts, dhclient keeps a list of leases it has been assigned in the dhclient.leases(5) file. On startup, after reading the dhclient.conf file, dhclient reads the dhclient.leases file to refresh its memory about what leases it has been assigned. .PP When a new lease is acquired, it is appended to the end of the dhclient.leases file. In order to prevent the file from becoming arbitrarily large, from time to time dhclient creates a new dhclient.leases file from its in-core lease database. The old version of the dhclient.leases file is retained under the name .IR dhclient.leases~ until the next time dhclient rewrites the database. .PP Old leases are kept around in case the DHCP server is unavailable when dhclient is first invoked (generally during the initial system boot process). In that event, old leases from the dhclient.leases file which have not yet expired are tested, and if they are determined to be valid, they are used until either they expire or the DHCP server becomes available. .PP A mobile host which may sometimes need to access a network on which no DHCP server exists may be preloaded with a lease for a fixed address on that network. When all attempts to contact a DHCP server have failed, dhclient will try to validate the static lease, and if it succeeds, will use that lease until it is restarted. .PP A mobile host may also travel to some networks on which DHCP is not available but BOOTP is. In that case, it may be advantageous to arrange with the network administrator for an entry on the BOOTP database, so that the host can boot quickly on that network rather than cycling through the list of old leases. .SH COMMAND LINE .PP The names of the network interfaces that dhclient should attempt to configure may be specified on the command line. If no interface names are specified on the command line dhclient will normally identify all network interfaces, eliminating non-broadcast interfaces if possible, and attempt to configure each interface. .PP It is also possible to specify interfaces by name in the .B dhclient.conf(5) file. If interfaces are specified in this way, then the client will only configure interfaces that are either specified in the configuration file or on the command line, and will ignore all other interfaces. .PP The .B -D flag causes .B dhclient to save the script it creates for use in conjunction with .B dhclient-script in .IR /tmp. .PP If the DHCP client should listen and transmit on a port other than the standard (port 68), the .B -p flag may used. It should be followed by the udp port number that dhclient should use. This is mostly useful for debugging purposes. If a different port is specified for the client to listen on and transmit on, the client will also use a different destination port - one greater than the specified destination port. .PP The DHCP client normally transmits any protocol messages it sends before acquiring an IP address to, 255.255.255.255, the IP limited broadcast address. For debugging purposes, it may be useful to have the server transmit these messages to some other address. This can be specified with the .B -s flag, followed by the IP address or domain name of the destination. .PP For testing purposes, the giaddr field of all packets that the client sends can be set using the .B -g flag, followed by the IP address to send. This is only useful for testing, and should not be expected to work in any consistent or useful way. .PP On FreeBSD, dhclient can be enabled to automatically handle the link status of the network card. Normally polling is done every five seconds. The polling interval can be set using the .B -i flag, followed by the numbers of seconds. Minimum is one second. .PP The DHCP client will normally run in the foreground until it has configured an interface, and then will revert to running in the background. To run force dhclient to always run as a foreground process, the .B -d flag should be specified. This is useful when running the client under a debugger, or when running it out of inittab on System V systems. .PP The client normally prints a startup message and displays the protocol sequence to the standard error descriptor until it has acquired an address, and then only logs messages using the .B syslog (3) facility. The .B -q flag prevents any messages other than errors from being printed to the standard error descriptor. .B -v flag turns on all messages. Opposite of .B -q . .PP The client normally doesn't release the current lease as it is not required by the DHCP protocol. Some cable ISPs require their clients to notify the server if they wish to release an assigned IP address. The .B -r flag explicitly releases the current lease, and once the lease has been released, the client exits. .PP The .B -1 flag cause dhclient to try once to get a lease. If it fails, dhclient exits with exit code two. .PP The DHCP client normally gets its configuration information from .B ETCDIR/dhclient.conf, its lease database from .B DBDIR/dhclient.leases, stores its process ID in a file called .B RUNDIR/dhclient.pid, and configures the network interface using .B CLIENTBINDIR/dhclient-script To specify different names and/or locations for these files, use the .B -cf, .B -lf, .B -pf and .B -sf flags, respectively, followed by the name of the file. This can be particularly useful if, for example, .B DBDIR or .B RUNDIR has not yet been mounted when the DHCP client is started. .PP The DHCP client normally exits if it isn't able to identify any network interfaces to configure. On laptop computers and other computers with hot-swappable I/O buses, it is possible that a broadcast interface may be added after system startup. The .B -w flag can be used to cause the client not to exit when it doesn't find any such interfaces. The .B omshell (8) program can then be used to notify the client when a network interface has been added or removed, so that the client can attempt to configure an IP address on that interface. .PP The DHCP client can be directed not to attempt to configure any interfaces using the .B -n flag. This is most likely to be useful in combination with the .B -w flag. .PP The client can also be instructed to become a daemon immediately, rather than waiting until it has acquired an IP address. This can be done by supplying the .B -nw flag. .SH CONFIGURATION The syntax of the dhclient.conf(5) file is discussed separately. .SH OMAPI The DHCP client provides some ability to control it while it is running, without stopping it. This capability is provided using OMAPI, an API for manipulating remote objects. OMAPI clients connect to the client using TCP/IP, authenticate, and can then examine the client's current status and make changes to it. .PP Rather than implementing the underlying OMAPI protocol directly, user programs should use the dhcpctl API or OMAPI itself. Dhcpctl is a wrapper that handles some of the housekeeping chores that OMAPI does not do automatically. Dhcpctl and OMAPI are documented in \fBdhcpctl(3)\fR and \fBomapi(3)\fR. Most things you'd want to do with the client can be done directly using the \fBomshell(1)\fR command, rather than having to write a special program. .SH THE CONTROL OBJECT The control object allows you to shut the client down, releasing all leases that it holds and deleting any DNS records it may have added. It also allows you to pause the client - this unconfigures any interfaces the client is using. You can then restart it, which causes it to reconfigure those interfaces. You would normally pause the client prior to going into hibernation or sleep on a laptop computer. You would then resume it after the power comes back. This allows PC cards to be shut down while the computer is hibernating or sleeping, and then reinitialized to their previous state once the computer comes out of hibernation or sleep. .PP The control object has one attribute - the state attribute. To shut the client down, set its state attribute to 2. It will automatically do a DHCPRELEASE. To pause it, set its state attribute to 3. To resume it, set its state attribute to 4. .PP .SH FILES .B CLIENTBINDIR/dhclient-script, .B ETCDIR/dhclient.conf, DBDIR/dhclient.leases, RUNDIR/dhclient.pid, .B DBDIR/dhclient.leases~. .SH SEE ALSO dhclient.conf(5), dhclient.leases(5), dhclient-script(8). .SH AUTHOR .B dhclient(8) -has been written for the Internet Software Consortium +has been written for Internet Systems Consortium by Ted Lemon in cooperation with Vixie -Enterprises. To learn more about the Internet Software Consortium, +Enterprises. To learn more about Internet Systems Consortium, see .B http://www.isc.org To learn more about Vixie Enterprises, see .B http://www.vix.com. .PP This client was substantially modified and enhanced by Elliot Poger for use on Linux while he was working on the MosquitoNet project at Stanford. .PP The current version owes much to Elliot's Linux enhancements, but was substantially reorganized and partially rewritten by Ted Lemon -so as to use the same networking framework that the Internet Software +so as to use the same networking framework that the Internet Systems Consortium DHCP server uses. Much system-specific configuration code was moved into a shell script so that as support for more operating systems is added, it will not be necessary to port and maintain system-specific configuration code to these operating systems - instead, the shell script can invoke the native tools to accomplish the same purpose. .PP Index: head/contrib/isc-dhcp/client/dhclient.c =================================================================== --- head/contrib/isc-dhcp/client/dhclient.c (revision 131139) +++ head/contrib/isc-dhcp/client/dhclient.c (revision 131140) @@ -1,3536 +1,3542 @@ /* dhclient.c DHCP Client. */ /* - * Copyright (c) 1995-2002 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1995-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * * This code is based on the original client state machine that was * written by Elliot Poger. The code has been extensively hacked on * by Ted Lemon since then, so any mistakes you find are probably his * fault and not Elliot's. */ #ifndef lint static char ocopyright[] = "$FreeBSD$\n" -"$Id: dhclient.c,v 1.129.2.16 2003/04/26 21:51:39 dhankins Exp $ Copyright (c) 1995-2002 Internet Software Consortium. All rights reserved.\n"; +"$Id: dhclient.c,v 1.129.2.18 2004/06/10 17:59:12 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include "version.h" #ifdef __FreeBSD__ #include #include #include #include #endif TIME cur_time; TIME default_lease_time = 43200; /* 12 hours... */ TIME max_lease_time = 86400; /* 24 hours... */ const char *path_dhclient_conf = _PATH_DHCLIENT_CONF; const char *path_dhclient_db = _PATH_DHCLIENT_DB; const char *path_dhclient_pid = _PATH_DHCLIENT_PID; static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT; char *path_dhclient_script = path_dhclient_script_array; int dhcp_max_agent_option_packet_length = 0; int interfaces_requested = 0; struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } }; struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } }; struct in_addr inaddr_any; struct sockaddr_in sockaddr_broadcast; struct in_addr giaddr; /* ASSERT_STATE() does nothing now; it used to be assert (state_is == state_shouldbe). */ #define ASSERT_STATE(state_is, state_shouldbe) {} -static char copyright[] = "Copyright 1995-2002 Internet Software Consortium."; +static char copyright[] = "Copyright 2004 Internet Systems Consortium."; static char arr [] = "All rights reserved."; -static char message [] = "Internet Software Consortium DHCP Client"; +static char message [] = "Internet Systems Consortium DHCP Client"; static char url [] = "For info, please visit http://www.isc.org/products/DHCP"; u_int16_t local_port=0; u_int16_t remote_port=0; int no_daemon=0; struct string_list *client_env=NULL; int client_env_count=0; int onetry=0; int quiet=1; int nowait=0; int doinitcheck=0; #ifdef ENABLE_POLLING_MODE int polling_interval = 5; #endif static void usage PROTO ((void)); void do_release(struct client_state *); int main (argc, argv, envp) int argc; char **argv, **envp; { int i; struct servent *ent; struct interface_info *ip; struct client_state *client; unsigned seed; char *server = (char *)0; char *relay = (char *)0; isc_result_t status; int release_mode = 0; omapi_object_t *listener; isc_result_t result; int persist = 0; int omapi_port; int no_dhclient_conf = 0; int no_dhclient_db = 0; int no_dhclient_pid = 0; int no_dhclient_script = 0; char *s; /* Make sure we have stdin, stdout and stderr. */ i = open ("/dev/null", O_RDWR); if (i == 0) i = open ("/dev/null", O_RDWR); if (i == 1) { i = open ("/dev/null", O_RDWR); log_perror = 0; /* No sense logging to /dev/null. */ } else if (i != -1) close (i); #ifdef SYSLOG_4_2 openlog ("dhclient", LOG_NDELAY); log_priority = LOG_DAEMON; #else openlog ("dhclient", LOG_NDELAY, LOG_DAEMON); #endif #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__)) setlogmask (LOG_UPTO (LOG_INFO)); #endif /* Set up the OMAPI. */ status = omapi_init (); if (status != ISC_R_SUCCESS) log_fatal ("Can't initialize OMAPI: %s", isc_result_totext (status)); /* Set up the OMAPI wrappers for various server database internal objects. */ dhcp_common_objects_setup (); dhcp_interface_discovery_hook = dhclient_interface_discovery_hook; dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook; dhcp_interface_startup_hook = dhclient_interface_startup_hook; for (i = 1; i < argc; i++) { if (!strcmp (argv [i], "-r")) { release_mode = 1; no_daemon = 1; } else if (!strcmp (argv [i], "-p")) { if (++i == argc) usage (); local_port = htons (atoi (argv [i])); log_debug ("binding to user-specified port %d", ntohs (local_port)); } else if (!strcmp (argv [i], "-d")) { no_daemon = 1; } else if (!strcmp (argv [i], "-pf")) { if (++i == argc) usage (); path_dhclient_pid = argv [i]; no_dhclient_pid = 1; } else if (!strcmp (argv [i], "-cf")) { if (++i == argc) usage (); path_dhclient_conf = argv [i]; no_dhclient_conf = 1; } else if (!strcmp (argv [i], "-lf")) { if (++i == argc) usage (); path_dhclient_db = argv [i]; no_dhclient_db = 1; } else if (!strcmp (argv [i], "-sf")) { if (++i == argc) usage (); path_dhclient_script = argv [i]; no_dhclient_script = 1; } else if (!strcmp (argv [i], "-1")) { onetry = 1; } else if (!strcmp (argv [i], "-q")) { quiet = 1; quiet_interface_discovery = 1; } else if (!strcmp (argv [i], "-v")) { quiet = 0; quiet_interface_discovery = 0; } else if (!strcmp (argv [i], "-s")) { if (++i == argc) usage (); server = argv [i]; } else if (!strcmp (argv [i], "-g")) { if (++i == argc) usage (); relay = argv [i]; } else if (!strcmp (argv [i], "-nw")) { nowait = 1; } else if (!strcmp (argv [i], "-n")) { /* do not start up any interfaces */ interfaces_requested = 1; #ifdef ENABLE_POLLING_MODE } else if (!strcmp (argv [i], "-i")) { if (++i == argc) usage (); polling_interval = (int)strtol (argv [i], (char **)NULL, 10); if (polling_interval <= 0) { log_info ("Incorrect polling interval %d", polling_interval); log_info ("Using a default of 5 seconds"); polling_interval = 5; } #endif } else if (!strcmp (argv [i], "-w")) { /* do not exit if there are no broadcast interfaces. */ persist = 1; } else if (!strcmp (argv [i], "-e")) { struct string_list *tmp; if (++i == argc) usage (); tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL); if (!tmp) log_fatal ("No memory for %s", argv [i]); strcpy (tmp -> string, argv [i]); tmp -> next = client_env; client_env = tmp; client_env_count++; } else if (!strcmp (argv [i], "--version")) { log_info ("isc-dhclient-%s", DHCP_VERSION); exit (0); } else if (argv [i][0] == '-') { usage (); } else { struct interface_info *tmp = (struct interface_info *)0; status = interface_allocate (&tmp, MDL); if (status != ISC_R_SUCCESS) log_fatal ("Can't record interface %s:%s", argv [i], isc_result_totext (status)); if (strlen (argv [i]) > sizeof tmp -> name) log_fatal ("%s: interface name too long (max %ld)", argv [i], (long)strlen (argv [i])); strlcpy (tmp -> name, argv [i], IFNAMSIZ); #ifdef __FreeBSD__ set_ieee80211 (tmp); #endif /* Init some interface vars, enable polling */ #ifdef ENABLE_POLLING_MODE tmp -> forcediscover = 0; tmp -> linkstate = HAVELINK; tmp -> polling = 1; #endif /* ifdef ENABLE_POLLING_MODE */ if (interfaces) { interface_reference (&tmp -> next, interfaces, MDL); interface_dereference (&interfaces, MDL); } interface_reference (&interfaces, tmp, MDL); tmp -> flags = INTERFACE_REQUESTED; interfaces_requested = 1; } } if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) { path_dhclient_conf = s; } if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) { path_dhclient_db = s; } if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) { path_dhclient_pid = s; } if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) { path_dhclient_script = s; } /* first kill of any currently running client */ if (release_mode) { FILE *pidfd; pid_t oldpid; long temp; int e; oldpid = 0; if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) { e = fscanf(pidfd, "%ld\n", &temp); oldpid = (pid_t)temp; if (e != 0 && e != EOF) { if (oldpid) { if (kill(oldpid, SIGTERM) == 0) unlink(path_dhclient_pid); } } fclose(pidfd); } } if (!quiet) { log_info ("%s %s", message, DHCP_VERSION); log_info (copyright); log_info (arr); log_info (url); log_info ("%s", ""); } else log_perror = 0; /* If we're given a relay agent address to insert, for testing purposes, figure out what it is. */ if (relay) { if (!inet_aton (relay, &giaddr)) { struct hostent *he; he = gethostbyname (relay); if (he) { memcpy (&giaddr, he -> h_addr_list [0], sizeof giaddr); } else { log_fatal ("%s: no such host", relay); } } } /* Default to the DHCP/BOOTP port. */ if (!local_port) { /* If we're faking a relay agent, and we're not using loopback, use the server port, not the client port. */ if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) { local_port = htons(67); } else { ent = getservbyname ("dhcpc", "udp"); if (!ent) local_port = htons (68); else local_port = ent -> s_port; #ifndef __CYGWIN32__ endservent (); #endif } } /* If we're faking a relay agent, and we're not using loopback, we're using the server port, not the client port. */ if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) { remote_port = local_port; } else remote_port = htons (ntohs (local_port) - 1); /* XXX */ /* Get the current time... */ GET_TIME (&cur_time); sockaddr_broadcast.sin_family = AF_INET; sockaddr_broadcast.sin_port = remote_port; if (server) { if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) { struct hostent *he; he = gethostbyname (server); if (he) { memcpy (&sockaddr_broadcast.sin_addr, he -> h_addr_list [0], sizeof sockaddr_broadcast.sin_addr); } else sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST; } } else { sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST; } inaddr_any.s_addr = INADDR_ANY; /* Discover all the network interfaces. */ discover_interfaces (DISCOVER_UNCONFIGURED); /* Parse the dhclient.conf file. */ read_client_conf (); /* Parse the lease database. */ read_client_leases (); /* Rewrite the lease database... */ rewrite_client_leases (); /* XXX */ /* config_counter(&snd_counter, &rcv_counter); */ /* If no broadcast interfaces were discovered, call the script and tell it so. */ if (!interfaces) { /* Call dhclient-script with the NBI flag, in case somebody cares. */ script_init ((struct client_state *)0, "NBI", (struct string_list *)0); script_go ((struct client_state *)0); /* If we haven't been asked to persist, waiting for new interfaces, then just exit. */ if (!persist) { /* Nothing more to do. */ log_info ("No broadcast interfaces found - exiting."); exit (0); } } else if (!release_mode) { /* Call the script with the list of interfaces. */ for (ip = interfaces; ip; ip = ip -> next) { /* If interfaces were specified, don't configure interfaces that weren't specified! */ if (interfaces_requested && ((ip -> flags & (INTERFACE_REQUESTED | INTERFACE_AUTOMATIC)) != INTERFACE_REQUESTED)) continue; #ifdef __FreeBSD__ set_ieee80211 (ip); #endif #ifdef ENABLE_POLLING_MODE ip -> forcediscover = 0; if (ip -> client -> config -> media != NULL) ip -> havemedia = 1; else ip -> havemedia = 0; #endif script_init (ip -> client, "PREINIT", (struct string_list *)0); if (ip -> client -> alias) script_write_params (ip -> client, "alias_", ip -> client -> alias); script_go (ip -> client); } } /* At this point, all the interfaces that the script thinks are relevant should be running, so now we once again call discover_interfaces(), and this time ask it to actually set up the interfaces. */ discover_interfaces (interfaces_requested ? DISCOVER_REQUESTED : DISCOVER_RUNNING); /* Make up a seed for the random number generator from current time plus the sum of the last four bytes of each interface's hardware address interpreted as an integer. Not much entropy, but we're booting, so we're not likely to find anything better. */ seed = 0; for (ip = interfaces; ip; ip = ip -> next) { int junk; memcpy (&junk, &ip -> hw_address.hbuf [ip -> hw_address.hlen - sizeof seed], sizeof seed); seed += junk; } srandom (seed + cur_time); /* Start a configuration state machine for each interface. */ for (ip = interfaces; ip; ip = ip -> next) { ip -> flags |= INTERFACE_RUNNING; for (client = ip -> client; client; client = client -> next) { if (release_mode) do_release (client); else { client -> state = S_INIT; /* Set up a timeout to start the initialization process. */ #ifdef ENABLE_POLLING_MODE add_timeout (cur_time + random () % 5 + 2, state_polling, client, 0, 0); #else add_timeout (cur_time + random () % 5, state_reboot, client, 0, 0); #endif } } } if (release_mode) return 0; /* Start up a listener for the object management API protocol. */ if (top_level_config.omapi_port != -1) { listener = (omapi_object_t *)0; result = omapi_generic_new (&listener, MDL); if (result != ISC_R_SUCCESS) log_fatal ("Can't allocate new generic object: %s\n", isc_result_totext (result)); result = omapi_protocol_listen (listener, (unsigned) top_level_config.omapi_port, 1); if (result != ISC_R_SUCCESS) log_fatal ("Can't start OMAPI protocol: %s", isc_result_totext (result)); } /* Set up the bootp packet handler... */ bootp_packet_handler = do_packet; #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) dmalloc_cutoff_generation = dmalloc_generation; dmalloc_longterm = dmalloc_outstanding; dmalloc_outstanding = 0; #endif /* If we're not supposed to wait before getting the address, don't. */ if (nowait) go_daemon (); /* If we're not going to daemonize, write the pid file now. */ if (no_daemon || nowait) write_client_pid_file (); /* Start dispatching packets and timeouts... */ dispatch (); /*NOTREACHED*/ return 0; } static void usage () { log_info ("%s %s", message, DHCP_VERSION); log_info (copyright); log_info (arr); log_info (url); log_error ("Usage: dhclient [-1Ddqr] [-nw] [-p ] %s", "[-s server]"); log_error (" [-cf config-file] [-lf lease-file]%s", "[-pf pid-file] [-e VAR=val]"); log_fatal (" [-sf script-file] [interface]"); } isc_result_t find_class (struct class **c, const char *s, const char *file, int line) { return 0; } int check_collection (packet, lease, collection) struct packet *packet; struct lease *lease; struct collection *collection; { return 0; } void classify (packet, class) struct packet *packet; struct class *class; { } int unbill_class (lease, class) struct lease *lease; struct class *class; { return 0; } int find_subnet (struct subnet **sp, struct iaddr addr, const char *file, int line) { return 0; } /* Individual States: * * Each routine is called from the dhclient_state_machine() in one of * these conditions: * -> entering INIT state * -> recvpacket_flag == 0: timeout in this state * -> otherwise: received a packet in this state * * Return conditions as handled by dhclient_state_machine(): * Returns 1, sendpacket_flag = 1: send packet, reset timer. * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone). * Returns 0: finish the nap which was interrupted for no good reason. * * Several per-interface variables are used to keep track of the process: * active_lease: the lease that is being used on the interface * (null pointer if not configured yet). * offered_leases: leases corresponding to DHCPOFFER messages that have * been sent to us by DHCP servers. * acked_leases: leases corresponding to DHCPACK messages that have been * sent to us by DHCP servers. * sendpacket: DHCP packet we're trying to send. * destination: IP address to send sendpacket to * In addition, there are several relevant per-lease variables. * T1_expiry, T2_expiry, lease_expiry: lease milestones * In the active lease, these control the process of renewing the lease; * In leases on the acked_leases list, this simply determines when we * can no longer legitimately use the lease. */ void state_reboot (cpp) void *cpp; { struct client_state *client = cpp; /* If we don't remember an active lease, go straight to INIT. */ if (!client -> active || client -> active -> is_bootp || client -> active -> expiry <= cur_time) { state_init (client); return; } /* We are in the rebooting state. */ client -> state = S_REBOOTING; /* make_request doesn't initialize xid because it normally comes from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER, so pick an xid now. */ client -> xid = random (); /* Make a DHCPREQUEST packet, and set appropriate per-interface flags. */ make_request (client, client -> active); client -> destination = iaddr_broadcast; client -> first_sending = cur_time; client -> interval = client -> config -> initial_interval; /* Zap the medium list... */ client -> medium = (struct string_list *)0; /* Send out the first DHCPREQUEST packet. */ send_request (client); } /* Called when a lease has completely expired and we've been unable to renew it. */ void state_init (cpp) void *cpp; { struct client_state *client = cpp; ASSERT_STATE(state, S_INIT); /* Make a DHCPDISCOVER packet, and set appropriate per-interface flags. */ make_discover (client, client -> active); client -> xid = client -> packet.xid; client -> destination = iaddr_broadcast; client -> state = S_SELECTING; client -> first_sending = cur_time; client -> interval = client -> config -> initial_interval; /* Add an immediate timeout to cause the first DHCPDISCOVER packet to go out. */ send_discover (client); } /* state_selecting is called when one or more DHCPOFFER packets have been received and a configurable period of time has passed. */ void state_selecting (cpp) void *cpp; { struct client_state *client = cpp; struct client_lease *lp, *next, *picked; ASSERT_STATE(state, S_SELECTING); /* Cancel state_selecting and send_discover timeouts, since either one could have got us here. */ cancel_timeout (state_selecting, client); cancel_timeout (send_discover, client); /* We have received one or more DHCPOFFER packets. Currently, the only criterion by which we judge leases is whether or not we get a response when we arp for them. */ picked = (struct client_lease *)0; for (lp = client -> offered_leases; lp; lp = next) { next = lp -> next; /* Check to see if we got an ARPREPLY for the address in this particular lease. */ if (!picked) { picked = lp; picked -> next = (struct client_lease *)0; } else { freeit: destroy_client_lease (lp); } } client -> offered_leases = (struct client_lease *)0; /* If we just tossed all the leases we were offered, go back to square one. */ if (!picked) { client -> state = S_INIT; state_init (client); return; } /* If it was a BOOTREPLY, we can just take the address right now. */ if (picked -> is_bootp) { client -> new = picked; /* Make up some lease expiry times XXX these should be configurable. */ client -> new -> expiry = cur_time + 12000; client -> new -> renewal += cur_time + 8000; client -> new -> rebind += cur_time + 10000; client -> state = S_REQUESTING; /* Bind to the address we received. */ bind_lease (client); return; } /* Go to the REQUESTING state. */ client -> destination = iaddr_broadcast; client -> state = S_REQUESTING; client -> first_sending = cur_time; client -> interval = client -> config -> initial_interval; /* Make a DHCPREQUEST packet from the lease we picked. */ make_request (client, picked); client -> xid = client -> packet.xid; /* Toss the lease we picked - we'll get it back in a DHCPACK. */ destroy_client_lease (picked); /* Add an immediate timeout to send the first DHCPREQUEST packet. */ send_request (client); } /* state_requesting is called when we receive a DHCPACK message after having sent out one or more DHCPREQUEST packets. */ void dhcpack (packet) struct packet *packet; { struct interface_info *ip = packet -> interface; struct client_state *client; struct client_lease *lease; struct option_cache *oc; struct data_string ds; int i; /* If we're not receptive to an offer right now, or if the offer has an unrecognizable transaction id, then just drop it. */ for (client = ip -> client; client; client = client -> next) { if (client -> xid == packet -> raw -> xid) break; } if (!client || (packet -> interface -> hw_address.hlen - 1 != packet -> raw -> hlen) || (memcmp (&packet -> interface -> hw_address.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen))) { #if defined (DEBUG) log_debug ("DHCPACK in wrong transaction."); #endif return; } if (client -> state != S_REBOOTING && client -> state != S_REQUESTING && client -> state != S_RENEWING && client -> state != S_REBINDING) { #if defined (DEBUG) log_debug ("DHCPACK in wrong state."); #endif return; } log_info ("DHCPACK from %s", piaddr (packet -> client_addr)); lease = packet_to_lease (packet, client); if (!lease) { log_info ("packet_to_lease failed."); return; } client -> new = lease; /* Stop resending DHCPREQUEST. */ cancel_timeout (send_request, client); /* Figure out the lease time. */ oc = lookup_option (&dhcp_universe, client -> new -> options, DHO_DHCP_LEASE_TIME); memset (&ds, 0, sizeof ds); if (oc && evaluate_option_cache (&ds, packet, (struct lease *)0, client, packet -> options, client -> new -> options, &global_scope, oc, MDL)) { if (ds.len > 3) client -> new -> expiry = getULong (ds.data); else client -> new -> expiry = 0; data_string_forget (&ds, MDL); } else client -> new -> expiry = 0; if (!client -> new -> expiry) { log_error ("no expiry time on offered lease."); /* XXX this is going to be bad - if this _does_ XXX happen, we should probably dynamically XXX disqualify the DHCP server that gave us the XXX bad packet from future selections and XXX then go back into the init state. */ state_init (client); return; } /* A number that looks negative here is really just very large, because the lease expiry offset is unsigned. */ if (client -> new -> expiry < 0) client -> new -> expiry = TIME_MAX; /* Take the server-provided renewal time if there is one. */ oc = lookup_option (&dhcp_universe, client -> new -> options, DHO_DHCP_RENEWAL_TIME); if (oc && evaluate_option_cache (&ds, packet, (struct lease *)0, client, packet -> options, client -> new -> options, &global_scope, oc, MDL)) { if (ds.len > 3) client -> new -> renewal = getULong (ds.data); else client -> new -> renewal = 0; data_string_forget (&ds, MDL); } else client -> new -> renewal = 0; /* If it wasn't specified by the server, calculate it. */ if (!client -> new -> renewal) - client -> new -> renewal = - client -> new -> expiry / 2; + client -> new -> renewal = client -> new -> expiry / 2 + 1; + if (client -> new -> renewal <= 0) + client -> new -> renewal = TIME_MAX; + /* Now introduce some randomness to the renewal time: */ - client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) + + if (client -> new -> renewal <= TIME_MAX / 3 - 3) + client -> new -> renewal = + (((client -> new -> renewal + 3) * 3 / 4) + (random () % /* XXX NUMS */ ((client -> new -> renewal + 3) / 4))); /* Same deal with the rebind time. */ oc = lookup_option (&dhcp_universe, client -> new -> options, DHO_DHCP_REBINDING_TIME); if (oc && evaluate_option_cache (&ds, packet, (struct lease *)0, client, packet -> options, client -> new -> options, &global_scope, oc, MDL)) { if (ds.len > 3) client -> new -> rebind = getULong (ds.data); else client -> new -> rebind = 0; data_string_forget (&ds, MDL); } else client -> new -> rebind = 0; - if (!client -> new -> rebind) - client -> new -> rebind = - (client -> new -> expiry * 7) / 8; /* XXX NUMS */ + if (client -> new -> rebind <= 0) { + if (client -> new -> expiry <= TIME_MAX / 7) + client -> new -> rebind = + client -> new -> expiry * 7 / 8; + else + client -> new -> rebind = + client -> new -> expiry / 8 * 7; + } /* Make sure our randomness didn't run the renewal time past the rebind time. */ - if (client -> new -> renewal > client -> new -> rebind) - client -> new -> renewal = (client -> new -> rebind * 3) / 4; + if (client -> new -> renewal > client -> new -> rebind) { + if (client -> new -> rebind <= TIME_MAX / 3) + client -> new -> renewal = + client -> new -> rebind * 3 / 4; + else + client -> new -> renewal = + client -> new -> rebind / 4 * 3; + } client -> new -> expiry += cur_time; /* Lease lengths can never be negative. */ if (client -> new -> expiry < cur_time) client -> new -> expiry = TIME_MAX; client -> new -> renewal += cur_time; if (client -> new -> renewal < cur_time) client -> new -> renewal = TIME_MAX; client -> new -> rebind += cur_time; if (client -> new -> rebind < cur_time) client -> new -> rebind = TIME_MAX; bind_lease (client); } void bind_lease (client) struct client_state *client; { struct interface_info *ip = client -> interface; /* Remember the medium. */ client -> new -> medium = client -> medium; /* Run the client script with the new parameters. */ script_init (client, (client -> state == S_REQUESTING ? "BOUND" : (client -> state == S_RENEWING ? "RENEW" : (client -> state == S_REBOOTING ? "REBOOT" : "REBIND"))), client -> new -> medium); if (client -> active && client -> state != S_REBOOTING) script_write_params (client, "old_", client -> active); script_write_params (client, "new_", client -> new); if (client -> alias) script_write_params (client, "alias_", client -> alias); /* If the BOUND/RENEW code detects another machine using the offered address, it exits nonzero. We need to send a DHCPDECLINE and toss the lease. */ if (script_go (client)) { make_decline (client, client -> new); send_decline (client); destroy_client_lease (client -> new); client -> new = (struct client_lease *)0; state_init (client); return; } /* Write out the new lease. */ write_client_lease (client, client -> new, 0, 0); /* * It's now possible that state_reboot can be called * after a interface link went down and is up again. * To prevent tons of equal leases saved on disk, we rewrite * them. */ read_client_leases (); rewrite_client_leases (); /* Replace the old active lease with the new one. */ if (client -> active) destroy_client_lease (client -> active); client -> active = client -> new; client -> new = (struct client_lease *)0; /* Set up a timeout to start the renewal process. */ add_timeout (client -> active -> renewal, state_bound, client, 0, 0); log_info ("bound to %s -- renewal in %ld seconds.", piaddr (client -> active -> address), (long)(client -> active -> renewal - cur_time)); client -> state = S_BOUND; #ifdef ENABLE_POLLING_MODE /* Init some interface vars, enable polling */ client -> interface -> linkstate = HAVELINK; client -> interface -> forcediscover = 0; client -> interface -> polling = 1; #endif /* ifdef ENABLE_POLLING_MODE */ reinitialize_interfaces (); go_daemon (); if (client -> config -> do_forward_update) { client -> dns_update_timeout = 1; add_timeout (cur_time + 1, client_dns_update_timeout, client, 0, 0); } } /* state_bound is called when we've successfully bound to a particular lease, but the renewal time on that lease has expired. We are expected to unicast a DHCPREQUEST to the server that gave us our original lease. */ void state_bound (cpp) void *cpp; { struct client_state *client = cpp; int i; struct option_cache *oc; struct data_string ds; ASSERT_STATE(state, S_BOUND); /* T1 has expired. */ make_request (client, client -> active); client -> xid = client -> packet.xid; memset (&ds, 0, sizeof ds); oc = lookup_option (&dhcp_universe, client -> active -> options, DHO_DHCP_SERVER_IDENTIFIER); if (oc && evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0, client, (struct option_state *)0, client -> active -> options, &global_scope, oc, MDL)) { if (ds.len > 3) { memcpy (client -> destination.iabuf, ds.data, 4); client -> destination.len = 4; } else client -> destination = iaddr_broadcast; } else client -> destination = iaddr_broadcast; client -> first_sending = cur_time; client -> interval = client -> config -> initial_interval; client -> state = S_RENEWING; /* Send the first packet immediately. */ send_request (client); } /* state_stop is called when we've been told to shut down. We unconfigure the interfaces, and then stop operating until told otherwise. */ void state_stop (cpp) void *cpp; { struct client_state *client = cpp; int i; /* Cancel all timeouts. */ cancel_timeout (state_selecting, client); cancel_timeout (send_discover, client); cancel_timeout (send_request, client); cancel_timeout (state_bound, client); /* If we have an address, unconfigure it. */ if (client -> active) { script_init (client, "STOP", client -> active -> medium); script_write_params (client, "old_", client -> active); if (client -> alias) script_write_params (client, "alias_", client -> alias); script_go (client); } } int commit_leases () { return 0; } int write_lease (lease) struct lease *lease; { return 0; } int write_host (host) struct host_decl *host; { return 0; } void db_startup (testp) int testp; { } void bootp (packet) struct packet *packet; { struct iaddrlist *ap; if (packet -> raw -> op != BOOTREPLY) return; /* If there's a reject list, make sure this packet's sender isn't on it. */ for (ap = packet -> interface -> client -> config -> reject_list; ap; ap = ap -> next) { if (addr_eq (packet -> client_addr, ap -> addr)) { log_info ("BOOTREPLY from %s rejected.", piaddr (ap -> addr)); return; } } dhcpoffer (packet); } void dhcp (packet) struct packet *packet; { struct iaddrlist *ap; void (*handler) PROTO ((struct packet *)); const char *type; switch (packet -> packet_type) { case DHCPOFFER: handler = dhcpoffer; type = "DHCPOFFER"; break; case DHCPNAK: handler = dhcpnak; type = "DHCPNACK"; break; case DHCPACK: handler = dhcpack; type = "DHCPACK"; break; default: return; } /* If there's a reject list, make sure this packet's sender isn't on it. */ for (ap = packet -> interface -> client -> config -> reject_list; ap; ap = ap -> next) { if (addr_eq (packet -> client_addr, ap -> addr)) { log_info ("%s from %s rejected.", type, piaddr (ap -> addr)); return; } } (*handler) (packet); } void dhcpoffer (packet) struct packet *packet; { struct interface_info *ip = packet -> interface; struct client_state *client; struct client_lease *lease, *lp; int i; int stop_selecting; const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY"; struct iaddrlist *ap; struct option_cache *oc; char obuf [1024]; #ifdef DEBUG_PACKET dump_packet (packet); #endif /* Find a client state that matches the xid... */ for (client = ip -> client; client; client = client -> next) if (client -> xid == packet -> raw -> xid) break; /* If we're not receptive to an offer right now, or if the offer has an unrecognizable transaction id, then just drop it. */ if (!client || client -> state != S_SELECTING || (packet -> interface -> hw_address.hlen - 1 != packet -> raw -> hlen) || (memcmp (&packet -> interface -> hw_address.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen))) { #if defined (DEBUG) log_debug ("%s in wrong transaction.", name); #endif return; } sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr)); /* If this lease doesn't supply the minimum required parameters, blow it off. */ if (client -> config -> required_options) { for (i = 0; client -> config -> required_options [i]; i++) { if (!lookup_option (&dhcp_universe, packet -> options, client -> config -> required_options [i])) { log_info ("%s: no %s option.", obuf, (dhcp_universe.options [client -> config -> required_options [i]] -> name)); return; } } } /* If we've already seen this lease, don't record it again. */ for (lease = client -> offered_leases; lease; lease = lease -> next) { if (lease -> address.len == sizeof packet -> raw -> yiaddr && !memcmp (lease -> address.iabuf, &packet -> raw -> yiaddr, lease -> address.len)) { log_debug ("%s: already seen.", obuf); return; } } lease = packet_to_lease (packet, client); if (!lease) { log_info ("%s: packet_to_lease failed.", obuf); return; } /* If this lease was acquired through a BOOTREPLY, record that fact. */ if (!packet -> options_valid || !packet -> packet_type) lease -> is_bootp = 1; /* Record the medium under which this lease was offered. */ lease -> medium = client -> medium; /* Figure out when we're supposed to stop selecting. */ stop_selecting = (client -> first_sending + client -> config -> select_interval); /* If this is the lease we asked for, put it at the head of the list, and don't mess with the arp request timeout. */ if (lease -> address.len == client -> requested_address.len && !memcmp (lease -> address.iabuf, client -> requested_address.iabuf, client -> requested_address.len)) { lease -> next = client -> offered_leases; client -> offered_leases = lease; } else { /* Put the lease at the end of the list. */ lease -> next = (struct client_lease *)0; if (!client -> offered_leases) client -> offered_leases = lease; else { for (lp = client -> offered_leases; lp -> next; lp = lp -> next) ; lp -> next = lease; } } /* If the selecting interval has expired, go immediately to state_selecting(). Otherwise, time out into state_selecting at the select interval. */ if (stop_selecting <= 0) state_selecting (client); else { add_timeout (stop_selecting, state_selecting, client, 0, 0); cancel_timeout (send_discover, client); } log_info ("%s", obuf); } /* Allocate a client_lease structure and initialize it from the parameters in the specified packet. */ struct client_lease *packet_to_lease (packet, client) struct packet *packet; struct client_state *client; { struct client_lease *lease; unsigned i; struct option_cache *oc; struct data_string data; lease = (struct client_lease *)new_client_lease (MDL); if (!lease) { log_error ("packet_to_lease: no memory to record lease.\n"); return (struct client_lease *)0; } memset (lease, 0, sizeof *lease); /* Copy the lease options. */ option_state_reference (&lease -> options, packet -> options, MDL); lease -> address.len = sizeof (packet -> raw -> yiaddr); memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr, lease -> address.len); memset (&data, 0, sizeof data); if (client -> config -> vendor_space_name) { i = DHO_VENDOR_ENCAPSULATED_OPTIONS; /* See if there was a vendor encapsulation option. */ oc = lookup_option (&dhcp_universe, lease -> options, i); if (oc && client -> config -> vendor_space_name && evaluate_option_cache (&data, packet, (struct lease *)0, client, packet -> options, lease -> options, &global_scope, oc, MDL)) { if (data.len) { parse_encapsulated_suboptions (packet -> options, &dhcp_options [i], data.data, data.len, &dhcp_universe, client -> config -> vendor_space_name ); } data_string_forget (&data, MDL); } } else i = 0; /* Figure out the overload flag. */ oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_OPTION_OVERLOAD); if (oc && evaluate_option_cache (&data, packet, (struct lease *)0, client, packet -> options, lease -> options, &global_scope, oc, MDL)) { if (data.len > 0) i = data.data [0]; else i = 0; data_string_forget (&data, MDL); } else i = 0; /* If the server name was filled out, copy it. */ if (!(i & 2) && packet -> raw -> sname [0]) { unsigned len; /* Don't count on the NUL terminator. */ for (len = 0; len < 64; len++) if (!packet -> raw -> sname [len]) break; lease -> server_name = dmalloc (len + 1, MDL); if (!lease -> server_name) { log_error ("dhcpoffer: no memory for filename.\n"); destroy_client_lease (lease); return (struct client_lease *)0; } else { memcpy (lease -> server_name, packet -> raw -> sname, len); lease -> server_name [len] = 0; } } /* Ditto for the filename. */ if (!(i & 1) && packet -> raw -> file [0]) { unsigned len; /* Don't count on the NUL terminator. */ for (len = 0; len < 64; len++) if (!packet -> raw -> file [len]) break; lease -> filename = dmalloc (len + 1, MDL); if (!lease -> filename) { log_error ("dhcpoffer: no memory for filename.\n"); destroy_client_lease (lease); return (struct client_lease *)0; } else { memcpy (lease -> filename, packet -> raw -> file, len); lease -> filename [len] = 0; } } execute_statements_in_scope ((struct binding_value **)0, (struct packet *)packet, (struct lease *)0, client, lease -> options, lease -> options, &global_scope, client -> config -> on_receipt, (struct group *)0); return lease; } void dhcpnak (packet) struct packet *packet; { struct interface_info *ip = packet -> interface; struct client_state *client; /* Find a client state that matches the xid... */ for (client = ip -> client; client; client = client -> next) if (client -> xid == packet -> raw -> xid) break; /* If we're not receptive to an offer right now, or if the offer has an unrecognizable transaction id, then just drop it. */ if (!client || (packet -> interface -> hw_address.hlen - 1 != packet -> raw -> hlen) || (memcmp (&packet -> interface -> hw_address.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen))) { #if defined (DEBUG) log_debug ("DHCPNAK in wrong transaction."); #endif return; } if (client -> state != S_REBOOTING && client -> state != S_REQUESTING && client -> state != S_RENEWING && client -> state != S_REBINDING) { #if defined (DEBUG) log_debug ("DHCPNAK in wrong state."); #endif return; } log_info ("DHCPNAK from %s", piaddr (packet -> client_addr)); if (!client -> active) { #if defined (DEBUG) log_info ("DHCPNAK with no active lease.\n"); #endif return; } destroy_client_lease (client -> active); client -> active = (struct client_lease *)0; /* Stop sending DHCPREQUEST packets... */ cancel_timeout (send_request, client); client -> state = S_INIT; state_init (client); } /* Send out a DHCPDISCOVER packet, and set a timeout to send out another one after the right interval has expired. If we don't get an offer by the time we reach the panic interval, call the panic function. */ void send_discover (cpp) void *cpp; { struct client_state *client = cpp; int result; int interval; int increase = 1; #ifdef ENABLE_POLLING_MODE /* Disable polling for this interface */ client -> interface -> polling = 0; #endif /* Figure out how long it's been since we started transmitting. */ interval = cur_time - client -> first_sending; /* If we're past the panic timeout, call the script and tell it we haven't found anything for this interface yet. */ if (interval > client -> config -> timeout) { state_panic (client); return; } /* If we're selecting media, try the whole list before doing the exponential backoff, but if we've already received an offer, stop looping, because we obviously have it right. */ if (!client -> offered_leases && client -> config -> media) { int fail = 0; again: if (client -> medium) { client -> medium = client -> medium -> next; increase = 0; } if (!client -> medium) { if (fail) log_fatal ("No valid media types for %s!", client -> interface -> name); client -> medium = client -> config -> media; increase = 1; } log_info ("Trying medium \"%s\" %d", client -> medium -> string, increase); script_init (client, "MEDIUM", client -> medium); if (script_go (client)) { fail = 1; goto again; } } /* If we're supposed to increase the interval, do so. If it's currently zero (i.e., we haven't sent any packets yet), set it to one; otherwise, add to it a random number between zero and two times itself. On average, this means that it will double with every transmission. */ if (increase) { if (!client -> interval) client -> interval = client -> config -> initial_interval; else client -> interval += ((random () >> 2) % (2 * client -> interval)); /* Don't backoff past cutoff. */ if (client -> interval > client -> config -> backoff_cutoff) client -> interval = ((client -> config -> backoff_cutoff / 2) + ((random () >> 2) % client -> config -> backoff_cutoff)); } else if (!client -> interval) client -> interval = client -> config -> initial_interval; /* If the backoff would take us to the panic timeout, just use that as the interval. */ if (cur_time + client -> interval > client -> first_sending + client -> config -> timeout) client -> interval = (client -> first_sending + client -> config -> timeout) - cur_time + 1; /* Record the number of seconds since we started sending. */ if (interval < 65536) client -> packet.secs = htons (interval); else client -> packet.secs = htons (65535); client -> secs = client -> packet.secs; log_info ("DHCPDISCOVER on %s to %s port %d interval %ld", client -> name ? client -> name : client -> interface -> name, inet_ntoa (sockaddr_broadcast.sin_addr), ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); /* Send out a packet. */ result = send_packet (client -> interface, (struct packet *)0, &client -> packet, client -> packet_length, inaddr_any, &sockaddr_broadcast, (struct hardware *)0); add_timeout (cur_time + client -> interval, send_discover, client, 0, 0); } /* state_panic gets called if we haven't received any offers in a preset amount of time. When this happens, we try to use existing leases that haven't yet expired, and failing that, we call the client script and hope it can do something. */ void state_panic (cpp) void *cpp; { struct client_state *client = cpp; struct client_lease *loop; struct client_lease *lp; if (client -> interface -> linkstate == NOLINK) return; loop = lp = client -> active; log_info ("No DHCPOFFERS received."); /* We may not have an active lease, but we may have some predefined leases that we can try. */ if (!client -> active && client -> leases) goto activate_next; /* Run through the list of leases and see if one can be used. */ while (client -> active) { if (client -> active -> expiry > cur_time) { log_info ("Trying recorded lease %s", piaddr (client -> active -> address)); /* Run the client script with the existing parameters. */ script_init (client, "TIMEOUT", client -> active -> medium); script_write_params (client, "new_", client -> active); if (client -> alias) script_write_params (client, "alias_", client -> alias); /* If the old lease is still good and doesn't yet need renewal, go into BOUND state and timeout at the renewal time. */ if (!script_go (client)) { if (cur_time < client -> active -> renewal) { client -> state = S_BOUND; log_info ("bound: renewal in %ld %s.", (long)(client -> active -> renewal - cur_time), "seconds"); #ifdef ENABLE_POLLING_MODE /* Enable polling for this interface */ client -> interface -> polling = 1; #endif add_timeout (client -> active -> renewal, state_bound, client, 0, 0); } else { client -> state = S_BOUND; log_info ("bound: immediate renewal."); state_bound (client); } /* * Set the link status back to nolink, even * if we have media settings. */ client -> interface -> linkstate = NOLINK; reinitialize_interfaces (); go_daemon (); return; } } /* If there are no other leases, give up. */ if (!client -> leases) { client -> leases = client -> active; client -> active = (struct client_lease *)0; break; } activate_next: /* Otherwise, put the active lease at the end of the lease list, and try another lease.. */ for (lp = client -> leases; lp -> next; lp = lp -> next) ; lp -> next = client -> active; if (lp -> next) { lp -> next -> next = (struct client_lease *)0; } client -> active = client -> leases; client -> leases = client -> leases -> next; /* If we already tried this lease, we've exhausted the set of leases, so we might as well give up for now. */ if (client -> active == loop) break; else if (!loop) loop = client -> active; } /* No leases were available, or what was available didn't work, so tell the shell script that we failed to allocate an address, and try again later. */ if (onetry) { if (!quiet) log_info ("Unable to obtain a lease on first try.%s", " Exiting."); exit (2); } log_info ("No working leases in persistent database - sleeping."); #ifdef ENABLE_POLLING_MODE /* Enable polling for this interface */ client -> interface -> polling = 1; #endif script_init (client, "FAIL", (struct string_list *)0); if (client -> alias) script_write_params (client, "alias_", client -> alias); script_go (client); client -> state = S_INIT; add_timeout (cur_time + ((client -> config -> retry_interval + 1) / 2 + (random () % client -> config -> retry_interval)), state_init, client, 0, 0); go_daemon (); } void send_request (cpp) void *cpp; { struct client_state *client = cpp; int result; int interval; struct sockaddr_in destination; struct in_addr from; /* Figure out how long it's been since we started transmitting. */ interval = cur_time - client -> first_sending; /* If we're in the INIT-REBOOT or REQUESTING state and we're past the reboot timeout, go to INIT and see if we can DISCOVER an address... */ /* XXX In the INIT-REBOOT state, if we don't get an ACK, it means either that we're on a network with no DHCP server, or that our server is down. In the latter case, assuming that there is a backup DHCP server, DHCPDISCOVER will get us a new address, but we could also have successfully reused our old address. In the former case, we're hosed anyway. This is not a win-prone situation. */ if ((client -> state == S_REBOOTING || client -> state == S_REQUESTING) && interval > client -> config -> reboot_timeout) { cancel: client -> state = S_INIT; cancel_timeout (send_request, client); state_init (client); return; } /* If we're in the reboot state, make sure the media is set up correctly. */ if (client -> state == S_REBOOTING && !client -> medium && client -> active -> medium ) { script_init (client, "MEDIUM", client -> active -> medium); /* If the medium we chose won't fly, go to INIT state. */ if (script_go (client)) goto cancel; /* Record the medium. */ client -> medium = client -> active -> medium; } /* If the lease has expired, relinquish the address and go back to the INIT state. */ if (client -> state != S_REQUESTING && cur_time > client -> active -> expiry) { /* Run the client script with the new parameters. */ script_init (client, "EXPIRE", (struct string_list *)0); script_write_params (client, "old_", client -> active); if (client -> alias) script_write_params (client, "alias_", client -> alias); script_go (client); /* Now do a preinit on the interface so that we can discover a new address. */ script_init (client, "PREINIT", (struct string_list *)0); if (client -> alias) script_write_params (client, "alias_", client -> alias); script_go (client); client -> state = S_INIT; state_init (client); return; } /* Do the exponential backoff... */ if (!client -> interval) client -> interval = client -> config -> initial_interval; else { client -> interval += ((random () >> 2) % (2 * client -> interval)); } /* Don't backoff past cutoff. */ if (client -> interval > client -> config -> backoff_cutoff) client -> interval = ((client -> config -> backoff_cutoff / 2) + ((random () >> 2) % client -> interval)); /* If the backoff would take us to the expiry time, just set the timeout to the expiry time. */ if (client -> state != S_REQUESTING && cur_time + client -> interval > client -> active -> expiry) client -> interval = client -> active -> expiry - cur_time + 1; /* If the lease T2 time has elapsed, or if we're not yet bound, broadcast the DHCPREQUEST rather than unicasting. */ if (client -> state == S_REQUESTING || client -> state == S_REBOOTING || cur_time > client -> active -> rebind) destination.sin_addr = sockaddr_broadcast.sin_addr; else memcpy (&destination.sin_addr.s_addr, client -> destination.iabuf, sizeof destination.sin_addr.s_addr); destination.sin_port = remote_port; destination.sin_family = AF_INET; #ifdef HAVE_SA_LEN destination.sin_len = sizeof destination; #endif if (client -> state == S_RENEWING || client -> state == S_REBINDING) memcpy (&from, client -> active -> address.iabuf, sizeof from); else from.s_addr = INADDR_ANY; /* Record the number of seconds since we started sending. */ if (client -> state == S_REQUESTING) client -> packet.secs = client -> secs; else { if (interval < 65536) client -> packet.secs = htons (interval); else client -> packet.secs = htons (65535); } /* * Only try the first ten seconds to renew a lease from a * given dhcp-server adress. After that, fall back to use * state_reboot with INADDR_BROADCAST. */ if (destination.sin_addr.s_addr != INADDR_BROADCAST && (client -> state == S_RENEWING || client -> state == S_REBINDING)) { if (client -> active && client -> active -> expiry > cur_time && interval >= 10) goto cancel; } log_info ("DHCPREQUEST on %s to %s port %d", client -> name ? client -> name : client -> interface -> name, inet_ntoa (destination.sin_addr), ntohs (destination.sin_port)); if (destination.sin_addr.s_addr != INADDR_BROADCAST && fallback_interface) result = send_packet (fallback_interface, (struct packet *)0, &client -> packet, client -> packet_length, from, &destination, (struct hardware *)0); else /* Send out a packet. */ result = send_packet (client -> interface, (struct packet *)0, &client -> packet, client -> packet_length, from, &destination, (struct hardware *)0); /* * If sendto() for a direct request fails, fall back to use * state_reboot with INADDR_BROADCAST. */ if (result == -1 && destination.sin_addr.s_addr != INADDR_BROADCAST && (client -> state == S_RENEWING || client -> state == S_REBINDING)) { if (client -> active && client -> active -> expiry > cur_time) goto cancel; } add_timeout (cur_time + client -> interval, send_request, client, 0, 0); } void send_decline (cpp) void *cpp; { struct client_state *client = cpp; int result; log_info ("DHCPDECLINE on %s to %s port %d", client -> name ? client -> name : client -> interface -> name, inet_ntoa (sockaddr_broadcast.sin_addr), ntohs (sockaddr_broadcast.sin_port)); /* Send out a packet. */ result = send_packet (client -> interface, (struct packet *)0, &client -> packet, client -> packet_length, inaddr_any, &sockaddr_broadcast, (struct hardware *)0); } void send_release (cpp) void *cpp; { struct client_state *client = cpp; int result; struct sockaddr_in destination; struct in_addr from; memcpy (&from, client -> active -> address.iabuf, sizeof from); memcpy (&destination.sin_addr.s_addr, client -> destination.iabuf, sizeof destination.sin_addr.s_addr); destination.sin_port = remote_port; destination.sin_family = AF_INET; #ifdef HAVE_SA_LEN destination.sin_len = sizeof destination; #endif /* Set the lease to end now, so that we don't accidentally reuse it if we restart before the old expiry time. */ client -> active -> expiry = client -> active -> renewal = client -> active -> rebind = cur_time; if (!write_client_lease (client, client -> active, 1, 1)) { log_error ("Can't release lease: lease write failed."); return; } log_info ("DHCPRELEASE on %s to %s port %d", client -> name ? client -> name : client -> interface -> name, inet_ntoa (destination.sin_addr), ntohs (destination.sin_port)); if (fallback_interface) result = send_packet (fallback_interface, (struct packet *)0, &client -> packet, client -> packet_length, from, &destination, (struct hardware *)0); else /* Send out a packet. */ result = send_packet (client -> interface, (struct packet *)0, &client -> packet, client -> packet_length, from, &destination, (struct hardware *)0); } void make_client_options (client, lease, type, sid, rip, prl, op) struct client_state *client; struct client_lease *lease; u_int8_t *type; struct option_cache *sid; struct iaddr *rip; u_int32_t *prl; struct option_state **op; { unsigned i; struct option_cache *oc; struct buffer *bp = (struct buffer *)0; /* If there are any leftover options, get rid of them. */ if (*op) option_state_dereference (op, MDL); /* Allocate space for options. */ option_state_allocate (op, MDL); /* Send the server identifier if provided. */ if (sid) save_option (&dhcp_universe, *op, sid); oc = (struct option_cache *)0; /* Send the requested address if provided. */ if (rip) { client -> requested_address = *rip; if (!(make_const_option_cache (&oc, (struct buffer **)0, rip -> iabuf, rip -> len, &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL))) log_error ("can't make requested address cache."); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } } else { client -> requested_address.len = 0; } if (!(make_const_option_cache (&oc, (struct buffer **)0, type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL))) log_error ("can't make message type."); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } if (prl) { /* Figure out how many parameters were requested. */ for (i = 0; prl [i]; i++) ; if (!buffer_allocate (&bp, i, MDL)) log_error ("can't make parameter list buffer."); else { for (i = 0; prl [i]; i++) bp -> data [i] = prl [i]; if (!(make_const_option_cache (&oc, &bp, (u_int8_t *)0, i, &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST], MDL))) log_error ("can't make option cache"); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } } } /* Run statements that need to be run on transmission. */ if (client -> config -> on_transmission) execute_statements_in_scope ((struct binding_value **)0, (struct packet *)0, (struct lease *)0, client, (lease ? lease -> options : (struct option_state *)0), *op, &global_scope, client -> config -> on_transmission, (struct group *)0); } void make_discover (client, lease) struct client_state *client; struct client_lease *lease; { unsigned char discover = DHCPDISCOVER; int i; struct option_state *options = (struct option_state *)0; memset (&client -> packet, 0, sizeof (client -> packet)); make_client_options (client, lease, &discover, (struct option_cache *)0, lease ? &lease -> address : (struct iaddr *)0, client -> config -> requested_options, &options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = random (); client -> packet.secs = 0; /* filled in by send_discover. */ if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); memset (&(client -> packet.ciaddr), 0, sizeof client -> packet.ciaddr); memset (&(client -> packet.yiaddr), 0, sizeof client -> packet.yiaddr); memset (&(client -> packet.siaddr), 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; if (client -> interface -> hw_address.hlen > 0) memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], (unsigned)(client -> interface -> hw_address.hlen - 1)); #ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length); #endif } void make_request (client, lease) struct client_state *client; struct client_lease *lease; { unsigned char request = DHCPREQUEST; int i, j; unsigned char *tmp, *digest; unsigned char *old_digest_loc; struct option_cache *oc; memset (&client -> packet, 0, sizeof (client -> packet)); if (client -> state == S_REQUESTING) oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); else oc = (struct option_cache *)0; make_client_options (client, lease, &request, oc, ((client -> state == S_REQUESTING || client -> state == S_REBOOTING) ? &lease -> address : (struct iaddr *)0), client -> config -> requested_options, &client -> sent_options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, client -> sent_options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&client -> sent_options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = client -> xid; client -> packet.secs = 0; /* Filled in by send_request. */ /* If we own the address we're requesting, put it in ciaddr; otherwise set ciaddr to zero. */ if (client -> state == S_BOUND || client -> state == S_RENEWING || client -> state == S_REBINDING) { memcpy (&client -> packet.ciaddr, lease -> address.iabuf, lease -> address.len); client -> packet.flags = 0; } else { memset (&client -> packet.ciaddr, 0, sizeof client -> packet.ciaddr); if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); } memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); if (client -> state != S_BOUND && client -> state != S_RENEWING) client -> packet.giaddr = giaddr; else memset (&client -> packet.giaddr, 0, sizeof client -> packet.giaddr); if (client -> interface -> hw_address.hlen > 0) memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], (unsigned)(client -> interface -> hw_address.hlen - 1)); #ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length); #endif } void make_decline (client, lease) struct client_state *client; struct client_lease *lease; { unsigned char decline = DHCPDECLINE; int i; struct option_cache *oc; struct option_state *options = (struct option_state *)0; oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); make_client_options (client, lease, &decline, oc, &lease -> address, (u_int32_t *)0, &options); /* Set up the option buffer... */ memset (&client -> packet, 0, sizeof (client -> packet)); client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, 0, (struct option_state *)0, options, &global_scope, 0, 0, 0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; option_state_dereference (&options, MDL); client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = client -> xid; client -> packet.secs = 0; /* Filled in by send_request. */ if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); /* ciaddr must always be zero. */ memset (&client -> packet.ciaddr, 0, sizeof client -> packet.ciaddr); memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], client -> interface -> hw_address.hlen); #ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length); #endif } void make_release (client, lease) struct client_state *client; struct client_lease *lease; { unsigned char request = DHCPRELEASE; int i; struct option_cache *oc; struct option_state *options = (struct option_state *)0; memset (&client -> packet, 0, sizeof (client -> packet)); oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); make_client_options (client, lease, &request, oc, (struct iaddr *)0, (u_int32_t *)0, &options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; option_state_dereference (&options, MDL); client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = random (); client -> packet.secs = 0; client -> packet.flags = 0; memcpy (&client -> packet.ciaddr, lease -> address.iabuf, lease -> address.len); memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], client -> interface -> hw_address.hlen); #ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length); #endif } void destroy_client_lease (lease) struct client_lease *lease; { int i; if (lease -> server_name) dfree (lease -> server_name, MDL); if (lease -> filename) dfree (lease -> filename, MDL); option_state_dereference (&lease -> options, MDL); free_client_lease (lease, MDL); } FILE *leaseFile; void rewrite_client_leases () { struct interface_info *ip; struct client_state *client; struct client_lease *lp; if (leaseFile) fclose (leaseFile); leaseFile = fopen (path_dhclient_db, "w"); if (!leaseFile) { log_error ("can't create %s: %m", path_dhclient_db); return; } /* Write out all the leases attached to configured interfaces that we know about. */ for (ip = interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { for (lp = client -> leases; lp; lp = lp -> next) { write_client_lease (client, lp, 1, 0); } if (client -> active) write_client_lease (client, client -> active, 1, 0); } } /* Write out any leases that are attached to interfaces that aren't currently configured. */ for (ip = dummy_interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { for (lp = client -> leases; lp; lp = lp -> next) { write_client_lease (client, lp, 1, 0); } if (client -> active) write_client_lease (client, client -> active, 1, 0); } } fflush (leaseFile); } void write_lease_option (struct option_cache *oc, 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) { const char *name, *dot; struct data_string ds; int status; struct client_state *client; memset (&ds, 0, sizeof ds); if (u != &dhcp_universe) { name = u -> name; dot = "."; } else { name = ""; dot = ""; } if (evaluate_option_cache (&ds, packet, lease, client_state, in_options, cfg_options, scope, oc, MDL)) { fprintf (leaseFile, " 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); } } int write_client_lease (client, lease, rewrite, makesure) struct client_state *client; struct client_lease *lease; int rewrite; int makesure; { int i; struct tm *t; static int leases_written; struct option_cache *oc; struct data_string ds; pair *hash; int errors = 0; char *s; if (!rewrite) { if (leases_written++ > 20) { rewrite_client_leases (); leases_written = 0; } } /* If the lease came from the config file, we don't need to stash a copy in the lease database. */ if (lease -> is_static) return 1; if (!leaseFile) { /* XXX */ leaseFile = fopen (path_dhclient_db, "w"); if (!leaseFile) { log_error ("can't create %s: %m", path_dhclient_db); return 0; } } errno = 0; fprintf (leaseFile, "lease {\n"); if (lease -> is_bootp) { fprintf (leaseFile, " bootp;\n"); if (errno) { ++errors; errno = 0; } } fprintf (leaseFile, " interface \"%s\";\n", client -> interface -> name); if (errno) { ++errors; errno = 0; } if (client -> name) { fprintf (leaseFile, " name \"%s\";\n", client -> name); if (errno) { ++errors; errno = 0; } } fprintf (leaseFile, " fixed-address %s;\n", piaddr (lease -> address)); if (errno) { ++errors; errno = 0; } if (lease -> filename) { s = quotify_string (lease -> filename, MDL); if (s) { fprintf (leaseFile, " filename \"%s\";\n", s); if (errno) { ++errors; errno = 0; } dfree (s, MDL); } else errors++; } if (lease -> server_name) { s = quotify_string (lease -> filename, MDL); if (s) { fprintf (leaseFile, " server-name \"%s\";\n", s); if (errno) { ++errors; errno = 0; } dfree (s, MDL); } else ++errors; } if (lease -> medium) { s = quotify_string (lease -> medium -> string, MDL); if (s) { fprintf (leaseFile, " medium \"%s\";\n", s); if (errno) { ++errors; errno = 0; } dfree (s, MDL); } else errors++; } if (errno != 0) { errors++; errno = 0; } memset (&ds, 0, sizeof ds); for (i = 0; i < lease -> options -> universe_count; i++) { option_space_foreach ((struct packet *)0, (struct lease *)0, client, (struct option_state *)0, lease -> options, &global_scope, universes [i], client, write_lease_option); } /* 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. */ t = gmtime (&lease -> renewal); fprintf (leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n", t -> tm_wday, t -> tm_year + 1900, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, t -> tm_sec); if (errno != 0) { errors++; errno = 0; } t = gmtime (&lease -> rebind); fprintf (leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n", t -> tm_wday, t -> tm_year + 1900, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, t -> tm_sec); if (errno != 0) { errors++; errno = 0; } t = gmtime (&lease -> expiry); fprintf (leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n", t -> tm_wday, t -> tm_year + 1900, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, t -> tm_sec); if (errno != 0) { errors++; errno = 0; } fprintf (leaseFile, "}\n"); if (errno != 0) { errors++; errno = 0; } fflush (leaseFile); if (errno != 0) { errors++; errno = 0; } if (!errors && makesure) { if (fsync (fileno (leaseFile)) < 0) { log_info ("write_client_lease: %m"); return 0; } } return errors ? 0 : 1; } /* Variables holding name of script and file pointer for writing to script. Needless to say, this is not reentrant - only one script can be invoked at a time. */ char scriptName [256]; FILE *scriptFile; void script_init (client, reason, medium) struct client_state *client; const char *reason; struct string_list *medium; { struct string_list *sl, *next; if (client) { for (sl = client -> env; sl; sl = next) { next = sl -> next; dfree (sl, MDL); } client -> env = (struct string_list *)0; client -> envc = 0; if (client -> interface) { client_envadd (client, "", "interface", "%s", client -> interface -> name); } if (client -> name) client_envadd (client, "", "client", "%s", client -> name); if (medium) client_envadd (client, "", "medium", "%s", medium -> string); client_envadd (client, "", "reason", "%s", reason); client_envadd (client, "", "pid", "%ld", (long int)getpid ()); } } struct envadd_state { struct client_state *client; const char *prefix; }; void client_option_envadd (struct option_cache *oc, 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) { struct envadd_state *es = stuff; struct data_string data; memset (&data, 0, sizeof data); if (evaluate_option_cache (&data, packet, lease, client_state, in_options, cfg_options, scope, oc, MDL)) { if (data.len) { char name [256]; if (dhcp_option_ev_name (name, sizeof name, oc -> option)) { client_envadd (es -> client, es -> prefix, name, "%s", (pretty_print_option (oc -> option, data.data, data.len, 0, 0))); data_string_forget (&data, MDL); } } } } void script_write_params (client, prefix, lease) struct client_state *client; const char *prefix; struct client_lease *lease; { int i; struct data_string data; struct option_cache *oc; pair *hash; char *s, *t; struct envadd_state es; es.client = client; es.prefix = prefix; client_envadd (client, prefix, "ip_address", "%s", piaddr (lease -> address)); /* For the benefit of Linux (and operating systems which may have similar needs), compute the network address based on the supplied ip address and netmask, if provided. Also compute the broadcast address (the host address all ones broadcast address, not the host address all zeroes broadcast address). */ memset (&data, 0, sizeof data); oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK); if (oc && evaluate_option_cache (&data, (struct packet *)0, (struct lease *)0, client, (struct option_state *)0, lease -> options, &global_scope, oc, MDL)) { if (data.len > 3) { struct iaddr netmask, subnet, broadcast; memcpy (netmask.iabuf, data.data, data.len); netmask.len = data.len; data_string_forget (&data, MDL); subnet = subnet_number (lease -> address, netmask); if (subnet.len) { client_envadd (client, prefix, "network_number", "%s", piaddr (subnet)); oc = lookup_option (&dhcp_universe, lease -> options, DHO_BROADCAST_ADDRESS); if (!oc || !(evaluate_option_cache (&data, (struct packet *)0, (struct lease *)0, client, (struct option_state *)0, lease -> options, &global_scope, oc, MDL))) { broadcast = broadcast_addr (subnet, netmask); if (broadcast.len) { client_envadd (client, prefix, "broadcast_address", "%s", piaddr (broadcast)); } } } } data_string_forget (&data, MDL); } if (lease -> filename) client_envadd (client, prefix, "filename", "%s", lease -> filename); if (lease -> server_name) client_envadd (client, prefix, "server_name", "%s", lease -> server_name); for (i = 0; i < lease -> options -> universe_count; i++) { option_space_foreach ((struct packet *)0, (struct lease *)0, client, (struct option_state *)0, lease -> options, &global_scope, universes [i], &es, client_option_envadd); } client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry)); } int script_go (client) struct client_state *client; { int rval; char *scriptName; char *argv [2]; char **envp; char *epp [3]; char reason [] = "REASON=NBI"; static char client_path [] = CLIENT_PATH; int i; struct string_list *sp, *next; int pid, wpid, wstatus; if (client) scriptName = client -> config -> script_name; else scriptName = top_level_config.script_name; envp = dmalloc (((client ? client -> envc : 2) + client_env_count + 2) * sizeof (char *), MDL); if (!envp) { log_error ("No memory for client script environment."); return 0; } i = 0; /* Copy out the environment specified on the command line, if any. */ for (sp = client_env; sp; sp = sp -> next) { envp [i++] = sp -> string; } /* Copy out the environment specified by dhclient. */ if (client) { for (sp = client -> env; sp; sp = sp -> next) { envp [i++] = sp -> string; } } else { envp [i++] = reason; } /* Set $PATH. */ envp [i++] = client_path; envp [i] = (char *)0; argv [0] = scriptName; argv [1] = (char *)0; pid = fork (); if (pid < 0) { log_error ("fork: %m"); wstatus = 0; } else if (pid) { do { wpid = wait (&wstatus); } while (wpid != pid && wpid > 0); if (wpid < 0) { log_error ("wait: %m"); wstatus = 0; } } else { if ((i = open(_PATH_DEVNULL, O_RDWR)) != -1) { dup2(i, STDIN_FILENO); dup2(i, STDOUT_FILENO); dup2(i, STDERR_FILENO); if (i > STDERR_FILENO) close(i); } execve (scriptName, argv, envp); log_error ("execve (%s, ...): %m", scriptName); exit (0); } if (client) { for (sp = client -> env; sp; sp = next) { next = sp -> next; dfree (sp, MDL); } client -> env = (struct string_list *)0; client -> envc = 0; } dfree (envp, MDL); GET_TIME (&cur_time); return (WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) : -WTERMSIG (wstatus)); } void client_envadd (struct client_state *client, const char *prefix, const char *name, const char *fmt, ...) { char spbuf [1024]; char *s; unsigned len, i; struct string_list *val; va_list list; va_start (list, fmt); len = vsnprintf (spbuf, sizeof spbuf, fmt, list); va_end (list); val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ + len + sizeof *val, MDL); if (!val) return; s = val -> string; strcpy (s, prefix); strcat (s, name); s += strlen (s); *s++ = '='; if (len >= sizeof spbuf) { va_start (list, fmt); vsnprintf (s, len + 1, fmt, list); va_end (list); } else strcpy (s, spbuf); val -> next = client -> env; client -> env = val; client -> envc++; } int dhcp_option_ev_name (buf, buflen, option) char *buf; size_t buflen; struct option *option; { int i, j; const char *s; j = 0; if (option -> universe != &dhcp_universe) { s = option -> universe -> name; i = 0; } else { s = option -> name; i = 1; } do { while (*s) { if (j + 1 == buflen) return 0; if (*s == '-') buf [j++] = '_'; else buf [j++] = *s; ++s; } if (!i) { s = option -> name; if (j + 1 == buflen) return 0; buf [j++] = '_'; } ++i; } while (i != 2); buf [j] = 0; return 1; } void go_daemon () { static int state = 0; int pid; int i; /* Don't become a daemon if the user requested otherwise. */ if (no_daemon) { write_client_pid_file (); return; } /* Only do it once. */ if (state) return; state = 1; /* Stop logging to stderr... */ log_perror = 0; /* Become a daemon... */ if ((pid = fork ()) < 0) log_fatal ("Can't fork daemon: %m"); else if (pid) exit (0); /* Become session leader and get pid... */ pid = setsid (); /* Close standard I/O descriptors. */ close(0); close(1); close(2); /* Reopen them on /dev/null. */ i = open ("/dev/null", O_RDWR); if (i == 0) i = open ("/dev/null", O_RDWR); if (i == 1) { i = open ("/dev/null", O_RDWR); log_perror = 0; /* No sense logging to /dev/null. */ } else if (i != -1) close (i); write_client_pid_file (); } void write_client_pid_file () { FILE *pf; int pfdesc; pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644); if (pfdesc < 0) { log_error ("Can't create %s: %m", path_dhclient_pid); return; } pf = fdopen (pfdesc, "w"); if (!pf) log_error ("Can't fdopen %s: %m", path_dhclient_pid); else { fprintf (pf, "%ld\n", (long)getpid ()); fclose (pf); } } void client_location_changed () { struct interface_info *ip; struct client_state *client; for (ip = interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { switch (client -> state) { case S_SELECTING: cancel_timeout (send_discover, client); break; case S_BOUND: cancel_timeout (state_bound, client); break; case S_REBOOTING: case S_REQUESTING: case S_RENEWING: cancel_timeout (send_request, client); break; case S_INIT: case S_REBINDING: case S_STOPPED: break; } #ifndef ENABLE_POLLING_MODE client -> state = S_INIT; state_reboot (client); #endif } } } void do_release(client) struct client_state *client; { struct data_string ds; struct option_cache *oc; /* Pick a random xid. */ client -> xid = random (); /* is there even a lease to release? */ if (client -> active) { /* Make a DHCPRELEASE packet, and set appropriate per-interface flags. */ make_release (client, client -> active); memset (&ds, 0, sizeof ds); oc = lookup_option (&dhcp_universe, client -> active -> options, DHO_DHCP_SERVER_IDENTIFIER); if (oc && evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0, client, (struct option_state *)0, client -> active -> options, &global_scope, oc, MDL)) { if (ds.len > 3) { memcpy (client -> destination.iabuf, ds.data, 4); client -> destination.len = 4; } else client -> destination = iaddr_broadcast; } else client -> destination = iaddr_broadcast; client -> first_sending = cur_time; client -> interval = client -> config -> initial_interval; /* Zap the medium list... */ client -> medium = (struct string_list *)0; /* Send out the first and only DHCPRELEASE packet. */ send_release (client); /* Do the client script RELEASE operation. */ script_init (client, "RELEASE", (struct string_list *)0); if (client -> alias) script_write_params (client, "alias_", client -> alias); script_write_params (client, "old_", client -> active); script_go (client); } /* Cancel any timeouts. */ cancel_timeout (state_bound, client); cancel_timeout (send_discover, client); cancel_timeout (state_init, client); cancel_timeout (send_request, client); cancel_timeout (state_reboot, client); client -> state = S_STOPPED; } int dhclient_interface_shutdown_hook (struct interface_info *interface) { do_release (interface -> client); return 1; } int dhclient_interface_discovery_hook (struct interface_info *tmp) { struct interface_info *last, *ip; /* See if we can find the client from dummy_interfaces */ last = 0; for (ip = dummy_interfaces; ip; ip = ip -> next) { if (!strcmp (ip -> name, tmp -> name)) { /* Remove from dummy_interfaces */ if (last) { ip = (struct interface_info *)0; interface_reference (&ip, last -> next, MDL); interface_dereference (&last -> next, MDL); if (ip -> next) { interface_reference (&last -> next, ip -> next, MDL); interface_dereference (&ip -> next, MDL); } } else { ip = (struct interface_info *)0; interface_reference (&ip, dummy_interfaces, MDL); interface_dereference (&dummy_interfaces, MDL); if (ip -> next) { interface_reference (&dummy_interfaces, ip -> next, MDL); interface_dereference (&ip -> next, MDL); } } /* Copy "client" to tmp */ if (ip -> client) { tmp -> client = ip -> client; tmp -> client -> interface = tmp; } interface_dereference (&ip, MDL); break; } last = ip; } return 1; } isc_result_t dhclient_interface_startup_hook (struct interface_info *interface) { struct interface_info *ip; struct client_state *client; /* This code needs some rethinking. It doesn't test against a signal name, and it just kind of bulls into doing something that may or may not be appropriate. */ if (interfaces) { interface_reference (&interface -> next, interfaces, MDL); interface_dereference (&interfaces, MDL); } interface_reference (&interfaces, interface, MDL); discover_interfaces (DISCOVER_UNCONFIGURED); for (ip = interfaces; ip; ip = ip -> next) { /* If interfaces were specified, don't configure interfaces that weren't specified! */ if (ip -> flags & INTERFACE_RUNNING || (ip -> flags & (INTERFACE_REQUESTED | INTERFACE_AUTOMATIC)) != INTERFACE_REQUESTED) continue; script_init (ip -> client, "PREINIT", (struct string_list *)0); if (ip -> client -> alias) script_write_params (ip -> client, "alias_", ip -> client -> alias); script_go (ip -> client); } discover_interfaces (interfaces_requested ? DISCOVER_REQUESTED : DISCOVER_RUNNING); for (ip = interfaces; ip; ip = ip -> next) { if (ip -> flags & INTERFACE_RUNNING) continue; ip -> flags |= INTERFACE_RUNNING; for (client = ip -> client; client; client = client -> next) { client -> state = S_INIT; /* Set up a timeout to start the initialization process. */ add_timeout (cur_time + random () % 5, state_reboot, client, 0, 0); } } return ISC_R_SUCCESS; } /* The client should never receive a relay agent information option, so if it does, log it and discard it. */ int parse_agent_information_option (packet, len, data) struct packet *packet; int len; u_int8_t *data; { return 1; } /* The client never sends relay agent information options. */ unsigned cons_agent_information_options (cfg_options, outpacket, agentix, length) struct option_state *cfg_options; struct dhcp_packet *outpacket; unsigned agentix; unsigned length; { return length; } static void shutdown_exit (void *foo) { exit (0); } isc_result_t dhcp_set_control_state (control_object_state_t oldstate, control_object_state_t newstate) { struct interface_info *ip; struct client_state *client; /* Do the right thing for each interface. */ for (ip = interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { switch (newstate) { case server_startup: return ISC_R_SUCCESS; case server_running: return ISC_R_SUCCESS; case server_shutdown: if (client -> active && client -> active -> expiry > cur_time) { if (client -> config -> do_forward_update) client_dns_update (client, 0, 0); do_release (client); } break; case server_hibernate: state_stop (client); break; case server_awaken: #ifndef ENABLE_POLLING_MODE state_reboot (client); #endif break; } } } if (newstate == server_shutdown) add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0); return ISC_R_SUCCESS; } /* Called after a timeout if the DNS update failed on the previous try. Retries the update, and if it times out, schedules a retry after ten times as long of a wait. */ void client_dns_update_timeout (void *cp) { struct client_state *client = cp; isc_result_t status; if (client -> active) { status = client_dns_update (client, 1, (client -> active -> renewal - cur_time)); if (status == ISC_R_TIMEDOUT) { client -> dns_update_timeout *= 10; add_timeout (cur_time + client -> dns_update_timeout, client_dns_update_timeout, client, 0, 0); } } } /* See if we should do a DNS update, and if so, do it. */ isc_result_t client_dns_update (struct client_state *client, int addp, int ttl) { struct data_string ddns_fqdn, ddns_fwd_name, ddns_dhcid, client_identifier; struct option_cache *oc; int ignorep; int result; isc_result_t rcode; /* If we didn't send an FQDN option, we certainly aren't going to be doing an update. */ if (!client -> sent_options) return ISC_R_SUCCESS; /* If we don't have a lease, we can't do an update. */ if (!client -> active) return ISC_R_SUCCESS; /* If we set the no client update flag, don't do the update. */ if ((oc = lookup_option (&fqdn_universe, client -> sent_options, FQDN_NO_CLIENT_UPDATE)) && evaluate_boolean_option_cache (&ignorep, (struct packet *)0, (struct lease *)0, client, client -> sent_options, (struct option_state *)0, &global_scope, oc, MDL)) return ISC_R_SUCCESS; /* If we set the "server, please update" flag, or didn't set it to false, don't do the update. */ if (!(oc = lookup_option (&fqdn_universe, client -> sent_options, FQDN_SERVER_UPDATE)) || evaluate_boolean_option_cache (&ignorep, (struct packet *)0, (struct lease *)0, client, client -> sent_options, (struct option_state *)0, &global_scope, oc, MDL)) return ISC_R_SUCCESS; /* If no FQDN option was supplied, don't do the update. */ memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name); if (!(oc = lookup_option (&fqdn_universe, client -> sent_options, FQDN_FQDN)) || !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0, (struct lease *)0, client, client -> sent_options, (struct option_state *)0, &global_scope, oc, MDL)) return ISC_R_SUCCESS; /* Make a dhcid string out of either the client identifier, if we are sending one, or the interface's MAC address, otherwise. */ memset (&ddns_dhcid, 0, sizeof ddns_dhcid); memset (&client_identifier, 0, sizeof client_identifier); if ((oc = lookup_option (&dhcp_universe, client -> sent_options, DHO_DHCP_CLIENT_IDENTIFIER)) && evaluate_option_cache (&client_identifier, (struct packet *)0, (struct lease *)0, client, client -> sent_options, (struct option_state *)0, &global_scope, oc, MDL)) { result = get_dhcid (&ddns_dhcid, DHO_DHCP_CLIENT_IDENTIFIER, client_identifier.data, client_identifier.len); data_string_forget (&client_identifier, MDL); } else result = get_dhcid (&ddns_dhcid, 0, client -> interface -> hw_address.hbuf, client -> interface -> hw_address.hlen); if (!result) { data_string_forget (&ddns_fwd_name, MDL); return ISC_R_SUCCESS; } /* Start the resolver, if necessary. */ if (!resolver_inited) { minires_ninit (&resolver_state); resolver_inited = 1; resolver_state.retrans = 1; resolver_state.retry = 1; } /* * Perform updates. */ if (ddns_fwd_name.len && ddns_dhcid.len) { if (addp) rcode = ddns_update_a (&ddns_fwd_name, client -> active -> address, &ddns_dhcid, ttl, 1); else rcode = ddns_remove_a (&ddns_fwd_name, client -> active -> address, &ddns_dhcid); } data_string_forget (&ddns_fwd_name, MDL); data_string_forget (&ddns_dhcid, MDL); return rcode; } /* Check to see if there's a wire plugged in */ int interface_active(struct interface_info *ip) { #ifdef __FreeBSD__ struct ifmediareq ifmr; int *media_list, i; char *ifname; int sock; ifname = ip -> name; if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) log_fatal ("Can't create interface_active socket"); (void) memset (&ifmr, 0, sizeof (ifmr)); (void) strncpy (ifmr.ifm_name, ifname, sizeof (ifmr.ifm_name)); if (ioctl (sock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { /* * Interface doesn't support SIOCGIFMEDIA, presume okay */ close (sock); return (HAVELINK); } close (sock); if (ifmr.ifm_count == 0) { /* * Assume that this means interface * does not support SIOCGIFMEDIA */ log_fatal ("%s: no media types?", ifname); return (HAVELINK); } if (ifmr.ifm_status & IFM_AVALID) { if (ip -> ieee80211) { /* * Wavelan devices need to be checked if they are * associated. */ if ((IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) && (ifmr.ifm_status & IFM_ACTIVE)) { return (HAVELINK); } } else { if (ifmr.ifm_status & IFM_ACTIVE) { return (HAVELINK); } } /* * We really have no link. */ return (NOLINK); } /* * IFM_AVALID is not set. We cannot check * the link state. Assume HAVELINK. */ #endif /* Other OSs */ /* * Always return a successful link if the OS * is not supported. */ return (HAVELINK); } #ifdef __FreeBSD__ void set_ieee80211 (struct interface_info *ip) { struct ieee80211req ireq; u_int8_t data[32]; int associated = 0; int *media_list, i; char *ifname; int sock; ifname = ip -> name; if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) log_fatal ("Can't create interface_active socket"); (void) memset (&ireq, 0, sizeof (ireq)); (void) strncpy (ireq.i_name, ifname, sizeof (ireq.i_name)); ireq.i_data = &data; ireq.i_type = IEEE80211_IOC_SSID; ireq.i_val = -1; /* * If we can't get the SSID, * this isn't an 802.11 device. */ if (ioctl (sock, SIOCG80211, &ireq) < 0) ip -> ieee80211 = 0; else { #ifdef DEBUG printf ("Device %s has 802.11\n", ifname); #endif ip -> ieee80211 = 1; } close (sock); } #endif /* __FreeBSD__ */ #ifdef ENABLE_POLLING_MODE /* Go to background after some time */ void state_background (cpp) void *cpp; { go_daemon (); } /* Check the state of the NICs if we have link */ void state_polling (cpp) void *cpp; { struct interface_info *ip; struct client_state *client; int result; for (ip = interfaces; ip; ip = ip -> next) { if (! ip -> polling) continue; #ifdef DEBUG printf ("%s: Polling interface state\n", ip -> name); for (client = ip -> client; client; client = client -> next) { printf ("%s: client state of %d\n", ip -> name, ip -> client -> state); printf ("%s: link = %d\n", ip -> name, ip -> linkstate); } #endif result = interface_active (ip); /* * If dhclient.conf contains media settings, we cannot * abort if the interface is not set to active mode. */ if (ip -> havemedia && ip -> client -> state != S_BOUND) { if (result == HAVELINK) ip -> forcediscover = 1; result = HAVELINK; } /* * The last status of the interface tells us * the we've got no link ... */ if (ip -> linkstate == NOLINK || ! doinitcheck) { /* * ... but we have now link. Let's send * requests. */ if (result == HAVELINK) { #ifdef DEBUG if (ip -> havemedia) printf ("%s: Trying media settings on interface\n", ip -> name); else printf ("%s: Found Link on interface\n", ip -> name); #endif /* * Set the interface to state_bound. We assume that we have * a working link. If we cannot reach the server directly, * INADDR_BROADCAST is used. */ for (client = ip -> client; client; client = client -> next) { cancel_timeout (state_init, client); cancel_timeout (state_reboot, client); cancel_timeout (state_selecting, client); if (client -> active) { add_timeout (cur_time + random () % 5, state_bound, client, 0, 0); } else { add_timeout (cur_time + random () % 5, state_reboot, client, 0, 0); } } ip -> linkstate = HAVELINK; } else { #ifdef DEBUG printf ("%s: No link on interface\n", ip -> name); #endif for (client = ip -> client; client; client = client -> next) { /* * Without this add_timout(), dhclient does * not poll on a interface if there * is no cable plugged in at startup * time. Because we add one additional second * to the time of a normal timeout, we always * skip and block a running one. This prevents * that polling is done twice at the same time. */ if (client -> state == S_INIT) { add_timeout (cur_time + (polling_interval + 1), state_polling, client, 0, 0); } } ip -> linkstate = NOLINK; /* * Automatically go into the background after * some time. Do this only if there are no * media options available for a interface. */ if (! ip -> havemedia && ! doinitcheck) { add_timeout (cur_time + (polling_interval * 2), state_background, client, 0, 0); } } } /* * The last status of the interface tells us * the we previously had link. */ if (ip -> linkstate == HAVELINK && doinitcheck) { if (result == NOLINK) { /* * We lost link on the interface, or it isn't * associated anymore. */ #ifdef DEBUG printf ("%s: Lost Link on interface\n", ip -> name); #endif /* * After we lost link, cycle again through the * different media settings if available. Else * set NOLINK. */ if (ip -> havemedia) ip -> forcediscover = 1; else ip -> linkstate = NOLINK; } /* * If we happen to have a real link, but no * active lease, force the interface into * state_reboot. Do the same if media settings * are available. */ if (ip -> forcediscover) { for (client = ip -> client; client; client = client -> next) { if (client -> state != S_REBOOTING && client -> state != S_SELECTING) { add_timeout (cur_time + random () % 5, state_reboot, client, 0, 0); } } ip -> forcediscover = 0; ip -> linkstate = HAVELINK; } /* We still have link, do nothing. */ } } doinitcheck = 1; } #endif /* ifdef ENABLE_POLLING_MODE */ Index: head/contrib/isc-dhcp/client/dhclient.conf.5 =================================================================== --- head/contrib/isc-dhcp/client/dhclient.conf.5 (revision 131139) +++ head/contrib/isc-dhcp/client/dhclient.conf.5 (revision 131140) @@ -1,633 +1,626 @@ -.\" dhclient.conf.5 +.\" $Id: dhclient.conf.5,v 1.12.2.10 2004/06/10 17:59:13 dhankins Exp $ .\" -.\" Copyright (c) 1996-2002 Internet Software Consortium. -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: +.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of The Internet Software Consortium nor the names -.\" of its contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. +.\" 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. .\" -.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND -.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR -.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. +.\" 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. .\" -.\" This software has been written for the Internet Software Consortium +.\" Internet Systems Consortium, Inc. +.\" 950 Charter Street +.\" Redwood City, CA 94063 +.\" +.\" http://www.isc.org/ +.\" +.\" This software has been written for Internet Software Consortium .\" by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. -.\" To learn more about the Internet Software Consortium, see +.\" To learn more about Internet Software 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: dhclient.conf.5,v 1.12.2.9 2003/02/23 03:27:26 dhankins Exp $ .\" $FreeBSD$ .\" .TH dhclient.conf 5 .SH NAME dhclient.conf - DHCP client configuration file .SH DESCRIPTION The dhclient.conf file contains configuration information for .IR dhclient, -the Internet Software Consortium DHCP Client. +the Internet Systems Consortium DHCP Client. .PP The dhclient.conf file is a free-form ASCII text file. It is parsed by the recursive-descent parser built into dhclient. The file may contain extra tabs and newlines for formatting purposes. Keywords in the file are case-insensitive. Comments may be placed anywhere within the file (except within quotes). Comments begin with the # character and end at the end of the line. .PP The dhclient.conf file can be used to configure the behaviour of the client in a wide variety of ways: protocol timing, information requested from the server, information required of the server, defaults to use if the server does not provide certain information, values with which to override information provided by the server, or values to prepend or append to information provided by the server. The configuration file can also be preinitialized with addresses to use on networks that don't have DHCP servers. .SH PROTOCOL TIMING The timing behaviour of the client need not be configured by the user. If no timing configuration is provided by the user, a fairly reasonable timing behaviour will be used by default - one which results in fairly timely updates without placing an inordinate load on the server. .PP The following statements can be used to adjust the timing behaviour of the DHCP client if required, however: .PP .I The .B timeout .I statement .PP .B timeout .I time .B ; .PP The .I timeout statement determines the amount of time that must pass between the time that the client begins to try to determine its address and the time that it decides that it's not going to be able to contact a server. By default, this timeout is sixty seconds. After the timeout has passed, if there are any static leases defined in the configuration file, or any leases remaining in the lease database that have not yet expired, the client will loop through these leases attempting to validate them, and if it finds one that appears to be valid, it will use that lease's address. If there are no valid static leases or unexpired leases in the lease database, the client will restart the protocol after the defined retry interval. .PP .I The .B retry .I statement .PP \fBretry \fItime\fR\fB;\fR .PP The .I retry statement determines the time that must pass after the client has determined that there is no DHCP server present before it tries again to contact a DHCP server. By default, this is five minutes. .PP .I The .B select-timeout .I statement .PP \fBselect-timeout \fItime\fR\fB;\fR .PP It is possible (some might say desirable) for there to be more than one DHCP server serving any given network. In this case, it is possible that a client may be sent more than one offer in response to its initial lease discovery message. It may be that one of these offers is preferable to the other (e.g., one offer may have the address the client previously used, and the other may not). .PP The .I select-timeout is the time after the client sends its first lease discovery request at which it stops waiting for offers from servers, assuming that it has received at least one such offer. If no offers have been received by the time the .I select-timeout has expired, the client will accept the first offer that arrives. .PP By default, the select-timeout is zero seconds - that is, the client will take the first offer it sees. .PP .I The .B reboot .I statement .PP \fBreboot \fItime\fR\fB;\fR .PP When the client is restarted, it first tries to reacquire the last address it had. This is called the INIT-REBOOT state. If it is still attached to the same network it was attached to when it last ran, this is the quickest way to get started. The .I reboot statement sets the time that must elapse after the client first tries to reacquire its old address before it gives up and tries to discover a new address. By default, the reboot timeout is ten seconds. .PP .I The .B backoff-cutoff .I statement .PP \fBbackoff-cutoff \fItime\fR\fB;\fR .PP The client uses an exponential backoff algorithm with some randomness, so that if many clients try to configure themselves at the same time, they will not make their requests in lockstep. The .I backoff-cutoff statement determines the maximum amount of time that the client is allowed to back off. It defaults to two minutes. .PP .I The .B initial-interval .I statement .PP \fBinitial-interval \fItime\fR\fB;\fR .PP The .I initial-interval statement sets the amount of time between the first attempt to reach a server and the second attempt to reach a server. Each time a message is sent, the interval between messages is incremented by twice the current interval multiplied by a random number between zero and one. If it is greater than the backoff-cutoff amount, it is set to that amount. It defaults to ten seconds. .SH LEASE REQUIREMENTS AND REQUESTS The DHCP protocol allows the client to request that the server send it specific information, and not send it other information that it is not prepared to accept. The protocol also allows the client to reject offers from servers if they don't contain information the client needs, or if the information provided is not satisfactory. .PP There is a variety of data contained in offers that DHCP servers send to DHCP clients. The data that can be specifically requested is what are called \fIDHCP Options\fR. DHCP Options are defined in \fBdhcp-options(5)\fR. .PP .I The .B request .I statement .PP \fBrequest [ \fIoption\fR ] [\fB,\fI ... \fIoption\fR ]\fB;\fR .PP The request statement causes the client to request that any server responding to the client send the client its values for the specified options. Only the option names should be specified in the request statement - not option parameters. By default, the DHCP server requests the subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers and host-name options. .PP In some cases, it may be desirable to send no parameter request list at all. To do this, simply write the request statement but specify no parameters: .PP .nf request; .fi .PP .I The .B require .I statement .PP \fBrequire [ \fIoption\fR ] [\fB,\fI ... \fIoption ]\fB;\fR .PP The require statement lists options that must be sent in order for an offer to be accepted. Offers that do not contain all the listed options will be ignored. .PP .I The .B send .I statement .PP \fBsend { [ \fIoption declaration\fR ] [\fB,\fI ... \fIoption declaration\fR ]\fB}\fR .PP The send statement causes the client to send the specified options to the server with the specified values. These are full option declarations as described in \fBdhcp-options(5)\fR. Options that are always sent in the DHCP protocol should not be specified here, except that the client can specify a \fBrequested-lease-time\fR option other than the default requested lease time, which is two hours. The other obvious use for this statement is to send information to the server that will allow it to differentiate between this client and other clients or kinds of clients. .SH DYNAMIC DNS The client now has some very limited support for doing DNS updates when a lease is acquired. This is prototypical, and probably doesn't do what you want. It also only works if you happen to have control over your DNS server, which isn't very likely. .PP To make it work, you have to declare a key and zone as in the DHCP server (see \fBdhcpd.conf\fR(5) for details). You also need to configure the fqdn option on the client, as follows: .PP .nf send fqdn.fqdn "grosse.fugue.com."; send fqdn.encoded on; send fqdn.server-update off; .fi .PP The \fIfqdn.fqdn\fR option \fBMUST\fR be a fully-qualified domain name. You \fBMUST\fR define a zone statement for the zone to be updated. The \fIfqdn.encoded\fR option may need to be set to \fIon\fR or \fIoff\fR, depending on the DHCP server you are using. .PP .I The .B do-forward-updates .I statement .PP \fBdo-forward-updates [ \fIflag\fR ] \fB;\fR .PP If you want to do DNS updates in the DHCP client script (see \fBdhclient-script(8)\fR) rather than having the DHCP client do the update directly (for example, if you want to use SIG(0) authentication, which is not supported directly by the DHCP client, you can instruct the client not to do the update using the \fBdo-forward-updates\fR statement. \fIFlag\fR should be \fBtrue\fR if you want the DHCP client to do the update, and \fBfalse\fR if you don't want the DHCP client to do the update. By default, the DHCP client will do the DNS update. .SH OPTION MODIFIERS In some cases, a client may receive option data from the server which is not really appropriate for that client, or may not receive information that it needs, and for which a useful default value exists. It may also receive information which is useful, but which needs to be supplemented with local information. To handle these needs, several option modifiers are available. .PP .I The .B default .I statement .PP \fBdefault [ \fIoption declaration\fR ] \fB;\fR .PP If for some option the client should use the value supplied by the server, but needs to use some default value if no value was supplied by the server, these values can be defined in the .B default statement. .PP .I The .B supersede .I statement .PP \fBsupersede [ \fIoption declaration\fR ] \fB;\fR .PP If for some option the client should always use a locally-configured value or values rather than whatever is supplied by the server, these values can be defined in the .B supersede statement. .PP .I The .B prepend .I statement .PP \fBprepend [ \fIoption declaration\fR ] \fB;\fR .PP If for some set of options the client should use a value you supply, and then use the values supplied by the server, if any, these values can be defined in the .B prepend statement. The .B prepend statement can only be used for options which allow more than one value to be given. This restriction is not enforced - if you ignore it, the behaviour will be unpredictable. .PP .I The .B append .I statement .PP \fBappend [ \fIoption declaration\fR ] \fB;\fR .PP If for some set of options the client should first use the values supplied by the server, if any, and then use values you supply, these values can be defined in the .B append statement. The .B append statement can only be used for options which allow more than one value to be given. This restriction is not enforced - if you ignore it, the behaviour will be unpredictable. .SH LEASE DECLARATIONS .PP .I The .B lease .I declaration .PP \fBlease {\fR \fIlease-declaration\fR [ ... \fIlease-declaration ] \fB}\fR .PP The DHCP client may decide after some period of time (see \fBPROTOCOL TIMING\fR) that it is not going to succeed in contacting a server. At that time, it consults its own database of old leases and tests each one that has not yet timed out by pinging the listed router for that lease to see if that lease could work. It is possible to define one or more \fIfixed\fR leases in the client configuration file for networks where there is no DHCP or BOOTP service, so that the client can still automatically configure its address. This is done with the .B lease statement. .PP NOTE: the lease statement is also used in the dhclient.leases file in order to record leases that have been received from DHCP servers. Some of the syntax for leases as described below is only needed in the dhclient.leases file. Such syntax is documented here for completeness. .PP A lease statement consists of the lease keyword, followed by a left curly brace, followed by one or more lease declaration statements, followed by a right curly brace. The following lease declarations are possible: .PP \fBbootp;\fR .PP The .B bootp statement is used to indicate that the lease was acquired using the BOOTP protocol rather than the DHCP protocol. It is never necessary to specify this in the client configuration file. The client uses this syntax in its lease database file. .PP \fBinterface\fR \fB"\fR\fIstring\fR\fB";\fR .PP The .B interface lease statement is used to indicate the interface on which the lease is valid. If set, this lease will only be tried on a particular interface. When the client receives a lease from a server, it always records the interface number on which it received that lease. If predefined leases are specified in the dhclient.conf file, the interface should also be specified, although this is not required. .PP \fBfixed-address\fR \fIip-address\fR\fB;\fR .PP The .B fixed-address statement is used to set the ip address of a particular lease. This is required for all lease statements. The IP address must be specified as a dotted quad (e.g., 12.34.56.78). .PP \fBfilename "\fR\fIstring\fR\fB";\fR .PP The .B filename statement specifies the name of the boot filename to use. This is not used by the standard client configuration script, but is included for completeness. .PP \fBserver-name "\fR\fIstring\fR\fB";\fR .PP The .B server-name statement specifies the name of the boot server name to use. This is also not used by the standard client configuration script. .PP \fBoption\fR \fIoption-declaration\fR\fB;\fR .PP The .B option statement is used to specify the value of an option supplied by the server, or, in the case of predefined leases declared in dhclient.conf, the value that the user wishes the client configuration script to use if the predefined lease is used. .PP \fBscript "\fIscript-name\fB";\fR .PP The .B script statement is used to specify the pathname of the dhcp client configuration script. This script is used by the dhcp client to set each interface's initial configuration prior to requesting an address, to test the address once it has been offered, and to set the interface's final configuration once a lease has been acquired. If no lease is acquired, the script is used to test predefined leases, if any, and also called once if no valid lease can be identified. For more information, see .B dhclient-script(8). .PP \fBvendor option space "\fIname\fB";\fR .PP The .B vendor option space statement is used to specify which option space should be used for decoding the vendor-encapsulate-options option if one is received. The \fIdhcp-vendor-identifier\fR can be used to request a specific class of vendor options from the server. See .B dhcp-options(5) for details. .PP \fBmedium "\fImedia setup\fB";\fR .PP The .B medium statement can be used on systems where network interfaces cannot automatically determine the type of network to which they are connected. The media setup string is a system-dependent parameter which is passed to the dhcp client configuration script when initializing the interface. On Unix and Unix-like systems, the argument is passed on the ifconfig command line when configuring the interface. .PP The dhcp client automatically declares this parameter if it uses a media type (see the .B media statement) when configuring the interface in order to obtain a lease. This statement should be used in predefined leases only if the network interface requires media type configuration. .PP \fBrenew\fR \fIdate\fB;\fR .PP \fBrebind\fR \fIdate\fB;\fR .PP \fBexpire\fR \fIdate\fB;\fR .PP The \fBrenew\fR statement defines the time at which the dhcp client should begin trying to contact its server to renew a lease that it is using. The \fBrebind\fR statement defines the time at which the dhcp client should begin to try to contact \fIany\fR dhcp server in order to renew its lease. The \fBexpire\fR statement defines the time at which the dhcp client must stop using a lease if it has not been able to contact a server in order to renew it. .PP These declarations are automatically set in leases acquired by the DHCP client, but must also be configured in predefined leases - a predefined lease whose expiry time has passed will not be used by the DHCP client. .PP Dates are specified as follows: .PP \fI \fB/\fI\fB/\fI \fB:\fI\fB:\fI\fR .PP The weekday is present to make it easy for a human to tell when a lease expires - it's specified as a number from zero to six, with zero being Sunday. When declaring a predefined lease, it can always be specified as zero. The year is specified with the century, so it should generally be four digits except for really long leases. The month is specified as a number starting with 1 for January. The day of the month is likewise specified starting with 1. The hour is a number between 0 and 23, the minute a number between 0 and 59, and the second also a number between 0 and 59. .SH ALIAS DECLARATIONS \fBalias { \fI declarations ... \fB}\fR .PP Some DHCP clients running TCP/IP roaming protocols may require that in addition to the lease they may acquire via DHCP, their interface also be configured with a predefined IP alias so that they can have a -permanent IP address even while roaming. The Internet Software +permanent IP address even while roaming. The Internet Systems Consortium DHCP client doesn't support roaming with fixed addresses directly, but in order to facilitate such experimentation, the dhcp client can be set up to configure an IP alias using the .B alias declaration. .PP The alias declaration resembles a lease declaration, except that options other than the subnet-mask option are ignored by the standard client configuration script, and expiry times are ignored. A typical alias declaration includes an interface declaration, a fixed-address declaration for the IP alias address, and a subnet-mask option declaration. A medium statement should never be included in an alias declaration. .SH OTHER DECLARATIONS \fBreject \fIip-address\fB;\fR .PP The .B reject statement causes the DHCP client to reject offers from servers who use the specified address as a server identifier. This can be used to avoid being configured by rogue or misconfigured dhcp servers, although it should be a last resort - better to track down the bad DHCP server and fix it. .PP \fBinterface "\fIname\fB" { \fIdeclarations ... \fB } .PP A client with more than one network interface may require different behaviour depending on which interface is being configured. All timing parameters and declarations other than lease and alias declarations can be enclosed in an interface declaration, and those parameters will then be used only for the interface that matches the specified name. Interfaces for which there is no interface declaration will use the parameters declared outside of any interface declaration, or the default settings. .PP \fBpseudo "\fIname\fR" "\fIreal-name\fB" { \fIdeclarations ... \fB } .PP Under some circumstances it can be useful to declare a pseudo-interface and have the DHCP client acquire a configuration for that interface. Each interface that the DHCP client is supporting normally has a DHCP client state machine running on it to acquire and maintain its lease. A pseudo-interface is just another state machine running on the interface named \fIreal-name\fR, with its own lease and its own state. If you use this feature, you must provide a client identifier for both the pseudo-interface and the actual interface, and the two identifiers must be different. You must also provide a separate client script for the pseudo-interface to do what you want with the IP address. For example: .PP .nf interface "ep0" { send dhcp-client-identifier "my-client-ep0"; } pseudo "secondary" "ep0" { send dhcp-client-identifier "my-client-ep0-secondary"; script "/etc/dhclient-secondary"; } .fi .PP The client script for the pseudo-interface should not configure the interface up or down - essentially, all it needs to handle are the states where a lease has been acquired or renewed, and the states where a lease has expired. See \fBdhclient-script(8)\fR for more information. .PP \fBmedia "\fImedia setup\fB"\fI [ \fB, "\fImedia setup\fB", \fI... ]\fB;\fR .PP The .B media statement defines one or more media configuration parameters which may be tried while attempting to acquire an IP address. The dhcp client will cycle through each media setup string on the list, configuring the interface using that setup and attempting to boot, and then trying the next one. This can be used for network interfaces which aren't capable of sensing the media type unaided - whichever media type succeeds in getting a request to the server and hearing the reply is probably right (no guarantees). .PP The media setup is only used for the initial phase of address acquisition (the DHCPDISCOVER and DHCPOFFER packets). Once an address has been acquired, the dhcp client will record it in its lease database and will record the media type used to acquire the address. Whenever the client tries to renew the lease, it will use that same media type. The lease must expire before the client will go back to cycling through media types. .SH SAMPLE The following configuration file is used on a laptop running NetBSD 1.3. The laptop has an IP alias of 192.5.5.213, and has one interface, ep0 (a 3com 3C589C). Booting intervals have been shortened somewhat from the default, because the client is known to spend most of its time on networks with little DHCP activity. The laptop does roam to multiple networks. .nf timeout 60; retry 60; reboot 10; select-timeout 5; initial-interval 2; reject 192.33.137.209; interface "ep0" { send host-name "andare.fugue.com"; send dhcp-client-identifier 1:0:a0:24:ab:fb:9c; send dhcp-lease-time 3600; supersede domain-name "fugue.com rc.vix.com home.vix.com"; prepend domain-name-servers 127.0.0.1; request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, host-name; require subnet-mask, domain-name-servers; script "CLIENTBINDIR/dhclient-script"; media "media 10baseT/UTP", "media 10base2/BNC"; } alias { interface "ep0"; fixed-address 192.5.5.213; option subnet-mask 255.255.255.255; } .fi This is a very complicated dhclient.conf file - in general, yours should be much simpler. In many cases, it's sufficient to just create an empty dhclient.conf file - the defaults are usually fine. .SH SEE ALSO dhcp-options(5), dhclient.leases(5), dhclient(8), RFC2132, RFC2131. .SH AUTHOR .B dhclient(8) was written by Ted Lemon under a contract with Vixie Labs. Funding -for this project was provided by the Internet Software Consortium. -Information about the Internet Software Consortium can be found at +for this project was provided by Internet Systems Consortium. +Information about Internet Systems Consortium can be found at .B http://www.isc.org. Index: head/contrib/isc-dhcp/client/dhclient.leases.5 =================================================================== --- head/contrib/isc-dhcp/client/dhclient.leases.5 (revision 131139) +++ head/contrib/isc-dhcp/client/dhclient.leases.5 (revision 131140) @@ -1,66 +1,57 @@ -.\" dhclient.conf.5 +.\" $Id: dhclient.leases.5,v 1.2.4.4 2004/06/10 17:59:13 dhankins Exp $ .\" -.\" Copyright (c) 1997-2002 The Internet Software Consortium. -.\" All rights reserved. +.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 1997-2003 by Internet Software Consortium .\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: +.\" 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. .\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of The Internet Software Consortium nor the names -.\" of its contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. +.\" 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. .\" -.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND -.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR -.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. +.\" Internet Systems Consortium, Inc. +.\" 950 Charter Street +.\" Redwood City, CA 94063 +.\" +.\" http://www.isc.org/ .\" -.\" This software has been written for the Internet Software Consortium +.\" This software has been written for Internet Systems Consortium .\" by Ted Lemon in cooperation with Vixie -.\" Enterprises. To learn more about the Internet Software Consortium, +.\" Enterprises. To learn more about Internet Systems Consortium, .\" see ``http://www.isc.org/isc''. To learn more about Vixie .\" Enterprises, see ``http://www.vix.com''. .\" .\" $Id: dhclient.leases.5,v 1.2.4.3 2002/11/17 02:25:44 dhankins Exp $ .\" $FreeBSD$ .\" .TH dhclient.leases 5 .SH NAME dhclient.leases - DHCP client lease database .SH DESCRIPTION -The Internet Software Consortium DHCP client keeps a persistent +The Internet Systems Consortium DHCP client keeps a persistent database of leases that it has acquired that are still valid. The database is a free-form ASCII file containing one valid declaration per lease. If more than one declaration appears for a given lease, the last one in the file is used. The file is written as a log, so this is not an unusual occurrance. .PP The format of the lease declarations is described in .B dhclient.conf(5). .SH FILES .B DBDIR/dhclient.leases .SH SEE ALSO dhclient(8), dhcp-options(5), dhclient.conf(5), RFC2132, RFC2131. .SH AUTHOR .B dhclient(8) was written by Ted Lemon under a contract with Vixie Labs. Funding -for this project was provided by the Internet Software Consortium. -Information about the Internet Software Consortium can be found at +for this project was provided by Internet Systems Consortium. +Information about Internet Systems Consortium can be found at .B http://www.isc.org. Index: head/contrib/isc-dhcp/client/scripts/freebsd =================================================================== --- head/contrib/isc-dhcp/client/scripts/freebsd (revision 131139) +++ head/contrib/isc-dhcp/client/scripts/freebsd (revision 131140) @@ -1,243 +1,243 @@ #!/bin/sh # -# $Id: freebsd,v 1.13.2.5 2003/04/27 19:44:01 dhankins Exp $ +# $Id: freebsd,v 1.13.2.6 2003/09/12 19:31:03 dhankins Exp $ # # $FreeBSD$ if [ -x /usr/bin/logger ]; then LOGGER="/usr/bin/logger -s -p user.notice -t dhclient" else LOGGER=echo fi make_resolv_conf() { if [ x"$new_domain_name_servers" != x ]; then if [ "x$new_domain_name" != x ]; then ( echo search $new_domain_name >/etc/resolv.conf ) exit_status=$? else ( rm /etc/resolv.conf ) exit_status=$? fi if [ $exit_status -ne 0 ]; then $LOGGER "WARNING: Unable to update resolv.conf: Error $exit_status" else for nameserver in $new_domain_name_servers; do ( echo nameserver $nameserver >>/etc/resolv.conf ) done fi fi } # Must be used on exit. Invokes the local dhcp client exit hooks, if any. exit_with_hooks() { exit_status=$1 if [ -f /etc/dhclient-exit-hooks ]; then . /etc/dhclient-exit-hooks fi # probably should do something with exit status of the local script exit $exit_status } # Invoke the local dhcp client enter hooks, if they exist. if [ -f /etc/dhclient-enter-hooks ]; then exit_status=0 . /etc/dhclient-enter-hooks # allow the local script to abort processing of this state # local script must set exit_status variable to nonzero. if [ $exit_status -ne 0 ]; then exit $exit_status fi fi if [ x$new_broadcast_address != x ]; then new_broadcast_arg="broadcast $new_broadcast_address" fi if [ x$old_broadcast_address != x ]; then old_broadcast_arg="broadcast $old_broadcast_address" fi if [ x$new_subnet_mask != x ]; then new_netmask_arg="netmask $new_subnet_mask" fi if [ x$old_subnet_mask != x ]; then old_netmask_arg="netmask $old_subnet_mask" fi if [ x$alias_subnet_mask != x ]; then alias_subnet_arg="netmask $alias_subnet_mask" fi # Get the interface to which our default route is bound to. if [ -x /usr/bin/netstat ]; then if_defaultroute=`/usr/bin/netstat -rn \ | /usr/bin/grep "^default" \ | /usr/bin/awk '{print $6}'` else if_defaultroute="x" fi if [ x$reason = xMEDIUM ]; then eval "ifconfig $interface $medium" eval "ifconfig $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1 sleep 1 exit_with_hooks 0 fi if [ x$reason = xPREINIT ]; then if [ x$alias_ip_address != x ]; then ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1 route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1 fi ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \ broadcast 255.255.255.255 up exit_with_hooks 0 fi if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then exit_with_hooks 0; fi if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \ [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then current_hostname=`/bin/hostname` if [ x$current_hostname = x ] || \ [ x$current_hostname = x$old_host_name ]; then if [ x$current_hostname = x ] || \ [ x$new_host_name != x$old_host_name ]; then $LOGGER "New Hostname: $new_host_name" hostname $new_host_name fi fi if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \ [ x$alias_ip_address != x$old_ip_address ]; then ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1 route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1 fi if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ] then eval "ifconfig $interface inet -alias $old_ip_address $medium" route delete $old_ip_address 127.1 >/dev/null 2>&1 for router in $old_routers; do route delete default $router >/dev/null 2>&1 done if [ -n "$old_static_routes" ]; then set -- $old_static_routes while [ $# -gt 1 ]; do route delete $1 $2 shift; shift done fi arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' |sh fi if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \ [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \ $new_broadcast_arg $medium" $LOGGER "New IP Address ($interface): $new_ip_address" $LOGGER "New Subnet Mask ($interface): $new_subnet_mask" $LOGGER "New Broadcast Address ($interface): $new_broadcast_address" if [ -n "$new_routers" ]; then $LOGGER "New Routers: $new_routers" fi route add $new_ip_address 127.1 >/dev/null 2>&1 for router in $new_routers; do route add default $router >/dev/null 2>&1 done if [ -n "$new_static_routes" ]; then $LOGGER "New Static Routes: $new_static_routes" set -- $new_static_routes while [ $# -gt 1 ]; do route add $1 $2 shift; shift done fi fi if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ]; then ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg route add $alias_ip_address 127.0.0.1 fi make_resolv_conf exit_with_hooks 0 fi if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \ || [ x$reason = xSTOP ]; then if [ x$alias_ip_address != x ]; then ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1 route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1 fi if [ x$old_ip_address != x ]; then eval "ifconfig $interface inet -alias $old_ip_address $medium" route delete $old_ip_address 127.1 >/dev/null 2>&1 for router in $old_routers; do if [ $if_defaultroute = x ] || [ $if_defaultroute = $interface ]; then route delete default $router >/dev/null 2>&1 fi done if [ -n "$old_static_routes" ]; then set -- $old_static_routes while [ $# -gt 1 ]; do route delete $1 $2 shift; shift done fi arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \ |sh >/dev/null 2>&1 fi if [ x$alias_ip_address != x ]; then ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg route add $alias_ip_address 127.0.0.1 fi exit_with_hooks 0 fi if [ x$reason = xTIMEOUT ]; then if [ x$alias_ip_address != x ]; then ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1 route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1 fi eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \ $new_broadcast_arg $medium" $LOGGER "New IP Address ($interface): $new_ip_address" $LOGGER "New Subnet Mask ($interface): $new_subnet_mask" $LOGGER "New Broadcast Address ($interface): $new_broadcast_address" sleep 1 if [ -n "$new_routers" ]; then $LOGGER "New Routers: $new_routers" set -- $new_routers if ping -q -c 1 $1; then if [ x$new_ip_address != x$alias_ip_address ] && \ [ x$alias_ip_address != x ]; then ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg route add $alias_ip_address 127.0.0.1 fi route add $new_ip_address 127.1 >/dev/null 2>&1 for router in $new_routers; do route add default $router >/dev/null 2>&1 done set -- $new_static_routes while [ $# -gt 1 ]; do route add $1 $2 shift; shift done make_resolv_conf exit_with_hooks 0 fi fi eval "ifconfig $interface inet -alias $new_ip_address $medium" for router in $old_routers; do route delete default $router >/dev/null 2>&1 done if [ -n "$old_static_routes" ]; then set -- $old_static_routes while [ $# -gt 1 ]; do route delete $1 $2 shift; shift done fi arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \ |sh >/dev/null 2>&1 exit_with_hooks 1 fi exit_with_hooks 0 Index: head/contrib/isc-dhcp/common/dhcp-options.5 =================================================================== --- head/contrib/isc-dhcp/common/dhcp-options.5 (revision 131139) +++ head/contrib/isc-dhcp/common/dhcp-options.5 (revision 131140) @@ -1,1530 +1,1523 @@ -.\" dhcp-options.5 +.\" $Id: dhcp-options.5,v 1.19.2.11 2004/06/10 17:59:15 dhankins Exp $ .\" -.\" Copyright (c) 1996-2002 Internet Software Consortium. -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: +.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of The Internet Software Consortium nor the names -.\" of its contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. +.\" 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. .\" -.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND -.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR -.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. +.\" 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. .\" -.\" This software has been written for the Internet Software Consortium +.\" Internet Systems Consortium, Inc. +.\" 950 Charter Street +.\" Redwood City, CA 94063 +.\" +.\" 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 the Internet Software Consortium, see +.\" 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 Software Consortium DHCP client and server provide the +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 Software Consortium DHCP Distribution was written by Ted +The Internet Systems Consortium DHCP Distribution was written by Ted Lemon under a contract with Vixie Labs. Funding for -this project was provided through the Internet Software Consortium. -Information about the Internet Software Consortium can be found at +this project was provided through Internet Systems Consortium. +Information about Internet Systems Consortium can be found at .B http://www.isc.org. Index: head/contrib/isc-dhcp/common/dispatch.c =================================================================== --- head/contrib/isc-dhcp/common/dispatch.c (revision 131139) +++ head/contrib/isc-dhcp/common/dispatch.c (revision 131140) @@ -1,248 +1,239 @@ /* dispatch.c Network input dispatcher... */ /* - * Copyright (c) 1995-2002 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1995-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * 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.3 2002/11/17 02:26:57 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium. All rights reserved.\n" +"$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 (u_int32_t 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; TIME cur_time; 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 Index: head/contrib/isc-dhcp/common/tables.c =================================================================== --- head/contrib/isc-dhcp/common/tables.c (revision 131139) +++ head/contrib/isc-dhcp/common/tables.c (revision 131140) @@ -1,1250 +1,1241 @@ /* tables.c Tables of information... */ /* - * Copyright (c) 1995-2002 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1995-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * 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.7 2003/07/25 22:53:38 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium. All rights reserved.\n"; +"$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); } Index: head/contrib/isc-dhcp/includes/cf/freebsd.h =================================================================== --- head/contrib/isc-dhcp/includes/cf/freebsd.h (revision 131139) +++ head/contrib/isc-dhcp/includes/cf/freebsd.h (revision 131140) @@ -1,160 +1,151 @@ /* freebsd.h System dependencies for FreeBSD... */ /* - * Copyright (c) 1996-1999 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * 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''. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include extern int h_errno; #include #include #include #if !defined (INADDR_LOOPBACK) # define INADDR_LOOPBACK ((u_int32_t)0x7f000001) #endif /* Varargs stuff... */ #include #define VA_DOTDOTDOT ... #define va_dcl #define VA_start(list, last) va_start (list, last) #ifndef _PATH_DHCPD_PID #define _PATH_DHCPD_PID "/var/run/dhcpd.pid" #endif #ifndef _PATH_DHCPD_DB #define _PATH_DHCPD_DB "/var/db/dhcpd.leases" #endif #ifndef _PATH_DHCLIENT_PID #define _PATH_DHCLIENT_PID "/var/run/dhclient.pid" #endif #ifndef _PATH_DHCLIENT_DB #define _PATH_DHCLIENT_DB "/var/db/dhclient.leases" #endif #define EOL '\n' #define VOIDPTR void * /* Time stuff... */ #include #define TIME time_t #define GET_TIME(x) time ((x)) #define HAVE_SA_LEN /* socklen_t was first defined on November 24 in sys/socket.h, and __FreeBSD_version was changed to 400013 on December 4, so if you get a compile error on this, and you updated between those dates, that's why. Also, it may be that some 3.x version after 3.4 will have socklen_t, but no such change has been made so far. */ #if __FreeBSD_version < 400013 #define SOCKLEN_T int #endif #ifdef RESCUE #define _PATH_DHCLIENT_SCRIPT "/rescue/dhclient-script" #endif #if defined (USE_DEFAULT_NETWORK) # define USE_BPF #endif #define HAVE_MKSTEMP #ifdef NEED_PRAND_CONF #ifndef HAVE_DEV_RANDOM # define HAVE_DEV_RANDOM 1 #endif /* HAVE_DEV_RANDOM */ const char *cmds[] = { #ifndef RESCUE /* rescue environment can't rely on these ... */ /* Actually, /sbin/dhclient shouldn't use these, either. */ "/bin/ps -axlw 2>&1", "/usr/sbin/arp -an 2>&1", "/usr/bin/netstat -an 2>&1", "/bin/df 2>&1", "/usr/bin/dig com. soa +ti=1 +retry=0 2>&1", "/usr/bin/netstat -an 2>&1", "/usr/bin/dig . soa +ti=1 +retry=0 2>&1", "/usr/sbin/iostat 2>&1", "/usr/bin/vmstat 2>&1", "/usr/bin/w 2>&1", #endif NULL }; const char *dirs[] = { #ifndef RESCUE "/tmp", "/usr/tmp", ".", "/", "/var/spool", "/dev", "/var/mail", "/home", "/usr/home", #endif NULL }; const char *files[] = { #ifndef RESCUE "/var/log/messages", "/var/log/wtmp", "/var/log/lastlog", #endif NULL }; #endif /* NEED_PRAND_CONF */ Index: head/contrib/isc-dhcp/includes/dhcpd.h =================================================================== --- head/contrib/isc-dhcp/includes/dhcpd.h (revision 131139) +++ head/contrib/isc-dhcp/includes/dhcpd.h (revision 131140) @@ -1,2652 +1,2643 @@ /* dhcpd.h Definitions for dhcpd... */ /* - * Copyright (c) 1996-2001 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 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. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * 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''. * * $FreeBSD$ */ #ifndef __CYGWIN32__ #include #include #include #include #include #include #else #define fd_set cygwin_fd_set #include #endif #include #include #include #include #include #include #include #include #include "cdefs.h" #include "osdep.h" #include "arpa/nameser.h" #if defined (NSUPDATE) # include "minires/minires.h" #endif struct hash_table; typedef struct hash_table group_hash_t; typedef struct hash_table universe_hash_t; typedef struct hash_table option_hash_t; typedef struct hash_table dns_zone_hash_t; typedef struct hash_table lease_hash_t; typedef struct hash_table host_hash_t; typedef struct hash_table class_hash_t; #include "dhcp.h" #include "statement.h" #include "tree.h" #include "inet.h" #include "dhctoken.h" #include #include #if !defined (OPTION_HASH_SIZE) # define OPTION_HASH_SIZE 17 # define OPTION_HASH_PTWO 32 /* Next power of two above option hash. */ # define OPTION_HASH_EXP 5 /* The exponent for that power of two. */ #endif #define compute_option_hash(x) \ (((x) & (OPTION_HASH_PTWO - 1)) + \ (((x) >> OPTION_HASH_EXP) & \ (OPTION_HASH_PTWO - 1))) % OPTION_HASH_SIZE; #define NOLINK 0 #define HAVELINK 1 enum dhcp_shutdown_state { shutdown_listeners, shutdown_omapi_connections, shutdown_drop_omapi_connections, shutdown_dhcp, shutdown_done }; /* Client FQDN option, failover FQDN option, etc. */ typedef struct { u_int8_t codes [2]; unsigned length; u_int8_t *data; } ddns_fqdn_t; #include "failover.h" /* A parsing context. */ struct parse { int lexline; int lexchar; char *token_line; char *prev_line; char *cur_line; const char *tlname; int eol_token; char line1 [81]; char line2 [81]; int lpos; int line; int tlpos; int tline; enum dhcp_token token; int ugflag; char *tval; int tlen; char tokbuf [1500]; #ifdef OLD_LEXER char comments [4096]; int comment_index; #endif int warnings_occurred; int file; char *inbuf; unsigned bufix, buflen; unsigned bufsiz; }; /* Variable-length array of data. */ struct string_list { struct string_list *next; char string [1]; }; /* A name server, from /etc/resolv.conf. */ struct name_server { struct name_server *next; struct sockaddr_in addr; TIME rcdate; }; /* A domain search list element. */ struct domain_search_list { struct domain_search_list *next; char *domain; TIME rcdate; }; /* Option tag structures are used to build chains of option tags, for when we're sure we're not going to have enough of them to justify maintaining an array. */ struct option_tag { struct option_tag *next; u_int8_t data [1]; }; /* An agent option structure. We need a special structure for the Relay Agent Information option because if more than one appears in a message, we have to keep them seperate. */ struct agent_options { struct agent_options *next; int length; struct option_tag *first; }; struct option_cache { int refcnt; struct option_cache *next; struct expression *expression; struct option *option; struct data_string data; }; struct option_state { int refcnt; int universe_count; int site_universe; int site_code_min; VOIDPTR universes [1]; }; /* A dhcp packet and the pointers to its option values. */ struct packet { struct dhcp_packet *raw; int refcnt; unsigned packet_length; int packet_type; int options_valid; int client_port; struct iaddr client_addr; struct interface_info *interface; /* Interface on which packet was received. */ struct hardware *haddr; /* Physical link address of local sender (maybe gateway). */ /* Information for relay agent options (see draft-ietf-dhc-agent-options-xx.txt). */ u_int8_t *circuit_id; /* Circuit ID of client connection. */ int circuit_id_len; u_int8_t *remote_id; /* Remote ID of client. */ int remote_id_len; int got_requested_address; /* True if client sent the dhcp-requested-address option. */ struct shared_network *shared_network; struct option_state *options; #if !defined (PACKET_MAX_CLASSES) # define PACKET_MAX_CLASSES 5 #endif int class_count; struct class *classes [PACKET_MAX_CLASSES]; int known; int authenticated; }; /* A network interface's MAC address. */ struct hardware { u_int8_t hlen; u_int8_t hbuf [17]; }; typedef enum { server_startup = 0, server_running = 1, server_shutdown = 2, server_hibernate = 3, server_awaken = 4 } control_object_state_t; typedef struct { OMAPI_OBJECT_PREAMBLE; control_object_state_t state; } dhcp_control_object_t; /* Lease states: */ typedef enum { FTS_FREE = 1, FTS_ACTIVE = 2, FTS_EXPIRED = 3, FTS_RELEASED = 4, FTS_ABANDONED = 5, FTS_RESET = 6, FTS_BACKUP = 7 } binding_state_t; /* FTS_LAST is the highest value that is valid for a lease binding state. */ #define FTS_LAST FTS_BACKUP /* A dhcp lease declaration structure. */ struct lease { OMAPI_OBJECT_PREAMBLE; struct lease *next; struct lease *n_uid, *n_hw; struct iaddr ip_addr; TIME starts, ends, timestamp, sort_time; char *client_hostname; struct binding_scope *scope; struct host_decl *host; struct subnet *subnet; struct pool *pool; struct class *billing_class; struct option_chain_head *agent_options; struct executable_statement *on_expiry; struct executable_statement *on_commit; struct executable_statement *on_release; unsigned char *uid; unsigned short uid_len; unsigned short uid_max; unsigned char uid_buf [7]; struct hardware hardware_addr; u_int8_t flags; # define STATIC_LEASE 1 # define BOOTP_LEASE 2 # define PERSISTENT_FLAGS (ON_ACK_QUEUE | ON_UPDATE_QUEUE) # define MS_NULL_TERMINATION 8 # define ON_UPDATE_QUEUE 16 # define ON_ACK_QUEUE 32 # define UNICAST_BROADCAST_HACK 64 # define ON_DEFERRED_QUEUE 128 # define EPHEMERAL_FLAGS (MS_NULL_TERMINATION | \ UNICAST_BROADCAST_HACK) binding_state_t __attribute__ ((mode (__byte__))) binding_state; binding_state_t __attribute__ ((mode (__byte__))) next_binding_state; binding_state_t __attribute__ ((mode (__byte__))) desired_binding_state; struct lease_state *state; TIME tstp; /* Time sent to partner. */ TIME tsfp; /* Time sent from partner. */ TIME cltt; /* Client last transaction time. */ struct lease *next_pending; }; struct lease_state { struct lease_state *next; struct interface_info *ip; struct packet *packet; /* The incoming packet. */ TIME offered_expiry; struct option_state *options; struct data_string parameter_request_list; int max_message_size; u_int32_t expiry, renewal, rebind; struct data_string filename, server_name; int got_requested_address; int got_server_identifier; struct shared_network *shared_network; /* Shared network of interface on which request arrived. */ u_int32_t xid; u_int16_t secs; u_int16_t bootp_flags; struct in_addr ciaddr; struct in_addr siaddr; struct in_addr giaddr; u_int8_t hops; u_int8_t offer; struct iaddr from; }; #define ROOT_GROUP 0 #define HOST_DECL 1 #define SHARED_NET_DECL 2 #define SUBNET_DECL 3 #define CLASS_DECL 4 #define GROUP_DECL 5 #define POOL_DECL 6 /* Possible modes in which discover_interfaces can run. */ #define DISCOVER_RUNNING 0 #define DISCOVER_SERVER 1 #define DISCOVER_UNCONFIGURED 2 #define DISCOVER_RELAY 3 #define DISCOVER_REQUESTED 4 /* Server option names. */ #define SV_DEFAULT_LEASE_TIME 1 #define SV_MAX_LEASE_TIME 2 #define SV_MIN_LEASE_TIME 3 #define SV_BOOTP_LEASE_CUTOFF 4 #define SV_BOOTP_LEASE_LENGTH 5 #define SV_BOOT_UNKNOWN_CLIENTS 6 #define SV_DYNAMIC_BOOTP 7 #define SV_ALLOW_BOOTP 8 #define SV_ALLOW_BOOTING 9 #define SV_ONE_LEASE_PER_CLIENT 10 #define SV_GET_LEASE_HOSTNAMES 11 #define SV_USE_HOST_DECL_NAMES 12 #define SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 13 #define SV_MIN_SECS 14 #define SV_FILENAME 15 #define SV_SERVER_NAME 16 #define SV_NEXT_SERVER 17 #define SV_AUTHORITATIVE 18 #define SV_VENDOR_OPTION_SPACE 19 #define SV_ALWAYS_REPLY_RFC1048 20 #define SV_SITE_OPTION_SPACE 21 #define SV_ALWAYS_BROADCAST 22 #define SV_DDNS_DOMAIN_NAME 23 #define SV_DDNS_HOST_NAME 24 #define SV_DDNS_REV_DOMAIN_NAME 25 #define SV_LEASE_FILE_NAME 26 #define SV_PID_FILE_NAME 27 #define SV_DUPLICATES 28 #define SV_DECLINES 29 #define SV_DDNS_UPDATES 30 #define SV_OMAPI_PORT 31 #define SV_LOCAL_PORT 32 #define SV_LIMITED_BROADCAST_ADDRESS 33 #define SV_REMOTE_PORT 34 #define SV_LOCAL_ADDRESS 35 #define SV_OMAPI_KEY 36 #define SV_STASH_AGENT_OPTIONS 37 #define SV_DDNS_TTL 38 #define SV_DDNS_UPDATE_STYLE 39 #define SV_CLIENT_UPDATES 40 #define SV_UPDATE_OPTIMIZATION 41 #define SV_PING_CHECKS 42 #define SV_UPDATE_STATIC_LEASES 43 #define SV_LOG_FACILITY 44 #define SV_DO_FORWARD_UPDATES 45 #define SV_PING_TIMEOUT 46 #if !defined (DEFAULT_PING_TIMEOUT) # define DEFAULT_PING_TIMEOUT 1 #endif #if !defined (DEFAULT_DEFAULT_LEASE_TIME) # define DEFAULT_DEFAULT_LEASE_TIME 43200 #endif #if !defined (DEFAULT_MIN_LEASE_TIME) # define DEFAULT_MIN_LEASE_TIME 0 #endif #if !defined (DEFAULT_MAX_LEASE_TIME) # define DEFAULT_MAX_LEASE_TIME 86400 #endif #if !defined (DEFAULT_DDNS_TTL) # define DEFAULT_DDNS_TTL 3600 #endif /* Client option names */ #define CL_TIMEOUT 1 #define CL_SELECT_INTERVAL 2 #define CL_REBOOT_TIMEOUT 3 #define CL_RETRY_INTERVAL 4 #define CL_BACKOFF_CUTOFF 5 #define CL_INITIAL_INTERVAL 6 #define CL_BOOTP_POLICY 7 #define CL_SCRIPT_NAME 8 #define CL_REQUESTED_OPTIONS 9 #define CL_REQUESTED_LEASE_TIME 10 #define CL_SEND_OPTIONS 11 #define CL_MEDIA 12 #define CL_REJECT_LIST 13 #ifndef CL_DEFAULT_TIMEOUT # define CL_DEFAULT_TIMEOUT 60 #endif #ifndef CL_DEFAULT_SELECT_INTERVAL # define CL_DEFAULT_SELECT_INTERVAL 0 #endif #ifndef CL_DEFAULT_REBOOT_TIMEOUT # define CL_DEFAULT_REBOOT_TIMEOUT 10 #endif #ifndef CL_DEFAULT_RETRY_INTERVAL # define CL_DEFAULT_RETRY_INTERVAL 300 #endif #ifndef CL_DEFAULT_BACKOFF_CUTOFF # define CL_DEFAULT_BACKOFF_CUTOFF 120 #endif #ifndef CL_DEFAULT_INITIAL_INTERVAL # define CL_DEFAULT_INITIAL_INTERVAL 10 #endif #ifndef CL_DEFAULT_BOOTP_POLICY # define CL_DEFAULT_BOOTP_POLICY P_ACCEPT #endif #ifndef CL_DEFAULT_REQUESTED_OPTIONS # define CL_DEFAULT_REQUESTED_OPTIONS \ { DHO_SUBNET_MASK, \ DHO_BROADCAST_ADDRESS, \ DHO_TIME_OFFSET, \ DHO_ROUTERS, \ DHO_DOMAIN_NAME, \ DHO_DOMAIN_NAME_SERVERS, \ DHO_HOST_NAME } #endif struct group_object { OMAPI_OBJECT_PREAMBLE; struct group_object *n_dynamic; struct group *group; char *name; int flags; #define GROUP_OBJECT_DELETED 1 #define GROUP_OBJECT_DYNAMIC 2 #define GROUP_OBJECT_STATIC 4 }; /* Group of declarations that share common parameters. */ struct group { struct group *next; int refcnt; struct group_object *object; struct subnet *subnet; struct shared_network *shared_network; int authoritative; struct executable_statement *statements; }; /* A dhcp host declaration structure. */ struct host_decl { OMAPI_OBJECT_PREAMBLE; struct host_decl *n_ipaddr; struct host_decl *n_dynamic; char *name; struct hardware interface; struct data_string client_identifier; struct option_cache *fixed_addr; struct group *group; struct group_object *named_group; struct data_string auth_key_id; int flags; #define HOST_DECL_DELETED 1 #define HOST_DECL_DYNAMIC 2 #define HOST_DECL_STATIC 4 }; struct permit { struct permit *next; enum { permit_unknown_clients, permit_known_clients, permit_authenticated_clients, permit_unauthenticated_clients, permit_all_clients, permit_dynamic_bootp_clients, permit_class } type; struct class *class; }; struct pool { OMAPI_OBJECT_PREAMBLE; struct pool *next; struct group *group; struct shared_network *shared_network; struct permit *permit_list; struct permit *prohibit_list; struct lease *active; struct lease *expired; struct lease *free; struct lease *backup; struct lease *abandoned; TIME next_event_time; int lease_count; int free_leases; int backup_leases; int index; #if defined (FAILOVER_PROTOCOL) dhcp_failover_state_t *failover_peer; #endif }; struct shared_network { OMAPI_OBJECT_PREAMBLE; struct shared_network *next; char *name; struct subnet *subnets; struct interface_info *interface; struct pool *pools; struct group *group; #if defined (FAILOVER_PROTOCOL) dhcp_failover_state_t *failover_peer; #endif }; struct subnet { OMAPI_OBJECT_PREAMBLE; struct subnet *next_subnet; struct subnet *next_sibling; struct shared_network *shared_network; struct interface_info *interface; struct iaddr interface_address; struct iaddr net; struct iaddr netmask; struct group *group; }; struct collection { struct collection *next; const char *name; struct class *classes; }; /* XXX classes must be reference-counted. */ struct class { OMAPI_OBJECT_PREAMBLE; struct class *nic; /* Next in collection. */ struct class *superclass; /* Set for spawned classes only. */ char *name; /* Not set for spawned classes. */ /* A class may be configured to permit a limited number of leases. */ int lease_limit; int leases_consumed; struct lease **billed_leases; /* If nonzero, class has not been saved since it was last modified. */ int dirty; /* Hash table containing subclasses. */ class_hash_t *hash; struct data_string hash_string; /* Expression used to match class. */ struct expression *expr; /* Expression used to compute subclass identifiers for spawning and to do subclass matching. */ struct expression *submatch; int spawning; struct group *group; /* Statements to execute if class matches. */ struct executable_statement *statements; }; /* DHCP client lease structure... */ struct client_lease { struct client_lease *next; /* Next lease in list. */ TIME expiry, renewal, rebind; /* Lease timeouts. */ struct iaddr address; /* Address being leased. */ char *server_name; /* Name of boot server. */ char *filename; /* Name of file we're supposed to boot. */ struct string_list *medium; /* Network medium. */ struct auth_key *key; /* Key used in basic DHCP authentication. */ unsigned int is_static : 1; /* If set, lease is from config file. */ unsigned int is_bootp: 1; /* If set, lease was acquired with BOOTP. */ struct option_state *options; /* Options supplied with lease. */ }; /* Possible states in which the client can be. */ enum dhcp_state { S_REBOOTING = 1, S_INIT = 2, S_SELECTING = 3, S_REQUESTING = 4, S_BOUND = 5, S_RENEWING = 6, S_REBINDING = 7, S_STOPPED = 8 }; /* Authentication and BOOTP policy possibilities (not all values work for each). */ enum policy { P_IGNORE, P_ACCEPT, P_PREFER, P_REQUIRE, P_DONT }; /* Configuration information from the config file... */ struct client_config { /* * When a message has been received, run these statements * over it. */ struct group *on_receipt; /* * When a message is sent, run these statements. */ struct group *on_transmission; u_int32_t *required_options; /* Options server must supply. */ u_int32_t *requested_options; /* Options to request from server. */ TIME timeout; /* Start to panic if we don't get a lease in this time period when SELECTING. */ TIME initial_interval; /* All exponential backoff intervals start here. */ TIME retry_interval; /* If the protocol failed to produce an address before the timeout, try the protocol again after this many seconds. */ TIME select_interval; /* Wait this many seconds from the first DHCPDISCOVER before picking an offered lease. */ TIME reboot_timeout; /* When in INIT-REBOOT, wait this long before giving up and going to INIT. */ TIME backoff_cutoff; /* When doing exponential backoff, never back off to an interval longer than this amount. */ u_int32_t requested_lease; /* Requested lease time, if user doesn't configure one. */ struct string_list *media; /* Possible network media values. */ char *script_name; /* Name of config script. */ char *vendor_space_name; /* Name of config script. */ enum policy bootp_policy; /* Ignore, accept or prefer BOOTP responses. */ enum policy auth_policy; /* Require authentication, prefer authentication, or don't try to authenticate. */ struct string_list *medium; /* Current network medium. */ struct iaddrlist *reject_list; /* Servers to reject. */ int omapi_port; /* port on which to accept OMAPI connections, or -1 for no listener. */ int do_forward_update; /* If nonzero, and if we have the information we need, update the A record for the address we get. */ }; /* Per-interface state used in the dhcp client... */ struct client_state { struct client_state *next; struct interface_info *interface; char *name; struct client_lease *active; /* Currently active lease. */ struct client_lease *new; /* New lease. */ struct client_lease *offered_leases; /* Leases offered to us. */ struct client_lease *leases; /* Leases we currently hold. */ struct client_lease *alias; /* Alias lease. */ enum dhcp_state state; /* Current state for this interface. */ struct iaddr destination; /* Where to send packet. */ u_int32_t xid; /* Transaction ID. */ u_int16_t secs; /* secs value from DHCPDISCOVER. */ TIME first_sending; /* When was first copy sent? */ TIME interval; /* What's the current resend interval? */ int dns_update_timeout; /* Last timeout set for DNS update. */ struct string_list *medium; /* Last media type tried. */ struct dhcp_packet packet; /* Outgoing DHCP packet. */ unsigned packet_length; /* Actual length of generated packet. */ struct iaddr requested_address; /* Address we would like to get. */ struct client_config *config; /* Client configuration. */ struct string_list *env; /* Client script environment. */ int envc; /* Number of entries in environment. */ struct option_state *sent_options; /* Options we sent. */ }; /* Information about each network interface. */ struct interface_info { OMAPI_OBJECT_PREAMBLE; struct interface_info *next; /* Next interface in list... */ struct shared_network *shared_network; /* Networks connected to this interface. */ struct hardware hw_address; /* Its physical address. */ struct in_addr primary_address; /* Primary interface address. */ u_int8_t *circuit_id; /* Circuit ID associated with this interface. */ unsigned circuit_id_len; /* Length of Circuit ID, if there is one. */ u_int8_t *remote_id; /* Remote ID associated with this interface (if any). */ unsigned remote_id_len; /* Length of Remote ID. */ char name [IFNAMSIZ]; /* Its name... */ int ieee80211; /* True if media is ieee802.11 */ int havemedia; /* True if we have a media table */ int linkstate; /* True if we have link */ int polling; /* True if polling is enabled */ int forcediscover; /* True if a discover is needed */ int index; /* Its index. */ int rfdesc; /* Its read file descriptor. */ int wfdesc; /* Its write file descriptor, if different. */ unsigned char *rbuf; /* Read buffer, if required. */ unsigned int rbuf_max; /* Size of read buffer. */ size_t rbuf_offset; /* Current offset into buffer. */ size_t rbuf_len; /* Length of data in buffer. */ struct ifreq *ifp; /* Pointer to ifreq struct. */ u_int32_t flags; /* Control flags... */ #define INTERFACE_REQUESTED 1 #define INTERFACE_AUTOMATIC 2 #define INTERFACE_RUNNING 4 /* Only used by DHCP client code. */ struct client_state *client; # if defined (USE_DLPI_SEND) || defined (USE_DLPI_RECEIVE) int dlpi_sap_length; struct hardware dlpi_broadcast_addr; # endif /* DLPI_SEND || DLPI_RECEIVE */ }; struct hardware_link { struct hardware_link *next; char name [IFNAMSIZ]; struct hardware address; }; typedef void (*tvref_t)(void *, void *, const char *, int); typedef void (*tvunref_t)(void *, const char *, int); struct timeout { struct timeout *next; TIME when; void (*func) PROTO ((void *)); void *what; tvref_t ref; tvunref_t unref; }; struct protocol { struct protocol *next; int fd; void (*handler) PROTO ((struct protocol *)); void *local; }; struct dns_query; /* forward */ struct dns_wakeup { struct dns_wakeup *next; /* Next wakeup in chain. */ void (*func) PROTO ((struct dns_query *)); }; struct dns_question { u_int16_t type; /* Type of query. */ u_int16_t class; /* Class of query. */ unsigned char data [1]; /* Query data. */ }; struct dns_answer { u_int16_t type; /* Type of answer. */ u_int16_t class; /* Class of answer. */ int count; /* Number of answers. */ unsigned char *answers[1]; /* Pointers to answers. */ }; struct dns_query { struct dns_query *next; /* Next query in hash bucket. */ u_int32_t hash; /* Hash bucket index. */ TIME expiry; /* Query expiry time (zero if not yet answered. */ u_int16_t id; /* Query ID (also hash table index) */ caddr_t waiters; /* Pointer to list of things waiting on this query. */ struct dns_question *question; /* Question, internal format. */ struct dns_answer *answer; /* Answer, internal format. */ unsigned char *query; /* Query formatted for DNS server. */ unsigned len; /* Length of entire query. */ int sent; /* The query has been sent. */ struct dns_wakeup *wakeups; /* Wakeups to call if this query is answered. */ struct name_server *next_server; /* Next server to try. */ int backoff; /* Current backoff, in seconds. */ }; struct dns_zone { int refcnt; TIME timeout; char *name; struct option_cache *primary; struct option_cache *secondary; struct auth_key *key; }; struct icmp_state { OMAPI_OBJECT_PREAMBLE; int socket; void (*icmp_handler) PROTO ((struct iaddr, u_int8_t *, int)); }; #include "ctrace.h" /* Bitmask of dhcp option codes. */ typedef unsigned char option_mask [16]; /* DHCP Option mask manipulation macros... */ #define OPTION_ZERO(mask) (memset (mask, 0, 16)) #define OPTION_SET(mask, bit) (mask [bit >> 8] |= (1 << (bit & 7))) #define OPTION_CLR(mask, bit) (mask [bit >> 8] &= ~(1 << (bit & 7))) #define OPTION_ISSET(mask, bit) (mask [bit >> 8] & (1 << (bit & 7))) #define OPTION_ISCLR(mask, bit) (!OPTION_ISSET (mask, bit)) /* An option occupies its length plus two header bytes (code and length) for every 255 bytes that must be stored. */ #define OPTION_SPACE(x) ((x) + 2 * ((x) / 255 + 1)) /* Default path to dhcpd config file. */ #ifdef DEBUG #undef _PATH_DHCPD_CONF #define _PATH_DHCPD_CONF "dhcpd.conf" #undef _PATH_DHCPD_DB #define _PATH_DHCPD_DB "dhcpd.leases" #undef _PATH_DHCPD_PID #define _PATH_DHCPD_PID "dhcpd.pid" #else #ifndef _PATH_DHCPD_CONF #define _PATH_DHCPD_CONF "/etc/dhcpd.conf" #endif #ifndef _PATH_DHCPD_DB #define _PATH_DHCPD_DB "/etc/dhcpd.leases" #endif #ifndef _PATH_DHCPD_PID #define _PATH_DHCPD_PID "/var/run/dhcpd.pid" #endif #endif #ifndef _PATH_DHCLIENT_CONF #define _PATH_DHCLIENT_CONF "/etc/dhclient.conf" #endif #ifndef _PATH_DHCLIENT_SCRIPT #define _PATH_DHCLIENT_SCRIPT "/sbin/dhclient-script" #endif #ifndef _PATH_DHCLIENT_PID #define _PATH_DHCLIENT_PID "/var/run/dhclient.pid" #endif #ifndef _PATH_DHCLIENT_DB #define _PATH_DHCLIENT_DB "/etc/dhclient.leases" #endif #ifndef _PATH_RESOLV_CONF #define _PATH_RESOLV_CONF "/etc/resolv.conf" #endif #ifndef _PATH_DHCRELAY_PID #define _PATH_DHCRELAY_PID "/var/run/dhcrelay.pid" #endif #ifndef DHCPD_LOG_FACILITY #define DHCPD_LOG_FACILITY LOG_DAEMON #endif #define MAX_TIME 0x7fffffff #define MIN_TIME 0 /* External definitions... */ HASH_FUNCTIONS_DECL (group, const char *, struct group_object, group_hash_t) HASH_FUNCTIONS_DECL (universe, const char *, struct universe, universe_hash_t) HASH_FUNCTIONS_DECL (option, const char *, struct option, option_hash_t) HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone, dns_zone_hash_t) HASH_FUNCTIONS_DECL (lease, const unsigned char *, struct lease, lease_hash_t) HASH_FUNCTIONS_DECL (host, const unsigned char *, struct host_decl, host_hash_t) HASH_FUNCTIONS_DECL (class, const char *, struct class, class_hash_t) /* options.c */ extern struct option *vendor_cfg_option; int parse_options PROTO ((struct packet *)); int parse_option_buffer PROTO ((struct option_state *, const unsigned char *, unsigned, struct universe *)); struct universe *find_option_universe (struct option *, const char *); int parse_encapsulated_suboptions (struct option_state *, struct option *, const unsigned char *, unsigned, struct universe *, const char *); int cons_options PROTO ((struct packet *, struct dhcp_packet *, struct lease *, struct client_state *, int, struct option_state *, struct option_state *, struct binding_scope **, int, int, int, struct data_string *, const char *)); int fqdn_universe_decode (struct option_state *, const unsigned char *, unsigned, struct universe *); int store_options PROTO ((unsigned char *, unsigned, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, unsigned *, int, unsigned, unsigned, int, const char *)); const char *pretty_print_option PROTO ((struct option *, const unsigned char *, unsigned, int, int)); int get_option (struct data_string *, struct universe *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct option_state *, struct binding_scope **, unsigned, const char *, int); void set_option (struct universe *, struct option_state *, struct option_cache *, enum statement_op); struct option_cache *lookup_option PROTO ((struct universe *, struct option_state *, unsigned)); struct option_cache *lookup_hashed_option PROTO ((struct universe *, struct option_state *, unsigned)); int save_option_buffer (struct universe *, struct option_state *, struct buffer *, unsigned char *, unsigned, struct option *, int); void save_option PROTO ((struct universe *, struct option_state *, struct option_cache *)); void save_hashed_option PROTO ((struct universe *, struct option_state *, struct option_cache *)); void delete_option PROTO ((struct universe *, struct option_state *, int)); void delete_hashed_option PROTO ((struct universe *, struct option_state *, int)); int option_cache_dereference PROTO ((struct option_cache **, const char *, int)); int hashed_option_state_dereference PROTO ((struct universe *, struct option_state *, const char *, int)); int store_option PROTO ((struct data_string *, struct universe *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct option_cache *)); int option_space_encapsulate PROTO ((struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct data_string *)); int hashed_option_space_encapsulate PROTO ((struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)); int nwip_option_space_encapsulate PROTO ((struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)); int fqdn_option_space_encapsulate (struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *); void suboption_foreach (struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *, void (*) (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 *, const char *); void option_space_foreach (struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *, void (*) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)); void hashed_option_space_foreach (struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *, void (*) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)); int linked_option_get PROTO ((struct data_string *, struct universe *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct option_state *, struct binding_scope **, unsigned)); int linked_option_state_dereference PROTO ((struct universe *, struct option_state *, const char *, int)); void save_linked_option (struct universe *, struct option_state *, struct option_cache *); void linked_option_space_foreach (struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *, void (*) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)); int linked_option_space_encapsulate (struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *); void delete_linked_option (struct universe *, struct option_state *, int); struct option_cache *lookup_linked_option (struct universe *, struct option_state *, unsigned); void do_packet PROTO ((struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)); /* dhcpd.c */ extern TIME cur_time; int ddns_update_style; extern const char *path_dhcpd_conf; extern const char *path_dhcpd_db; extern const char *path_dhcpd_pid; extern int dhcp_max_agent_option_packet_length; int main PROTO ((int, char **, char **)); void postconf_initialization (int); void postdb_startup (void); void cleanup PROTO ((void)); void lease_pinged PROTO ((struct iaddr, u_int8_t *, int)); void lease_ping_timeout PROTO ((void *)); int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia); enum dhcp_shutdown_state shutdown_state; isc_result_t dhcp_io_shutdown (omapi_object_t *, void *); isc_result_t dhcp_set_control_state (control_object_state_t oldstate, control_object_state_t newstate); /* conflex.c */ isc_result_t new_parse PROTO ((struct parse **, int, char *, unsigned, const char *, int)); isc_result_t end_parse PROTO ((struct parse **)); enum dhcp_token next_token PROTO ((const char **, unsigned *, struct parse *)); enum dhcp_token peek_token PROTO ((const char **, unsigned *, struct parse *)); /* confpars.c */ void parse_trace_setup (void); isc_result_t readconf PROTO ((void)); isc_result_t read_conf_file (const char *, struct group *, int, int); #if defined (TRACING) void trace_conf_input (trace_type_t *, unsigned, char *); void trace_conf_stop (trace_type_t *ttype); #endif isc_result_t conf_file_subparse (struct parse *, struct group *, int); isc_result_t lease_file_subparse (struct parse *); int parse_statement PROTO ((struct parse *, struct group *, int, struct host_decl *, int)); #if defined (FAILOVER_PROTOCOL) void parse_failover_peer PROTO ((struct parse *, struct group *, int)); void parse_failover_state_declaration (struct parse *, dhcp_failover_state_t *); void parse_failover_state PROTO ((struct parse *, enum failover_state *, TIME *)); #endif int permit_list_match (struct permit *, struct permit *); void parse_pool_statement PROTO ((struct parse *, struct group *, int)); int parse_boolean PROTO ((struct parse *)); int parse_lbrace PROTO ((struct parse *)); void parse_host_declaration PROTO ((struct parse *, struct group *)); int parse_class_declaration PROTO ((struct class **, struct parse *, struct group *, int)); void parse_shared_net_declaration PROTO ((struct parse *, struct group *)); void parse_subnet_declaration PROTO ((struct parse *, struct shared_network *)); void parse_group_declaration PROTO ((struct parse *, struct group *)); int parse_fixed_addr_param PROTO ((struct option_cache **, struct parse *)); TIME parse_timestamp PROTO ((struct parse *)); int parse_lease_declaration PROTO ((struct lease **, struct parse *)); void parse_address_range PROTO ((struct parse *, struct group *, int, struct pool *, struct lease **)); /* ddns.c */ int ddns_updates PROTO ((struct packet *, struct lease *, struct lease *, struct lease_state *)); int ddns_removals PROTO ((struct lease *)); /* parse.c */ void add_enumeration (struct enumeration *); struct enumeration *find_enumeration (const char *, int); struct enumeration_value *find_enumeration_value (const char *, int, const char *); void skip_to_semi PROTO ((struct parse *)); void skip_to_rbrace PROTO ((struct parse *, int)); int parse_semi PROTO ((struct parse *)); int parse_string PROTO ((struct parse *, char **, unsigned *)); char *parse_host_name PROTO ((struct parse *)); int parse_ip_addr_or_hostname PROTO ((struct expression **, struct parse *, int)); void parse_hardware_param PROTO ((struct parse *, struct hardware *)); void parse_lease_time PROTO ((struct parse *, TIME *)); unsigned char *parse_numeric_aggregate PROTO ((struct parse *, unsigned char *, unsigned *, int, int, unsigned)); void convert_num PROTO ((struct parse *, unsigned char *, const char *, int, unsigned)); TIME parse_date PROTO ((struct parse *)); struct option *parse_option_name PROTO ((struct parse *, int, int *)); void parse_option_space_decl PROTO ((struct parse *)); int parse_option_code_definition PROTO ((struct parse *, struct option *)); int parse_base64 (struct data_string *, struct parse *); int parse_cshl PROTO ((struct data_string *, struct parse *)); int parse_executable_statement PROTO ((struct executable_statement **, struct parse *, int *, enum expression_context)); int parse_executable_statements PROTO ((struct executable_statement **, struct parse *, int *, enum expression_context)); int parse_zone (struct dns_zone *, struct parse *); int parse_key (struct parse *); int parse_on_statement PROTO ((struct executable_statement **, struct parse *, int *)); int parse_switch_statement PROTO ((struct executable_statement **, struct parse *, int *)); int parse_case_statement PROTO ((struct executable_statement **, struct parse *, int *, enum expression_context)); int parse_if_statement PROTO ((struct executable_statement **, struct parse *, int *)); int parse_boolean_expression PROTO ((struct expression **, struct parse *, int *)); int parse_data_expression PROTO ((struct expression **, struct parse *, int *)); int parse_numeric_expression PROTO ((struct expression **, struct parse *, int *)); int parse_dns_expression PROTO ((struct expression **, struct parse *, int *)); int parse_non_binary PROTO ((struct expression **, struct parse *, int *, enum expression_context)); int parse_expression PROTO ((struct expression **, struct parse *, int *, enum expression_context, struct expression **, enum expr_op)); int parse_option_statement PROTO ((struct executable_statement **, struct parse *, int, struct option *, enum statement_op)); int parse_option_token PROTO ((struct expression **, struct parse *, const char **, struct expression *, int, int)); int parse_allow_deny PROTO ((struct option_cache **, struct parse *, int)); int parse_auth_key PROTO ((struct data_string *, struct parse *)); int parse_warn (struct parse *, const char *, ...) __attribute__((__format__(__printf__,2,3))); /* tree.c */ #if defined (NSUPDATE) extern struct __res_state resolver_state; extern int resolver_inited; #endif extern struct binding_scope *global_scope; pair cons PROTO ((caddr_t, pair)); int make_const_option_cache PROTO ((struct option_cache **, struct buffer **, u_int8_t *, unsigned, struct option *, const char *, int)); int make_host_lookup PROTO ((struct expression **, const char *)); int enter_dns_host PROTO ((struct dns_host_entry **, const char *)); int make_const_data (struct expression **, const unsigned char *, unsigned, int, int, const char *, int); int make_const_int PROTO ((struct expression **, unsigned long)); int make_concat PROTO ((struct expression **, struct expression *, struct expression *)); int make_encapsulation PROTO ((struct expression **, struct data_string *)); int make_substring PROTO ((struct expression **, struct expression *, struct expression *, struct expression *)); int make_limit PROTO ((struct expression **, struct expression *, int)); int make_let PROTO ((struct executable_statement **, const char *)); int option_cache PROTO ((struct option_cache **, struct data_string *, struct expression *, struct option *, const char *, int)); int evaluate_expression (struct binding_value **, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *, const char *, int); int binding_value_dereference (struct binding_value **, const char *, int); #if defined (NSUPDATE) int evaluate_dns_expression PROTO ((ns_updrec **, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *)); #endif int evaluate_boolean_expression PROTO ((int *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *)); int evaluate_data_expression PROTO ((struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *, const char *, int)); int evaluate_numeric_expression (unsigned long *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *); int evaluate_option_cache PROTO ((struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct option_cache *, const char *, int)); int evaluate_boolean_option_cache PROTO ((int *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct option_cache *, const char *, int)); int evaluate_boolean_expression_result PROTO ((int *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *)); void expression_dereference PROTO ((struct expression **, const char *, int)); int is_dns_expression PROTO ((struct expression *)); int is_boolean_expression PROTO ((struct expression *)); int is_data_expression PROTO ((struct expression *)); int is_numeric_expression PROTO ((struct expression *)); int is_compound_expression PROTO ((struct expression *)); int op_precedence PROTO ((enum expr_op, enum expr_op)); enum expression_context expression_context (struct expression *); enum expression_context op_context PROTO ((enum expr_op)); int write_expression PROTO ((FILE *, struct expression *, int, int, int)); struct binding *find_binding PROTO ((struct binding_scope *, const char *)); int free_bindings PROTO ((struct binding_scope *, const char *, int)); int binding_scope_dereference PROTO ((struct binding_scope **, const char *, int)); int fundef_dereference (struct fundef **, const char *, int); int data_subexpression_length (int *, struct expression *); int expr_valid_for_context (struct expression *, enum expression_context); struct binding *create_binding (struct binding_scope **, const char *); int bind_ds_value (struct binding_scope **, const char *, struct data_string *); int find_bound_string (struct data_string *, struct binding_scope *, const char *); int unset (struct binding_scope *, const char *); /* dhcp.c */ extern int outstanding_pings; void dhcp PROTO ((struct packet *)); void dhcpdiscover PROTO ((struct packet *, int)); void dhcprequest PROTO ((struct packet *, int, struct lease *)); void dhcprelease PROTO ((struct packet *, int)); void dhcpdecline PROTO ((struct packet *, int)); void dhcpinform PROTO ((struct packet *, int)); void nak_lease PROTO ((struct packet *, struct iaddr *cip)); void ack_lease PROTO ((struct packet *, struct lease *, unsigned int, TIME, char *, int)); void dhcp_reply PROTO ((struct lease *)); int find_lease PROTO ((struct lease **, struct packet *, struct shared_network *, int *, int *, struct lease *, const char *, int)); int mockup_lease PROTO ((struct lease **, struct packet *, struct shared_network *, struct host_decl *)); void static_lease_dereference PROTO ((struct lease *, const char *, int)); int allocate_lease PROTO ((struct lease **, struct packet *, struct pool *, int *)); int permitted PROTO ((struct packet *, struct permit *)); int locate_network PROTO ((struct packet *)); int parse_agent_information_option PROTO ((struct packet *, int, u_int8_t *)); unsigned cons_agent_information_options PROTO ((struct option_state *, struct dhcp_packet *, unsigned, unsigned)); /* bootp.c */ void bootp PROTO ((struct packet *)); /* memory.c */ int (*group_write_hook) (struct group_object *); extern struct group *root_group; extern group_hash_t *group_name_hash; isc_result_t delete_group (struct group_object *, int); isc_result_t supersede_group (struct group_object *, int); int clone_group (struct group **, struct group *, const char *, int); int write_group PROTO ((struct group_object *)); /* salloc.c */ void relinquish_lease_hunks (void); struct lease *new_leases PROTO ((unsigned, const char *, int)); #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) void relinquish_free_lease_states (void); #endif OMAPI_OBJECT_ALLOC_DECL (lease, struct lease, dhcp_type_lease) OMAPI_OBJECT_ALLOC_DECL (class, struct class, dhcp_type_class) OMAPI_OBJECT_ALLOC_DECL (pool, struct pool, dhcp_type_pool) OMAPI_OBJECT_ALLOC_DECL (host, struct host_decl, dhcp_type_host) /* alloc.c */ OMAPI_OBJECT_ALLOC_DECL (subnet, struct subnet, dhcp_type_subnet) OMAPI_OBJECT_ALLOC_DECL (shared_network, struct shared_network, dhcp_type_shared_network) OMAPI_OBJECT_ALLOC_DECL (group_object, struct group_object, dhcp_type_group) OMAPI_OBJECT_ALLOC_DECL (dhcp_control, dhcp_control_object_t, dhcp_type_control) #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) void relinquish_free_pairs (void); void relinquish_free_expressions (void); void relinquish_free_binding_values (void); void relinquish_free_option_caches (void); void relinquish_free_packets (void); #endif int option_chain_head_allocate (struct option_chain_head **, const char *, int); int option_chain_head_reference (struct option_chain_head **, struct option_chain_head *, const char *, int); int option_chain_head_dereference (struct option_chain_head **, const char *, int); int group_allocate (struct group **, const char *, int); int group_reference (struct group **, struct group *, const char *, int); int group_dereference (struct group **, const char *, int); struct dhcp_packet *new_dhcp_packet PROTO ((const char *, int)); struct protocol *new_protocol PROTO ((const char *, int)); struct lease_state *new_lease_state PROTO ((const char *, int)); struct domain_search_list *new_domain_search_list PROTO ((const char *, int)); struct name_server *new_name_server PROTO ((const char *, int)); void free_name_server PROTO ((struct name_server *, const char *, int)); struct option *new_option PROTO ((const char *, int)); int group_allocate (struct group **, const char *, int); int group_reference (struct group **, struct group *, const char *, int); int group_dereference (struct group **, const char *, int); void free_option PROTO ((struct option *, const char *, int)); struct universe *new_universe PROTO ((const char *, int)); void free_universe PROTO ((struct universe *, const char *, int)); void free_domain_search_list PROTO ((struct domain_search_list *, const char *, int)); void free_lease_state PROTO ((struct lease_state *, const char *, int)); void free_protocol PROTO ((struct protocol *, const char *, int)); void free_dhcp_packet PROTO ((struct dhcp_packet *, const char *, int)); struct client_lease *new_client_lease PROTO ((const char *, int)); void free_client_lease PROTO ((struct client_lease *, const char *, int)); struct permit *new_permit PROTO ((const char *, int)); void free_permit PROTO ((struct permit *, const char *, int)); pair new_pair PROTO ((const char *, int)); void free_pair PROTO ((pair, const char *, int)); int expression_allocate PROTO ((struct expression **, const char *, int)); int expression_reference PROTO ((struct expression **, struct expression *, const char *, int)); void free_expression PROTO ((struct expression *, const char *, int)); int binding_value_allocate PROTO ((struct binding_value **, const char *, int)); int binding_value_reference PROTO ((struct binding_value **, struct binding_value *, const char *, int)); void free_binding_value PROTO ((struct binding_value *, const char *, int)); int fundef_allocate PROTO ((struct fundef **, const char *, int)); int fundef_reference PROTO ((struct fundef **, struct fundef *, const char *, int)); int option_cache_allocate PROTO ((struct option_cache **, const char *, int)); int option_cache_reference PROTO ((struct option_cache **, struct option_cache *, const char *, int)); int buffer_allocate PROTO ((struct buffer **, unsigned, const char *, int)); int buffer_reference PROTO ((struct buffer **, struct buffer *, const char *, int)); int buffer_dereference PROTO ((struct buffer **, const char *, int)); int dns_host_entry_allocate PROTO ((struct dns_host_entry **, const char *, const char *, int)); int dns_host_entry_reference PROTO ((struct dns_host_entry **, struct dns_host_entry *, const char *, int)); int dns_host_entry_dereference PROTO ((struct dns_host_entry **, const char *, int)); int option_state_allocate PROTO ((struct option_state **, const char *, int)); int option_state_reference PROTO ((struct option_state **, struct option_state *, const char *, int)); int option_state_dereference PROTO ((struct option_state **, const char *, int)); void data_string_copy PROTO ((struct data_string *, struct data_string *, const char *, int)); void data_string_forget PROTO ((struct data_string *, const char *, int)); void data_string_truncate PROTO ((struct data_string *, int)); int executable_statement_allocate PROTO ((struct executable_statement **, const char *, int)); int executable_statement_reference PROTO ((struct executable_statement **, struct executable_statement *, const char *, int)); int packet_allocate PROTO ((struct packet **, const char *, int)); int packet_reference PROTO ((struct packet **, struct packet *, const char *, int)); int packet_dereference PROTO ((struct packet **, const char *, int)); int binding_scope_allocate PROTO ((struct binding_scope **, const char *, int)); int binding_scope_reference PROTO ((struct binding_scope **, struct binding_scope *, const char *, int)); int dns_zone_allocate PROTO ((struct dns_zone **, const char *, int)); int dns_zone_reference PROTO ((struct dns_zone **, struct dns_zone *, const char *, int)); /* print.c */ char *quotify_string (const char *, const char *, int); char *quotify_buf (const unsigned char *, unsigned, const char *, int); char *print_base64 (const unsigned char *, unsigned, const char *, int); char *print_hw_addr PROTO ((int, int, unsigned char *)); void print_lease PROTO ((struct lease *)); void dump_raw PROTO ((const unsigned char *, unsigned)); void dump_packet_option (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *); void dump_packet PROTO ((struct packet *)); void hash_dump PROTO ((struct hash_table *)); char *print_hex_1 PROTO ((unsigned, const u_int8_t *, unsigned)); char *print_hex_2 PROTO ((unsigned, const u_int8_t *, unsigned)); char *print_hex_3 PROTO ((unsigned, const u_int8_t *, unsigned)); char *print_dotted_quads PROTO ((unsigned, const u_int8_t *)); char *print_dec_1 PROTO ((unsigned long)); char *print_dec_2 PROTO ((unsigned long)); void print_expression PROTO ((const char *, struct expression *)); int token_print_indent_concat (FILE *, int, int, const char *, const char *, ...); int token_indent_data_string (FILE *, int, int, const char *, const char *, struct data_string *); int token_print_indent (FILE *, int, int, const char *, const char *, const char *); void indent_spaces (FILE *, int); #if defined (NSUPDATE) void print_dns_status (int, ns_updque *); #endif /* socket.c */ #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \ || defined (USE_SOCKET_FALLBACK) int if_register_socket PROTO ((struct interface_info *)); #endif #if defined (USE_SOCKET_FALLBACK) && !defined (USE_SOCKET_SEND) void if_reinitialize_fallback PROTO ((struct interface_info *)); void if_register_fallback PROTO ((struct interface_info *)); ssize_t send_fallback PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_SOCKET_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_SOCKET_RECEIVE void if_reinitialize_receive PROTO ((struct interface_info *)); void if_register_receive PROTO ((struct interface_info *)); void if_deregister_receive PROTO ((struct interface_info *)); ssize_t receive_packet PROTO ((struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)); #endif #if defined (USE_SOCKET_FALLBACK) isc_result_t fallback_discard PROTO ((omapi_object_t *)); #endif #if defined (USE_SOCKET_SEND) int can_unicast_without_arp PROTO ((struct interface_info *)); int can_receive_unicast_unconfigured PROTO ((struct interface_info *)); int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback PROTO ((void)); #endif /* bpf.c */ #if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE) int if_register_bpf PROTO ( (struct interface_info *)); #endif #ifdef USE_BPF_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_BPF_RECEIVE void if_reinitialize_receive PROTO ((struct interface_info *)); void if_register_receive PROTO ((struct interface_info *)); void if_deregister_receive PROTO ((struct interface_info *)); ssize_t receive_packet PROTO ((struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)); #endif #if defined (USE_BPF_SEND) int can_unicast_without_arp PROTO ((struct interface_info *)); int can_receive_unicast_unconfigured PROTO ((struct interface_info *)); int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback PROTO ((void)); #endif /* lpf.c */ #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) int if_register_lpf PROTO ( (struct interface_info *)); #endif #ifdef USE_LPF_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_LPF_RECEIVE void if_reinitialize_receive PROTO ((struct interface_info *)); void if_register_receive PROTO ((struct interface_info *)); void if_deregister_receive PROTO ((struct interface_info *)); ssize_t receive_packet PROTO ((struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)); #endif #if defined (USE_LPF_SEND) int can_unicast_without_arp PROTO ((struct interface_info *)); int can_receive_unicast_unconfigured PROTO ((struct interface_info *)); int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback PROTO ((void)); #endif /* nit.c */ #if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE) int if_register_nit PROTO ( (struct interface_info *)); #endif #ifdef USE_NIT_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_NIT_RECEIVE void if_reinitialize_receive PROTO ((struct interface_info *)); void if_register_receive PROTO ((struct interface_info *)); void if_deregister_receive PROTO ((struct interface_info *)); ssize_t receive_packet PROTO ((struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)); #endif #if defined (USE_NIT_SEND) int can_unicast_without_arp PROTO ((struct interface_info *)); int can_receive_unicast_unconfigured PROTO ((struct interface_info *)); int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback PROTO ((void)); #endif /* dlpi.c */ #if defined (USE_DLPI_SEND) || defined (USE_DLPI_RECEIVE) int if_register_dlpi PROTO ( (struct interface_info *)); #endif #ifdef USE_DLPI_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); #endif #ifdef USE_DLPI_RECEIVE void if_reinitialize_receive PROTO ((struct interface_info *)); void if_register_receive PROTO ((struct interface_info *)); void if_deregister_receive PROTO ((struct interface_info *)); ssize_t receive_packet PROTO ((struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)); #endif /* raw.c */ #ifdef USE_RAW_SEND void if_reinitialize_send PROTO ((struct interface_info *)); void if_register_send PROTO ((struct interface_info *)); void if_deregister_send PROTO ((struct interface_info *)); ssize_t send_packet PROTO ((struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)); int can_unicast_without_arp PROTO ((struct interface_info *)); int can_receive_unicast_unconfigured PROTO ((struct interface_info *)); int supports_multiple_interfaces (struct interface_info *); void maybe_setup_fallback PROTO ((void)); #endif /* discover.c */ extern struct interface_info *interfaces, *dummy_interfaces, *fallback_interface; extern struct protocol *protocols; extern int quiet_interface_discovery; isc_result_t interface_setup (void); void interface_trace_setup (void); extern struct in_addr limited_broadcast; extern struct in_addr local_address; extern u_int16_t local_port; extern u_int16_t remote_port; extern int (*dhcp_interface_setup_hook) (struct interface_info *, struct iaddr *); extern int (*dhcp_interface_discovery_hook) (struct interface_info *); isc_result_t (*dhcp_interface_startup_hook) (struct interface_info *); extern void (*bootp_packet_handler) PROTO ((struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)); extern struct timeout *timeouts; extern 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 extern struct interface_info **interface_vector; extern int interface_count; extern int interface_max; isc_result_t interface_initialize (omapi_object_t *, const char *, int); void discover_interfaces PROTO ((int)); int setup_fallback (struct interface_info **, const char *, int); int if_readsocket PROTO ((omapi_object_t *)); void reinitialize_interfaces PROTO ((void)); /* dispatch.c */ void set_time (u_int32_t); struct timeval *process_outstanding_timeouts (struct timeval *); void dispatch PROTO ((void)); isc_result_t got_one PROTO ((omapi_object_t *)); isc_result_t interface_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t interface_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t interface_destroy (omapi_object_t *, const char *, int); isc_result_t interface_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t interface_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *, tvref_t, tvunref_t)); void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *)); void cancel_all_timeouts (void); void relinquish_timeouts (void); #if 0 struct protocol *add_protocol PROTO ((const char *, int, void (*) PROTO ((struct protocol *)), void *)); void remove_protocol PROTO ((struct protocol *)); #endif OMAPI_OBJECT_ALLOC_DECL (interface, struct interface_info, dhcp_type_interface) /* tables.c */ extern struct universe dhcp_universe; extern struct option dhcp_options [256]; extern struct universe nwip_universe; extern struct option nwip_options [256]; extern struct universe fqdn_universe; extern struct option fqdn_options [256]; extern int dhcp_option_default_priority_list []; extern int dhcp_option_default_priority_list_count; extern const char *hardware_types [256]; int universe_count, universe_max; struct universe **universes; extern universe_hash_t *universe_hash; void initialize_common_option_spaces PROTO ((void)); struct universe *config_universe; /* stables.c */ #if defined (FAILOVER_PROTOCOL) extern failover_option_t null_failover_option; extern failover_option_t skip_failover_option; extern struct failover_option_info ft_options []; extern u_int32_t fto_allowed []; extern int ft_sizes []; extern const char *dhcp_flink_state_names []; #endif extern const char *binding_state_names []; extern struct universe agent_universe; extern struct option agent_options [256]; extern struct universe server_universe; extern struct option server_options [256]; extern struct enumeration ddns_styles; extern struct enumeration syslog_enum; void initialize_server_option_spaces PROTO ((void)); /* inet.c */ struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr)); struct iaddr ip_addr PROTO ((struct iaddr, struct iaddr, u_int32_t)); struct iaddr broadcast_addr PROTO ((struct iaddr, struct iaddr)); u_int32_t host_addr PROTO ((struct iaddr, struct iaddr)); int addr_eq PROTO ((struct iaddr, struct iaddr)); char *piaddr PROTO ((struct iaddr)); char *piaddrmask (struct iaddr, struct iaddr, const char *, int); char *piaddr1 PROTO ((struct iaddr)); /* dhclient.c */ extern const char *path_dhclient_conf; extern const char *path_dhclient_db; extern const char *path_dhclient_pid; extern char *path_dhclient_script; extern int interfaces_requested; extern struct client_config top_level_config; void dhcpoffer PROTO ((struct packet *)); void dhcpack PROTO ((struct packet *)); void dhcpnak PROTO ((struct packet *)); void send_discover PROTO ((void *)); void send_request PROTO ((void *)); void send_release PROTO ((void *)); void send_decline PROTO ((void *)); void state_reboot PROTO ((void *)); #ifdef ENABLE_POLLING_MODE void state_polling PROTO (()); void state_background PROTO ((void *)); #endif void state_init PROTO ((void *)); void state_selecting PROTO ((void *)); void state_requesting PROTO ((void *)); void state_bound PROTO ((void *)); void state_stop PROTO ((void *)); void state_panic PROTO ((void *)); #ifdef __FreeBSD__ void set_ieee80211 PROTO ((struct interface_info *)); #endif int interface_active PROTO ((struct interface_info *)); void bind_lease PROTO ((struct client_state *)); void make_client_options PROTO ((struct client_state *, struct client_lease *, u_int8_t *, struct option_cache *, struct iaddr *, u_int32_t *, struct option_state **)); void make_discover PROTO ((struct client_state *, struct client_lease *)); void make_request PROTO ((struct client_state *, struct client_lease *)); void make_decline PROTO ((struct client_state *, struct client_lease *)); void make_release PROTO ((struct client_state *, struct client_lease *)); void destroy_client_lease PROTO ((struct client_lease *)); void rewrite_client_leases PROTO ((void)); void write_lease_option (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *); int write_client_lease PROTO ((struct client_state *, struct client_lease *, int, int)); int dhcp_option_ev_name (char *, size_t, struct option *); void script_init PROTO ((struct client_state *, const char *, struct string_list *)); void client_option_envadd (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *); void script_write_params PROTO ((struct client_state *, const char *, struct client_lease *)); int script_go PROTO ((struct client_state *)); void client_envadd (struct client_state *, const char *, const char *, const char *, ...) __attribute__((__format__(__printf__,4,5))); struct client_lease *packet_to_lease (struct packet *, struct client_state *); void go_daemon PROTO ((void)); void write_client_pid_file PROTO ((void)); void client_location_changed PROTO ((void)); void do_release PROTO ((struct client_state *)); int dhclient_interface_shutdown_hook (struct interface_info *); int dhclient_interface_discovery_hook (struct interface_info *); isc_result_t dhclient_interface_startup_hook (struct interface_info *); void client_dns_update_timeout (void *cp); isc_result_t client_dns_update (struct client_state *client, int, int); /* db.c */ int write_lease PROTO ((struct lease *)); int write_host PROTO ((struct host_decl *)); #if defined (FAILOVER_PROTOCOL) int write_failover_state (dhcp_failover_state_t *); #endif int db_printable PROTO ((const char *)); int db_printable_len PROTO ((const unsigned char *, unsigned)); void write_named_billing_class (const char *, unsigned, struct class *); void write_billing_classes (void); int write_billing_class PROTO ((struct class *)); void commit_leases_timeout PROTO ((void *)); int commit_leases PROTO ((void)); void db_startup PROTO ((int)); int new_lease_file PROTO ((void)); int group_writer (struct group_object *); /* packet.c */ u_int32_t checksum PROTO ((unsigned char *, unsigned, u_int32_t)); u_int32_t wrapsum PROTO ((u_int32_t)); void assemble_hw_header PROTO ((struct interface_info *, unsigned char *, unsigned *, struct hardware *)); void assemble_udp_ip_header PROTO ((struct interface_info *, unsigned char *, unsigned *, u_int32_t, u_int32_t, u_int32_t, unsigned char *, unsigned)); ssize_t decode_hw_header PROTO ((struct interface_info *, unsigned char *, unsigned, struct hardware *)); ssize_t decode_udp_ip_header PROTO ((struct interface_info *, unsigned char *, unsigned, struct sockaddr_in *, unsigned char *, unsigned)); /* ethernet.c */ void assemble_ethernet_header PROTO ((struct interface_info *, unsigned char *, unsigned *, struct hardware *)); ssize_t decode_ethernet_header PROTO ((struct interface_info *, unsigned char *, unsigned, struct hardware *)); /* tr.c */ void assemble_tr_header PROTO ((struct interface_info *, unsigned char *, unsigned *, struct hardware *)); ssize_t decode_tr_header PROTO ((struct interface_info *, unsigned char *, unsigned, struct hardware *)); /* dhxpxlt.c */ void convert_statement PROTO ((struct parse *)); void convert_host_statement PROTO ((struct parse *, jrefproto)); void convert_host_name PROTO ((struct parse *, jrefproto)); void convert_class_statement PROTO ((struct parse *, jrefproto, int)); void convert_class_decl PROTO ((struct parse *, jrefproto)); void convert_lease_time PROTO ((struct parse *, jrefproto, char *)); void convert_shared_net_statement PROTO ((struct parse *, jrefproto)); void convert_subnet_statement PROTO ((struct parse *, jrefproto)); void convert_subnet_decl PROTO ((struct parse *, jrefproto)); void convert_host_decl PROTO ((struct parse *, jrefproto)); void convert_hardware_decl PROTO ((struct parse *, jrefproto)); void convert_hardware_addr PROTO ((struct parse *, jrefproto)); void convert_filename_decl PROTO ((struct parse *, jrefproto)); void convert_servername_decl PROTO ((struct parse *, jrefproto)); void convert_ip_addr_or_hostname PROTO ((struct parse *, jrefproto, int)); void convert_fixed_addr_decl PROTO ((struct parse *, jrefproto)); void convert_option_decl PROTO ((struct parse *, jrefproto)); void convert_timestamp PROTO ((struct parse *, jrefproto)); void convert_lease_statement PROTO ((struct parse *, jrefproto)); void convert_address_range PROTO ((struct parse *, jrefproto)); void convert_date PROTO ((struct parse *, jrefproto, char *)); void convert_numeric_aggregate PROTO ((struct parse *, jrefproto, int, int, int, int)); void indent PROTO ((int)); /* route.c */ void add_route_direct PROTO ((struct interface_info *, struct in_addr)); void add_route_net PROTO ((struct interface_info *, struct in_addr, struct in_addr)); void add_route_default_gateway PROTO ((struct interface_info *, struct in_addr)); void remove_routes PROTO ((struct in_addr)); void remove_if_route PROTO ((struct interface_info *, struct in_addr)); void remove_all_if_routes PROTO ((struct interface_info *)); void set_netmask PROTO ((struct interface_info *, struct in_addr)); void set_broadcast_addr PROTO ((struct interface_info *, struct in_addr)); void set_ip_address PROTO ((struct interface_info *, struct in_addr)); /* clparse.c */ isc_result_t read_client_conf PROTO ((void)); int read_client_conf_file (const char *, struct interface_info *, struct client_config *); void read_client_leases PROTO ((void)); void parse_client_statement PROTO ((struct parse *, struct interface_info *, struct client_config *)); int parse_X PROTO ((struct parse *, u_int8_t *, unsigned)); void parse_option_list PROTO ((struct parse *, u_int32_t **)); void parse_interface_declaration PROTO ((struct parse *, struct client_config *, char *)); int interface_or_dummy PROTO ((struct interface_info **, const char *)); void make_client_state PROTO ((struct client_state **)); void make_client_config PROTO ((struct client_state *, struct client_config *)); void parse_client_lease_statement PROTO ((struct parse *, int)); void parse_client_lease_declaration PROTO ((struct parse *, struct client_lease *, struct interface_info **, struct client_state **)); int parse_option_decl PROTO ((struct option_cache **, struct parse *)); void parse_string_list PROTO ((struct parse *, struct string_list **, int)); int parse_ip_addr PROTO ((struct parse *, struct iaddr *)); void parse_reject_statement PROTO ((struct parse *, struct client_config *)); /* dhcrelay.c */ void relay PROTO ((struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)); int strip_relay_agent_options PROTO ((struct interface_info *, struct interface_info **, struct dhcp_packet *, unsigned)); int find_interface_by_agent_option PROTO ((struct dhcp_packet *, struct interface_info **, u_int8_t *, int)); int add_relay_agent_options PROTO ((struct interface_info *, struct dhcp_packet *, unsigned, struct in_addr)); /* icmp.c */ OMAPI_OBJECT_ALLOC_DECL (icmp_state, struct icmp_state, dhcp_type_icmp) extern struct icmp_state *icmp_state; void icmp_startup PROTO ((int, void (*) PROTO ((struct iaddr, u_int8_t *, int)))); int icmp_readsocket PROTO ((omapi_object_t *)); int icmp_echorequest PROTO ((struct iaddr *)); isc_result_t icmp_echoreply PROTO ((omapi_object_t *)); /* dns.c */ #if defined (NSUPDATE) isc_result_t find_tsig_key (ns_tsig_key **, const char *, struct dns_zone *); void tkey_free (ns_tsig_key **); #endif isc_result_t enter_dns_zone (struct dns_zone *); isc_result_t dns_zone_lookup (struct dns_zone **, const char *); int dns_zone_dereference PROTO ((struct dns_zone **, const char *, int)); #if defined (NSUPDATE) isc_result_t find_cached_zone (const char *, ns_class, char *, size_t, struct in_addr *, int, int *, struct dns_zone **); void forget_zone (struct dns_zone **); void repudiate_zone (struct dns_zone **); void cache_found_zone (ns_class, char *, struct in_addr *, int); int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned); isc_result_t ddns_update_a (struct data_string *, struct iaddr, struct data_string *, unsigned long, int); isc_result_t ddns_remove_a (struct data_string *, struct iaddr, struct data_string *); #endif /* NSUPDATE */ /* resolv.c */ extern char path_resolv_conf []; struct name_server *name_servers; struct domain_search_list *domains; void read_resolv_conf PROTO ((TIME)); struct name_server *first_name_server PROTO ((void)); /* inet_addr.c */ #ifdef NEED_INET_ATON int inet_aton PROTO ((const char *, struct in_addr *)); #endif /* class.c */ extern int have_billing_classes; struct class unknown_class; struct class known_class; struct collection default_collection; struct collection *collections; struct executable_statement *default_classification_rules; void classification_setup PROTO ((void)); void classify_client PROTO ((struct packet *)); int check_collection PROTO ((struct packet *, struct lease *, struct collection *)); void classify PROTO ((struct packet *, struct class *)); isc_result_t find_class PROTO ((struct class **, const char *, const char *, int)); int unbill_class PROTO ((struct lease *, struct class *)); int bill_class PROTO ((struct lease *, struct class *)); /* execute.c */ int execute_statements PROTO ((struct binding_value **result, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct executable_statement *)); void execute_statements_in_scope PROTO ((struct binding_value **result, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct group *, struct group *)); int executable_statement_dereference PROTO ((struct executable_statement **, const char *, int)); void write_statements (FILE *, struct executable_statement *, int); int find_matching_case (struct executable_statement **, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *, struct executable_statement *); int executable_statement_foreach (struct executable_statement *, int (*) (struct executable_statement *, void *, int), void *, int); /* comapi.c */ extern omapi_object_type_t *dhcp_type_interface; extern omapi_object_type_t *dhcp_type_group; extern omapi_object_type_t *dhcp_type_shared_network; extern omapi_object_type_t *dhcp_type_subnet; extern omapi_object_type_t *dhcp_type_control; extern dhcp_control_object_t *dhcp_control_object; void dhcp_common_objects_setup (void); isc_result_t dhcp_group_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_group_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_group_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_group_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_group_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_group_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_group_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_group_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_control_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_control_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_control_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_control_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_control_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_control_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_control_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_control_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subnet_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_subnet_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_subnet_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_subnet_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_subnet_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subnet_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subnet_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_subnet_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_shared_network_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_shared_network_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_shared_network_remove (omapi_object_t *, omapi_object_t *); /* omapi.c */ extern int (*dhcp_interface_shutdown_hook) (struct interface_info *); extern omapi_object_type_t *dhcp_type_lease; extern omapi_object_type_t *dhcp_type_pool; extern omapi_object_type_t *dhcp_type_class; #if defined (FAILOVER_PROTOCOL) extern omapi_object_type_t *dhcp_type_failover_state; extern omapi_object_type_t *dhcp_type_failover_link; extern omapi_object_type_t *dhcp_type_failover_listener; #endif void dhcp_db_objects_setup (void); isc_result_t dhcp_lease_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_lease_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_lease_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_lease_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_lease_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_lease_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_lease_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_lease_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_group_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_group_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_group_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_group_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_group_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_group_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_group_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_group_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_host_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_host_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_host_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_host_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_host_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_host_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_host_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_host_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_pool_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_pool_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_pool_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_pool_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_pool_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_pool_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_pool_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_pool_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_class_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_class_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_class_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_class_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_class_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_class_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_class_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_class_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subclass_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_subclass_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_subclass_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_subclass_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_subclass_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subclass_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subclass_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_subclass_remove (omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_shared_network_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_shared_network_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_shared_network_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_subnet_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_subnet_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_subnet_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_subnet_signal_handler (omapi_object_t *, const char *, va_list); isc_result_t dhcp_subnet_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subnet_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_subnet_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_interface_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t dhcp_interface_get_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **); isc_result_t dhcp_interface_destroy (omapi_object_t *, const char *, int); isc_result_t dhcp_interface_signal_handler (omapi_object_t *, const char *, va_list ap); isc_result_t dhcp_interface_stuff_values (omapi_object_t *, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_interface_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_interface_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_interface_remove (omapi_object_t *, omapi_object_t *); void interface_stash (struct interface_info *); void interface_snorf (struct interface_info *, int); isc_result_t binding_scope_set_value (struct binding_scope *, int, omapi_data_string_t *, omapi_typed_data_t *); isc_result_t binding_scope_get_value (omapi_value_t **, struct binding_scope *, omapi_data_string_t *); isc_result_t binding_scope_stuff_values (omapi_object_t *, struct binding_scope *); /* mdb.c */ extern struct subnet *subnets; extern struct shared_network *shared_networks; extern host_hash_t *host_hw_addr_hash; extern host_hash_t *host_uid_hash; extern host_hash_t *host_name_hash; extern lease_hash_t *lease_uid_hash; extern lease_hash_t *lease_ip_addr_hash; extern lease_hash_t *lease_hw_addr_hash; extern omapi_object_type_t *dhcp_type_host; isc_result_t enter_host PROTO ((struct host_decl *, int, int)); isc_result_t delete_host PROTO ((struct host_decl *, int)); int find_hosts_by_haddr PROTO ((struct host_decl **, int, const unsigned char *, unsigned, const char *, int)); int find_hosts_by_uid PROTO ((struct host_decl **, const unsigned char *, unsigned, const char *, int)); int find_host_for_network PROTO ((struct subnet **, struct host_decl **, struct iaddr *, struct shared_network *)); void new_address_range PROTO ((struct parse *, struct iaddr, struct iaddr, struct subnet *, struct pool *, struct lease **)); isc_result_t dhcp_lease_free (omapi_object_t *, const char *, int); isc_result_t dhcp_lease_get (omapi_object_t **, const char *, int); int find_grouped_subnet PROTO ((struct subnet **, struct shared_network *, struct iaddr, const char *, int)); int find_subnet (struct subnet **, struct iaddr, const char *, int); void enter_shared_network PROTO ((struct shared_network *)); void new_shared_network_interface PROTO ((struct parse *, struct shared_network *, const char *)); int subnet_inner_than PROTO ((struct subnet *, struct subnet *, int)); void enter_subnet PROTO ((struct subnet *)); void enter_lease PROTO ((struct lease *)); int supersede_lease PROTO ((struct lease *, struct lease *, int, int, int)); void make_binding_state_transition (struct lease *); int lease_copy PROTO ((struct lease **, struct lease *, const char *, int)); void release_lease PROTO ((struct lease *, struct packet *)); void abandon_lease PROTO ((struct lease *, const char *)); void dissociate_lease PROTO ((struct lease *)); void pool_timer PROTO ((void *)); int find_lease_by_uid PROTO ((struct lease **, const unsigned char *, unsigned, const char *, int)); int find_lease_by_hw_addr PROTO ((struct lease **, const unsigned char *, unsigned, const char *, int)); int find_lease_by_ip_addr PROTO ((struct lease **, struct iaddr, const char *, int)); void uid_hash_add PROTO ((struct lease *)); void uid_hash_delete PROTO ((struct lease *)); void hw_hash_add PROTO ((struct lease *)); void hw_hash_delete PROTO ((struct lease *)); int write_leases PROTO ((void)); int lease_enqueue (struct lease *); void lease_instantiate (const unsigned char *, unsigned, struct lease *); void expire_all_pools PROTO ((void)); void dump_subnets PROTO ((void)); #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) void free_everything (void); #endif /* nsupdate.c */ char *ddns_rev_name (struct lease *, struct lease_state *, struct packet *); char *ddns_fwd_name (struct lease *, struct lease_state *, struct packet *); int nsupdateA (const char *, const unsigned char *, u_int32_t, int); int nsupdatePTR (const char *, const unsigned char *, u_int32_t, int); void nsupdate (struct lease *, struct lease_state *, struct packet *, int); int updateA (const struct data_string *, const struct data_string *, unsigned int, struct lease *); int updatePTR (const struct data_string *, const struct data_string *, unsigned int, struct lease *); int deleteA (const struct data_string *, const struct data_string *, struct lease *); int deletePTR (const struct data_string *, const struct data_string *, struct lease *); /* failover.c */ #if defined (FAILOVER_PROTOCOL) extern dhcp_failover_state_t *failover_states; void dhcp_failover_startup PROTO ((void)); int dhcp_failover_write_all_states (void); isc_result_t enter_failover_peer PROTO ((dhcp_failover_state_t *)); isc_result_t find_failover_peer PROTO ((dhcp_failover_state_t **, const char *, const char *, int)); isc_result_t dhcp_failover_link_initiate PROTO ((omapi_object_t *)); isc_result_t dhcp_failover_link_signal PROTO ((omapi_object_t *, const char *, va_list)); isc_result_t dhcp_failover_link_set_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)); isc_result_t dhcp_failover_link_get_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **)); isc_result_t dhcp_failover_link_destroy PROTO ((omapi_object_t *, const char *, int)); isc_result_t dhcp_failover_link_stuff_values PROTO ((omapi_object_t *, omapi_object_t *, omapi_object_t *)); isc_result_t dhcp_failover_listen PROTO ((omapi_object_t *)); isc_result_t dhcp_failover_listener_signal PROTO ((omapi_object_t *, const char *, va_list)); isc_result_t dhcp_failover_listener_set_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)); isc_result_t dhcp_failover_listener_get_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **)); isc_result_t dhcp_failover_listener_destroy PROTO ((omapi_object_t *, const char *, int)); isc_result_t dhcp_failover_listener_stuff PROTO ((omapi_object_t *, omapi_object_t *, omapi_object_t *)); isc_result_t dhcp_failover_register PROTO ((omapi_object_t *)); isc_result_t dhcp_failover_state_signal PROTO ((omapi_object_t *, const char *, va_list)); isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *, const char *); isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state); isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *, enum failover_state); isc_result_t dhcp_failover_peer_state_changed (dhcp_failover_state_t *, failover_message_t *); int dhcp_failover_pool_rebalance (dhcp_failover_state_t *); int dhcp_failover_pool_check (struct pool *); int dhcp_failover_state_pool_check (dhcp_failover_state_t *); void dhcp_failover_timeout (void *); void dhcp_failover_send_contact (void *); isc_result_t dhcp_failover_send_state (dhcp_failover_state_t *); isc_result_t dhcp_failover_send_updates (dhcp_failover_state_t *); int dhcp_failover_queue_update (struct lease *, int); int dhcp_failover_send_acks (dhcp_failover_state_t *); void dhcp_failover_toack_queue_timeout (void *); int dhcp_failover_queue_ack (dhcp_failover_state_t *, failover_message_t *msg); void dhcp_failover_ack_queue_remove (dhcp_failover_state_t *, struct lease *); isc_result_t dhcp_failover_state_set_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)); void dhcp_failover_keepalive (void *); void dhcp_failover_reconnect (void *); void dhcp_failover_startup_timeout (void *); void dhcp_failover_link_startup_timeout (void *); void dhcp_failover_listener_restart (void *); isc_result_t dhcp_failover_state_get_value PROTO ((omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **)); isc_result_t dhcp_failover_state_destroy PROTO ((omapi_object_t *, const char *, int)); isc_result_t dhcp_failover_state_stuff PROTO ((omapi_object_t *, omapi_object_t *, omapi_object_t *)); isc_result_t dhcp_failover_state_lookup PROTO ((omapi_object_t **, omapi_object_t *, omapi_object_t *)); isc_result_t dhcp_failover_state_create PROTO ((omapi_object_t **, omapi_object_t *)); isc_result_t dhcp_failover_state_remove PROTO ((omapi_object_t *, omapi_object_t *)); int dhcp_failover_state_match (dhcp_failover_state_t *, u_int8_t *, unsigned); const char *dhcp_failover_reject_reason_print (int); const char *dhcp_failover_state_name_print (enum failover_state); const char *dhcp_failover_message_name (unsigned); const char *dhcp_failover_option_name (unsigned); failover_option_t *dhcp_failover_option_printf (unsigned, char *, unsigned *, unsigned, const char *, ...) __attribute__((__format__(__printf__,5,6))); failover_option_t *dhcp_failover_make_option (unsigned, char *, unsigned *, unsigned, ...); isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *, omapi_object_t *, int, ...); isc_result_t dhcp_failover_send_connect PROTO ((omapi_object_t *)); isc_result_t dhcp_failover_send_connectack PROTO ((omapi_object_t *, dhcp_failover_state_t *, int, const char *)); isc_result_t dhcp_failover_send_disconnect PROTO ((omapi_object_t *, int, const char *)); isc_result_t dhcp_failover_send_bind_update (dhcp_failover_state_t *, struct lease *); isc_result_t dhcp_failover_send_bind_ack (dhcp_failover_state_t *, failover_message_t *, int, const char *); isc_result_t dhcp_failover_send_poolreq (dhcp_failover_state_t *); isc_result_t dhcp_failover_send_poolresp (dhcp_failover_state_t *, int); isc_result_t dhcp_failover_send_update_request (dhcp_failover_state_t *); isc_result_t dhcp_failover_send_update_request_all (dhcp_failover_state_t *); isc_result_t dhcp_failover_send_update_done (dhcp_failover_state_t *); isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *, failover_message_t *); isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *, failover_message_t *); isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *, int); isc_result_t dhcp_failover_process_update_request (dhcp_failover_state_t *, failover_message_t *); isc_result_t dhcp_failover_process_update_request_all (dhcp_failover_state_t *, failover_message_t *); isc_result_t dhcp_failover_process_update_done (dhcp_failover_state_t *, failover_message_t *); void dhcp_failover_recover_done (void *); void failover_print PROTO ((char *, unsigned *, unsigned, const char *)); void update_partner PROTO ((struct lease *)); int load_balance_mine (struct packet *, dhcp_failover_state_t *); binding_state_t normal_binding_state_transition_check (struct lease *, dhcp_failover_state_t *, binding_state_t, u_int32_t); binding_state_t conflict_binding_state_transition_check (struct lease *, dhcp_failover_state_t *, binding_state_t, u_int32_t); int lease_mine_to_reallocate (struct lease *); OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_state, dhcp_failover_state_t, dhcp_type_failover_state) OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_listener, dhcp_failover_listener_t, dhcp_type_failover_listener) OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_link, dhcp_failover_link_t, dhcp_type_failover_link) #endif /* FAILOVER_PROTOCOL */ const char *binding_state_print (enum failover_state);