summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>1997-02-22 12:59:29 +0000
committerTed Lemon <source@isc.org>1997-02-22 12:59:29 +0000
commited1d504ffb0987764e95fee023d30ddc690a0e2a (patch)
treec62eb52776d819cad8c4043d2afac373d334d018
parent6e5382c00db22b9da5e4804970eb7e5754a9634c (diff)
downloadisc-dhcp-ed1d504ffb0987764e95fee023d30ddc690a0e2a.tar.gz
moved to client/
-rw-r--r--clparse.c898
-rw-r--r--dhclient.8163
-rw-r--r--dhclient.c1617
-rw-r--r--dhclient.conf.563
-rw-r--r--dhclient.conf.cat566
5 files changed, 0 insertions, 2807 deletions
diff --git a/clparse.c b/clparse.c
deleted file mode 100644
index 80ad82a5..00000000
--- a/clparse.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/* clparse.c
-
- Parser for dhclient config and lease files... */
-
-/*
- * Copyright (c) 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: clparse.c,v 1.4 1997/02/22 12:23:22 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "dhctoken.h"
-
-static TIME parsed_time;
-
-/* client-conf-file :== client-declarations EOF
- client-declarations :== <nil>
- | client-declaration
- | client-declarations client-declaration */
-
-int read_client_conf ()
-{
- FILE *cfile;
- char *val;
- int token;
- int declaration = 0;
- struct client_config *config;
- struct client_state *state;
- struct interface_info *ip;
-
- new_parse (path_dhclient_conf);
-
- /* Set up the initial dhcp option universe. */
- initialize_universes ();
-
- /* Initialize the top level client configuration. */
- memset (&top_level_config, 0, sizeof top_level_config);
-
- if ((cfile = fopen (path_dhclient_conf, "r")) == NULL)
- error ("Can't open %s: %m", path_dhclient_conf);
- do {
- token = peek_token (&val, cfile);
- if (token == EOF)
- break;
- parse_client_statement (cfile, (struct interface_info *)0,
- &top_level_config);
- } while (1);
- token = next_token (&val, cfile); /* Clear the peek buffer */
-
- /* Set up state and config structures for clients that don't
- have per-interface configuration declarations. */
- config = (struct client_config *)0;
- for (ip = interfaces; ip; ip = ip -> next) {
- if (!ip -> client) {
- ip -> client = (struct client_state *)
- malloc (sizeof (struct client_state));
- if (!ip -> client)
- error ("no memory for client state.");
- memset (ip -> client, 0, sizeof *(ip -> client));
- }
- if (!ip -> client -> config) {
- if (!config) {
- config = (struct client_config *)
- malloc (sizeof (struct client_config));
- if (!config)
- error ("no memory for client config.");
- memcpy (config, &top_level_config,
- sizeof top_level_config);
- }
- ip -> client -> config = config;
- }
- }
-
- return !warnings_occurred;
-}
-
-/* lease-file :== client-lease-statements EOF
- client-lease-statements :== <nil>
- | client-lease-statements LEASE client-lease-statement */
-
-void read_client_leases ()
-{
- FILE *cfile;
- char *val;
- int token;
-
- new_parse (path_dhclient_db);
-
- /* Open the lease file. If we can't open it, just return -
- we can safely trust the server to remember our state. */
- if ((cfile = fopen (path_dhclient_db, "r")) == NULL)
- return;
- do {
- token = next_token (&val, cfile);
- if (token == EOF)
- break;
- if (token != LEASE) {
- warn ("Corrupt lease file - possible data loss!");
- skip_to_semi (cfile);
- break;
- } else
- parse_client_lease_statement (cfile, 0);
-
- } while (1);
-}
-
-/* client-declaration :==
- SEND option-decl |
- DEFAULT option-decl |
- hardware-declaration |
- REQUEST option-list |
- REQUIRE option-list |
- TIMEOUT number |
- RETRY number |
- SELECT_TIMEOUT number |
- SCRIPT string |
- interface-declaration |
- LEASE client-lease-statement |
- ALIAS client-lease-statement */
-
-void parse_client_statement (cfile, ip, config)
- FILE *cfile;
- struct interface_info *ip;
- struct client_config *config;
-{
- int token;
- char *val;
-
- switch (next_token (&val, cfile)) {
- case SEND:
- parse_option_decl (cfile, &config -> send_options [0]);
- return;
-
- case DEFAULT:
- parse_option_decl (cfile, &config -> defaults [0]);
- return;
-
- case MEDIA:
- parse_string_list (cfile, &config -> media, 1);
- return;
-
- case HARDWARE:
- if (ip) {
- parse_hardware_param (cfile, &ip -> hw_address);
- } else {
- parse_warn ("hardware address parameter %s",
- "not allowed here.");
- skip_to_semi (cfile);
- }
- return;
-
- case REQUEST:
- config -> requested_option_count =
- parse_option_list (cfile, config -> requested_options);
- return;
-
- case REQUIRE:
- memset (config -> required_options, 0,
- sizeof config -> required_options);
- parse_option_list (cfile, config -> required_options);
- return;
-
- case TIMEOUT:
- parse_lease_time (cfile, &config -> timeout);
- return;
-
- case RETRY:
- parse_lease_time (cfile, &config -> retry_interval);
- return;
-
- case SELECT_TIMEOUT:
- parse_lease_time (cfile, &config -> select_interval);
- return;
-
- case SCRIPT:
- config -> script_name = parse_string (cfile);
- return;
-
- case INTERFACE:
- if (ip)
- parse_warn ("nested interface declaration.");
- parse_interface_declaration (cfile, config);
- return;
-
- case LEASE:
- parse_client_lease_statement (cfile, 1);
- return;
-
- case ALIAS:
- parse_client_lease_statement (cfile, 2);
- return;
-
- default:
- parse_warn ("expecting a statement.");
- skip_to_semi (cfile);
- break;
- }
- token = next_token (&val, cfile);
- if (token != SEMI) {
- parse_warn ("semicolon expected.");
- skip_to_semi (cfile);
- }
-}
-
-int parse_X (cfile, buf, max)
- FILE *cfile;
- u_int8_t *buf;
- int max;
-{
- int token;
- char *val;
- int len;
- u_int8_t *s;
-
- token = peek_token (&val, cfile);
- if (token == NUMBER_OR_NAME || token == NUMBER) {
- len = 0;
- do {
- token = next_token (&val, cfile);
- if (token != NUMBER && token != NUMBER_OR_NAME) {
- parse_warn ("expecting hexadecimal constant.");
- skip_to_semi (cfile);
- return 0;
- }
- convert_num (&buf [len], val, 16, 8);
- if (len++ > max) {
- parse_warn ("hexadecimal constant too long.");
- skip_to_semi (cfile);
- return 0;
- }
- token = peek_token (&val, cfile);
- if (token == COLON)
- token = next_token (&val, cfile);
- } while (token == COLON);
- val = buf;
- } else if (token == STRING) {
- token = next_token (&val, cfile);
- len = strlen (val);
- if (len + 1 > max) {
- parse_warn ("string constant too long.");
- skip_to_semi (cfile);
- return 0;
- }
- memcpy (buf, val, len + 1);
- } else {
- parse_warn ("expecting string or hexadecimal data");
- skip_to_semi (cfile);
- return 0;
- }
- return len;
-}
-
-/* option-list :== option_name |
- option_list COMMA option_name */
-
-int parse_option_list (cfile, list)
- FILE *cfile;
- u_int8_t *list;
-{
- int ix, i;
- int token;
- char *val;
-
- ix = 0;
- do {
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expected option name.");
- skip_to_semi (cfile);
- return 0;
- }
- for (i = 0; i < 256; i++) {
- if (!strcasecmp (dhcp_options [i].name, val))
- break;
- }
- if (i == 256) {
- parse_warn ("%s: expected option name.");
- skip_to_semi (cfile);
- return 0;
- }
- list [ix++] = i;
- if (ix == 256) {
- parse_warn ("%s: too many options.", val);
- skip_to_semi (cfile);
- return 0;
- }
- token = next_token (&val, cfile);
- } while (token == COMMA);
- if (token != SEMI) {
- parse_warn ("expecting semicolon.");
- skip_to_semi (cfile);
- return 0;
- }
- return ix;
-}
-
-/* interface-declaration :==
- INTERFACE string LBRACE client-declarations RBRACE */
-
-void parse_interface_declaration (cfile, outer_config)
- FILE *cfile;
- struct client_config *outer_config;
-{
- int token;
- char *val;
-
- struct interface_info dummy_interface, *ip;
- struct client_state dummy_state;
- struct client_config dummy_config;
-
- token = next_token (&val, cfile);
- if (token != STRING) {
- parse_warn ("expecting interface name (in quotes).");
- skip_to_semi (cfile);
- return;
- }
-
- ip = interface_or_dummy (val);
-
- if (!ip -> client)
- make_client_state (ip);
-
- if (!ip -> client -> config)
- make_client_config (ip, outer_config);
-
- token = next_token (&val, cfile);
- if (token != LBRACE) {
- parse_warn ("expecting left brace.");
- skip_to_semi (cfile);
- return;
- }
-
- do {
- token = peek_token (&val, cfile);
- if (token == EOF) {
- parse_warn ("unterminated interface declaration.");
- return;
- }
- if (token == RBRACE)
- break;
- parse_client_statement (cfile, ip, ip -> client -> config);
- } while (1);
- token = next_token (&val, cfile);
-}
-
-struct interface_info *interface_or_dummy (name)
- char *name;
-{
- struct interface_info *ip;
-
- /* Find the interface (if any) that matches the name. */
- for (ip = interfaces; ip; ip = ip -> next) {
- if (!strcmp (ip -> name, name))
- 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))
- break;
- }
- }
-
- /* If we didn't find an interface, make a dummy interface as
- a placeholder. */
- if (!ip) {
- ip = ((struct interface_info *)malloc (sizeof *ip));
- if (!ip)
- error ("Insufficient memory to record interface %s",
- name);
- memset (ip, 0, sizeof *ip);
- strcpy (ip -> name, name);
- ip -> next = dummy_interfaces;
- dummy_interfaces = ip;
- }
- return ip;
-}
-
-void make_client_state (ip)
- struct interface_info *ip;
-{
- ip -> client =
- ((struct client_state *)malloc (sizeof *(ip -> client)));
- if (!ip -> client)
- error ("no memory for state on %s\n", ip -> name);
- memset (ip -> client, 0, sizeof *(ip -> client));
-}
-
-void make_client_config (ip, config)
- struct interface_info *ip;
- struct client_config *config;
-{
- ip -> client -> config =
- ((struct client_config *)
- malloc (sizeof (struct client_config)));
- if (!ip -> client -> config)
- error ("no memory for config for %s\n", ip -> name);
- memset (ip -> client -> config, 0,
- sizeof *(ip -> client -> config));
- memcpy (ip -> client -> config, config, sizeof *config);
-}
-
-/* client-lease-statement :==
- RBRACE client-lease-declarations LBRACE
-
- client-lease-declarations :==
- <nil> |
- client-lease-declaration |
- client-lease-declarations client-lease-declaration */
-
-
-void parse_client_lease_statement (cfile, is_static)
- FILE *cfile;
- int is_static;
-{
- struct client_lease *lease, *lp, *pl;
- struct interface_info *ip;
- int token;
- char *val;
-
- token = next_token (&val, cfile);
- if (token != LBRACE) {
- parse_warn ("expecting left brace.");
- skip_to_semi (cfile);
- return;
- }
-
- lease = (struct client_lease *)malloc (sizeof (struct client_lease));
- if (!lease)
- error ("no memory for lease.\n");
- memset (lease, 0, sizeof *lease);
- lease -> is_static = is_static;
-
- ip = (struct interface_info *)0;
-
- do {
- token = peek_token (&val, cfile);
- if (token == EOF) {
- parse_warn ("unterminated lease declaration.");
- return;
- }
- if (token == RBRACE)
- break;
- parse_client_lease_declaration (cfile, lease, &ip);
- } while (1);
- token = next_token (&val, cfile);
-
- /* If the lease declaration didn't include an interface
- declaration that we recognized, it's of no use to us. */
- if (!ip) {
- free_client_lease (lease);
- return;
- }
-
- /* Make sure there's a client state structure... */
- if (!ip -> client)
- make_client_state (ip);
-
- /* If this is an alias lease, it doesn't need to be sorted in. */
- if (is_static == 2) {
- ip -> client -> alias = 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 (ip -> client -> active) {
- if (ip -> client -> active -> expiry < cur_time)
- free_client_lease (ip -> client -> active);
- else if (ip -> client -> active -> address.len ==
- lease -> address.len &&
- !memcmp (ip -> client -> active -> address.iabuf,
- lease -> address.iabuf,
- lease -> address.len))
- free_client_lease (ip -> client -> active);
- else {
- ip -> client -> active -> next =
- ip -> client -> leases;
- ip -> client -> leases = ip -> client -> active;
- }
- }
- ip -> client -> active = lease;
-
- /* The current 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 = ip -> client -> leases; lp; lp = 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;
- else
- ip -> client -> leases = lp -> next;
- free_client_lease (lp);
- break;
- }
- }
- /* phew. */
-}
-
-/* client-lease-declaration :==
- INTERFACE string |
- FIXED_ADDR ip_address |
- FILENAME string |
- SERVER_NAME string |
- OPTION option-decl |
- RENEW time-decl |
- REBIND time-decl |
- EXPIRE time-decl */
-
-void parse_client_lease_declaration (cfile, lease, ipp)
- FILE *cfile;
- struct client_lease *lease;
- struct interface_info **ipp;
-{
- int token;
- char *val;
- char *t, *n;
- struct interface_info *ip;
-
- switch (next_token (&val, cfile)) {
- case INTERFACE:
- token = next_token (&val, cfile);
- if (token != STRING) {
- parse_warn ("expecting interface name (in quotes).");
- skip_to_semi (cfile);
- break;
- }
- ip = interface_or_dummy (val);
- *ipp = ip;
- break;
-
- case FIXED_ADDR:
- parse_ip_addr (cfile, &lease -> address);
- break;
-
- case MEDIUM:
- parse_string_list (cfile, &lease -> medium, 0);
- return;
-
- case FILENAME:
- lease -> filename = parse_string (cfile);
- return;
-
- case SERVER_NAME:
- lease -> server_name = parse_string (cfile);
- 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:
- parse_option_decl (cfile, lease -> options);
- return;
-
- default:
- parse_warn ("expecting lease declaration.");
- skip_to_semi (cfile);
- break;
- }
- token = next_token (&val, cfile);
- if (token != SEMI) {
- parse_warn ("expecting semicolon.");
- skip_to_semi (cfile);
- }
-}
-
-void parse_ip_addr (cfile, addr)
- FILE *cfile;
- struct iaddr *addr;
-{
- char *val;
- int token;
-
- addr -> len = 4;
- parse_numeric_aggregate (cfile, addr -> iabuf,
- &addr -> len, DOT, 10, 8);
-}
-
-void parse_option_decl (cfile, options)
- FILE *cfile;
- struct option_data *options;
-{
- char *val;
- int token;
- u_int8_t buf [4];
- u_int8_t hunkbuf [1024];
- int hunkix = 0;
- char *vendor;
- char *fmt;
- struct universe *universe;
- struct option *option;
- struct iaddr ip_addr;
- char *dp;
- int len;
- int nul_term = 0;
-
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier after option keyword.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return;
- }
- vendor = malloc (strlen (val) + 1);
- if (!vendor)
- error ("no memory for vendor information.");
- strcpy (vendor, val);
- token = peek_token (&val, cfile);
- if (token == DOT) {
- /* Go ahead and take the DOT token... */
- token = next_token (&val, cfile);
-
- /* The next token should be an identifier... */
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier after '.'");
- if (token != SEMI)
- skip_to_semi (cfile);
- return;
- }
-
- /* Look up the option name hash table for the specified
- vendor. */
- universe = (struct universe *)hash_lookup (&universe_hash,
- vendor, 0);
- /* If it's not there, we can't parse the rest of the
- declaration. */
- if (!universe) {
- parse_warn ("no vendor named %s.", vendor);
- skip_to_semi (cfile);
- return;
- }
- } else {
- /* Use the default hash table, which contains all the
- standard dhcp option names. */
- val = vendor;
- universe = &dhcp_universe;
- }
-
- /* Look up the actual option info... */
- option = (struct option *)hash_lookup (universe -> hash, val, 0);
-
- /* If we didn't get an option structure, it's an undefined option. */
- if (!option) {
- if (val == vendor)
- parse_warn ("no option named %s", val);
- else
- parse_warn ("no option named %s for vendor %s",
- val, vendor);
- skip_to_semi (cfile);
- return;
- }
-
- /* Free the initial identifier token. */
- free (vendor);
-
- /* Parse the option data... */
- do {
- /* Set a flag if this is an array of a simple type (i.e.,
- not an array of pairs of IP addresses, or something
- like that. */
- int uniform = option -> format [1] == 'A';
-
- for (fmt = option -> format; *fmt; fmt++) {
- if (*fmt == 'A')
- break;
- switch (*fmt) {
- case 'X':
- len = parse_X (cfile, &hunkbuf [hunkix],
- sizeof hunkbuf - hunkix);
- hunkix += len;
- break;
-
- case 't': /* Text string... */
- token = next_token (&val, cfile);
- if (token != STRING) {
- parse_warn ("expecting string.");
- skip_to_semi (cfile);
- return;
- }
- len = strlen (val);
- if (hunkix + len + 1 > sizeof hunkbuf) {
- parse_warn ("option data buffer %s",
- "overflow");
- skip_to_semi (cfile);
- return;
- }
- memcpy (&hunkbuf [hunkix], val, len + 1);
- nul_term = 1;
- hunkix += len;
- break;
-
- case 'I': /* IP address. */
- parse_ip_addr (cfile, &ip_addr);
- len = ip_addr.len;
- dp = ip_addr.iabuf;
-
- alloc:
- if (hunkix + len > sizeof hunkbuf) {
- parse_warn ("option data buffer %s",
- "overflow");
- skip_to_semi (cfile);
- return;
- }
- memcpy (&hunkbuf [hunkix], dp, len);
- hunkix += len;
- break;
-
- case 'L': /* Unsigned 32-bit integer... */
- case 'l': /* Signed 32-bit integer... */
- token = next_token (&val, cfile);
- if (token != NUMBER) {
- need_number:
- parse_warn ("expecting number.");
- if (token != SEMI)
- skip_to_semi (cfile);
- return;
- }
- convert_num (buf, val, 0, 32);
- len = 4;
- dp = buf;
- goto alloc;
-
- case 's': /* Signed 16-bit integer. */
- case 'S': /* Unsigned 16-bit integer. */
- token = next_token (&val, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (buf, val, 0, 16);
- len = 2;
- dp = buf;
- goto alloc;
-
- case 'b': /* Signed 8-bit integer. */
- case 'B': /* Unsigned 8-bit integer. */
- token = next_token (&val, cfile);
- if (token != NUMBER)
- goto need_number;
- convert_num (buf, val, 0, 8);
- len = 1;
- dp = buf;
- goto alloc;
-
- case 'f': /* Boolean flag. */
- token = next_token (&val, cfile);
- if (!is_identifier (token)) {
- parse_warn ("expecting identifier.");
- bad_flag:
- if (token != SEMI)
- skip_to_semi (cfile);
- return;
- }
- if (!strcasecmp (val, "true")
- || !strcasecmp (val, "on"))
- buf [0] = 1;
- else if (!strcasecmp (val, "false")
- || !strcasecmp (val, "off"))
- buf [0] = 0;
- else {
- parse_warn ("expecting boolean.");
- goto bad_flag;
- }
- len = 1;
- dp = buf;
- goto alloc;
-
- default:
- warn ("Bad format %c in parse_option_param.",
- *fmt);
- skip_to_semi (cfile);
- return;
- }
- }
- token = next_token (&val, cfile);
- } while (*fmt == 'A' && token == COMMA);
-
- if (token != SEMI) {
- parse_warn ("semicolon expected.");
- skip_to_semi (cfile);
- return;
- }
-
- options [option -> code].data = malloc (hunkix + nul_term);
- if (!options [option -> code].data)
- error ("out of memory allocating option data.");
- memcpy (options [option -> code].data, hunkbuf, hunkix + nul_term);
- options [option -> code].len = hunkix;
-}
-
-void parse_string_list (cfile, lp, multiple)
- FILE *cfile;
- struct string_list **lp;
- int multiple;
-{
- int token;
- 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, cfile);
- if (token != STRING) {
- parse_warn ("Expecting media options.");
- skip_to_semi (cfile);
- return;
- }
-
- tmp = (struct string_list *)malloc (strlen (val) + 1 +
- sizeof
- (struct string_list *));
- if (!tmp)
- error ("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, cfile);
- } while (multiple && token == COMMA);
-
- if (token != SEMI) {
- parse_warn ("expecting semicolon.");
- skip_to_semi (cfile);
- }
-}
diff --git a/dhclient.8 b/dhclient.8
deleted file mode 100644
index 6edd6a31..00000000
--- a/dhclient.8
+++ /dev/null
@@ -1,163 +0,0 @@
-.\" dhclient.8
-.\"
-.\" Copyright (c) 1997 The Internet Software Consortium.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The Internet Software Consortium nor the names
-.\" of its contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
-.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" This software has been written for the Internet Software Consortium
-.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-.\" Enterprises. To learn more about the Internet Software Consortium,
-.\" see ``http://www.isc.org/isc''. To learn more about Vixie
-.\" Enterprises, see ``http://www.vix.com''.
-.TH dhclient 8
-.SH NAME
-dhcpd - Dynamic Host Configuration Protocol Client
-.SH SYNOPSIS
-.B dhclient
-[
-.B -p
-.I port
-]
-[
-.B -d
-]
-[
-.I if0
-[
-.I ...ifN
-]
-]
-.SH DESCRIPTION
-The Internet Software 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 dhcpd.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 identify all network
-interfaces, elimininating non-broadcast interfaces if possible, and
-attempt to configure each interface.
-.PP
-If dhclient 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.
-.PP
-Dhclient 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 dhclient under
-a debugger, or when running it out of inittab on System V systems.
-.PP
-.SH CONFIGURATION
-The syntax of the dhclient.conf(8) file is discussed seperately.
-.SH FILES
-.B ETCDIR/dhclient.conf, DBDIR/dhclient.leases, RUNDIR/dhclient.pid,
-.B DBDIR/dhclient.leases~.
-.SH SEE ALSO
-dhcpd(8), dhcrelay(8), dhclient.conf(5), dhclient.leases(5)
-.SH AUTHOR
-.B dhclient(8)
-has been written for the Internet Software Consortium
-by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-Enterprises. To learn more about the Internet Software Consortium,
-see
-.B http://www.vix.com/isc.
-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
-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
diff --git a/dhclient.c b/dhclient.c
deleted file mode 100644
index 150547b8..00000000
--- a/dhclient.c
+++ /dev/null
@@ -1,1617 +0,0 @@
-/* dhclient.c
-
- DHCP Client. */
-
-/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- *
- * This client was substantially modified and enhanced by Elliot Poger
- * for use on Linux while he was working on the MosquitoNet project at
- * Stanford.
- *
- * 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
- * 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.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dhclient.c,v 1.26 1997/02/22 12:24:28 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-TIME cur_time;
-TIME default_lease_time = 43200; /* 12 hours... */
-TIME max_lease_time = 86400; /* 24 hours... */
-struct tree_cache *global_options [256];
-
-struct client_config top_level_config;
-
-char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
-char *path_dhclient_db = _PATH_DHCLIENT_DB;
-char *path_dhclient_pid = _PATH_DHCLIENT_PID;
-
-int log_perror = 1;
-
-struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
-struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
-struct in_addr inaddr_any = { INADDR_ANY };
-struct sockaddr_in sockaddr_broadcast;
-
-/* ASSERT_STATE() does nothing now; it used to be
- assert (state_is == state_shouldbe). */
-#define ASSERT_STATE(state_is, state_shouldbe) {}
-
-#ifdef USE_FALLBACK
-struct interface_info fallback_interface;
-#endif
-
-u_int16_t local_port;
-u_int16_t remote_port;
-int log_priority;
-int no_daemon;
-
-static void usage PROTO ((void));
-
-int main (argc, argv, envp)
- int argc;
- char **argv, **envp;
-{
- int i;
- struct servent *ent;
- struct interface_info *ip;
-
-#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))
- setlogmask (LOG_UPTO (LOG_INFO));
-#endif
-
- for (i = 1; i < argc; i++) {
- if (!strcmp (argv [i], "-p")) {
- if (++i == argc)
- usage ();
- local_port = htons (atoi (argv [i]));
- debug ("binding to user-specified port %d",
- ntohs (local_port));
- } else if (!strcmp (argv [i], "-d")) {
- no_daemon = 1;
- } else if (argv [i][0] == '-') {
- usage ();
- } else {
- struct interface_info *tmp =
- ((struct interface_info *)
- dmalloc (sizeof *tmp, "specified_interface"));
- if (!tmp)
- error ("Insufficient memory to %s %s",
- "record interface", argv [i]);
- memset (tmp, 0, sizeof *tmp);
- strcpy (tmp -> name, argv [i]);
- tmp -> next = interfaces;
- tmp -> flags = INTERFACE_REQUESTED;
- interfaces = tmp;
- }
- }
- /* Default to the DHCP/BOOTP port. */
- if (!local_port) {
- ent = getservbyname ("dhcpc", "udp");
- if (!ent)
- local_port = htons (68);
- else
- local_port = ent -> s_port;
- endservent ();
- }
- 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_len = sizeof sockaddr_broadcast;
- sockaddr_broadcast.sin_port = remote_port;
- sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
-#ifdef HAVE_SA_LEN
- sockaddr_broadcast.sin_len = sizeof sockaddr_broadcast;
-#endif
-
- /* 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 ();
-
- /* If no broadcast interfaces were discovered, call the script
- and tell it so. */
- if (!interfaces) {
- script_init ((struct interface_info *)0, "NBI",
- (struct string_list *)0);
- script_go ((struct interface_info *)0);
-
- /* Nothing more to do. */
- exit (0);
- } else {
- /* Call the script with the list of interfaces. */
- for (ip = interfaces; ip; ip = ip -> next) {
- script_init (ip, "PREINIT", (struct string_list *)0);
- if (ip -> client -> alias)
- script_write_params (ip, "alias_",
- ip -> client -> alias);
- script_go (ip);
- }
- }
-
- /* 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 (DISCOVER_RUNNING);
-
- /* Start a configuration state machine for each interface. */
- for (ip = interfaces; ip; ip = ip -> next) {
- srandom (cur_time + *(int *)&ip -> hw_address.haddr);
- ip -> client -> state = S_INIT;
- state_init (ip);
- }
-
- /* Start dispatching packets and timeouts... */
- dispatch (1);
- /*NOTREACHED*/
- return 0;
-}
-
-static void usage ()
-{
- error ("Usage: dhclient [-c] [-p <port>] [interface]");
-}
-
-void cleanup ()
-{
-}
-
-void relay (ip, packet, length)
- struct interface_info *ip;
- struct dhcp_packet *packet;
- int length;
-{
-}
-
-/* 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.
- */
-
-/* Called on startup and also when a lease has completely expired and
- we've been unable to renew it. */
-
-void state_init (ip)
- struct interface_info *ip;
-{
- ASSERT_STATE(state, S_INIT);
-
- /* Make a DHCPDISCOVER packet, and set appropriate per-interface
- flags. */
- make_discover (ip, ip -> client -> active);
- ip -> client -> xid = ip -> client -> packet.xid;
- ip -> client -> destination = iaddr_broadcast;
- ip -> client -> state = S_SELECTING;
- ip -> client -> first_sending = cur_time;
- ip -> client -> interval = 0;
-
- /* Add an immediate timeout to cause the first DHCPDISCOVER packet
- to go out. */
- send_discover (ip);
-}
-
-/* state_selecting is called when one or more DHCPOFFER packets have been
- received and a configurable period of time has passed. */
-
-void state_selecting (ip)
- struct interface_info *ip;
-{
- 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, ip);
- cancel_timeout (send_discover, ip);
-
- /* 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 = ip -> 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) {
- script_init (ip, "ARPCHECK", lp -> medium);
- script_write_params (ip, "check_", lp);
-
- /* If the ARPCHECK code detects another
- machine using the offered address, it exits
- nonzero. We need to send a DHCPDECLINE and
- toss the lease. */
- if (script_go (ip)) {
- make_decline (ip, lp);
- send_decline (ip);
- goto freeit;
- }
- picked = lp;
- picked -> next = (struct client_lease *)0;
- } else {
- freeit:
- free_client_lease (lp);
- }
- }
- ip -> client -> offered_leases = (struct client_lease *)0;
-
- /* If we just tossed all the leases we were offered, go back
- to square one. */
- if (!picked) {
- send_discover (ip);
- return;
- }
-
- /* Go to the REQUESTING state. */
- ip -> client -> destination = iaddr_broadcast;
- ip -> client -> state = S_REQUESTING;
- ip -> client -> first_sending = cur_time;
- ip -> client -> interval = 0;
-
- /* Make a DHCPREQUEST packet from the lease we picked. */
- make_request (ip, picked);
- ip -> client -> xid = ip -> client -> packet.xid;
-
- /* Toss the lease we picked - we'll get it back in a DHCPACK. */
- free_client_lease (picked);
-
- /* Add an immediate timeout to send the first DHCPREQUEST packet. */
- send_request (ip);
-}
-
-/* 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_lease *lease;
- int i;
-
- note ("DHCPACK from %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
-
- /* If we're not receptive to an offer right now, or if the offer
- has an unrecognizable transaction id, then just drop it. */
- if (packet -> interface -> client -> xid != packet -> raw -> xid) {
- note ("DHCPACK in wrong transaction.");
- return;
- }
-
- if (ip -> client -> state != S_REQUESTING &&
- ip -> client -> state != S_RENEWING &&
- ip -> client -> state != S_REBINDING) {
- note ("DHCPACK in wrong state.");
- return;
- }
-
- lease = packet_to_lease (packet);
- if (!lease) {
- note ("packet_to_lease failed.");
- return;
- }
-
- ip -> client -> new = lease;
-
- /* Stop resending DHCPREQUEST. */
- cancel_timeout (send_request, ip);
-
- /* Figure out the lease time. */
- ip -> client -> new -> expiry =
- getULong (ip -> client ->
- new -> options [DHO_DHCP_LEASE_TIME].data);
-
- /* Take the server-provided renewal time if there is one;
- otherwise figure it out according to the spec. */
- if (ip -> client -> new -> options [DHO_DHCP_RENEWAL_TIME].len)
- ip -> client -> new -> renewal =
- getULong (ip -> client ->
- new -> options [DHO_DHCP_RENEWAL_TIME].data);
- else
- ip -> client -> new -> renewal =
- ip -> client -> new -> expiry / 2;
-
- /* Same deal with the rebind time. */
- if (ip -> client -> new -> options [DHO_DHCP_REBINDING_TIME].len)
- ip -> client -> new -> rebind =
- getULong (ip -> client -> new ->
- options [DHO_DHCP_REBINDING_TIME].data);
- else
- ip -> client -> new -> rebind =
- ip -> client -> new -> renewal +
- ip -> client -> new -> renewal / 2 +
- ip -> client -> new -> renewal / 4;
-
- ip -> client -> new -> expiry += cur_time;
- ip -> client -> new -> renewal += cur_time;
- ip -> client -> new -> rebind += cur_time;
-
- /* Write out the new lease. */
- write_client_lease (ip, ip -> client -> new);
-
- /* Remember the medium. */
- ip -> client -> new -> medium = ip -> client -> medium;
-
- /* Run the client script with the new parameters. */
- script_init (ip, (ip -> client -> state == S_REQUESTING
- ? "BOUND"
- : (ip -> client -> state == S_RENEWING
- ? "RENEW"
- : "REBIND")), ip -> client -> new -> medium);
- if (ip -> client -> active)
- script_write_params (ip, "old_", ip -> client -> active);
- script_write_params (ip, "new_", ip -> client -> new);
- if (ip -> client -> alias)
- script_write_params (ip, "alias_", ip -> client -> alias);
- script_go (ip);
-
- /* Replace the old active lease with the new one. */
- if (ip -> client -> active)
- free_client_lease (ip -> client -> active);
- ip -> client -> active = ip -> client -> new;
- ip -> client -> new = (struct client_lease *)0;
-
- /* Set up a timeout to start the renewal process. */
- add_timeout (ip -> client -> active -> renewal,
- state_bound, ip);
-
- note ("bound: renewal in %d seconds.",
- ip -> client -> active -> renewal - cur_time);
- ip -> client -> state = S_BOUND;
- reinitialize_interfaces ();
- go_daemon ();
-}
-
-/* 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 (ip)
- struct interface_info *ip;
-{
- ASSERT_STATE(state, S_BOUND);
-
- /* T1 has expired. */
- make_request (ip, ip -> client -> active);
- ip -> client -> xid = ip -> client -> packet.xid;
-
- if (ip -> client -> active ->
- options [DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
- memcpy (ip -> client -> destination.iabuf,
- ip -> client -> active ->
- options [DHO_DHCP_SERVER_IDENTIFIER].data, 4);
- ip -> client -> destination.len = 4;
- } else
- ip -> client -> destination = iaddr_broadcast;
-
- ip -> client -> first_sending = cur_time;
- ip -> client -> interval = 0;
- ip -> client -> state = S_RENEWING;
-
- /* Send the first packet immediately. */
- send_request (ip);
-}
-
-int commit_leases ()
-{
- return 0;
-}
-
-int write_lease (lease)
- struct lease *lease;
-{
- return 0;
-}
-
-void db_startup ()
-{
-}
-
-void bootp (packet)
- struct packet *packet;
-{
- note ("BOOTREPLY from %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
-}
-
-void dhcp (packet)
- struct packet *packet;
-{
- switch (packet -> packet_type) {
- case DHCPOFFER:
- dhcpoffer (packet);
- break;
-
- case DHCPNAK:
- dhcpnak (packet);
- break;
-
- case DHCPACK:
- dhcpack (packet);
- break;
-
- default:
- break;
- }
-}
-
-void dhcpoffer (packet)
- struct packet *packet;
-{
- struct interface_info *ip = packet -> interface;
- struct client_lease *lease, *lp;
- int i;
- int arp_timeout_needed, stop_selecting;
-
- note ("DHCPOFFER from %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
-
-
-#ifdef DEBUG_PACKET
- dump_packet (packet);
-#endif
-
- /* If we're not receptive to an offer right now, or if the offer
- has an unrecognizable transaction id, then just drop it. */
- if (ip -> client -> state != S_SELECTING ||
- packet -> interface -> client -> xid != packet -> raw -> xid) {
- note ("DHCPOFFER in wrong transaction.");
- return;
- }
-
- /* If this lease doesn't supply the minimum required parameters,
- blow it off. */
- for (i = 0; ip -> client -> config -> required_options [i]; i++) {
- if (!packet -> options [ip -> client -> config ->
- required_options [i]].len) {
- note ("DHCPOFFER isn't satisfactory.");
- return;
- }
- }
-
- /* If we've already seen this lease, don't record it again. */
- for (lease = ip -> 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)) {
- note ("DHCPOFFER already seen.");
- return;
- }
- }
-
- lease = packet_to_lease (packet);
- if (!lease) {
- note ("packet_to_lease failed.");
- return;
- }
-
- /* Record the medium under which this lease was offered. */
- lease -> medium = ip -> client -> medium;
-
- /* Send out an ARP Request for the offered IP address. */
- script_init (ip, "ARPSEND", lease -> medium);
- script_write_params (ip, "check_", lease);
- /* If the script can't send an ARP request without waiting,
- we'll be waiting when we do the ARPCHECK, so don't wait now. */
- if (script_go (ip))
- arp_timeout_needed = 0;
- else
- arp_timeout_needed = 2;
-
- /* Figure out when we're supposed to stop selecting. */
- stop_selecting = (ip -> client -> first_sending +
- ip -> 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 == ip -> client -> requested_address.len &&
- !memcmp (lease -> address.iabuf,
- ip -> client -> requested_address.iabuf,
- ip -> client -> requested_address.len)) {
- lease -> next = ip -> client -> offered_leases;
- ip -> client -> offered_leases = lease;
- } else {
- /* If we already have an offer, and arping for this
- offer would take us past the selection timeout,
- then don't extend the timeout - just hope for the
- best. */
- if (ip -> client -> offered_leases &&
- (cur_time + arp_timeout_needed) > stop_selecting)
- arp_timeout_needed = 0;
-
- /* Put the lease at the end of the list. */
- lease -> next = (struct client_lease *)0;
- if (!ip -> client -> offered_leases)
- ip -> client -> offered_leases = lease;
- else {
- for (lp = ip -> client -> offered_leases; lp -> next;
- lp = lp -> next)
- ;
- lp -> next = lease;
- }
- }
-
- /* If we're supposed to stop selecting before we've had time
- to wait for the ARPREPLY, add some delay to wait for
- the ARPREPLY. */
- if (stop_selecting - cur_time < arp_timeout_needed)
- stop_selecting = cur_time + arp_timeout_needed;
-
- /* 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 (ip);
- else
- add_timeout (stop_selecting, state_selecting, ip);
-}
-
-/* Allocate a client_lease structure and initialize it from the parameters
- in the specified packet. */
-
-struct client_lease *packet_to_lease (packet)
- struct packet *packet;
-{
- struct client_lease *lease;
- int i;
-
- lease = (struct client_lease *)malloc (sizeof (struct client_lease));
-
- if (!lease) {
- warn ("dhcpoffer: no memory to record lease.\n");
- return (struct client_lease *)0;
- }
-
- memset (lease, 0, sizeof *lease);
-
- /* Copy the lease options. */
- for (i = 0; i < 256; i++) {
- if (packet -> options [i].len) {
- lease -> options [i].data =
- malloc (packet -> options [i].len);
- if (!lease -> options [i].data) {
- warn ("dhcpoffer: no memory for option %d\n",
- i);
- free_client_lease (lease);
- return (struct client_lease *)0;
- } else {
- memcpy (lease -> options [i].data,
- packet -> options [i].data,
- packet -> options [i].len);
- lease -> options [i].len =
- packet -> options [i].len;
- }
- }
- }
-
- lease -> address.len = sizeof (packet -> raw -> yiaddr);
- memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
- lease -> address.len);
-
- /* If the server name was filled out, copy it. */
- if ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD].len ||
- !(packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)) &&
- packet -> raw -> sname [0]) {
- int len;
- /* Don't count on the NUL terminator. */
- for (len = 0; len < 64; len++)
- if (!packet -> raw -> sname [len])
- break;
- lease -> server_name = malloc (len + 1);
- if (!lease -> server_name) {
- warn ("dhcpoffer: no memory for filename.\n");
- free_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 ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD].len ||
- !(packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)) &&
- packet -> raw -> file [0]) {
- int len;
- /* Don't count on the NUL terminator. */
- for (len = 0; len < 64; len++)
- if (!packet -> raw -> file [len])
- break;
- lease -> filename = malloc (len + 1);
- if (!lease -> filename) {
- warn ("dhcpoffer: no memory for filename.\n");
- free_client_lease (lease);
- return (struct client_lease *)0;
- } else {
- memcpy (lease -> filename,
- packet -> raw -> file, len);
- lease -> filename [len] = 0;
- }
- }
- return lease;
-}
-
-void dhcpnak (packet)
- struct packet *packet;
-{
- note ("DHCPNAK from %s",
- print_hw_addr (packet -> raw -> htype,
- packet -> raw -> hlen,
- packet -> raw -> chaddr));
-}
-
-/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
- one after the right interval has expired. If we are past the renewal
- (T1) interval but not yet past the rebind (T2) interval, unicast
- the message; otherwise broadcast it. If the lease expires, go back to
- the INIT state. */
-
-void send_discover (ip)
- struct interface_info *ip;
-{
- int result;
- int interval;
- int increase = 1;
-
- /* Figure out how long it's been since we started transmitting. */
- interval = cur_time - ip -> 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 > ip -> client -> config -> timeout) {
- state_panic (ip);
- 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 (!ip -> client -> offered_leases &&
- ip -> client -> config -> media) {
- int fail = 0;
- again:
- if (ip -> client -> medium) {
- ip -> client -> medium =
- ip -> client -> medium -> next;
- increase = 0;
- }
- if (!ip -> client -> medium) {
- if (fail)
- error ("No valid media types for %s!",
- ip -> name);
- ip -> client -> medium =
- ip -> client -> config -> media;
- increase = 1;
- }
-
- note ("Trying medium \"%s\" %d",
- ip -> client -> medium -> string, increase);
- script_init (ip, "MEDIUM", ip -> client -> medium);
- if (script_go (ip)) {
- 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 (!ip -> client -> interval)
- ip -> client -> interval = 1;
- else {
- ip -> client -> interval +=
- random () % (2 * ip -> client -> interval);
- }
-
- /* Don't backoff past 30 seconds. */
- if (ip -> client -> interval > 30)
- ip -> client -> interval =
- 15 + random () % ip -> client -> interval;
- } else if (!ip -> client -> interval)
- ip -> client -> interval = 1;
-
- /* If the backoff would take us to the panic timeout, just use that
- as the interval. */
- if (cur_time + ip -> client -> interval >
- ip -> client -> first_sending + ip -> client -> config -> timeout)
- ip -> client -> interval =
- (ip -> client -> first_sending +
- ip -> client -> config -> timeout) - cur_time + 1;
-
- note ("DHCPDISCOVER on %s to %s port %d interval %ld",
- ip -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
- ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
-
- /* Send out a packet. */
- result = send_packet (ip, (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- inaddr_any, &sockaddr_broadcast,
- (struct hardware *)0);
- if (result < 0)
- warn ("send_packet: %m");
-
- add_timeout (cur_time + ip -> client -> interval, send_discover, ip);
-}
-
-/* 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 (ip)
- struct interface_info *ip;
-{
- struct client_lease *loop = ip -> client -> active;
- struct client_lease *lp;
-
- note ("No DHCPOFFERS received.");
-
- /* Run through the list of leases and see if one can be used. */
- while (ip -> client -> active) {
- if (ip -> client -> active -> expiry > cur_time) {
- note ("Trying recorded lease %s",
- piaddr (ip -> client -> active -> address));
- /* Run the client script with the existing
- parameters. */
- script_init (ip, "TIMEOUT",
- ip -> client -> active -> medium);
- script_write_params (ip, "new_",
- ip -> client -> active);
- if (ip -> client -> alias)
- script_write_params (ip, "alias_",
- ip -> 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 (ip)) {
- if (cur_time <
- ip -> client -> active -> renewal) {
- ip -> client -> state = S_BOUND;
- note ("bound: renewal in %d seconds.",
- ip -> client -> active -> renewal
- - cur_time);
- add_timeout ((ip -> client ->
- active -> renewal),
- state_bound, ip);
- } else {
- ip -> client -> state = S_BOUND;
- note ("bound: immediate renewal.");
- state_bound (ip);
- }
- reinitialize_interfaces ();
- go_daemon ();
- return;
- }
- }
-
- /* If there are no other leases, give up. */
- if (!ip -> client -> leases) {
- ip -> client -> leases = ip -> client -> active;
- ip -> client -> active = (struct client_lease *)0;
- break;
- }
-
- /* Otherwise, put the active lease at the end of the
- lease list, and try another lease.. */
- for (lp = ip -> client -> leases; lp -> next; lp = lp -> next)
- ;
- lp -> next = ip -> client -> active;
- lp -> next -> next = (struct client_lease *)0;
- ip -> client -> active = ip -> client -> leases;
- ip -> client -> leases = ip -> 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 (ip -> client -> active == loop)
- break;
- }
-
- /* 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. */
- note ("No working leases in persistent database - sleeping.\n");
- script_init (ip, "FAIL", (struct string_list *)0);
- if (ip -> client -> alias)
- script_write_params (ip, "alias_", ip -> client -> alias);
- script_go (ip);
- ip -> client -> state = S_INIT;
- add_timeout (cur_time + ip -> client -> config -> retry_interval,
- state_init, ip);
-}
-
-void send_request (ip)
- struct interface_info *ip;
-{
- 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 - ip -> client -> first_sending;
-
- /* If the lease has expired, relinquish the address and go back
- to the INIT state. */
- if (ip -> client -> state != S_REQUESTING &&
- cur_time > ip -> client -> active -> expiry) {
- /* Run the client script with the new parameters. */
- script_init (ip, "EXPIRE", (struct string_list *)0);
- script_write_params (ip, "old_", ip -> client -> active);
- if (ip -> client -> alias)
- script_write_params (ip, "alias_",
- ip -> client -> alias);
- script_go (ip);
-
- ip -> client -> state = S_INIT;
- state_init (ip);
- return;
- }
-
- /* Do the exponential backoff... */
- if (!ip -> client -> interval)
- ip -> client -> interval = 1;
- else
- ip -> client -> interval +=
- random () % (2 * ip -> client -> interval);
-
- /* Don't backoff past 30 seconds. */
- if (ip -> client -> interval > 30)
- ip -> client -> interval =
- 15 + random () % ip -> client -> interval;
-
- /* If the backoff would take us to the expiry time, just set the
- timeout to the expiry time. */
- if (ip -> client -> state != S_REQUESTING &&
- cur_time + ip -> client -> interval >
- ip -> client -> active -> expiry)
- ip -> client -> interval =
- ip -> 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 (ip -> client -> state == S_REQUESTING ||
- cur_time > ip -> client -> active -> rebind)
- destination.sin_addr.s_addr = INADDR_BROADCAST;
- else
- memcpy (&destination.sin_addr.s_addr,
- ip -> 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 (ip -> client -> state != S_REQUESTING)
- memcpy (&from, ip -> client -> active -> address.iabuf,
- sizeof from);
- else
- from.s_addr = INADDR_ANY;
-
- note ("DHCPREQUEST on %s to %s port %d", ip -> name,
- inet_ntoa (destination.sin_addr),
- ntohs (destination.sin_port));
-
-#ifdef USE_FALLBACK
- if (destination.sin_addr.s_addr != INADDR_BROADCAST)
- result = send_fallback (&fallback_interface,
- (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- from, &destination,
- (struct hardware *)0);
- else
-#endif /* USE_FALLBACK */
- /* Send out a packet. */
- result = send_packet (ip, (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- from, &destination,
- (struct hardware *)0);
-
- if (result < 0)
- warn ("send_packet: %m");
-
- add_timeout (cur_time + ip -> client -> interval,
- send_request, ip);
-}
-
-void send_decline (ip)
- struct interface_info *ip;
-{
- int result;
-
- note ("DHCPDECLINE on %s to %s port %d", ip -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
- ntohs (sockaddr_broadcast.sin_port));
-
- /* Send out a packet. */
- result = send_packet (ip, (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- inaddr_any, &sockaddr_broadcast,
- (struct hardware *)0);
- if (result < 0)
- warn ("send_packet: %m");
-}
-
-void send_release (ip)
- struct interface_info *ip;
-{
- int result;
-
- note ("DHCPRELEASE on %s to %s port %d", ip -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
- ntohs (sockaddr_broadcast.sin_port));
-
- /* Send out a packet. */
- result = send_packet (ip, (struct packet *)0,
- &ip -> client -> packet,
- ip -> client -> packet_length,
- inaddr_any, &sockaddr_broadcast,
- (struct hardware *)0);
- if (result < 0)
- warn ("send_packet: %m");
-}
-
-void make_discover (ip, lease)
- struct interface_info *ip;
- struct client_lease *lease;
-{
- struct dhcp_packet *raw;
- unsigned char discover = DHCPDISCOVER;
-
- struct tree_cache *options [256];
- struct tree_cache message_type_tree;
- struct tree_cache requested_options_tree;
- struct tree_cache requested_address_tree;
-
- memset (options, 0, sizeof options);
- memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
-
- /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
- options [DHO_DHCP_MESSAGE_TYPE] = &message_type_tree;
- message_type_tree.value = &discover;
- message_type_tree.len = sizeof discover;
- message_type_tree.buf_size = sizeof discover;
- message_type_tree.timeout = 0xFFFFFFFF;
- message_type_tree.tree = (struct tree *)0;
-
- /* Request the options we want */
- options [DHO_DHCP_PARAMETER_REQUEST_LIST] = &requested_options_tree;
- requested_options_tree.value =
- ip -> client -> config -> requested_options;
- requested_options_tree.len =
- ip -> client -> config -> requested_option_count;
- requested_options_tree.buf_size =
- ip -> client -> config -> requested_option_count;
- requested_options_tree.timeout = 0xFFFFFFFF;
- requested_options_tree.tree = (struct tree *)0;
-
- /* If we had an address, try to get it again. */
- if (lease) {
- ip -> client -> requested_address = lease -> address;
- options [DHO_DHCP_REQUESTED_ADDRESS] = &requested_address_tree;
- requested_address_tree.value = lease -> address.iabuf;
- requested_address_tree.len = lease -> address.len;
- requested_address_tree.buf_size = lease -> address.len;
- requested_address_tree.timeout = 0xFFFFFFFF;
- requested_address_tree.tree = (struct tree *)0;
- } else {
- ip -> client -> requested_address.len = 0;
- }
-
- /* Set up the option buffer... */
- ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet,
- options, 0, 0);
-
- ip -> client -> packet.op = BOOTREQUEST;
- ip -> client -> packet.htype = ip -> hw_address.htype;
- ip -> client -> packet.hlen = ip -> hw_address.hlen;
- ip -> client -> packet.hops = 0;
- ip -> client -> packet.xid = random ();
- ip -> client -> packet.secs = 0; /* filled in by send_discover. */
- ip -> client -> packet.flags = htons (BOOTP_BROADCAST); /* XXX */
- memset (&(ip -> client -> packet.ciaddr),
- 0, sizeof ip -> client -> packet.ciaddr);
- memset (&(ip -> client -> packet.yiaddr),
- 0, sizeof ip -> client -> packet.yiaddr);
- memset (&(ip -> client -> packet.siaddr),
- 0, sizeof ip -> client -> packet.siaddr);
- memset (&(ip -> client -> packet.giaddr),
- 0, sizeof ip -> client -> packet.giaddr);
- memcpy (ip -> client -> packet.chaddr,
- ip -> hw_address.haddr, ip -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
- dump_packet (sendpkt);
- dump_raw ((unsigned char *)ip -> client -> packet,
- sendpkt->packet_length);
-#endif
-}
-
-
-void make_request (ip, lease)
- struct interface_info *ip;
- struct client_lease *lease;
-{
- unsigned char request = DHCPREQUEST;
-
- struct tree_cache *options [256];
- struct tree_cache message_type_tree;
- struct tree_cache requested_options_tree;
- struct tree_cache requested_address_tree;
- struct tree_cache server_id_tree;
-
- memset (options, 0, sizeof options);
- memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
-
- /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
- options [DHO_DHCP_MESSAGE_TYPE] = &message_type_tree;
- message_type_tree.value = &request;
- message_type_tree.len = sizeof request;
- message_type_tree.buf_size = sizeof request;
- message_type_tree.timeout = 0xFFFFFFFF;
- message_type_tree.tree = (struct tree *)0;
-
- /* Request the options we want */
- options [DHO_DHCP_PARAMETER_REQUEST_LIST] = &requested_options_tree;
- requested_options_tree.value =
- ip -> client -> config -> requested_options;
- requested_options_tree.len =
- ip -> client -> config -> requested_option_count;
- requested_options_tree.buf_size =
- ip -> client -> config -> requested_option_count;
- requested_options_tree.timeout = 0xFFFFFFFF;
- requested_options_tree.tree = (struct tree *)0;
-
- /* Send back the server identifier... */
- options [DHO_DHCP_SERVER_IDENTIFIER] = &server_id_tree;
- server_id_tree.value =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].data;
- server_id_tree.len =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.buf_size =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.timeout = 0xFFFFFFFF;
- server_id_tree.tree = (struct tree *)0;
-
- /* If we are requesting an address that hasn't yet been assigned
- to us, use the DHCP Requested Address option. */
- if (ip -> client -> state == S_REQUESTING) {
- ip -> client -> requested_address = lease -> address;
- options [DHO_DHCP_REQUESTED_ADDRESS] = &requested_address_tree;
- requested_address_tree.value = lease -> address.iabuf;
- requested_address_tree.len = lease -> address.len;
- requested_address_tree.buf_size = lease -> address.len;
- requested_address_tree.timeout = 0xFFFFFFFF;
- requested_address_tree.tree = (struct tree *)0;
- } else {
- ip -> client -> requested_address.len = 0;
- }
-
- /* Set up the option buffer... */
- ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet,
- options, 0, 0);
-
- ip -> client -> packet.op = BOOTREQUEST;
- ip -> client -> packet.htype = ip -> hw_address.htype;
- ip -> client -> packet.hlen = ip -> hw_address.hlen;
- ip -> client -> packet.hops = 0;
- ip -> client -> packet.xid = ip -> client -> xid;
- ip -> client -> packet.secs = 0; /* Filled in by send_request. */
- ip -> client -> packet.flags = htons (BOOTP_BROADCAST);
-
- /* If we own the address we're requesting, put it in ciaddr;
- otherwise set ciaddr to zero. */
- if (ip -> client -> state == S_BOUND ||
- ip -> client -> state == S_RENEWING ||
- ip -> client -> state == S_REBINDING)
- memcpy (&ip -> client -> packet.ciaddr,
- lease -> address.iabuf, lease -> address.len);
- else
- memset (&ip -> client -> packet.ciaddr, 0,
- sizeof ip -> client -> packet.ciaddr);
-
- memset (&ip -> client -> packet.yiaddr, 0,
- sizeof ip -> client -> packet.yiaddr);
- memset (&ip -> client -> packet.siaddr, 0,
- sizeof ip -> client -> packet.siaddr);
- memset (&ip -> client -> packet.giaddr, 0,
- sizeof ip -> client -> packet.giaddr);
- memcpy (ip -> client -> packet.chaddr,
- ip -> hw_address.haddr, ip -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
- dump_packet (sendpkt);
- dump_raw ((unsigned char *)ip -> client -> packet, sendpkt->packet_length);
-#endif
-}
-
-void make_decline (ip, lease)
- struct interface_info *ip;
- struct client_lease *lease;
-{
- unsigned char decline = DHCPDECLINE;
-
- struct tree_cache *options [256];
- struct tree_cache message_type_tree;
- struct tree_cache requested_address_tree;
- struct tree_cache server_id_tree;
-
- memset (options, 0, sizeof options);
- memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
-
- /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
- options [DHO_DHCP_MESSAGE_TYPE] = &message_type_tree;
- message_type_tree.value = &decline;
- message_type_tree.len = sizeof decline;
- message_type_tree.buf_size = sizeof decline;
- message_type_tree.timeout = 0xFFFFFFFF;
- message_type_tree.tree = (struct tree *)0;
-
- /* Send back the server identifier... */
- options [DHO_DHCP_SERVER_IDENTIFIER] = &server_id_tree;
- server_id_tree.value =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].data;
- server_id_tree.len =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.buf_size =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.timeout = 0xFFFFFFFF;
- server_id_tree.tree = (struct tree *)0;
-
- /* Send back the address we're declining. */
- options [DHO_DHCP_REQUESTED_ADDRESS] = &requested_address_tree;
- requested_address_tree.value = lease -> address.iabuf;
- requested_address_tree.len = lease -> address.len;
- requested_address_tree.buf_size = lease -> address.len;
- requested_address_tree.timeout = 0xFFFFFFFF;
- requested_address_tree.tree = (struct tree *)0;
-
- /* Set up the option buffer... */
- ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet,
- options, 0, 0);
-
- ip -> client -> packet.op = BOOTREQUEST;
- ip -> client -> packet.htype = ip -> hw_address.htype;
- ip -> client -> packet.hlen = ip -> hw_address.hlen;
- ip -> client -> packet.hops = 0;
- ip -> client -> packet.xid = ip -> client -> xid;
- ip -> client -> packet.secs = 0; /* Filled in by send_request. */
- ip -> client -> packet.flags = htons (BOOTP_BROADCAST);
-
- /* ciaddr must always be zero. */
- memset (&ip -> client -> packet.ciaddr, 0,
- sizeof ip -> client -> packet.ciaddr);
- memset (&ip -> client -> packet.yiaddr, 0,
- sizeof ip -> client -> packet.yiaddr);
- memset (&ip -> client -> packet.siaddr, 0,
- sizeof ip -> client -> packet.siaddr);
- memset (&ip -> client -> packet.giaddr, 0,
- sizeof ip -> client -> packet.giaddr);
- memcpy (ip -> client -> packet.chaddr,
- ip -> hw_address.haddr, ip -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
- dump_packet (sendpkt);
- dump_raw ((unsigned char *)ip -> client -> packet, sendpkt->packet_length);
-#endif
-}
-
-void make_release (ip, lease)
- struct interface_info *ip;
- struct client_lease *lease;
-{
- unsigned char request = DHCPRELEASE;
-
- struct tree_cache *options [256];
- struct tree_cache message_type_tree;
- struct tree_cache requested_address_tree;
- struct tree_cache server_id_tree;
-
- memset (options, 0, sizeof options);
- memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
-
- /* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
- options [DHO_DHCP_MESSAGE_TYPE] = &message_type_tree;
- message_type_tree.value = &request;
- message_type_tree.len = sizeof request;
- message_type_tree.buf_size = sizeof request;
- message_type_tree.timeout = 0xFFFFFFFF;
- message_type_tree.tree = (struct tree *)0;
-
- /* Send back the server identifier... */
- options [DHO_DHCP_SERVER_IDENTIFIER] = &server_id_tree;
- server_id_tree.value =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].data;
- server_id_tree.len =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.buf_size =
- lease -> options [DHO_DHCP_SERVER_IDENTIFIER].len;
- server_id_tree.timeout = 0xFFFFFFFF;
- server_id_tree.tree = (struct tree *)0;
-
- /* Set up the option buffer... */
- ip -> client -> packet_length =
- cons_options ((struct packet *)0, &ip -> client -> packet,
- options, 0, 0);
-
- ip -> client -> packet.op = BOOTREQUEST;
- ip -> client -> packet.htype = ip -> hw_address.htype;
- ip -> client -> packet.hlen = ip -> hw_address.hlen;
- ip -> client -> packet.hops = 0;
- ip -> client -> packet.xid = ip -> client -> packet.xid;
- ip -> client -> packet.secs = 0;
- ip -> client -> packet.flags = 0;
- memcpy (&ip -> client -> packet.ciaddr,
- lease -> address.iabuf, lease -> address.len);
- memset (&ip -> client -> packet.yiaddr, 0,
- sizeof ip -> client -> packet.yiaddr);
- memset (&ip -> client -> packet.siaddr, 0,
- sizeof ip -> client -> packet.siaddr);
- memset (&ip -> client -> packet.giaddr, 0,
- sizeof ip -> client -> packet.giaddr);
- memcpy (ip -> client -> packet.chaddr,
- ip -> hw_address.haddr, ip -> hw_address.hlen);
-
-#ifdef DEBUG_PACKET
- dump_packet (sendpkt);
- dump_raw ((unsigned char *)ip -> client -> packet,
- ip -> client -> packet_length);
-#endif
-}
-
-void free_client_lease (lease)
- struct client_lease *lease;
-{
- int i;
-
- if (lease -> server_name)
- free (lease -> server_name);
- if (lease -> filename)
- free (lease -> filename);
- for (i = 0; i < 256; i++) {
- if (lease -> options [i].len)
- free (lease -> options [i].data);
- }
- free (lease);
-}
-
-FILE *leaseFile;
-
-void rewrite_client_leases ()
-{
- struct interface_info *ip;
- struct client_lease *lp;
-
- if (leaseFile)
- fclose (leaseFile);
- leaseFile = fopen (path_dhclient_db, "w");
- if (!leaseFile)
- error ("can't create /var/db/dhclient.leases: %m");
-
- /* Write out all the leases attached to configured interfaces that
- we know about. */
- for (ip = interfaces; ip; ip = ip -> next) {
- for (lp = ip -> client -> leases; lp; lp = lp -> next) {
- write_client_lease (ip, lp);
- }
- if (ip -> client -> active)
- write_client_lease (ip, ip -> client -> active);
- }
-
- /* Write out any leases that are attached to interfaces that aren't
- currently configured. */
- for (ip = dummy_interfaces; ip; ip = ip -> next) {
- for (lp = ip -> client -> leases; lp; lp = lp -> next) {
- write_client_lease (ip, lp);
- }
- if (ip -> client -> active)
- write_client_lease (ip, ip -> client -> active);
- }
- fflush (leaseFile);
-}
-
-void write_client_lease (ip, lease)
- struct interface_info *ip;
- struct client_lease *lease;
-{
- int i;
- struct tm *t;
-
- /* 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;
-
- if (!leaseFile) { /* XXX */
- leaseFile = fopen (path_dhclient_db, "w");
- if (!leaseFile)
- error ("can't create /var/db/dhclient.leases: %m");
- }
-
- fprintf (leaseFile, "lease {\n");
- fprintf (leaseFile, " interface \"%s\";\n", ip -> name);
- fprintf (leaseFile, " fixed-address %s;\n",
- piaddr (lease -> address));
- if (lease -> filename)
- fprintf (leaseFile, " filename \"%s\";\n",
- lease -> filename);
- if (lease -> server_name)
- fprintf (leaseFile, " server-name \"%s\";\n",
- lease -> filename);
- if (lease -> medium)
- fprintf (leaseFile, " medium \"%s\";\n",
- lease -> medium -> string);
- for (i = 0; i < 256; i++) {
- if (lease -> options [i].len) {
- fprintf (leaseFile,
- " option %s %s;\n",
- dhcp_options [i].name,
- pretty_print_option
- (i, lease -> options [i].data,
- lease -> options [i].len, 1));
- }
- }
- 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);
- 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);
- 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);
- fprintf (leaseFile, "}\n");
- fflush (leaseFile);
-}
-
-/* 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 (ip, reason, medium)
- struct interface_info *ip;
- char *reason;
- struct string_list *medium;
-{
- strcpy (scriptName, "/tmp/dcsXXXXXX");
- mktemp (scriptName);
-
- scriptFile = fopen (scriptName, "w");
- if (!scriptFile)
- error ("can't write script file: %m");
- fprintf (scriptFile, "#!/bin/sh\n\n");
- if (ip) {
- fprintf (scriptFile, "interface=\"%s\"\n", ip -> name);
- fprintf (scriptFile, "export interface\n");
- }
- if (medium) {
- fprintf (scriptFile, "medium=\"%s\"\n",
- ip -> client -> medium -> string);
- fprintf (scriptFile, "export medium\n");
- }
- fprintf (scriptFile, "reason=\"%s\"\n", reason);
- fprintf (scriptFile, "export reason\n");
-}
-
-void script_write_params (ip, prefix, lease)
- struct interface_info *ip;
- char *prefix;
- struct client_lease *lease;
-{
- int i;
-
- fprintf (scriptFile, "%sip_address=\"%s\"\n",
- prefix, piaddr (lease -> address));
- fprintf (scriptFile, "export %sip_address\n", prefix);
- if (lease -> filename) {
- fprintf (scriptFile, "%sfilename=\"%s\";\n",
- prefix, lease -> filename);
- fprintf (scriptFile, "export %sfilename\n", prefix);
- }
- if (lease -> server_name) {
- fprintf (scriptFile, "%sserver_name=\"%s\";\n",
- prefix, lease -> server_name);
- fprintf (scriptFile, "export %sserver_name\n", prefix);
- }
- for (i = 0; i < 256; i++) {
- if (lease -> options [i].len) {
- char *s = dhcp_option_ev_name (&dhcp_options [i]);
- fprintf (scriptFile,
- "%s%s=\"%s\"\n", prefix, s,
- pretty_print_option
- (i, lease -> options [i].data,
- lease -> options [i].len, 0));
- fprintf (scriptFile, "export %s%s\n", prefix, s);
- }
- }
- fprintf (scriptFile, "%sexpiry=\"%d\"\n",
- prefix, (int)lease -> expiry); /* XXX */
- fprintf (scriptFile, "export %sexpiry\n", prefix);
-}
-
-int script_go (ip)
- struct interface_info *ip;
-{
- int rval;
-
- if (ip)
- fprintf (scriptFile, "%s\n",
- ip -> client -> config -> script_name);
- else
- fprintf (scriptFile, "%s\n",
- top_level_config.script_name);
- fprintf (scriptFile, "exit $?\n");
- fclose (scriptFile);
- chmod (scriptName, 0700);
- rval = system (scriptName);
- /* unlink (scriptName); */
- return rval;
-}
-
-char *dhcp_option_ev_name (option)
- struct option *option;
-{
- static char evbuf [256];
- int i;
-
- if (strlen (option -> name) + 1 > sizeof evbuf)
- error ("option %s name is larger than static buffer.");
- for (i = 0; option -> name [i]; i++) {
- if (option -> name [i] == '-')
- evbuf [i] = '_';
- else
- evbuf [i] = option -> name [i];
- }
-
- evbuf [i] = 0;
- return evbuf;
-}
-
-void go_daemon ()
-{
- static int state = 0;
- int pid;
-
- /* Don't become a daemon if the user requested otherwise. */
- if (no_daemon)
- return;
-
- /* Only do it once. */
- if (state)
- return;
- state = 1;
-
- /* Stop logging to stderr... */
- log_perror = 0;
-
- /* Become a daemon... */
- if ((pid = fork ()) < 0)
- error ("Can't fork daemon: %m");
- else if (pid)
- exit (0);
- /* Become session leader and get pid... */
- pid = setsid ();
-}
-
diff --git a/dhclient.conf.5 b/dhclient.conf.5
deleted file mode 100644
index 25d5d8f2..00000000
--- a/dhclient.conf.5
+++ /dev/null
@@ -1,63 +0,0 @@
-.\" dhclient.conf.5
-.\"
-.\" Copyright (c) 1997 The Internet Software Consortium.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The Internet Software Consortium nor the names
-.\" of its contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
-.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" This software has been written for the Internet Software Consortium
-.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-.\" Enterprises. To learn more about the Internet Software Consortium,
-.\" see ``http://www.isc.org/isc''. To learn more about Vixie
-.\" Enterprises, see ``http://www.vix.com''.
-.TH dhcpd.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.
-.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
- \fBTHIS DOCUMENTATION IS NOT YET COMPLETE - SORRY\fR
-.SH SEE ALSO
-dhcpd.conf(5), dhclient.leases(5),
-draft-ietf-dhc-options-1533update-04.txt, draft-ietf-dhc-dhcp-07.txt.
-.SH AUTHOR
-.B dhclient(8)
-was written by Ted Lemon <mellon@vix.com>
-under a contract with Vixie Labs. Funding
-for this project was provided by the Internet Software Corporation.
-Information about the Internet Software Consortium can be found at
-.B http://www.isc.org/isc.
diff --git a/dhclient.conf.cat5 b/dhclient.conf.cat5
deleted file mode 100644
index 519856c2..00000000
--- a/dhclient.conf.cat5
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-dhcpd.conf(5) dhcpd.conf(5)
-
-
-NNAAMMEE
- dhclient.conf - DHCP client configuration file
-
-DDEESSCCRRIIPPTTIIOONN
- The dhclient.conf file contains configuration information
- for _d_h_c_l_i_e_n_t_, the Internet Software Consortium DHCP
- Client.
-
- 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.
-
- TTHHIISS DDOOCCUUMMEENNTTAATTIIOONN IISS NNOOTT YYEETT CCOOMMPPLLEETTEE -- SSOORRRRYY
-
-SSEEEE AALLSSOO
- dhcpd.conf(5), dhclient.leases(5), draft-ietf-dhc-
- options-1533update-04.txt, draft-ietf-dhc-dhcp-07.txt.
-
-AAUUTTHHOORR
- ddhhcclliieenntt((88)) was written by Ted Lemon <mellon@vix.com>
- under a contract with Vixie Labs. Funding for this pro-
- ject was provided by the Internet Software Corporation.
- Information about the Internet Software Consortium can be
- found at hhttttpp::////wwwwww..iisscc..oorrgg//iisscc..
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-