mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 18:07:25 +00:00
[master] Added lease-id-format to server and client
Merges in rt26378
This commit is contained in:
parent
7f4e6f9778
commit
cc1bd34e09
8
RELNOTES
8
RELNOTES
@ -236,7 +236,7 @@ by Eric Young (eay@cryptsoft.com).
|
||||
Please look at doc/DHCPv4-over-DHCPv6 for more details.
|
||||
[ISC-Bugs #35711]
|
||||
|
||||
- Corrected interface name formation when using DLPI under Solaris 11. As of
|
||||
- Correct interface name formation when using DLPI under Solaris 11. As of
|
||||
Solaris 11, ethernet device files are located in "/dev/net". The configure
|
||||
script has been modified to detect this situation and adjust the directory
|
||||
used accordingly. Thanks to Jarkko Torppa for reporting this issue and
|
||||
@ -248,6 +248,12 @@ by Eric Young (eay@cryptsoft.com).
|
||||
decoding a packet.
|
||||
[ISC-Bugs #41774]
|
||||
|
||||
- Add a new parameter, lease-id-format, to both dhcpd and dhclient. The
|
||||
parameter controls the format in which certain values are written to lease
|
||||
files. Formats supported are octal - quoted string containing octal
|
||||
escapes, and hex - unquoted, colon separated hex digits.
|
||||
[ISC-Busg #26378]
|
||||
|
||||
Changes since 4.3.3b1
|
||||
|
||||
- None
|
||||
|
@ -3,7 +3,7 @@
|
||||
Parser for dhclient config and lease files... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2014,2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-2003 by Internet Software Consortium
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -45,6 +45,8 @@ static struct dhc6_addr *parse_client6_iaaddr_statement(struct parse *cfile);
|
||||
static struct dhc6_addr *parse_client6_iaprefix_statement(struct parse *cfile);
|
||||
#endif /* DHCPv6 */
|
||||
|
||||
static void parse_lease_id_format (struct parse *cfile);
|
||||
|
||||
/* client-conf-file :== client-declarations END_OF_FILE
|
||||
client-declarations :== <nil>
|
||||
| client-declaration
|
||||
@ -168,6 +170,7 @@ isc_result_t read_client_conf ()
|
||||
top_level_config.retry_interval = 300;
|
||||
top_level_config.backoff_cutoff = 15;
|
||||
top_level_config.initial_interval = 3;
|
||||
top_level_config.lease_id_format = TOKEN_OCTAL;
|
||||
|
||||
/*
|
||||
* RFC 2131, section 4.4.1 specifies that the client SHOULD wait a
|
||||
@ -809,6 +812,12 @@ void parse_client_statement (cfile, ip, config)
|
||||
parse_reject_statement (cfile, config);
|
||||
return;
|
||||
|
||||
case LEASE_ID_FORMAT:
|
||||
skip_token(&val, (unsigned *)0, cfile);
|
||||
parse_lease_id_format(cfile);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
lose = 0;
|
||||
stmt = (struct executable_statement *)0;
|
||||
@ -1324,25 +1333,17 @@ static void
|
||||
parse_client_default_duid(struct parse *cfile)
|
||||
{
|
||||
struct data_string new_duid;
|
||||
const char *val = NULL;
|
||||
u_int8_t buf[128];
|
||||
unsigned len;
|
||||
int token;
|
||||
|
||||
memset(&new_duid, 0, sizeof(new_duid));
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "Expected DUID string.");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
len = parse_X(cfile, buf, sizeof(buf));
|
||||
if (len <= 2) {
|
||||
parse_warn(cfile, "Invalid DUID contents.");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&new_duid, 0, sizeof(new_duid));
|
||||
if (!buffer_allocate(&new_duid.buffer, len, MDL)) {
|
||||
parse_warn(cfile, "Out of memory parsing default DUID.");
|
||||
skip_to_semi(cfile);
|
||||
@ -1351,7 +1352,7 @@ parse_client_default_duid(struct parse *cfile)
|
||||
new_duid.data = new_duid.buffer->data;
|
||||
new_duid.len = len;
|
||||
|
||||
memcpy(new_duid.buffer->data, val, len);
|
||||
memcpy(new_duid.buffer->data, buf, len);
|
||||
|
||||
/* Rotate the last entry into place. */
|
||||
if (default_duid.buffer != NULL)
|
||||
@ -2310,3 +2311,45 @@ int parse_allow_deny (oc, cfile, flag)
|
||||
skip_to_semi (cfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Parses an lease-id-format statement
|
||||
*
|
||||
* A valid statement looks like this:
|
||||
*
|
||||
* lease-id-format :==
|
||||
* LEASE_ID_FORMAT TOKEN_OCTAL | TOKEN_HEX ;
|
||||
*
|
||||
* This function is used to parse the lease-id-format statement. It sets
|
||||
* top_level_config.lease_id_format.
|
||||
*
|
||||
* \param cfile the current parse file
|
||||
*
|
||||
*/
|
||||
void parse_lease_id_format (struct parse *cfile)
|
||||
{
|
||||
enum dhcp_token token;
|
||||
const char *val;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
switch(token) {
|
||||
case TOKEN_OCTAL:
|
||||
top_level_config.lease_id_format = TOKEN_OCTAL;
|
||||
break;
|
||||
case TOKEN_HEX:
|
||||
top_level_config.lease_id_format = TOKEN_HEX;
|
||||
break;
|
||||
default:
|
||||
parse_warn(cfile, "lease-id-format is invalid: "
|
||||
" it must be octal or hex.");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("lease_id_format is: %s",
|
||||
(top_level_config.lease_id_format == TOKEN_OCTAL
|
||||
? "octal" : "hex"));
|
||||
|
||||
}
|
||||
|
@ -3489,10 +3489,12 @@ form_duid(struct data_string *duid, const char *file, int line)
|
||||
ip->hw_address.hlen - 1);
|
||||
}
|
||||
|
||||
str = quotify_buf(duid->data, duid->len, MDL);
|
||||
if (str == NULL)
|
||||
log_info("Created duid.");
|
||||
else {
|
||||
/* Now format the output based on lease-id-format */
|
||||
str = format_lease_id(duid->data, duid->len,
|
||||
top_level_config.lease_id_format, MDL);
|
||||
if (str == NULL) {
|
||||
log_info("form_duid: Couldn't allocate memory to log duid!");
|
||||
} else {
|
||||
log_info("Created duid %s.", str);
|
||||
dfree(str, MDL);
|
||||
}
|
||||
@ -3516,16 +3518,13 @@ write_duid(struct data_string *duid)
|
||||
}
|
||||
}
|
||||
|
||||
/* It would make more sense to write this as a hex string,
|
||||
* but our function to do that (print_hex_n) uses a fixed
|
||||
* length buffer...and we can't guarantee a duid would be
|
||||
* less than the fixed length.
|
||||
*/
|
||||
str = quotify_buf(duid->data, duid->len, MDL);
|
||||
/* Generate a formatted duid string per lease-id-format */
|
||||
str = format_lease_id(duid->data, duid->len,
|
||||
top_level_config.lease_id_format, MDL);
|
||||
if (str == NULL)
|
||||
return ISC_R_NOMEMORY;
|
||||
|
||||
stat = fprintf(leaseFile, "default-duid \"%s\";\n", str);
|
||||
stat = fprintf(leaseFile, "default-duid %s;\n", str);
|
||||
dfree(str, MDL);
|
||||
if (stat <= 0)
|
||||
return ISC_R_IOERROR;
|
||||
@ -3586,8 +3585,35 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease,
|
||||
ianame = "ia-pd";
|
||||
break;
|
||||
}
|
||||
stat = fprintf(leaseFile, " %s %s {\n",
|
||||
ianame, print_hex_1(4, ia->iaid, 12));
|
||||
|
||||
/* For some reason IAID was never octal or hex, but string or
|
||||
* hex. Go figure. So for compatibilty's sake we will either
|
||||
* do hex or "legacy" i.e string rather than octal. What a
|
||||
* cluster. */
|
||||
switch(top_level_config.lease_id_format) {
|
||||
case TOKEN_HEX: {
|
||||
char* iaid_str = format_lease_id(
|
||||
(const unsigned char *) &ia->iaid, 4,
|
||||
top_level_config.lease_id_format, MDL);
|
||||
|
||||
if (!iaid_str) {
|
||||
log_error("Can't format iaid");
|
||||
return ISC_R_IOERROR;
|
||||
}
|
||||
|
||||
stat = fprintf(leaseFile, " %s %s {\n",
|
||||
ianame, iaid_str);
|
||||
dfree(iaid_str, MDL);
|
||||
break;
|
||||
}
|
||||
|
||||
case TOKEN_OCTAL:
|
||||
default:
|
||||
stat = fprintf(leaseFile, " %s %s {\n", ianame,
|
||||
print_hex_1(4, ia->iaid, 12));
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat <= 0)
|
||||
return ISC_R_IOERROR;
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
.\" $Id: dhclient.conf.5,v 1.34 2012/01/24 22:23:39 sar Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014,2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 1996-2003 by Internet Software Consortium
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
@ -599,6 +597,28 @@ day-and-time in UTC, whereas \fIlocal\fR uses a seconds-since-epoch to store
|
||||
the time value, and helpfully places a local timezone time in a comment on
|
||||
the same line. The formats are described in detail in this manpage, within
|
||||
the LEASE DECLARATIONS section.
|
||||
.PP
|
||||
The
|
||||
.I lease-id-format
|
||||
parameter
|
||||
.RS 0.25i
|
||||
.PP
|
||||
.B lease-id-format \fIformat\fB;\fR
|
||||
.PP
|
||||
The \fIformat\fR parameter must be either \fBoctal\fR or \fBhex\fR.
|
||||
This parameter governs the format used to write certain values to lease
|
||||
files. With the default format, octal, values are written as quoted strings in
|
||||
which non-printable characters are represented as octal escapes -
|
||||
a backslash character followed by three octal digits. When the hex format
|
||||
is specified, values are written as an unquoted series of hexadecimal digit
|
||||
pairs, separated by colons.
|
||||
|
||||
Currently, the values written out based on lease-id-format are the default-duid
|
||||
and the IAID value (DHCPv6 only). The client automatically reads the values
|
||||
in either format. Note that when the format is octal, rather than as an octal
|
||||
string, IAID is output as hex if it contains no printable characters or as a
|
||||
string if contains only printable characters. This is done to maintain backward
|
||||
compatibility.
|
||||
.PP
|
||||
\fBreject \fIcidr-ip-address\fR [\fB,\fR \fI...\fB \fIcidr-ip-address\fR ] \fB;\fR
|
||||
.PP
|
||||
|
@ -3,7 +3,7 @@
|
||||
Lexical scanner for dhcpd config file... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1995-2003 by Internet Software Consortium
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -1050,6 +1050,9 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||
return HOSTNAME;
|
||||
if (!strcasecmp (atom + 1, "elp"))
|
||||
return TOKEN_HELP;
|
||||
if (!strcasecmp (atom + 1, "ex")) {
|
||||
return TOKEN_HEX;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if (!strcasecmp(atom+1, "a-na"))
|
||||
@ -1136,6 +1139,9 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||
if (!strcasecmp(atom+1, "ittle-endian")) {
|
||||
return TOKEN_LITTLE_ENDIAN;
|
||||
}
|
||||
if (!strcasecmp (atom + 1, "ease-id-format")) {
|
||||
return LEASE_ID_FORMAT;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (!strncasecmp (atom + 1, "ax", 2)) {
|
||||
@ -1236,6 +1242,9 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||
return OF;
|
||||
if (!strcasecmp (atom + 1, "wner"))
|
||||
return OWNER;
|
||||
if (!strcasecmp (atom + 1, "ctal")) {
|
||||
return TOKEN_OCTAL;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if (!strcasecmp (atom + 1, "arse-vendor-option"))
|
||||
|
100
common/print.c
100
common/print.c
@ -3,7 +3,7 @@
|
||||
Turn data structures into printable text. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2014 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2009-2014,2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1995-2003 by Internet Software Consortium
|
||||
*
|
||||
@ -69,7 +69,7 @@ char *quotify_string (const char *s, const char *file, int line)
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *quotify_buf (const unsigned char *s, unsigned len,
|
||||
char *quotify_buf (const unsigned char *s, unsigned len, char enclose_char,
|
||||
const char *file, int line)
|
||||
{
|
||||
unsigned nulen = 0;
|
||||
@ -87,9 +87,17 @@ char *quotify_buf (const unsigned char *s, unsigned len,
|
||||
nulen++;
|
||||
}
|
||||
|
||||
if (enclose_char) {
|
||||
nulen +=2 ;
|
||||
}
|
||||
|
||||
buf = dmalloc (nulen + 1, MDL);
|
||||
if (buf) {
|
||||
nsp = buf;
|
||||
if (enclose_char) {
|
||||
*nsp++ = enclose_char;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (s [i] == ' ')
|
||||
*nsp++ = ' ';
|
||||
@ -102,6 +110,10 @@ char *quotify_buf (const unsigned char *s, unsigned len,
|
||||
} else
|
||||
*nsp++ = s [i];
|
||||
}
|
||||
|
||||
if (enclose_char) {
|
||||
*nsp++ = enclose_char;
|
||||
}
|
||||
*nsp++ = 0;
|
||||
}
|
||||
return buf;
|
||||
@ -1517,3 +1529,87 @@ print_time(TIME t)
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* !brief Return the given data as a string of hex digits "xx:xx:xx ..."
|
||||
*
|
||||
* Converts the given data into a null-terminated, string of hex digits,
|
||||
* stored in an allocated buffer. It is the caller's responsiblity to free
|
||||
* the buffer.
|
||||
*
|
||||
* \param s - pointer to the data to convert
|
||||
* \param len - length of the data to convert
|
||||
* \param file - source file of invocation
|
||||
* \param line - line number of invocation
|
||||
*
|
||||
* \return Returns an allocated buffer containing the hex string
|
||||
*/
|
||||
char *buf_to_hex (const unsigned char *s, unsigned len,
|
||||
const char *file, int line)
|
||||
{
|
||||
unsigned nulen = 0;
|
||||
char *buf;
|
||||
|
||||
/* If somebody hands us length of zero, we'll give them
|
||||
* back an empty string */
|
||||
if (!len) {
|
||||
buf = dmalloc (1, MDL);
|
||||
if (buf) {
|
||||
*buf = 0x0;
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
/* Figure out how big it needs to be. print_to_hex uses
|
||||
* "%02x:" per character. Note since there's no trailing colon
|
||||
* we'll have room for the null */
|
||||
nulen = (len * 3);
|
||||
|
||||
/* Allocate our buffer */
|
||||
buf = dmalloc (nulen, MDL);
|
||||
|
||||
/* Hex-ify it */
|
||||
if (buf) {
|
||||
print_hex_only (len, s, nulen, buf);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* !brief Formats data into a string based on a lease id format
|
||||
*
|
||||
* Takes the given data and returns an allocated string whose contents are
|
||||
* the string version of that data, formatted according to the output lease
|
||||
* id format. Note it is the caller's responsiblity to delete the string.
|
||||
*
|
||||
* Currently two formats are supported:
|
||||
*
|
||||
* OCTAL - Default or "legacy" CSL format enclosed in quotes '"'.
|
||||
*
|
||||
* HEX - Bytes represented as string colon seperated of hex digit pairs
|
||||
* (xx:xx:xx...)
|
||||
*
|
||||
* \param s - data to convert
|
||||
* \param len - length of the data to convert
|
||||
* \param format - desired format of the result
|
||||
* \param file - source file of invocation
|
||||
* \param line - line number of invocation
|
||||
*
|
||||
* \return A pointer to the allocated, null-terminated string
|
||||
*/
|
||||
char *format_lease_id(const unsigned char *s, unsigned len,
|
||||
int format, const char *file, int line) {
|
||||
char *idstr = NULL;
|
||||
|
||||
switch (format) {
|
||||
case TOKEN_HEX:
|
||||
idstr = buf_to_hex(s, len, MDL);
|
||||
break;
|
||||
case TOKEN_OCTAL:
|
||||
default:
|
||||
idstr = quotify_buf(s, len, '"', MDL);
|
||||
break;
|
||||
}
|
||||
return (idstr);
|
||||
}
|
||||
|
@ -1243,6 +1243,9 @@ struct client_config {
|
||||
int do_forward_update; /* If nonzero, and if we have the
|
||||
information we need, update the
|
||||
A record for the address we get. */
|
||||
|
||||
int lease_id_format; /* format for IDs in lease file,
|
||||
TOKEN_OCTAL or TOKEN_HEX */
|
||||
};
|
||||
|
||||
/* Per-interface state used in the dhcp client... */
|
||||
@ -2065,6 +2068,7 @@ extern int server_id_check;
|
||||
|
||||
extern int prefix_length_mode;
|
||||
extern int authoring_byte_order;
|
||||
extern int lease_id_format;
|
||||
|
||||
extern const char *path_dhcpd_conf;
|
||||
extern const char *path_dhcpd_db;
|
||||
@ -2089,6 +2093,7 @@ extern enum dhcp_shutdown_state shutdown_state;
|
||||
isc_result_t dhcp_io_shutdown (omapi_object_t *, void *);
|
||||
isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
|
||||
control_object_state_t newstate);
|
||||
|
||||
#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
|
||||
void relinquish_ackqueue(void);
|
||||
#endif
|
||||
@ -2532,13 +2537,13 @@ int binding_scope_reference (struct binding_scope **,
|
||||
int dns_zone_allocate (struct dns_zone **, const char *, int);
|
||||
int dns_zone_reference (struct dns_zone **,
|
||||
struct dns_zone *, const char *, int);
|
||||
|
||||
/* print.c */
|
||||
#define DEFAULT_TIME_FORMAT 0
|
||||
#define LOCAL_TIME_FORMAT 1
|
||||
extern int db_time_format;
|
||||
char *quotify_string (const char *, const char *, int);
|
||||
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
|
||||
char *quotify_buf (const unsigned char *, unsigned, const char,
|
||||
const char *, int);
|
||||
char *print_base64 (const unsigned char *, unsigned, const char *, int);
|
||||
char *print_hw_addr (const int, const int, const unsigned char *);
|
||||
void print_lease (struct lease *);
|
||||
@ -2572,7 +2577,10 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
|
||||
const char *print_time(TIME);
|
||||
|
||||
void get_hw_addr(const char *name, struct hardware *hw);
|
||||
|
||||
char *buf_to_hex (const unsigned char *s, unsigned len,
|
||||
const char *file, int line);
|
||||
char *format_lease_id(const unsigned char *s, unsigned len, int format,
|
||||
const char *file, int line);
|
||||
/* socket.c */
|
||||
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
|
||||
|| defined (USE_SOCKET_FALLBACK)
|
||||
|
@ -3,7 +3,7 @@
|
||||
Tokens for config file lexer and parser. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011-2015 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2011-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2004,2007-2009 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-2003 by Internet Software Consortium
|
||||
*
|
||||
@ -371,7 +371,10 @@ enum dhcp_token {
|
||||
PARSE_VENDOR_OPT = 672,
|
||||
AUTHORING_BYTE_ORDER = 673,
|
||||
TOKEN_LITTLE_ENDIAN = 674,
|
||||
TOKEN_BIG_ENDIAN = 675
|
||||
TOKEN_BIG_ENDIAN = 675,
|
||||
LEASE_ID_FORMAT = 676,
|
||||
TOKEN_HEX = 677,
|
||||
TOKEN_OCTAL = 678
|
||||
};
|
||||
|
||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||
|
@ -36,6 +36,9 @@ static int parse_binding_value(struct parse *cfile,
|
||||
struct binding_value *value);
|
||||
|
||||
static void parse_authoring_byte_order (struct parse *cfile);
|
||||
static void parse_lease_id_format (struct parse *cfile);
|
||||
static int parse_iaid_duid(struct parse *cfile, struct ia_xx** ia,
|
||||
u_int32_t *iaid, const char* file, int line);
|
||||
|
||||
#if defined (TRACING)
|
||||
trace_type_t *trace_readconf_type;
|
||||
@ -802,6 +805,11 @@ int parse_statement (cfile, group, type, host_decl, declaration)
|
||||
break;
|
||||
#endif /* DHCPv6 */
|
||||
|
||||
case LEASE_ID_FORMAT:
|
||||
token = next_token (&val, (unsigned *)0, cfile);
|
||||
parse_lease_id_format(cfile);
|
||||
break;
|
||||
|
||||
default:
|
||||
et = (struct executable_statement *)0;
|
||||
lose = 0;
|
||||
@ -1451,6 +1459,52 @@ void parse_authoring_byte_order (struct parse *cfile)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses a lease-id-format statement
|
||||
*
|
||||
* A valid statement looks like this:
|
||||
*
|
||||
* lease-id-format :==
|
||||
* LEASE_ID_FORMAT TOKEN_OCTAL | TOKEN_HEX ;
|
||||
*
|
||||
* This function is used to parse the lease-id-format statement. It sets the
|
||||
* global variable, lease_id_format.
|
||||
*
|
||||
* \param cfile the current parse file
|
||||
*
|
||||
*/
|
||||
void parse_lease_id_format (struct parse *cfile)
|
||||
{
|
||||
enum dhcp_token token;
|
||||
const char *val;
|
||||
unsigned int len;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
switch(token) {
|
||||
case TOKEN_OCTAL:
|
||||
lease_id_format = TOKEN_OCTAL;
|
||||
break;
|
||||
case TOKEN_HEX:
|
||||
lease_id_format = TOKEN_HEX;
|
||||
break;
|
||||
default:
|
||||
parse_warn(cfile, "lease-id-format is invalid: "
|
||||
" it must be octal or hex.");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("lease_id_format is: %s",
|
||||
lease_id_format == TOKEN_OCTAL ? "octal" : "hex");
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != SEMI) {
|
||||
parse_warn(cfile, "corrupt lease file; expecting a semicolon");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Parse allow and deny statements
|
||||
@ -4664,10 +4718,9 @@ parse_ia_na_declaration(struct parse *cfile) {
|
||||
skip_to_semi(cfile);
|
||||
#else /* defined(DHCPv6) */
|
||||
enum dhcp_token token;
|
||||
struct ia_xx *ia;
|
||||
struct ia_xx *ia = NULL;
|
||||
const char *val;
|
||||
struct ia_xx *old_ia;
|
||||
unsigned int len;
|
||||
u_int32_t iaid;
|
||||
struct iaddr iaddr;
|
||||
binding_state_t state;
|
||||
@ -4690,26 +4743,10 @@ parse_ia_na_declaration(struct parse *cfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"expecting an iaid+ia_na string");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
if (len < 5) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"iaid+ia_na string too short");
|
||||
skip_to_semi(cfile);
|
||||
if (!parse_iaid_duid(cfile, &ia, &iaid, MDL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
iaid = parse_byte_order_uint32(val);
|
||||
|
||||
ia = NULL;
|
||||
if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
|
||||
log_fatal("Out of memory.");
|
||||
}
|
||||
ia->ia_type = D6O_IA_NA;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
@ -5117,10 +5154,9 @@ parse_ia_ta_declaration(struct parse *cfile) {
|
||||
skip_to_semi(cfile);
|
||||
#else /* defined(DHCPv6) */
|
||||
enum dhcp_token token;
|
||||
struct ia_xx *ia;
|
||||
struct ia_xx *ia = NULL;
|
||||
const char *val;
|
||||
struct ia_xx *old_ia;
|
||||
unsigned int len;
|
||||
u_int32_t iaid;
|
||||
struct iaddr iaddr;
|
||||
binding_state_t state;
|
||||
@ -5143,26 +5179,10 @@ parse_ia_ta_declaration(struct parse *cfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"expecting an iaid+ia_ta string");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
if (len < 5) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"iaid+ia_ta string too short");
|
||||
skip_to_semi(cfile);
|
||||
if (!parse_iaid_duid(cfile, &ia, &iaid, MDL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
iaid = parse_byte_order_uint32(val);
|
||||
|
||||
ia = NULL;
|
||||
if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
|
||||
log_fatal("Out of memory.");
|
||||
}
|
||||
ia->ia_type = D6O_IA_TA;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
@ -5570,10 +5590,9 @@ parse_ia_pd_declaration(struct parse *cfile) {
|
||||
skip_to_semi(cfile);
|
||||
#else /* defined(DHCPv6) */
|
||||
enum dhcp_token token;
|
||||
struct ia_xx *ia;
|
||||
struct ia_xx *ia = NULL;
|
||||
const char *val;
|
||||
struct ia_xx *old_ia;
|
||||
unsigned int len;
|
||||
u_int32_t iaid;
|
||||
struct iaddr iaddr;
|
||||
u_int8_t plen;
|
||||
@ -5597,26 +5616,10 @@ parse_ia_pd_declaration(struct parse *cfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"expecting an iaid+ia_pd string");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
if (len < 5) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"iaid+ia_pd string too short");
|
||||
skip_to_semi(cfile);
|
||||
if (!parse_iaid_duid(cfile, &ia, &iaid, MDL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
iaid = parse_byte_order_uint32(val);
|
||||
|
||||
ia = NULL;
|
||||
if (ia_allocate(&ia, iaid, val+4, len-4, MDL) != ISC_R_SUCCESS) {
|
||||
log_fatal("Out of memory.");
|
||||
}
|
||||
ia->ia_type = D6O_IA_PD;
|
||||
|
||||
token = next_token(&val, NULL, cfile);
|
||||
@ -6024,39 +6027,37 @@ parse_ia_pd_declaration(struct parse *cfile) {
|
||||
* DUID stored in a string:
|
||||
*
|
||||
* server-duid "\000\001\000\001\015\221\034JRT\000\0224Y";
|
||||
*
|
||||
* OR as a hex string of digits:
|
||||
*
|
||||
* server-duid 00:01:00:01:1e:68:b3:db:0a:00:27:00:00:02;
|
||||
*/
|
||||
void
|
||||
parse_server_duid(struct parse *cfile) {
|
||||
enum dhcp_token token;
|
||||
const char *val;
|
||||
unsigned int len;
|
||||
struct data_string duid;
|
||||
unsigned char bytes[128]; /* Maximum valid DUID is 128 */
|
||||
unsigned int len;
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != STRING) {
|
||||
parse_warn(cfile, "corrupt lease file; expecting a DUID");
|
||||
len = parse_X(cfile, bytes, sizeof(bytes));
|
||||
if (len <= 2) {
|
||||
parse_warn(cfile, "Invalid duid contents");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&duid, 0, sizeof(duid));
|
||||
duid.len = len;
|
||||
if (!buffer_allocate(&duid.buffer, duid.len, MDL)) {
|
||||
log_fatal("Out of memory storing DUID");
|
||||
memset(&duid, 0x0, sizeof(duid));
|
||||
if (!buffer_allocate(&duid.buffer, len, MDL)) {
|
||||
log_fatal("parse_server_duid: out of memory");
|
||||
}
|
||||
duid.data = (unsigned char *)duid.buffer->data;
|
||||
memcpy(duid.buffer->data, val, len);
|
||||
|
||||
memcpy(duid.buffer->data, bytes, len);
|
||||
duid.len = len;
|
||||
duid.data = duid.buffer->data;
|
||||
|
||||
set_server_duid(&duid);
|
||||
|
||||
data_string_forget(&duid, MDL);
|
||||
|
||||
token = next_token(&val, &len, cfile);
|
||||
if (token != SEMI) {
|
||||
parse_warn(cfile, "corrupt lease file; expecting a semicolon");
|
||||
skip_to_semi(cfile);
|
||||
return;
|
||||
}
|
||||
parse_semi(cfile);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6343,5 +6344,51 @@ uint32_t parse_byte_order_uint32(const void *source) {
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* !brief Parses an iaid/duid string into an iaid and struct ia
|
||||
*
|
||||
* Given a string containing the iaid-duid value read from the file,
|
||||
* and using the format specified by input lease-id-format, convert
|
||||
* it into an IAID value and an ia_xx struct.
|
||||
*
|
||||
* \param cfile - file being parsed
|
||||
* \param ia - pointer in which to store the allocated ia_xx struct
|
||||
* \param iaid - pointer in which to return the IAID value
|
||||
* \param file - source file name of invocation
|
||||
* \param line - line numbe of invocation
|
||||
*
|
||||
* \return 0 if parsing fails, non-zero otherwise
|
||||
*/
|
||||
int
|
||||
parse_iaid_duid(struct parse* cfile, struct ia_xx** ia, u_int32_t *iaid,
|
||||
const char* file, int line) {
|
||||
unsigned char bytes[132]; /* Maximum valid IAID-DUID is 132 */
|
||||
unsigned int len;
|
||||
|
||||
if (!ia) {
|
||||
log_error("parse_iaid_duid: ia ptr cannot be null");
|
||||
return (0);
|
||||
}
|
||||
|
||||
*ia = NULL;
|
||||
len = parse_X(cfile, bytes, sizeof(bytes));
|
||||
if (len <= 5) {
|
||||
parse_warn(cfile, "corrupt lease file; "
|
||||
"iaid+ia_xx string too short");
|
||||
skip_to_semi(cfile);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Extract the IAID from the front */
|
||||
*iaid = parse_byte_order_uint32(bytes);
|
||||
|
||||
/* Instantiate the ia_xx */
|
||||
if (ia_allocate(ia, *iaid, (const char*)bytes + 4, len - 4, file, line)
|
||||
!= ISC_R_SUCCESS) {
|
||||
log_fatal("parse_iaid_duid:Out of memory.");
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* DHCPv6 */
|
||||
|
||||
|
29
server/db.c
29
server/db.c
@ -3,7 +3,7 @@
|
||||
Persistent database management routines for DHCPD... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2015 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2012-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1995-2003 by Internet Software Consortium
|
||||
*
|
||||
@ -56,10 +56,10 @@ write_binding_scope(FILE *db_file, struct binding *bnd, char *prepend) {
|
||||
if (bnd->value->type == binding_data) {
|
||||
if (bnd->value->value.data.data != NULL) {
|
||||
s = quotify_buf(bnd->value->value.data.data,
|
||||
bnd->value->value.data.len, MDL);
|
||||
bnd->value->value.data.len, '"', MDL);
|
||||
if (s != NULL) {
|
||||
errno = 0;
|
||||
fprintf(db_file, "%sset %s = \"%s\";",
|
||||
fprintf(db_file, "%sset %s = %s;",
|
||||
prepend, bnd->name, s);
|
||||
dfree(s, MDL);
|
||||
if (errno)
|
||||
@ -207,10 +207,11 @@ int write_lease (lease)
|
||||
++errors;
|
||||
}
|
||||
if (lease -> uid_len) {
|
||||
s = quotify_buf (lease -> uid, lease -> uid_len, MDL);
|
||||
s = format_lease_id(lease->uid, lease->uid_len, lease_id_format,
|
||||
MDL);
|
||||
if (s) {
|
||||
errno = 0;
|
||||
fprintf (db_file, "\n uid \"%s\";", s);
|
||||
fprintf (db_file, "\n uid %s;", s);
|
||||
if (errno)
|
||||
++errors;
|
||||
dfree (s, MDL);
|
||||
@ -539,23 +540,23 @@ write_ia(const struct ia_xx *ia) {
|
||||
++count;
|
||||
}
|
||||
|
||||
|
||||
s = quotify_buf(ia->iaid_duid.data, ia->iaid_duid.len, MDL);
|
||||
s = format_lease_id(ia->iaid_duid.data, ia->iaid_duid.len,
|
||||
lease_id_format, MDL);
|
||||
if (s == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
switch (ia->ia_type) {
|
||||
case D6O_IA_NA:
|
||||
fprintf_ret = fprintf(db_file, "ia-na \"%s\" {\n", s);
|
||||
fprintf_ret = fprintf(db_file, "ia-na %s {\n", s);
|
||||
break;
|
||||
case D6O_IA_TA:
|
||||
fprintf_ret = fprintf(db_file, "ia-ta \"%s\" {\n", s);
|
||||
fprintf_ret = fprintf(db_file, "ia-ta %s {\n", s);
|
||||
break;
|
||||
case D6O_IA_PD:
|
||||
fprintf_ret = fprintf(db_file, "ia-pd \"%s\" {\n", s);
|
||||
fprintf_ret = fprintf(db_file, "ia-pd %s {\n", s);
|
||||
break;
|
||||
default:
|
||||
log_error("Unknown ia type %u for \"%s\" at %s:%d",
|
||||
log_error("Unknown ia type %u for %s at %s:%d",
|
||||
(unsigned)ia->ia_type, s, MDL);
|
||||
fprintf_ret = -1;
|
||||
}
|
||||
@ -712,7 +713,8 @@ write_server_duid(void) {
|
||||
*/
|
||||
memset(&server_duid, 0, sizeof(server_duid));
|
||||
copy_server_duid(&server_duid, MDL);
|
||||
s = quotify_buf(server_duid.data, server_duid.len, MDL);
|
||||
s = format_lease_id(server_duid.data, server_duid.len, lease_id_format,
|
||||
MDL);
|
||||
data_string_forget(&server_duid, MDL);
|
||||
if (s == NULL) {
|
||||
goto error_exit;
|
||||
@ -721,7 +723,7 @@ write_server_duid(void) {
|
||||
/*
|
||||
* Write to the leases file.
|
||||
*/
|
||||
fprintf_ret = fprintf(db_file, "server-duid \"%s\";\n\n", s);
|
||||
fprintf_ret = fprintf(db_file, "server-duid %s;\n\n", s);
|
||||
dfree(s, MDL);
|
||||
if (fprintf_ret < 0) {
|
||||
goto error_exit;
|
||||
@ -1183,7 +1185,6 @@ int new_lease_file ()
|
||||
if (errno)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* At this point we have a new lease file that, so far, could not
|
||||
* be described as either corrupt nor valid.
|
||||
*/
|
||||
|
@ -77,6 +77,7 @@ int server_id_check = 0; /* 0 = default, don't check server id, 1 = do check */
|
||||
int prefix_length_mode = PLM_EXACT;
|
||||
|
||||
int authoring_byte_order = 0; /* 0 = not set */
|
||||
int lease_id_format = TOKEN_OCTAL; /* octal by default */
|
||||
|
||||
const char *path_dhcpd_conf = _PATH_DHCPD_CONF;
|
||||
const char *path_dhcpd_db = _PATH_DHCPD_DB;
|
||||
|
@ -2509,6 +2509,26 @@ is, the latter value will be used.
|
||||
.RE
|
||||
.PP
|
||||
The
|
||||
.I lease-id-format
|
||||
parameter
|
||||
.RS 0.25i
|
||||
.PP
|
||||
.B lease-id-format \fIformat\fB;\fR
|
||||
.PP
|
||||
The \fIformat\fR parameter must be either \fBoctal\fR or \fBhex\fR.
|
||||
This parameter governs the format used to write certain values to lease
|
||||
files. With the default format, octal, values are written as quoted strings in
|
||||
which non-printable characters are represented as octal escapes -
|
||||
a backslash character followed by three octal digits. When the hex format
|
||||
is specified, values are written as an unquoted series of pairs of
|
||||
hexadecimal digits, separated by colons.
|
||||
|
||||
Currently, the values written out based on lease-id-format are the server-duid,
|
||||
the uid (DHCPv4 leases), and the IAID_DUID (DHCPv6 leases). Note the server
|
||||
automatically reads the values in either format.
|
||||
.RE
|
||||
.PP
|
||||
The
|
||||
.I local-port
|
||||
statement
|
||||
.RS 0.25i
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" dhcpd.leases.5
|
||||
.\"
|
||||
.\" Copyright (c) 2014-2015 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 2014-2016 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC")
|
||||
.\" Copyright (c) 1996-2003 by Internet Software Consortium
|
||||
.\"
|
||||
@ -246,7 +246,8 @@ The client identifier is recorded as a colon-separated hexadecimal
|
||||
list or as a quoted string. If it is recorded as a quoted string and
|
||||
it contains one or more non-printable characters, those characters are
|
||||
represented as octal escapes - a backslash character followed by three
|
||||
octal digits.
|
||||
octal digits. The format used is determined by the lease-id-format
|
||||
parameter, which defaults to octal.
|
||||
.PP
|
||||
.B client-hostname "\fIhostname\fB";\fR
|
||||
.PP
|
||||
@ -327,7 +328,8 @@ The IAID_DUID value is recorded as a colon-separated hexadecimal
|
||||
list or as a quoted string. If it is recorded as a quoted string and
|
||||
it contains one or more non-printable characters, those characters are
|
||||
represented as octal escapes - a backslash character followed by three
|
||||
octal digits.
|
||||
octal digits. The format used is governed by the lease-id-format parameter,
|
||||
which defaults to octal.
|
||||
.PP
|
||||
.B cltt \fIdate\fB;\fR
|
||||
.PP
|
||||
|
Loading…
x
Reference in New Issue
Block a user