2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 09:57:20 +00:00
isc-dhcp/common/print.c

512 lines
11 KiB
C
Raw Normal View History

1995-11-29 07:40:04 +00:00
/* print.c
Turn data structures into printable text. */
/*
1999-03-16 05:50:46 +00:00
* Copyright (c) 1996-1999 Internet Software Consortium.
* Use is subject to license terms which appear in the file named
* ISC-LICENSE that should have accompanied this file when you
* received it. If a file named ISC-LICENSE did not accompany this
* file, or you are not sure the one you have is correct, you may
* obtain an applicable copy of the license at:
1995-11-29 07:40:04 +00:00
*
1999-03-16 05:50:46 +00:00
* http://www.isc.org/isc-license-1.0.html.
1995-11-29 07:40:04 +00:00
*
1999-03-16 05:50:46 +00:00
* This file is part of the ISC DHCP distribution. The documentation
* associated with this file is listed in the file DOCUMENTATION,
* included in the top-level directory of this release.
1995-11-29 07:40:04 +00:00
*
1999-03-16 05:50:46 +00:00
* Support and other services are available for ISC products - see
* http://www.isc.org for more information.
1995-11-29 07:40:04 +00:00
*/
#ifndef lint
static char copyright[] =
1999-03-16 05:50:46 +00:00
"$Id: print.c,v 1.21 1999/03/16 05:50:36 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
1995-11-29 07:40:04 +00:00
#endif /* not lint */
#include "dhcpd.h"
1995-11-29 07:40:04 +00:00
char *print_hw_addr (htype, hlen, data)
int htype;
int hlen;
unsigned char *data;
{
static char habuf [49];
char *s;
int i;
if (htype == 0 || hlen == 0) {
strcpy (habuf, "<null>");
} else {
s = habuf;
for (i = 0; i < hlen; i++) {
1997-11-29 07:52:10 +00:00
sprintf (s, "%02x", data [i]);
s += strlen (s);
*s++ = ':';
}
*--s = 0;
1995-11-29 07:40:04 +00:00
}
return habuf;
}
void print_lease (lease)
struct lease *lease;
{
struct tm *t;
char tbuf [32];
log_debug (" Lease %s",
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
1999-02-14 19:04:05 +00:00
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
log_debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
1999-02-14 19:04:05 +00:00
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
log_debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
1999-02-14 19:04:05 +00:00
strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
log_debug (" stamp %s", tbuf);
log_debug (" hardware addr = %s",
print_hw_addr (lease -> hardware_addr.htype,
lease -> hardware_addr.hlen,
lease -> hardware_addr.haddr));
log_debug (" host %s ",
1997-03-05 06:33:06 +00:00
lease -> host ? lease -> host -> name : "<none>");
}
1996-02-25 21:28:38 +00:00
#if defined (DEBUG)
1996-02-25 21:28:38 +00:00
void dump_packet (tp)
struct packet *tp;
{
struct dhcp_packet *tdp = tp -> raw;
log_debug ("packet length %d", tp -> packet_length);
log_debug ("op = %d htype = %d hlen = %d hops = %d",
1996-02-25 21:28:38 +00:00
tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
log_debug ("xid = %x secs = %d flags = %x",
1996-02-25 21:28:38 +00:00
tdp -> xid, tdp -> secs, tdp -> flags);
log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
log_debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
1996-02-25 21:28:38 +00:00
((unsigned char *)(tdp -> chaddr)) [0],
((unsigned char *)(tdp -> chaddr)) [1],
((unsigned char *)(tdp -> chaddr)) [2],
((unsigned char *)(tdp -> chaddr)) [3],
((unsigned char *)(tdp -> chaddr)) [4],
((unsigned char *)(tdp -> chaddr)) [5]);
log_debug ("filename = %s", tdp -> file);
log_debug ("server_name = %s", tdp -> sname);
1996-02-25 21:28:38 +00:00
if (tp -> options_valid) {
int i;
for (i = 0; i < 256; i++) {
if (tp -> options [i].data)
log_debug (" %s = %s",
1996-02-25 21:28:38 +00:00
dhcp_options [i].name,
pretty_print_option
(i, tp -> options [i].data,
tp -> options [i].len, 1, 1));
1996-02-25 21:28:38 +00:00
}
}
log_debug ("");
}
#endif
void dump_raw (buf, len)
unsigned char *buf;
int len;
{
int i;
char lbuf [80];
int lbix = 0;
1996-05-28 18:15:22 +00:00
lbuf [0] = 0;
for (i = 0; i < len; i++) {
if ((i & 15) == 0) {
if (lbix)
log_info (lbuf);
sprintf (lbuf, "%03x:", i);
lbix = 4;
} else if ((i & 7) == 0)
lbuf [lbix++] = ' ';
sprintf (&lbuf [lbix], " %02x", buf [i]);
lbix += 3;
}
log_info (lbuf);
1996-02-25 21:28:38 +00:00
}
1996-05-22 07:28:42 +00:00
void hash_dump (table)
struct hash_table *table;
{
int i;
struct hash_bucket *bp;
if (!table)
return;
for (i = 0; i < table -> hash_count; i++) {
if (!table -> buckets [i])
continue;
log_info ("hash bucket %d:", i);
1996-05-22 07:28:42 +00:00
for (bp = table -> buckets [i]; bp; bp = bp -> next) {
if (bp -> len)
dump_raw (bp -> name, bp -> len);
else
log_info ((char *)bp -> name);
1996-05-22 07:28:42 +00:00
}
}
}
#define HBLEN 60
#define DECLARE_HEX_PRINTER(x) \
char *print_hex##x (len, data, limit) \
int len; \
u_int8_t *data; \
{ \
\
static char hex_buf##x [HBLEN + 1]; \
int 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)
DECLARE_HEX_PRINTER (_3)
#define DQLEN 80
char *print_dotted_quads (len, data)
int len;
u_int8_t *data;
{
static char dq_buf [DQLEN + 1];
int i;
char *s, *last;
s = &dq_buf [0];
last = s;
i = 0;
do {
sprintf (s, "%d.%d.%d.%d, ",
data [i], data [i + 1], data [i + 2], data [i + 3]);
s += strlen (s);
i += 4;
} while ((s - &dq_buf [0] > DQLEN - 21) &&
i + 3 < len);
if (i == len)
s [-2] = 0;
else
strcpy (s, "...");
return dq_buf;
}
char *print_dec_1 (val)
int val;
{
static char vbuf [32];
sprintf (vbuf, "%d", val);
return vbuf;
}
char *print_dec_2 (val)
int val;
{
static char vbuf [32];
sprintf (vbuf, "%d", val);
return vbuf;
}
static int print_subexpression PROTO ((struct expression *, char *, int));
static int print_subexpression (expr, buf, len)
struct expression *expr;
char *buf;
int len;
{
int rv;
char *s;
switch (expr -> op) {
case expr_none:
if (len > 3) {
strcpy (buf, "nil");
return 3;
}
break;
case expr_match:
if (len > 7) {
strcpy (buf, "(match)");
return 7;
}
break;
case expr_check:
rv = 10 + strlen (expr -> data.check -> name);
if (len > rv) {
sprintf (buf, "(check %s)",
expr -> data.check -> name);
return rv;
}
break;
case expr_equal:
if (len > 6) {
rv = 4;
strcpy (buf, "(eq ");
rv += print_subexpression (expr -> data.equal [0],
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.equal [1],
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_substring:
if (len > 11) {
rv = 8;
strcpy (buf, "(substr ");
rv += print_subexpression (expr -> data.substring.expr,
buf + rv, len - rv - 3);
buf [rv++] = ' ';
rv += print_subexpression
(expr -> data.substring.offset,
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.substring.len,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_suffix:
if (len > 10) {
rv = 8;
strcpy (buf, "(substr ");
rv += print_subexpression (expr -> data.suffix.expr,
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.suffix.len,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_concat:
if (len > 10) {
rv = 8;
strcpy (buf, "(concat ");
rv += print_subexpression (expr -> data.concat [0],
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.concat [1],
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_host_lookup:
rv = 15 + strlen (expr -> data.host_lookup -> hostname);
if (len > rv) {
sprintf (buf, "(dns-lookup %s)",
expr -> data.host_lookup -> hostname);
return rv;
}
break;
case expr_and:
if (len > 7) {
rv = 5;
strcpy (buf, "(and ");
rv += print_subexpression (expr -> data.and [0],
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.and [1],
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_or:
if (len > 6) {
rv = 4;
strcpy (buf, "(or ");
rv += print_subexpression (expr -> data.or [0],
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.or [1],
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_not:
if (len > 6) {
rv = 5;
strcpy (buf, "(not ");
rv += print_subexpression (expr -> data.not,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_option:
rv = 10 + (strlen (expr -> data.option -> name) +
strlen (expr -> data.option -> universe -> name));
if (len > rv) {
sprintf (buf, "(option %s.%s)",
expr -> data.option -> universe -> name,
expr -> data.option -> name);
return rv;
}
break;
case expr_hardware:
if (len > 10) {
strcpy (buf, "(hardware)");
return 10;
}
break;
case expr_packet:
if (len > 10) {
rv = 8;
strcpy (buf, "(substr ");
rv += print_subexpression (expr -> data.packet.offset,
buf + rv, len - rv - 2);
buf [rv++] = ' ';
rv += print_subexpression (expr -> data.packet.len,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_const_data:
s = print_hex_1 (expr -> data.const_data.len,
expr -> data.const_data.data, len);
rv = strlen (s);
if (rv >= len)
rv = len - 1;
strncpy (buf, s, rv);
buf [rv] = 0;
return rv;
case expr_extract_int8:
if (len > 7) {
rv = 6;
strcpy (buf, "(int8 ");
rv += print_subexpression (expr -> data.extract_int,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_extract_int16:
if (len > 8) {
rv = 7;
strcpy (buf, "(int16 ");
rv += print_subexpression (expr -> data.extract_int,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_extract_int32:
if (len > 8) {
rv = 7;
strcpy (buf, "(int32 ");
rv += print_subexpression (expr -> data.extract_int,
buf + rv, len - rv - 1);
buf [rv++] = ')';
buf [rv] = 0;
return rv;
}
break;
case expr_const_int:
s = print_dec_1 (expr -> data.const_int);
rv = strlen (s);
if (len > rv) {
strcpy (buf, s);
return rv;
}
break;
case expr_exists:
rv = 10 + (strlen (expr -> data.option -> name) +
strlen (expr -> data.option -> universe -> name));
if (len > rv) {
sprintf (buf, "(exists %s.%s)",
expr -> data.option -> universe -> name,
expr -> data.option -> name);
return rv;
}
break;
}
return 0;
}
void print_expression (name, expr)
char *name;
struct expression *expr;
{
char buf [1024];
print_subexpression (expr, buf, sizeof buf);
log_info ("%s: %s", name, buf);
}