2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-09-02 15:25:48 +00:00

Add support for pseudo-clients

This commit is contained in:
Ted Lemon
1998-11-09 02:43:23 +00:00
parent 74a2049e09
commit 02d9e45397
2 changed files with 622 additions and 537 deletions

View File

@@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: clparse.c,v 1.19 1998/11/06 00:10:58 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n"; "$Id: clparse.c,v 1.20 1998/11/09 02:42:58 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -198,6 +198,7 @@ void parse_client_statement (cfile, ip, config)
struct executable_statement *stmt, **p; struct executable_statement *stmt, **p;
enum statement_op op; enum statement_op op;
int lose; int lose;
char *name;
switch (peek_token (&val, cfile)) { switch (peek_token (&val, cfile)) {
case SEND: case SEND:
@@ -300,9 +301,19 @@ void parse_client_statement (cfile, ip, config)
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (ip) if (ip)
parse_warn ("nested interface declaration."); parse_warn ("nested interface declaration.");
parse_interface_declaration (cfile, config); parse_interface_declaration (cfile, config, (char *)0);
return; return;
case PSEUDO:
token = next_token (&val, cfile);
token = next_token (&val, cfile);
name = dmalloc (strlen (val) + 1, "parse_client_statement");
if (!name)
error ("no memory for pseudo interface name");
strcpy (name, val);
parse_interface_declaration (cfile, config, name);
return;
case LEASE: case LEASE:
token = next_token (&val, cfile); token = next_token (&val, cfile);
parse_client_lease_statement (cfile, 1); parse_client_lease_statement (cfile, 1);
@@ -459,16 +470,15 @@ void parse_option_list (cfile, list)
/* interface-declaration :== /* interface-declaration :==
INTERFACE string LBRACE client-declarations RBRACE */ INTERFACE string LBRACE client-declarations RBRACE */
void parse_interface_declaration (cfile, outer_config) void parse_interface_declaration (cfile, outer_config, name)
FILE *cfile; FILE *cfile;
struct client_config *outer_config; struct client_config *outer_config;
char *name;
{ {
int token; int token;
char *val; char *val;
struct client_state *client, **cp;
struct interface_info dummy_interface, *ip; struct interface_info *ip;
struct client_state dummy_state;
struct client_config dummy_config;
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != STRING) { if (token != STRING) {
@@ -479,11 +489,24 @@ void parse_interface_declaration (cfile, outer_config)
ip = interface_or_dummy (val); ip = interface_or_dummy (val);
if (!ip -> client) /* If we were given a name, this is a pseudo-interface. */
make_client_state (ip); 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 (!ip -> client -> config) if (!client -> config)
make_client_config (ip, outer_config); make_client_config (client, outer_config);
ip -> flags &= ~INTERFACE_AUTOMATIC; ip -> flags &= ~INTERFACE_AUTOMATIC;
interfaces_requested = 1; interfaces_requested = 1;
@@ -503,7 +526,7 @@ void parse_interface_declaration (cfile, outer_config)
} }
if (token == RBRACE) if (token == RBRACE)
break; break;
parse_client_statement (cfile, ip, ip -> client -> config); parse_client_statement (cfile, ip, client -> config);
} while (1); } while (1);
token = next_token (&val, cfile); token = next_token (&val, cfile);
} }
@@ -542,28 +565,28 @@ struct interface_info *interface_or_dummy (name)
return ip; return ip;
} }
void make_client_state (ip) void make_client_state (state)
struct interface_info *ip; struct client_state **state;
{ {
ip -> client = *state = ((struct client_state *)dmalloc (sizeof **state,
((struct client_state *)malloc (sizeof *(ip -> client))); "make_client_state"));
if (!ip -> client) if (!*state)
error ("no memory for state on %s\n", ip -> name); error ("no memory for client state\n");
memset (ip -> client, 0, sizeof *(ip -> client)); memset (*state, 0, sizeof **state);
} }
void make_client_config (ip, config) void make_client_config (client, config)
struct interface_info *ip; struct client_state *client;
struct client_config *config; struct client_config *config;
{ {
ip -> client -> config = client -> config = (((struct client_config *)
((struct client_config *) dmalloc (sizeof (struct client_config),
malloc (sizeof (struct client_config))); "make_client_config")));
if (!ip -> client -> config) if (!client -> config)
error ("no memory for config for %s\n", ip -> name); error ("no memory for client config\n");
memset (ip -> client -> config, 0, memset (client -> config, 0,
sizeof *(ip -> client -> config)); sizeof *(client -> config));
memcpy (ip -> client -> config, config, sizeof *config); memcpy (client -> config, config, sizeof *config);
} }
/* client-lease-statement :== /* client-lease-statement :==
@@ -580,9 +603,10 @@ void parse_client_lease_statement (cfile, is_static)
int is_static; int is_static;
{ {
struct client_lease *lease, *lp, *pl; struct client_lease *lease, *lp, *pl;
struct interface_info *ip; struct interface_info *ip = (struct interface_info *)0;
int token; int token;
char *val; char *val;
struct client_state *client = (struct client_state *)0;
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (token != LBRACE) { if (token != LBRACE) {
@@ -597,8 +621,6 @@ void parse_client_lease_statement (cfile, is_static)
memset (lease, 0, sizeof *lease); memset (lease, 0, sizeof *lease);
lease -> is_static = is_static; lease -> is_static = is_static;
ip = (struct interface_info *)0;
do { do {
token = peek_token (&val, cfile); token = peek_token (&val, cfile);
if (token == EOF) { if (token == EOF) {
@@ -607,7 +629,7 @@ void parse_client_lease_statement (cfile, is_static)
} }
if (token == RBRACE) if (token == RBRACE)
break; break;
parse_client_lease_declaration (cfile, lease, &ip); parse_client_lease_declaration (cfile, lease, &ip, &client);
} while (1); } while (1);
token = next_token (&val, cfile); token = next_token (&val, cfile);
@@ -619,8 +641,12 @@ void parse_client_lease_statement (cfile, is_static)
} }
/* Make sure there's a client state structure... */ /* Make sure there's a client state structure... */
if (!ip -> client) if (!ip -> client) {
make_client_state (ip); 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 this is an alias lease, it doesn't need to be sorted in. */
if (is_static == 2) { if (is_static == 2) {
@@ -633,14 +659,14 @@ void parse_client_lease_statement (cfile, is_static)
lease list looking for a lease with the same address, and lease list looking for a lease with the same address, and
if we find it, toss it. */ if we find it, toss it. */
pl = (struct client_lease *)0; pl = (struct client_lease *)0;
for (lp = ip -> client -> leases; lp; lp = lp -> next) { for (lp = client -> leases; lp; lp = lp -> next) {
if (lp -> address.len == lease -> address.len && if (lp -> address.len == lease -> address.len &&
!memcmp (lp -> address.iabuf, lease -> address.iabuf, !memcmp (lp -> address.iabuf, lease -> address.iabuf,
lease -> address.len)) { lease -> address.len)) {
if (pl) if (pl)
pl -> next = lp -> next; pl -> next = lp -> next;
else else
ip -> client -> leases = lp -> next; client -> leases = lp -> next;
destroy_client_lease (lp); destroy_client_lease (lp);
break; break;
} }
@@ -649,8 +675,8 @@ void parse_client_lease_statement (cfile, is_static)
/* If this is a preloaded lease, just put it on the list of recorded /* If this is a preloaded lease, just put it on the list of recorded
leases - don't make it the active lease. */ leases - don't make it the active lease. */
if (is_static) { if (is_static) {
lease -> next = ip -> client -> leases; lease -> next = client -> leases;
ip -> client -> leases = lease; client -> leases = lease;
return; return;
} }
@@ -665,22 +691,21 @@ void parse_client_lease_statement (cfile, is_static)
then if the old active lease has expired, we dump it; if not, 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 we put it on the list of leases for this interface which are
still valid but no longer active. */ still valid but no longer active. */
if (ip -> client -> active) { if (client -> active) {
if (ip -> client -> active -> expiry < cur_time) if (client -> active -> expiry < cur_time)
destroy_client_lease (ip -> client -> active); destroy_client_lease (client -> active);
else if (ip -> client -> active -> address.len == else if (client -> active -> address.len ==
lease -> address.len && lease -> address.len &&
!memcmp (ip -> client -> active -> address.iabuf, !memcmp (client -> active -> address.iabuf,
lease -> address.iabuf, lease -> address.iabuf,
lease -> address.len)) lease -> address.len))
destroy_client_lease (ip -> client -> active); destroy_client_lease (client -> active);
else { else {
ip -> client -> active -> next = client -> active -> next = client -> leases;
ip -> client -> leases; client -> leases = client -> active;
ip -> client -> leases = ip -> client -> active;
} }
} }
ip -> client -> active = lease; client -> active = lease;
/* phew. */ /* phew. */
} }
@@ -696,16 +721,18 @@ void parse_client_lease_statement (cfile, is_static)
REBIND time-decl | REBIND time-decl |
EXPIRE time-decl */ EXPIRE time-decl */
void parse_client_lease_declaration (cfile, lease, ipp) void parse_client_lease_declaration (cfile, lease, ipp, clientp)
FILE *cfile; FILE *cfile;
struct client_lease *lease; struct client_lease *lease;
struct interface_info **ipp; struct interface_info **ipp;
struct client_state **clientp;
{ {
int token; int token;
char *val; char *val;
char *t, *n; char *t, *n;
struct interface_info *ip; struct interface_info *ip;
struct option_cache *oc; struct option_cache *oc;
struct client_state *client = (struct client_state *)0;
switch (next_token (&val, cfile)) { switch (next_token (&val, cfile)) {
case BOOTP: case BOOTP:
@@ -723,6 +750,21 @@ void parse_client_lease_declaration (cfile, lease, ipp)
*ipp = ip; *ipp = ip;
break; break;
case NAME:
token = next_token (&val, cfile);
ip = *ipp;
if (!ip) {
parse_warn ("state name precedes interface.");
break;
}
for (client = ip -> client; client; client = client -> next)
if (!strcmp (client -> name, val))
break;
if (!client)
parse_warn ("lease specified for unknown pseudo.");
*clientp = client;
break;
case FIXED_ADDR: case FIXED_ADDR:
if (!parse_ip_addr (cfile, &lease -> address)) if (!parse_ip_addr (cfile, &lease -> address))
return; return;

File diff suppressed because it is too large Load Diff