diff options
author | Shawn Routhier <sar@isc.org> | 2010-09-13 22:20:43 +0000 |
---|---|---|
committer | Shawn Routhier <sar@isc.org> | 2010-09-13 22:20:43 +0000 |
commit | 4b0135fed295b69ed7d102b5876fb4465a1bf2a4 (patch) | |
tree | 94cc74b07126e322d8ff352295a08c240e534862 | |
parent | e09f62934a13592b5acd3440ec14cdd2bd18c8e1 (diff) | |
download | isc-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-- | RELNOTES | 8 | ||||
-rw-r--r-- | client/clparse.c | 65 | ||||
-rw-r--r-- | common/print.c | 156 | ||||
-rw-r--r-- | dhcpctl/omshell.c | 12 | ||||
-rw-r--r-- | includes/dhcpd.h | 8 | ||||
-rw-r--r-- | server/db.c | 6 |
6 files changed, 160 insertions, 95 deletions
@@ -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; } |