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:
142
client/clparse.c
142
client/clparse.c
@@ -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;
|
||||||
|
1017
client/dhclient.c
1017
client/dhclient.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user