2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 06:15:55 +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
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 */
#include "dhcpd.h"
@@ -198,6 +198,7 @@ void parse_client_statement (cfile, ip, config)
struct executable_statement *stmt, **p;
enum statement_op op;
int lose;
char *name;
switch (peek_token (&val, cfile)) {
case SEND:
@@ -300,9 +301,19 @@ void parse_client_statement (cfile, ip, config)
token = next_token (&val, cfile);
if (ip)
parse_warn ("nested interface declaration.");
parse_interface_declaration (cfile, config);
parse_interface_declaration (cfile, config, (char *)0);
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:
token = next_token (&val, cfile);
parse_client_lease_statement (cfile, 1);
@@ -459,16 +470,15 @@ void parse_option_list (cfile, list)
/* interface-declaration :==
INTERFACE string LBRACE client-declarations RBRACE */
void parse_interface_declaration (cfile, outer_config)
void parse_interface_declaration (cfile, outer_config, name)
FILE *cfile;
struct client_config *outer_config;
char *name;
{
int token;
char *val;
struct interface_info dummy_interface, *ip;
struct client_state dummy_state;
struct client_config dummy_config;
struct client_state *client, **cp;
struct interface_info *ip;
token = next_token (&val, cfile);
if (token != STRING) {
@@ -479,11 +489,24 @@ void parse_interface_declaration (cfile, outer_config)
ip = interface_or_dummy (val);
if (!ip -> client)
make_client_state (ip);
/* If we were given a name, this is a pseudo-interface. */
if (name) {
make_client_state (&client);
client -> name = name;
client -> interface = ip;
for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
;
*cp = client;
} else {
if (!ip -> client) {
make_client_state (&ip -> client);
ip -> client -> interface = ip;
}
client = ip -> client;
}
if (!ip -> client -> config)
make_client_config (ip, outer_config);
if (!client -> config)
make_client_config (client, outer_config);
ip -> flags &= ~INTERFACE_AUTOMATIC;
interfaces_requested = 1;
@@ -503,7 +526,7 @@ void parse_interface_declaration (cfile, outer_config)
}
if (token == RBRACE)
break;
parse_client_statement (cfile, ip, ip -> client -> config);
parse_client_statement (cfile, ip, client -> config);
} while (1);
token = next_token (&val, cfile);
}
@@ -542,28 +565,28 @@ struct interface_info *interface_or_dummy (name)
return ip;
}
void make_client_state (ip)
struct interface_info *ip;
void make_client_state (state)
struct client_state **state;
{
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));
*state = ((struct client_state *)dmalloc (sizeof **state,
"make_client_state"));
if (!*state)
error ("no memory for client state\n");
memset (*state, 0, sizeof **state);
}
void make_client_config (ip, config)
struct interface_info *ip;
void make_client_config (client, config)
struct client_state *client;
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 -> config = (((struct client_config *)
dmalloc (sizeof (struct client_config),
"make_client_config")));
if (!client -> config)
error ("no memory for client config\n");
memset (client -> config, 0,
sizeof *(client -> config));
memcpy (client -> config, config, sizeof *config);
}
/* client-lease-statement :==
@@ -580,9 +603,10 @@ void parse_client_lease_statement (cfile, is_static)
int is_static;
{
struct client_lease *lease, *lp, *pl;
struct interface_info *ip;
struct interface_info *ip = (struct interface_info *)0;
int token;
char *val;
struct client_state *client = (struct client_state *)0;
token = next_token (&val, cfile);
if (token != LBRACE) {
@@ -597,8 +621,6 @@ void parse_client_lease_statement (cfile, is_static)
memset (lease, 0, sizeof *lease);
lease -> is_static = is_static;
ip = (struct interface_info *)0;
do {
token = peek_token (&val, cfile);
if (token == EOF) {
@@ -607,7 +629,7 @@ void parse_client_lease_statement (cfile, is_static)
}
if (token == RBRACE)
break;
parse_client_lease_declaration (cfile, lease, &ip);
parse_client_lease_declaration (cfile, lease, &ip, &client);
} while (1);
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... */
if (!ip -> client)
make_client_state (ip);
if (!ip -> client) {
make_client_state (&ip -> client);
ip -> client -> interface = ip;
}
if (!client)
client = ip -> client;
/* If this is an alias lease, it doesn't need to be sorted in. */
if (is_static == 2) {
@@ -633,14 +659,14 @@ void parse_client_lease_statement (cfile, is_static)
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) {
for (lp = 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;
client -> leases = lp -> next;
destroy_client_lease (lp);
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
leases - don't make it the active lease. */
if (is_static) {
lease -> next = ip -> client -> leases;
ip -> client -> leases = lease;
lease -> next = client -> leases;
client -> leases = lease;
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,
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)
destroy_client_lease (ip -> client -> active);
else if (ip -> client -> active -> address.len ==
if (client -> active) {
if (client -> active -> expiry < cur_time)
destroy_client_lease (client -> active);
else if (client -> active -> address.len ==
lease -> address.len &&
!memcmp (ip -> client -> active -> address.iabuf,
!memcmp (client -> active -> address.iabuf,
lease -> address.iabuf,
lease -> address.len))
destroy_client_lease (ip -> client -> active);
destroy_client_lease (client -> active);
else {
ip -> client -> active -> next =
ip -> client -> leases;
ip -> client -> leases = ip -> client -> active;
client -> active -> next = client -> leases;
client -> leases = client -> active;
}
}
ip -> client -> active = lease;
client -> active = lease;
/* phew. */
}
@@ -696,16 +721,18 @@ void parse_client_lease_statement (cfile, is_static)
REBIND time-decl |
EXPIRE time-decl */
void parse_client_lease_declaration (cfile, lease, ipp)
void parse_client_lease_declaration (cfile, lease, ipp, clientp)
FILE *cfile;
struct client_lease *lease;
struct interface_info **ipp;
struct client_state **clientp;
{
int token;
char *val;
char *t, *n;
struct interface_info *ip;
struct option_cache *oc;
struct client_state *client = (struct client_state *)0;
switch (next_token (&val, cfile)) {
case BOOTP:
@@ -723,6 +750,21 @@ void parse_client_lease_declaration (cfile, lease, ipp)
*ipp = ip;
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:
if (!parse_ip_addr (cfile, &lease -> address))
return;