summaryrefslogtreecommitdiff
path: root/server/confpars.c
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2016-03-04 14:16:29 -0500
committerThomas Markwalder <tmark@isc.org>2016-03-04 14:16:29 -0500
commitcc1bd34e09bad3313a16d89f7ad491ff16754dc7 (patch)
treeaefafa2e9b960601a4071c684b1dc58905be90d3 /server/confpars.c
parent7f4e6f97789799a76aa0b8b5ffab39042bcbff5e (diff)
downloadisc-dhcp-cc1bd34e09bad3313a16d89f7ad491ff16754dc7.tar.gz
[master] Added lease-id-format to server and client
Merges in rt26378
Diffstat (limited to 'server/confpars.c')
-rw-r--r--server/confpars.c199
1 files changed, 123 insertions, 76 deletions
diff --git a/server/confpars.c b/server/confpars.c
index 1b37a22e..e4c690b6 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -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;
@@ -1452,6 +1460,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);
+ 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);
@@ -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);
- 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);
}
/*
@@ -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 */