📄 print.c
字号:
/* print.c Turn data structures into printable text. *//* * Copyright (c) 2004 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 * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Internet Systems Consortium, Inc. * 950 Charter Street * Redwood City, CA 94063 * <info@isc.org> * http://www.isc.org/ * * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. * To learn more about Internet Systems Consortium, see * ``http://www.isc.org/''. To learn more about Vixie Enterprises, * see ``http://www.vix.com''. To learn more about Nominum, Inc., see * ``http://www.nominum.com''. */#ifndef lintstatic char copyright[] ="$Id: print.c,v 1.53.2.11 2004/06/17 20:54:39 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";#endif /* not lint */#include "dhcpd.h"char *quotify_string (const char *s, const char *file, int line){ unsigned len = 0; const char *sp; char *buf, *nsp; for (sp = s; sp && *sp; sp++) { if (*sp == ' ') len++; else if (!isascii (*sp) || !isprint (*sp)) len += 4; else if (*sp == '"' || *sp == '\\') len += 2; else len++; } buf = dmalloc (len + 1, file, line); if (buf) { nsp = buf; for (sp = s; sp && *sp; sp++) { if (*sp == ' ') *nsp++ = ' '; else if (!isascii (*sp) || !isprint (*sp)) { sprintf (nsp, "\\%03o", *(const unsigned char *)sp); nsp += 4; } else if (*sp == '"' || *sp == '\\') { *nsp++ = '\\'; *nsp++ = *sp; } else *nsp++ = *sp; } *nsp++ = 0; } return buf;}char *quotify_buf (const unsigned char *s, unsigned len, const char *file, int line){ unsigned nulen = 0; char *buf, *nsp; int i; for (i = 0; i < len; i++) { if (s [i] == ' ') nulen++; else if (!isascii (s [i]) || !isprint (s [i])) nulen += 4; else if (s [i] == '"' || s [i] == '\\') nulen += 2; else nulen++; } buf = dmalloc (nulen + 1, MDL); if (buf) { nsp = buf; for (i = 0; i < len; i++) { if (s [i] == ' ') *nsp++ = ' '; else if (!isascii (s [i]) || !isprint (s [i])) { sprintf (nsp, "\\%03o", s [i]); nsp += 4; } else if (s [i] == '"' || s [i] == '\\') { *nsp++ = '\\'; *nsp++ = s [i]; } else *nsp++ = s [i]; } *nsp++ = 0; } return buf;}char *print_base64 (const unsigned char *buf, unsigned len, const char *file, int line){ char *s, *b; unsigned bl; int i; unsigned val, extra; static char to64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; bl = ((len * 4 + 2) / 3) + 1; b = dmalloc (bl + 1, file, line); if (!b) return (char *)0; i = 0; s = b; while (i != len) { val = buf [i++]; extra = val & 3; val = val >> 2; *s++ = to64 [val]; if (i == len) { *s++ = to64 [extra << 4]; *s++ = '='; break; } val = (extra << 8) + buf [i++]; extra = val & 15; val = val >> 4; *s++ = to64 [val]; if (i == len) { *s++ = to64 [extra << 2]; *s++ = '='; break; } val = (extra << 8) + buf [i++]; extra = val & 0x3f; val = val >> 6; *s++ = to64 [val]; *s++ = to64 [extra]; } if (!len) *s++ = '='; *s++ = 0; if (s > b + bl + 1) abort (); return b;}char *print_hw_addr (htype, hlen, data) int htype; int hlen; unsigned char *data;{ static char habuf [49]; char *s; int i; if (hlen <= 0) habuf [0] = 0; else { s = habuf; for (i = 0; i < hlen; i++) { sprintf (s, "%02x", data [i]); s += strlen (s); *s++ = ':'; } *--s = 0; } 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); strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t); log_debug (" start %s", tbuf); t = gmtime (&lease -> ends); strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t); log_debug (" end %s", tbuf); if (lease -> hardware_addr.hlen) log_debug (" hardware addr = %s", print_hw_addr (lease -> hardware_addr.hbuf [0], lease -> hardware_addr.hlen - 1, &lease -> hardware_addr.hbuf [1])); log_debug (" host %s ", lease -> host ? lease -> host -> name : "<none>");} #if defined (DEBUG_PACKET)void dump_packet_option (struct option_cache *oc, struct packet *packet, struct lease *lease, struct client_state *client, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *foo){ const char *name, *dot; struct data_string ds; memset (&ds, 0, sizeof ds); if (u != &dhcp_universe) { name = u -> name; dot = "."; } else { name = ""; dot = ""; } if (evaluate_option_cache (&ds, packet, lease, client, in_options, cfg_options, scope, oc, MDL)) { log_debug (" option %s%s%s %s;\n", name, dot, oc -> option -> name, pretty_print_option (oc -> option, ds.data, ds.len, 1, 1)); data_string_forget (&ds, MDL); }}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", tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops); log_debug ("xid = %x secs = %ld flags = %x", tdp -> xid, (unsigned long)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 = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", ((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); if (tp -> options_valid) { int i; for (i = 0; i < tp -> options -> universe_count; i++) { if (tp -> options -> universes [i]) { option_space_foreach (tp, (struct lease *)0, (struct client_state *)0, (struct option_state *)0, tp -> options, &global_scope, universes [i], 0, dump_packet_option); } } } log_debug ("%s", "");}#endifvoid dump_raw (buf, len) const unsigned char *buf; unsigned len;{ int i; char lbuf [80]; int lbix = 0;/* 1 2 3 4 5 6 701234567890123456789012345678901234567890123456789012345678901234567890123280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................. */ memset(lbuf, ' ', 79); lbuf [79] = 0; for (i = 0; i < len; i++) { if ((i & 15) == 0) { if (lbix) { lbuf[53]=' '; lbuf[54]=' '; lbuf[55]=' '; lbuf[73]='\0'; log_info (lbuf); } memset(lbuf, ' ', 79); lbuf [79] = 0; sprintf (lbuf, "%03x:", i); lbix = 4; } else if ((i & 7) == 0) lbuf [lbix++] = ' '; if(isprint(buf[i])) { lbuf[56+(i%16)]=buf[i]; } else { lbuf[56+(i%16)]='.'; } sprintf (&lbuf [lbix], " %02x", buf [i]); lbix += 3; lbuf[lbix]=' '; } lbuf[53]=' '; lbuf[54]=' '; lbuf[55]=' '; lbuf[73]='\0'; log_info (lbuf);}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); for (bp = table -> buckets [i]; bp; bp = bp -> next) { if (bp -> len) dump_raw (bp -> name, bp -> len); else log_info ("%s", (const char *)bp -> name); } }}#define HBLEN 60#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; \}DECLARE_HEX_PRINTER (_1)DECLARE_HEX_PRINTER (_2)DECLARE_HEX_PRINTER (_3)#define DQLEN 80char *print_dotted_quads (len, data) unsigned len; const u_int8_t *data;{ static char dq_buf [DQLEN + 1]; int i; char *s, *last; s = &dq_buf [0]; last = s; i = 0; /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe% * The sprintf can't exceed 18 bytes, and since the loop enforces * 21 bytes of space per iteration at no time can we exit the * loop without at least 3 bytes spare. */ do { sprintf (s, "%u.%u.%u.%u, ", 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) unsigned long val;{ static char vbuf [32]; sprintf (vbuf, "%lu", val); return vbuf;}char *print_dec_2 (val) unsigned long val;{ static char vbuf [32]; sprintf (vbuf, "%lu", val); return vbuf;}static unsigned print_subexpression PROTO ((struct expression *, char *, unsigned));static unsigned print_subexpression (expr, buf, len) struct expression *expr; char *buf; unsigned len;{ unsigned rv, left; const 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_not_equal: if (len > 7) { rv = 5; strcpy (buf, "(neq "); 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, "(suffix "); rv += print_subexpression (expr -> data.suffix.expr, buf + rv, len - rv - 2); if (len > rv) buf [rv++] = ' '; rv += print_subexpression (expr -> data.suffix.len, buf + rv, len - rv - 1); if (len > rv) 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_pick_first_value: if (len > 8) { rv = 6; strcpy (buf, "(pick1st "); rv += print_subexpression (expr -> data.pick_first_value.car, buf + rv, len - rv - 2); buf [rv++] = ' '; rv += print_subexpression (expr -> data.pick_first_value.cdr, 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: s = "and"; binop: rv = strlen (s); if (len > rv + 4) { buf [0] = '('; strcpy (&buf [1], s); rv += 1; buf [rv++] = ' '; 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: s = "or"; goto binop; case expr_add: s = "+"; goto binop; case expr_subtract: s = "-"; goto binop; case expr_multiply: s = "*"; goto binop; case expr_divide: s = "/"; goto binop; case expr_remainder: s = "%"; goto binop; case expr_binary_and: s = "&"; goto binop; case expr_binary_or: s = "|"; goto binop; case expr_binary_xor: s = "^"; goto binop; 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_config_option: s = "cfg-option"; goto dooption; case expr_option: s = "option"; dooption: rv = strlen (s) + 2 + (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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -