2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00

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.
This commit is contained in:
Shawn Routhier 2010-09-13 22:06:37 +00:00
parent 83d409ae59
commit 6aaaf6a460
6 changed files with 160 additions and 95 deletions

View File

@ -107,6 +107,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. date strings correctly. Thanks to a patch from Jiri Popelka at Red Hat.
[ISC-Bugs #21501, #20598] [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.2.0b2 Changes since 4.2.0b2
- Add declaration for variable in debug code in alloc.c. [ISC-Bugs #21472] - Add declaration for variable in debug code in alloc.c. [ISC-Bugs #21472]

View File

@ -3,7 +3,7 @@
Parser for dhclient config and lease files... */ 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 * Copyright (c) 1996-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -1521,12 +1521,12 @@ parse_client6_lease_statement(struct parse *cfile)
static struct dhc6_ia * static struct dhc6_ia *
parse_client6_ia_na_statement(struct parse *cfile) parse_client6_ia_na_statement(struct parse *cfile)
{ {
struct data_string id;
struct option_cache *oc = NULL; struct option_cache *oc = NULL;
struct dhc6_ia *ia; struct dhc6_ia *ia;
struct dhc6_addr **addr; struct dhc6_addr **addr;
const char *val; const char *val;
int token, no_semi; int token, no_semi, len;
u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL); ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) { if (ia == NULL) {
@ -1537,20 +1537,11 @@ parse_client6_ia_na_statement(struct parse *cfile)
ia->ia_type = D6O_IA_NA; ia->ia_type = D6O_IA_NA;
/* Get IAID. */ /* Get IAID. */
memset(&id, 0, sizeof(id)); len = parse_X(cfile, buf, 5);
if (parse_cshl(&id, cfile)) { if (len == 4) {
if (id.len == 4) memcpy(ia->iaid, buf, 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);
} else { } else {
parse_warn(cfile, "Expecting IAID."); parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile); skip_to_semi(cfile);
dfree(ia, MDL); dfree(ia, MDL);
return NULL; return NULL;
@ -1658,12 +1649,12 @@ parse_client6_ia_na_statement(struct parse *cfile)
static struct dhc6_ia * static struct dhc6_ia *
parse_client6_ia_ta_statement(struct parse *cfile) parse_client6_ia_ta_statement(struct parse *cfile)
{ {
struct data_string id;
struct option_cache *oc = NULL; struct option_cache *oc = NULL;
struct dhc6_ia *ia; struct dhc6_ia *ia;
struct dhc6_addr **addr; struct dhc6_addr **addr;
const char *val; const char *val;
int token, no_semi; int token, no_semi, len;
u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL); ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) { if (ia == NULL) {
@ -1674,20 +1665,11 @@ parse_client6_ia_ta_statement(struct parse *cfile)
ia->ia_type = D6O_IA_TA; ia->ia_type = D6O_IA_TA;
/* Get IAID. */ /* Get IAID. */
memset(&id, 0, sizeof(id)); len = parse_X(cfile, buf, 5);
if (parse_cshl(&id, cfile)) { if (len == 4) {
if (id.len == 4) memcpy(ia->iaid, buf, 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);
} else { } else {
parse_warn(cfile, "Expecting IAID."); parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile); skip_to_semi(cfile);
dfree(ia, MDL); dfree(ia, MDL);
return NULL; return NULL;
@ -1775,12 +1757,12 @@ parse_client6_ia_ta_statement(struct parse *cfile)
static struct dhc6_ia * static struct dhc6_ia *
parse_client6_ia_pd_statement(struct parse *cfile) parse_client6_ia_pd_statement(struct parse *cfile)
{ {
struct data_string id;
struct option_cache *oc = NULL; struct option_cache *oc = NULL;
struct dhc6_ia *ia; struct dhc6_ia *ia;
struct dhc6_addr **pref; struct dhc6_addr **pref;
const char *val; const char *val;
int token, no_semi; int token, no_semi, len;
u_int8_t buf[5];
ia = dmalloc(sizeof(*ia), MDL); ia = dmalloc(sizeof(*ia), MDL);
if (ia == NULL) { if (ia == NULL) {
@ -1791,20 +1773,11 @@ parse_client6_ia_pd_statement(struct parse *cfile)
ia->ia_type = D6O_IA_PD; ia->ia_type = D6O_IA_PD;
/* Get IAID. */ /* Get IAID. */
memset(&id, 0, sizeof(id)); len = parse_X(cfile, buf, 5);
if (parse_cshl(&id, cfile)) { if (len == 4) {
if (id.len == 4) memcpy(ia->iaid, buf, 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);
} else { } else {
parse_warn(cfile, "Expecting IAID."); parse_warn(cfile, "Expecting IAID of length 4, got %d.", len);
skip_to_semi(cfile); skip_to_semi(cfile);
dfree(ia, MDL); dfree(ia, MDL);
return NULL; return NULL;

View File

@ -358,44 +358,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;
#define DECLARE_HEX_PRINTER(x) \ if ((buf == NULL) || (limit < 3))
char *print_hex##x (len, data, limit) \ return;
unsigned len; \
const u_int8_t *data; \ for (i = 0; (i < limit / 3) && (i < len); i++) {
unsigned limit; \ sprintf(&buf[i*3], "%02x:", data[i]);
{ \ }
\ buf[(i * 3) - 1] = 0;
static char hex_buf##x [HBLEN + 1]; \ return;
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; \
} }
DECLARE_HEX_PRINTER (_1) /*
DECLARE_HEX_PRINTER (_2) * print a string as either text if all the characters
DECLARE_HEX_PRINTER (_3) * 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;
}
}
buf[0] = '"';
i = len;
if (i > (limit - 3))
i = limit - 3;
memcpy(&buf[1], data, i);
buf[i + 1] = '"';
buf[i + 2] = 0;
return;
}
/*
* 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 #define DQLEN 80
@ -1391,6 +1465,8 @@ print_time(TIME t)
{ {
static char buf[sizeof("epoch 9223372036854775807; " static char buf[sizeof("epoch 9223372036854775807; "
"# Wed Jun 30 21:49:08 2147483647")]; "# 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;" /* The string: "6 2147483647/12/31 23:59:60;"
* is smaller than the other, used to declare the buffer size, so * is smaller than the other, used to declare the buffer size, so
* we can use one buffer for both. * we can use one buffer for both.
@ -1412,10 +1488,14 @@ print_time(TIME t)
#endif #endif
if (db_time_format == LOCAL_TIME_FORMAT) { if (db_time_format == LOCAL_TIME_FORMAT) {
if (strftime(buf, sizeof(buf), since_epoch = mktime(localtime(&t));
"epoch %s; # %a %b %d %H:%M:%S %Y", if ((strftime(buf1, sizeof(buf1),
localtime(&t)) == 0) "# %a %b %d %H:%M:%S %Y",
localtime(&t)) == 0) ||
(snprintf(buf, sizeof(buf), "epoch %u; %s",
since_epoch, buf1) >= sizeof(buf)))
return NULL; return NULL;
} else { } else {
/* No bounds check for the year is necessary - in this case, /* No bounds check for the year is necessary - in this case,
* strftime() will run out of space and assert an error. * strftime() will run out of space and assert an error.

View File

@ -3,7 +3,8 @@
Examine and modify omapi objects. */ 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 * Copyright (c) 2001-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -98,6 +99,7 @@ main(int argc, char **argv) {
char buf[1024]; char buf[1024];
char s1[1024]; char s1[1024];
int connected = 0; int connected = 0;
char hex_buf[61];
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
usage(argv[0]); usage(argv[0]);
@ -159,10 +161,10 @@ main(int argc, char **argv) {
break; break;
case omapi_datatype_data: case omapi_datatype_data:
printf ("%s\n", print_hex_only(v->value->u.buffer.len,
print_hex_1 (v -> value -> u.buffer.len,
v->value->u.buffer.value, v->value->u.buffer.value,
60)); sizeof(hex_buf), hex_buf);
printf("%s\n", hex_buf);
break; break;
case omapi_datatype_object: case omapi_datatype_object:

View File

@ -2302,9 +2302,11 @@ void dump_packet_option (struct option_cache *, struct packet *,
struct binding_scope **, struct universe *, void *); struct binding_scope **, struct universe *, void *);
void dump_packet PROTO ((struct packet *)); void dump_packet PROTO ((struct packet *));
void hash_dump PROTO ((struct hash_table *)); void hash_dump PROTO ((struct hash_table *));
char *print_hex_1 PROTO ((unsigned, const u_int8_t *, unsigned)); char *print_hex PROTO ((unsigned, const u_int8_t *, unsigned, unsigned));
char *print_hex_2 PROTO ((unsigned, const u_int8_t *, unsigned)); void print_hex_only PROTO ((unsigned, const u_int8_t *, unsigned, char *));
char *print_hex_3 PROTO ((unsigned, const u_int8_t *, unsigned)); #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_dotted_quads PROTO ((unsigned, const u_int8_t *));
char *print_dec_1 PROTO ((unsigned long)); char *print_dec_1 PROTO ((unsigned long));
char *print_dec_2 PROTO ((unsigned long)); char *print_dec_2 PROTO ((unsigned long));

View File

@ -3,7 +3,7 @@
Persistent database management routines for DHCPD... */ 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 * Copyright (c) 1995-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -594,11 +594,11 @@ write_ia(const struct ia_xx *ia) {
binding_state) < 0) { binding_state) < 0) {
goto error_exit; goto error_exit;
} }
if (fprintf(db_file, " preferred-life %u\n", if (fprintf(db_file, " preferred-life %u;\n",
(unsigned)iasubopt->prefer) < 0) { (unsigned)iasubopt->prefer) < 0) {
goto error_exit; goto error_exit;
} }
if (fprintf(db_file, " max-life %u\n", if (fprintf(db_file, " max-life %u;\n",
(unsigned)iasubopt->valid) < 0) { (unsigned)iasubopt->valid) < 0) {
goto error_exit; goto error_exit;
} }