summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Routhier <sar@isc.org>2010-09-13 22:20:43 +0000
committerShawn Routhier <sar@isc.org>2010-09-13 22:20:43 +0000
commit4b0135fed295b69ed7d102b5876fb4465a1bf2a4 (patch)
tree94cc74b07126e322d8ff352295a08c240e534862
parente09f62934a13592b5acd3440ec14cdd2bd18c8e1 (diff)
downloadisc-dhcp-4b0135fed295b69ed7d102b5876fb4465a1bf2a4.tar.gz
Fixes to lease input and output.
[ISC-Bugs #20418] - Some systems don't support the "%s" argument to strftime, paste together the same string using mktime instead. [ISC-Bugs #19596] - When parsing iaid values accept printable characters. [ISC-Bugs #21585] - Always print time values in omshell as hex instead of ascii if the values happen to be printable characters.
-rw-r--r--RELNOTES8
-rw-r--r--client/clparse.c65
-rw-r--r--common/print.c156
-rw-r--r--dhcpctl/omshell.c12
-rw-r--r--includes/dhcpd.h8
-rw-r--r--server/db.c6
6 files changed, 160 insertions, 95 deletions
diff --git a/RELNOTES b/RELNOTES
index ead8758c..09348ada 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -136,6 +136,14 @@ work on other platforms. Please report any problems and suggested fixes to
date strings correctly. Thanks to a patch from Jiri Popelka at Red Hat.
[ISC-Bugs #21501, #20598]
+- Fixes to lease input and output.
+ [ISC-Bugs #20418] - Some systems don't support the "%s" argument to
+ strftime, paste together the same string using mktime instead.
+ [ISC-Bugs #19596] - When parsing iaid values accept printable
+ characters.
+ [ISC-Bugs #21585] - Always print time values in omshell as hex
+ instead of ascii if the values happen to be printable characters.
+
Changes since 4.1.1rc1
- When using 'ignore client-updates;', the FQDN returned to the client
diff --git a/client/clparse.c b/client/clparse.c
index afe58be5..aa00caa6 100644
--- a/client/clparse.c
+++ b/client/clparse.c
@@ -3,7 +3,7 @@
Parser for dhclient config and lease files... */
/*
- * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2010 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
@@ -1510,12 +1510,12 @@ parse_client6_lease_statement(struct parse *cfile)
static struct dhc6_ia *
parse_client6_ia_na_statement(struct parse *cfile)
{
- struct data_string id;
struct option_cache *oc = NULL;
struct dhc6_ia *ia;
struct dhc6_addr **addr;
const char *val;
- int token, no_semi;
+ int token, no_semi, len;
+ u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) {
@@ -1526,20 +1526,11 @@ parse_client6_ia_na_statement(struct parse *cfile)
ia->ia_type = D6O_IA_NA;
/* Get IAID. */
- memset(&id, 0, sizeof(id));
- if (parse_cshl(&id, cfile)) {
- if (id.len == 4)
- memcpy(ia->iaid, id.data, 4);
- else {
- parse_warn(cfile, "Expecting IAID of length 4, got %d.",
- id.len);
- skip_to_semi(cfile);
- dfree(ia, MDL);
- return NULL;
- }
- data_string_forget(&id, MDL);
+ len = parse_X(cfile, buf, 5);
+ if (len == 4) {
+ memcpy(ia->iaid, buf, 4);
} else {
- parse_warn(cfile, "Expecting IAID.");
+ parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile);
dfree(ia, MDL);
return NULL;
@@ -1647,12 +1638,12 @@ parse_client6_ia_na_statement(struct parse *cfile)
static struct dhc6_ia *
parse_client6_ia_ta_statement(struct parse *cfile)
{
- struct data_string id;
struct option_cache *oc = NULL;
struct dhc6_ia *ia;
struct dhc6_addr **addr;
const char *val;
- int token, no_semi;
+ int token, no_semi, len;
+ u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) {
@@ -1663,20 +1654,11 @@ parse_client6_ia_ta_statement(struct parse *cfile)
ia->ia_type = D6O_IA_TA;
/* Get IAID. */
- memset(&id, 0, sizeof(id));
- if (parse_cshl(&id, cfile)) {
- if (id.len == 4)
- memcpy(ia->iaid, id.data, 4);
- else {
- parse_warn(cfile, "Expecting IAID of length 4, got %d.",
- id.len);
- skip_to_semi(cfile);
- dfree(ia, MDL);
- return NULL;
- }
- data_string_forget(&id, MDL);
+ len = parse_X(cfile, buf, 5);
+ if (len == 4) {
+ memcpy(ia->iaid, buf, 4);
} else {
- parse_warn(cfile, "Expecting IAID.");
+ parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile);
dfree(ia, MDL);
return NULL;
@@ -1764,12 +1746,12 @@ parse_client6_ia_ta_statement(struct parse *cfile)
static struct dhc6_ia *
parse_client6_ia_pd_statement(struct parse *cfile)
{
- struct data_string id;
struct option_cache *oc = NULL;
struct dhc6_ia *ia;
struct dhc6_addr **pref;
const char *val;
- int token, no_semi;
+ int token, no_semi, len;
+ u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) {
@@ -1780,20 +1762,11 @@ parse_client6_ia_pd_statement(struct parse *cfile)
ia->ia_type = D6O_IA_PD;
/* Get IAID. */
- memset(&id, 0, sizeof(id));
- if (parse_cshl(&id, cfile)) {
- if (id.len == 4)
- memcpy(ia->iaid, id.data, 4);
- else {
- parse_warn(cfile, "Expecting IAID of length 4, got %d.",
- id.len);
- skip_to_semi(cfile);
- dfree(ia, MDL);
- return NULL;
- }
- data_string_forget(&id, MDL);
+ len = parse_X(cfile, buf, 5);
+ if (len == 4) {
+ memcpy(ia->iaid, buf, 4);
} else {
- parse_warn(cfile, "Expecting IAID.");
+ parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile);
dfree(ia, MDL);
return NULL;
diff --git a/common/print.c b/common/print.c
index 3abfc35f..72c002e6 100644
--- a/common/print.c
+++ b/common/print.c
@@ -357,44 +357,118 @@ void hash_dump (table)
}
}
-#define HBLEN 60
+/*
+ * print a string as hex. This only outputs
+ * colon separated hex list no matter what
+ * the input looks like. See print_hex
+ * for a function that prints either cshl
+ * or a string if all bytes are printible
+ * It only uses limit characters from buf
+ * and doesn't do anything if buf == NULL
+ *
+ * len - length of data
+ * data - input data
+ * limit - length of buf to use
+ * buf - output buffer
+ */
+void print_hex_only (len, data, limit, buf)
+ unsigned len;
+ const u_int8_t *data;
+ unsigned limit;
+ char *buf;
+{
+ unsigned i;
+
+ if ((buf == NULL) || (limit < 3))
+ return;
+
+ for (i = 0; (i < limit / 3) && (i < len); i++) {
+ sprintf(&buf[i*3], "%02x:", data[i]);
+ }
+ buf[(i * 3) - 1] = 0;
+ return;
+}
+
+/*
+ * print a string as either text if all the characters
+ * are printable or colon separated hex if they aren't
+ *
+ * len - length of data
+ * data - input data
+ * limit - length of buf to use
+ * buf - output buffer
+ */
+void print_hex_or_string (len, data, limit, buf)
+ unsigned len;
+ const u_int8_t *data;
+ unsigned limit;
+ char *buf;
+{
+ unsigned i;
+ if ((buf == NULL) || (limit < 3))
+ return;
+
+ for (i = 0; (i < (limit - 3)) && (i < len); i++) {
+ if (!isascii(data[i]) || !isprint(data[i])) {
+ print_hex_only(len, data, limit, buf);
+ return;
+ }
+ }
-#define DECLARE_HEX_PRINTER(x) \
-char *print_hex##x (len, data, limit) \
- unsigned len; \
- const u_int8_t *data; \
- unsigned limit; \
-{ \
- \
- static char hex_buf##x [HBLEN + 1]; \
- unsigned i; \
- \
- if (limit > HBLEN) \
- limit = HBLEN; \
- \
- for (i = 0; i < (limit - 2) && i < len; i++) { \
- if (!isascii (data [i]) || !isprint (data [i])) { \
- for (i = 0; i < limit / 3 && i < len; i++) { \
- sprintf (&hex_buf##x [i * 3], \
- "%02x:", data [i]); \
- } \
- hex_buf##x [i * 3 - 1] = 0; \
- return hex_buf##x; \
- } \
- } \
- hex_buf##x [0] = '"'; \
- i = len; \
- if (i > limit - 2) \
- i = limit - 2; \
- memcpy (&hex_buf##x [1], data, i); \
- hex_buf##x [i + 1] = '"'; \
- hex_buf##x [i + 2] = 0; \
- return hex_buf##x; \
+ buf[0] = '"';
+ i = len;
+ if (i > (limit - 3))
+ i = limit - 3;
+ memcpy(&buf[1], data, i);
+ buf[i + 1] = '"';
+ buf[i + 2] = 0;
+ return;
}
-DECLARE_HEX_PRINTER (_1)
-DECLARE_HEX_PRINTER (_2)
-DECLARE_HEX_PRINTER (_3)
+/*
+ * print a string as either hex or text
+ * using static buffers to hold the output
+ *
+ * len - length of data
+ * data - input data
+ * limit - length of buf
+ * buf_num - the output buffer to use
+ */
+#define HBLEN 60
+char *print_hex(len, data, limit, buf_num)
+ unsigned len;
+ const u_int8_t *data;
+ unsigned limit;
+ unsigned buf_num;
+{
+ static char hex_buf_1[HBLEN + 1];
+ static char hex_buf_2[HBLEN + 1];
+ static char hex_buf_3[HBLEN + 1];
+ char *hex_buf;
+
+ switch(buf_num) {
+ case 0:
+ hex_buf = hex_buf_1;
+ if (limit >= sizeof(hex_buf_1))
+ limit = sizeof(hex_buf_1);
+ break;
+ case 1:
+ hex_buf = hex_buf_2;
+ if (limit >= sizeof(hex_buf_2))
+ limit = sizeof(hex_buf_2);
+ break;
+ case 2:
+ hex_buf = hex_buf_3;
+ if (limit >= sizeof(hex_buf_3))
+ limit = sizeof(hex_buf_3);
+ break;
+ default:
+ return(NULL);
+ }
+
+ print_hex_or_string(len, data, limit, hex_buf);
+ return(hex_buf);
+}
#define DQLEN 80
@@ -1457,6 +1531,8 @@ print_time(TIME t)
{
static char buf[sizeof("epoch 9223372036854775807; "
"# Wed Jun 30 21:49:08 2147483647")];
+ static char buf1[sizeof("# Wed Jun 30 21:49:08 2147483647")];
+ time_t since_epoch;
/* The string: "6 2147483647/12/31 23:59:60;"
* is smaller than the other, used to declare the buffer size, so
* we can use one buffer for both.
@@ -1478,10 +1554,14 @@ print_time(TIME t)
#endif
if (db_time_format == LOCAL_TIME_FORMAT) {
- if (strftime(buf, sizeof(buf),
- "epoch %s; # %a %b %d %H:%M:%S %Y",
- localtime(&t)) == 0)
+ since_epoch = mktime(localtime(&t));
+ if ((strftime(buf1, sizeof(buf1),
+ "# %a %b %d %H:%M:%S %Y",
+ localtime(&t)) == 0) ||
+ (snprintf(buf, sizeof(buf), "epoch %u; %s",
+ since_epoch, buf1) >= sizeof(buf)))
return NULL;
+
} else {
/* No bounds check for the year is necessary - in this case,
* strftime() will run out of space and assert an error.
diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c
index 54be3b39..423cd80f 100644
--- a/dhcpctl/omshell.c
+++ b/dhcpctl/omshell.c
@@ -3,7 +3,8 @@
Examine and modify omapi objects. */
/*
- * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -98,6 +99,7 @@ main(int argc, char **argv) {
char buf[1024];
char s1[1024];
int connected = 0;
+ char hex_buf[61];
for (i = 1; i < argc; i++) {
usage(argv[0]);
@@ -159,10 +161,10 @@ main(int argc, char **argv) {
break;
case omapi_datatype_data:
- printf ("%s\n",
- print_hex_1 (v -> value -> u.buffer.len,
- v -> value -> u.buffer.value,
- 60));
+ print_hex_only(v->value->u.buffer.len,
+ v->value->u.buffer.value,
+ sizeof(hex_buf), hex_buf);
+ printf("%s\n", hex_buf);
break;
case omapi_datatype_object:
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 3b58f873..2dbc33ba 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2122,9 +2122,11 @@ void dump_packet_option (struct option_cache *, struct packet *,
struct binding_scope **, struct universe *, void *);
void dump_packet PROTO ((struct packet *));
void hash_dump PROTO ((struct hash_table *));
-char *print_hex_1 PROTO ((unsigned, const u_int8_t *, unsigned));
-char *print_hex_2 PROTO ((unsigned, const u_int8_t *, unsigned));
-char *print_hex_3 PROTO ((unsigned, const u_int8_t *, unsigned));
+char *print_hex PROTO ((unsigned, const u_int8_t *, unsigned, unsigned));
+void print_hex_only PROTO ((unsigned, const u_int8_t *, unsigned, char *));
+#define print_hex_1(len, data, limit) print_hex(len, data, limit, 0)
+#define print_hex_2(len, data, limit) print_hex(len, data, limit, 1)
+#define print_hex_3(len, data, limit) print_hex(len, data, limit, 2)
char *print_dotted_quads PROTO ((unsigned, const u_int8_t *));
char *print_dec_1 PROTO ((unsigned long));
char *print_dec_2 PROTO ((unsigned long));
diff --git a/server/db.c b/server/db.c
index a4e15580..f04e3dd1 100644
--- a/server/db.c
+++ b/server/db.c
@@ -3,7 +3,7 @@
Persistent database management routines for DHCPD... */
/*
- * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2010 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
@@ -580,11 +580,11 @@ write_ia(const struct ia_xx *ia) {
binding_state) < 0) {
goto error_exit;
}
- if (fprintf(db_file, " preferred-life %u\n",
+ if (fprintf(db_file, " preferred-life %u;\n",
(unsigned)iasubopt->prefer) < 0) {
goto error_exit;
}
- if (fprintf(db_file, " max-life %u\n",
+ if (fprintf(db_file, " max-life %u;\n",
(unsigned)iasubopt->valid) < 0) {
goto error_exit;
}