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
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
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
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
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
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;
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);
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)
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"));
+
+}
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);
}
}
}
- /* 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;
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;
.\" $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
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
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
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"))
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)) {
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"))
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
*
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;
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++ = ' ';
} else
*nsp++ = s [i];
}
+
+ if (enclose_char) {
+ *nsp++ = enclose_char;
+ }
*nsp++ = 0;
}
return buf;
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);
+}
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... */
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;
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
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 *);
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)
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
*
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 && \
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;
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;
}
}
+/*!
+ * \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
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;
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);
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;
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);
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;
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);
+ if (!parse_iaid_duid(cfile, &ia, &iaid, MDL)) {
return;
}
- if (len < 5) {
- parse_warn(cfile, "corrupt lease file; "
- "iaid+ia_pd string too short");
- skip_to_semi(cfile);
- 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);
* 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);
- set_server_duid(&duid);
+ 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);
}
/*
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 */
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
*
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)
++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);
++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;
}
*/
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;
/*
* 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;
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.
*/
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;
.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
.\" 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
.\"
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
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