ISC DHCP  4.4.2b1
A reference DHCPv4 and DHCPv6 implementation
print.c
Go to the documentation of this file.
1 /* print.c
2 
3  Turn data structures into printable text. */
4 
5 /*
6  * Copyright (c) 2004-2018 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-2003 by Internet Software Consortium
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  */
28 
29 #include "dhcpd.h"
30 
32 
33 char *quotify_string (const char *s, const char *file, int line)
34 {
35  unsigned len = 0;
36  const char *sp;
37  char *buf, *nsp;
38 
39  for (sp = s; sp && *sp; sp++) {
40  if (*sp == ' ')
41  len++;
42  else if (!isascii ((int)*sp) || !isprint ((int)*sp))
43  len += 4;
44  else if (*sp == '"' || *sp == '\\')
45  len += 2;
46  else
47  len++;
48  }
49 
50  buf = dmalloc (len + 1, file, line);
51  if (buf) {
52  nsp = buf;
53  for (sp = s; sp && *sp; sp++) {
54  if (*sp == ' ')
55  *nsp++ = ' ';
56  else if (!isascii ((int)*sp) || !isprint ((int)*sp)) {
57  sprintf (nsp, "\\%03o",
58  *(const unsigned char *)sp);
59  nsp += 4;
60  } else if (*sp == '"' || *sp == '\\') {
61  *nsp++ = '\\';
62  *nsp++ = *sp;
63  } else
64  *nsp++ = *sp;
65  }
66  *nsp++ = 0;
67  }
68  return buf;
69 }
70 
71 char *quotify_buf (const unsigned char *s, unsigned len, char enclose_char,
72  const char *file, int line)
73 {
74  unsigned nulen = 0;
75  char *buf, *nsp;
76  int i;
77 
78  for (i = 0; i < len; i++) {
79  if (s [i] == ' ')
80  nulen++;
81  else if (!isascii (s [i]) || !isprint (s [i]))
82  nulen += 4;
83  else if (s [i] == '"' || s [i] == '\\')
84  nulen += 2;
85  else
86  nulen++;
87  }
88 
89  if (enclose_char) {
90  nulen +=2 ;
91  }
92 
93  buf = dmalloc (nulen + 1, MDL);
94  if (buf) {
95  nsp = buf;
96  if (enclose_char) {
97  *nsp++ = enclose_char;
98  }
99 
100  for (i = 0; i < len; i++) {
101  if (s [i] == ' ')
102  *nsp++ = ' ';
103  else if (!isascii (s [i]) || !isprint (s [i])) {
104  sprintf (nsp, "\\%03o", s [i]);
105  nsp += 4;
106  } else if (s [i] == '"' || s [i] == '\\') {
107  *nsp++ = '\\';
108  *nsp++ = s [i];
109  } else
110  *nsp++ = s [i];
111  }
112 
113  if (enclose_char) {
114  *nsp++ = enclose_char;
115  }
116  *nsp++ = 0;
117  }
118  return buf;
119 }
120 
121 char *print_base64 (const unsigned char *buf, unsigned len,
122  const char *file, int line)
123 {
124  char *s, *b;
125  unsigned bl;
126  int i;
127  unsigned val, extra;
128  static char to64 [] =
129  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
130 
131  bl = ((len * 4 + 2) / 3) + 1;
132  b = dmalloc (bl + 1, file, line);
133  if (!b)
134  return (char *)0;
135 
136  i = 0;
137  s = b;
138  while (i != len) {
139  val = buf [i++];
140  extra = val & 3;
141  val = val >> 2;
142  *s++ = to64 [val];
143  if (i == len) {
144  *s++ = to64 [extra << 4];
145  *s++ = '=';
146  break;
147  }
148  val = (extra << 8) + buf [i++];
149  extra = val & 15;
150  val = val >> 4;
151  *s++ = to64 [val];
152  if (i == len) {
153  *s++ = to64 [extra << 2];
154  *s++ = '=';
155  break;
156  }
157  val = (extra << 8) + buf [i++];
158  extra = val & 0x3f;
159  val = val >> 6;
160  *s++ = to64 [val];
161  *s++ = to64 [extra];
162  }
163  if (!len)
164  *s++ = '=';
165  *s++ = 0;
166  if (s > b + bl + 1)
167  abort ();
168  return b;
169 }
170 
171 char *print_hw_addr (htype, hlen, data)
172  const int htype;
173  const int hlen;
174  const unsigned char *data;
175 {
176  static char habuf [49];
177  char *s;
178  int i;
179 
180  if (hlen <= 0)
181  habuf [0] = 0;
182  else {
183  s = habuf;
184  for (i = 0; i < hlen; i++) {
185  sprintf (s, "%02x", data [i]);
186  s += strlen (s);
187  *s++ = ':';
188  }
189  *--s = 0;
190  }
191  return habuf;
192 }
193 
195  struct lease *lease;
196 {
197  struct tm *t;
198  char tbuf [32];
199 
200  log_debug (" Lease %s",
201  piaddr (lease -> ip_addr));
202 
203  t = gmtime (&lease -> starts);
204  strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
205  log_debug (" start %s", tbuf);
206 
207  t = gmtime (&lease -> ends);
208  strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
209  log_debug (" end %s", tbuf);
210 
211  if (lease -> hardware_addr.hlen)
212  log_debug (" hardware addr = %s",
213  print_hw_addr (lease -> hardware_addr.hbuf [0],
214  lease -> hardware_addr.hlen - 1,
215  &lease -> hardware_addr.hbuf [1]));
216  log_debug (" host %s ",
217  lease -> host ? lease -> host -> name : "<none>");
218 }
219 
220 #if defined (DEBUG_PACKET)
221 void dump_packet_option (struct option_cache *oc,
222  struct packet *packet,
223  struct lease *lease,
224  struct client_state *client,
225  struct option_state *in_options,
226  struct option_state *cfg_options,
227  struct binding_scope **scope,
228  struct universe *u, void *foo)
229 {
230  const char *name, *dot;
231  struct data_string ds;
232  memset (&ds, 0, sizeof ds);
233 
234  if (u != &dhcp_universe) {
235  name = u -> name;
236  dot = ".";
237  } else {
238  name = "";
239  dot = "";
240  }
241  if (evaluate_option_cache (&ds, packet, lease, client,
242  in_options, cfg_options, scope, oc, MDL)) {
243  log_debug (" option %s%s%s %s;\n",
244  name, dot, oc -> option -> name,
246  ds.data, ds.len, 1, 1));
247  data_string_forget (&ds, MDL);
248  }
249 }
250 
251 void dump_packet (tp)
252  struct packet *tp;
253 {
254  struct dhcp_packet *tdp = tp -> raw;
255 
256  log_debug ("packet length %d", tp -> packet_length);
257  log_debug ("op = %d htype = %d hlen = %d hops = %d",
258  tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
259  log_debug ("xid = %x secs = %ld flags = %x",
260  tdp -> xid, (unsigned long)tdp -> secs, tdp -> flags);
261  log_debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
262  log_debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
263  log_debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
264  log_debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
265  log_debug ("chaddr = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
266  ((unsigned char *)(tdp -> chaddr)) [0],
267  ((unsigned char *)(tdp -> chaddr)) [1],
268  ((unsigned char *)(tdp -> chaddr)) [2],
269  ((unsigned char *)(tdp -> chaddr)) [3],
270  ((unsigned char *)(tdp -> chaddr)) [4],
271  ((unsigned char *)(tdp -> chaddr)) [5]);
272  log_debug ("filename = %s", tdp -> file);
273  log_debug ("server_name = %s", tdp -> sname);
274  if (tp -> options_valid) {
275  int i;
276 
277  for (i = 0; i < tp -> options -> universe_count; i++) {
278  if (tp -> options -> universes [i]) {
279  option_space_foreach (tp, (struct lease *)0,
280  (struct client_state *)0,
281  (struct option_state *)0,
282  tp -> options,
283  &global_scope,
284  universes [i], 0,
286  }
287  }
288  }
289  log_debug ("%s", "");
290 }
291 #endif
292 
293 void dump_raw (buf, len)
294  const unsigned char *buf;
295  unsigned len;
296 {
297  int i;
298  char lbuf [80];
299  int lbix = 0;
300 
301 /*
302  1 2 3 4 5 6 7
303 01234567890123456789012345678901234567890123456789012345678901234567890123
304 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
305 */
306 
307  memset(lbuf, ' ', 79);
308  lbuf [79] = 0;
309 
310  for (i = 0; i < len; i++) {
311  if ((i & 15) == 0) {
312  if (lbix) {
313  lbuf[53]=' ';
314  lbuf[54]=' ';
315  lbuf[55]=' ';
316  lbuf[73]='\0';
317  log_info ("%s", lbuf);
318  }
319  memset(lbuf, ' ', 79);
320  lbuf [79] = 0;
321  sprintf (lbuf, "%03x:", i);
322  lbix = 4;
323  } else if ((i & 7) == 0)
324  lbuf [lbix++] = ' ';
325 
326  if(isprint(buf[i])) {
327  lbuf[56+(i%16)]=buf[i];
328  } else {
329  lbuf[56+(i%16)]='.';
330  }
331 
332  sprintf (&lbuf [lbix], " %02x", buf [i]);
333  lbix += 3;
334  lbuf[lbix]=' ';
335 
336  }
337  lbuf[53]=' ';
338  lbuf[54]=' ';
339  lbuf[55]=' ';
340  lbuf[73]='\0';
341  log_info ("%s", lbuf);
342 }
343 
344 void hash_dump (table)
345  struct hash_table *table;
346 {
347  int i;
348  struct hash_bucket *bp;
349 
350  if (!table)
351  return;
352 
353  for (i = 0; i < table -> hash_count; i++) {
354  if (!table -> buckets [i])
355  continue;
356  log_info ("hash bucket %d:", i);
357  for (bp = table -> buckets [i]; bp; bp = bp -> next) {
358  if (bp -> len)
359  dump_raw (bp -> name, bp -> len);
360  else
361  log_info ("%s", (const char *)bp -> name);
362  }
363  }
364 }
365 
366 /*
367  * print a string as hex. This only outputs
368  * colon separated hex list no matter what
369  * the input looks like. See print_hex
370  * for a function that prints either cshl
371  * or a string if all bytes are printible
372  * It only uses limit characters from buf
373  * and doesn't do anything if buf == NULL
374  *
375  * len - length of data
376  * data - input data
377  * limit - length of buf to use
378  * buf - output buffer
379  */
380 void print_hex_only (len, data, limit, buf)
381  unsigned len;
382  const u_int8_t *data;
383  unsigned limit;
384  char *buf;
385 {
386  char *bufptr = buf;
387  int byte = 0;
388 
389  if (data == NULL || bufptr == NULL || limit == 0) {
390  return;
391  }
392 
393  if (((len == 0) || ((len * 3) > limit))) {
394  *bufptr = 0x0;
395  return;
396  }
397 
398  for ( ; byte < len; ++byte) {
399  if (byte > 0) {
400  *bufptr++ = ':';
401  }
402 
403  sprintf(bufptr, "%02x", data[byte]);
404  bufptr += 2;
405  }
406 
407  return;
408 }
409 
410 /*
411  * print a string as either text if all the characters
412  * are printable or colon separated hex if they aren't
413  *
414  * len - length of data
415  * data - input data
416  * limit - length of buf to use
417  * buf - output buffer
418  */
419 void print_hex_or_string (len, data, limit, buf)
420  unsigned len;
421  const u_int8_t *data;
422  unsigned limit;
423  char *buf;
424 {
425  unsigned i;
426  if ((buf == NULL) || (limit < 3))
427  return;
428 
429  for (i = 0; (i < (limit - 3)) && (i < len); i++) {
430  if (!isascii(data[i]) || !isprint(data[i])) {
431  print_hex_only(len, data, limit, buf);
432  return;
433  }
434  }
435 
436  buf[0] = '"';
437  i = len;
438  if (i > (limit - 3))
439  i = limit - 3;
440  memcpy(&buf[1], data, i);
441  buf[i + 1] = '"';
442  buf[i + 2] = 0;
443  return;
444 }
445 
446 /*
447  * print a string as either hex or text
448  * using static buffers to hold the output
449  *
450  * len - length of data
451  * data - input data
452  * limit - length of buf
453  * buf_num - the output buffer to use
454  */
455 #define HBLEN 1024
456 char *print_hex(len, data, limit, buf_num)
457  unsigned len;
458  const u_int8_t *data;
459  unsigned limit;
460  unsigned buf_num;
461 {
462  static char hex_buf_1[HBLEN + 1];
463  static char hex_buf_2[HBLEN + 1];
464  static char hex_buf_3[HBLEN + 1];
465  char *hex_buf;
466 
467  switch(buf_num) {
468  case 0:
469  hex_buf = hex_buf_1;
470  if (limit >= sizeof(hex_buf_1))
471  limit = sizeof(hex_buf_1);
472  break;
473  case 1:
474  hex_buf = hex_buf_2;
475  if (limit >= sizeof(hex_buf_2))
476  limit = sizeof(hex_buf_2);
477  break;
478  case 2:
479  hex_buf = hex_buf_3;
480  if (limit >= sizeof(hex_buf_3))
481  limit = sizeof(hex_buf_3);
482  break;
483  default:
484  return(NULL);
485  }
486 
487  print_hex_or_string(len, data, limit, hex_buf);
488  return(hex_buf);
489 }
490 
491 #define DQLEN 80
492 
493 char *print_dotted_quads (len, data)
494  unsigned len;
495  const u_int8_t *data;
496 {
497  static char dq_buf [DQLEN + 1];
498  int i;
499  char *s;
500 
501  s = &dq_buf [0];
502 
503  i = 0;
504 
505  /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
506  * The sprintf can't exceed 18 bytes, and since the loop enforces
507  * 21 bytes of space per iteration at no time can we exit the
508  * loop without at least 3 bytes spare.
509  */
510  do {
511  sprintf (s, "%u.%u.%u.%u, ",
512  data [i], data [i + 1], data [i + 2], data [i + 3]);
513  s += strlen (s);
514  i += 4;
515  } while ((s - &dq_buf [0] > DQLEN - 21) &&
516  i + 3 < len);
517  if (i == len)
518  s [-2] = 0;
519  else
520  strcpy (s, "...");
521  return dq_buf;
522 }
523 
524 char *print_dec_1 (val)
525  unsigned long val;
526 {
527  static char vbuf [32];
528  sprintf (vbuf, "%lu", val);
529  return vbuf;
530 }
531 
532 char *print_dec_2 (val)
533  unsigned long val;
534 {
535  static char vbuf [32];
536  sprintf (vbuf, "%lu", val);
537  return vbuf;
538 }
539 
540 static unsigned print_subexpression (struct expression *, char *, unsigned);
541 
542 static unsigned print_subexpression (expr, buf, len)
543  struct expression *expr;
544  char *buf;
545  unsigned len;
546 {
547  unsigned rv, left;
548  const char *s;
549 
550  switch (expr -> op) {
551  case expr_none:
552  if (len > 3) {
553  strcpy (buf, "nil");
554  return 3;
555  }
556  break;
557 
558  case expr_match:
559  if (len > 7) {
560  strcpy (buf, "(match)");
561  return 7;
562  }
563  break;
564 
565  case expr_check:
566  rv = 10 + strlen (expr -> data.check -> name);
567  if (len > rv) {
568  sprintf (buf, "(check %s)",
569  expr -> data.check -> name);
570  return rv;
571  }
572  break;
573 
574  case expr_equal:
575  if (len > 6) {
576  rv = 4;
577  strcpy (buf, "(eq ");
578  rv += print_subexpression (expr -> data.equal [0],
579  buf + rv, len - rv - 2);
580  buf [rv++] = ' ';
581  rv += print_subexpression (expr -> data.equal [1],
582  buf + rv, len - rv - 1);
583  buf [rv++] = ')';
584  buf [rv] = 0;
585  return rv;
586  }
587  break;
588 
589  case expr_not_equal:
590  if (len > 7) {
591  rv = 5;
592  strcpy (buf, "(neq ");
593  rv += print_subexpression (expr -> data.equal [0],
594  buf + rv, len - rv - 2);
595  buf [rv++] = ' ';
596  rv += print_subexpression (expr -> data.equal [1],
597  buf + rv, len - rv - 1);
598  buf [rv++] = ')';
599  buf [rv] = 0;
600  return rv;
601  }
602  break;
603 
604  case expr_regex_match:
605  if (len > 10) {
606  rv = 4;
607  strcpy(buf, "(regex ");
608  rv += print_subexpression(expr->data.equal[0],
609  buf + rv, len - rv - 2);
610  buf[rv++] = ' ';
611  rv += print_subexpression(expr->data.equal[1],
612  buf + rv, len - rv - 1);
613  buf[rv++] = ')';
614  buf[rv] = 0;
615  return rv;
616  }
617  break;
618 
619  case expr_substring:
620  if (len > 11) {
621  rv = 8;
622  strcpy (buf, "(substr ");
623  rv += print_subexpression (expr -> data.substring.expr,
624  buf + rv, len - rv - 3);
625  buf [rv++] = ' ';
626  rv += print_subexpression
627  (expr -> data.substring.offset,
628  buf + rv, len - rv - 2);
629  buf [rv++] = ' ';
630  rv += print_subexpression (expr -> data.substring.len,
631  buf + rv, len - rv - 1);
632  buf [rv++] = ')';
633  buf [rv] = 0;
634  return rv;
635  }
636  break;
637 
638  case expr_suffix:
639  if (len > 10) {
640  rv = 8;
641  strcpy (buf, "(suffix ");
642  rv += print_subexpression (expr -> data.suffix.expr,
643  buf + rv, len - rv - 2);
644  if (len > rv)
645  buf [rv++] = ' ';
646  rv += print_subexpression (expr -> data.suffix.len,
647  buf + rv, len - rv - 1);
648  if (len > rv)
649  buf [rv++] = ')';
650  buf [rv] = 0;
651  return rv;
652  }
653  break;
654 
655  case expr_lcase:
656  if (len > 9) {
657  rv = 7;
658  strcpy(buf, "(lcase ");
659  rv += print_subexpression(expr->data.lcase,
660  buf + rv, len - rv - 1);
661  buf[rv++] = ')';
662  buf[rv] = 0;
663  return rv;
664  }
665  break;
666 
667  case expr_ucase:
668  if (len > 9) {
669  rv = 7;
670  strcpy(buf, "(ucase ");
671  rv += print_subexpression(expr->data.ucase,
672  buf + rv, len - rv - 1);
673  buf[rv++] = ')';
674  buf[rv] = 0;
675  return rv;
676  }
677  break;
678 
679  case expr_concat:
680  if (len > 10) {
681  rv = 8;
682  strcpy (buf, "(concat ");
683  rv += print_subexpression (expr -> data.concat [0],
684  buf + rv, len - rv - 2);
685  buf [rv++] = ' ';
686  rv += print_subexpression (expr -> data.concat [1],
687  buf + rv, len - rv - 1);
688  buf [rv++] = ')';
689  buf [rv] = 0;
690  return rv;
691  }
692  break;
693 
695  if (len > 8) {
696  rv = 6;
697  strcpy (buf, "(pick1st ");
698  rv += print_subexpression
699  (expr -> data.pick_first_value.car,
700  buf + rv, len - rv - 2);
701  buf [rv++] = ' ';
702  rv += print_subexpression
703  (expr -> data.pick_first_value.cdr,
704  buf + rv, len - rv - 1);
705  buf [rv++] = ')';
706  buf [rv] = 0;
707  return rv;
708  }
709  break;
710 
711  case expr_host_lookup:
712  rv = 15 + strlen (expr -> data.host_lookup -> hostname);
713  if (len > rv) {
714  sprintf (buf, "(dns-lookup %s)",
715  expr -> data.host_lookup -> hostname);
716  return rv;
717  }
718  break;
719 
720  case expr_and:
721  s = "and";
722  binop:
723  rv = strlen (s);
724  if (len > rv + 4) {
725  buf [0] = '(';
726  strcpy (&buf [1], s);
727  rv += 1;
728  buf [rv++] = ' ';
729  rv += print_subexpression (expr -> data.and [0],
730  buf + rv, len - rv - 2);
731  buf [rv++] = ' ';
732  rv += print_subexpression (expr -> data.and [1],
733  buf + rv, len - rv - 1);
734  buf [rv++] = ')';
735  buf [rv] = 0;
736  return rv;
737  }
738  break;
739 
740  case expr_or:
741  s = "or";
742  goto binop;
743 
744  case expr_add:
745  s = "+";
746  goto binop;
747 
748  case expr_subtract:
749  s = "-";
750  goto binop;
751 
752  case expr_multiply:
753  s = "*";
754  goto binop;
755 
756  case expr_divide:
757  s = "/";
758  goto binop;
759 
760  case expr_remainder:
761  s = "%";
762  goto binop;
763 
764  case expr_binary_and:
765  s = "&";
766  goto binop;
767 
768  case expr_binary_or:
769  s = "|";
770  goto binop;
771 
772  case expr_binary_xor:
773  s = "^";
774  goto binop;
775 
776  case expr_not:
777  if (len > 6) {
778  rv = 5;
779  strcpy (buf, "(not ");
780  rv += print_subexpression (expr -> data.not,
781  buf + rv, len - rv - 1);
782  buf [rv++] = ')';
783  buf [rv] = 0;
784  return rv;
785  }
786  break;
787 
788  case expr_config_option:
789  s = "cfg-option";
790  goto dooption;
791 
792  case expr_option:
793  s = "option";
794  dooption:
795  rv = strlen (s) + 2 + (strlen (expr -> data.option -> name) +
796  strlen (expr -> data.option -> universe -> name));
797  if (len > rv) {
798  sprintf (buf, "(option %s.%s)",
799  expr -> data.option -> universe -> name,
800  expr -> data.option -> name);
801  return rv;
802  }
803  break;
804 
805  case expr_hardware:
806  if (len > 10) {
807  strcpy (buf, "(hardware)");
808  return 10;
809  }
810  break;
811 
812  case expr_packet:
813  if (len > 10) {
814  rv = 8;
815  strcpy (buf, "(substr ");
816  rv += print_subexpression (expr -> data.packet.offset,
817  buf + rv, len - rv - 2);
818  buf [rv++] = ' ';
819  rv += print_subexpression (expr -> data.packet.len,
820  buf + rv, len - rv - 1);
821  buf [rv++] = ')';
822  buf [rv] = 0;
823  return rv;
824  }
825  break;
826 
827  case expr_const_data:
828  s = print_hex_1 (expr -> data.const_data.len,
829  expr -> data.const_data.data, len);
830  rv = strlen (s);
831  if (rv >= len)
832  rv = len - 1;
833  strncpy (buf, s, rv);
834  buf [rv] = 0;
835  return rv;
836 
837  case expr_encapsulate:
838  rv = 13;
839  strcpy (buf, "(encapsulate ");
840  rv += expr -> data.encapsulate.len;
841  if (rv + 2 > len)
842  rv = len - 2;
843  strncpy (buf,
844  (const char *)expr -> data.encapsulate.data, rv - 13);
845  buf [rv++] = ')';
846  buf [rv++] = 0;
847  break;
848 
849  case expr_extract_int8:
850  if (len > 7) {
851  rv = 6;
852  strcpy (buf, "(int8 ");
853  rv += print_subexpression (expr -> data.extract_int,
854  buf + rv, len - rv - 1);
855  buf [rv++] = ')';
856  buf [rv] = 0;
857  return rv;
858  }
859  break;
860 
861  case expr_extract_int16:
862  if (len > 8) {
863  rv = 7;
864  strcpy (buf, "(int16 ");
865  rv += print_subexpression (expr -> data.extract_int,
866  buf + rv, len - rv - 1);
867  buf [rv++] = ')';
868  buf [rv] = 0;
869  return rv;
870  }
871  break;
872 
873  case expr_extract_int32:
874  if (len > 8) {
875  rv = 7;
876  strcpy (buf, "(int32 ");
877  rv += print_subexpression (expr -> data.extract_int,
878  buf + rv, len - rv - 1);
879  buf [rv++] = ')';
880  buf [rv] = 0;
881  return rv;
882  }
883  break;
884 
885  case expr_encode_int8:
886  if (len > 7) {
887  rv = 6;
888  strcpy (buf, "(to-int8 ");
889  rv += print_subexpression (expr -> data.encode_int,
890  buf + rv, len - rv - 1);
891  buf [rv++] = ')';
892  buf [rv] = 0;
893  return rv;
894  }
895  break;
896 
897  case expr_encode_int16:
898  if (len > 8) {
899  rv = 7;
900  strcpy (buf, "(to-int16 ");
901  rv += print_subexpression (expr -> data.encode_int,
902  buf + rv, len - rv - 1);
903  buf [rv++] = ')';
904  buf [rv] = 0;
905  return rv;
906  }
907  break;
908 
909  case expr_encode_int32:
910  if (len > 8) {
911  rv = 7;
912  strcpy (buf, "(to-int32 ");
913  rv += print_subexpression (expr -> data.encode_int,
914  buf + rv, len - rv - 1);
915  buf [rv++] = ')';
916  buf [rv] = 0;
917  return rv;
918  }
919  break;
920 
921  case expr_const_int:
922  s = print_dec_1 (expr -> data.const_int);
923  rv = strlen (s);
924  if (len > rv) {
925  strcpy (buf, s);
926  return rv;
927  }
928  break;
929 
930  case expr_exists:
931  rv = 10 + (strlen (expr -> data.option -> name) +
932  strlen (expr -> data.option -> universe -> name));
933  if (len > rv) {
934  sprintf (buf, "(exists %s.%s)",
935  expr -> data.option -> universe -> name,
936  expr -> data.option -> name);
937  return rv;
938  }
939  break;
940 
942  rv = 10 + strlen (expr -> data.variable);
943  if (len > rv) {
944  sprintf (buf, "(defined %s)", expr -> data.variable);
945  return rv;
946  }
947  break;
948 
950  rv = strlen (expr -> data.variable);
951  if (len > rv) {
952  sprintf (buf, "%s", expr -> data.variable);
953  return rv;
954  }
955  break;
956 
957  case expr_known:
958  s = "known";
959  astring:
960  rv = strlen (s);
961  if (len > rv) {
962  strcpy (buf, s);
963  return rv;
964  }
965  break;
966 
967  case expr_leased_address:
968  s = "leased-address";
969  goto astring;
970 
971  case expr_client_state:
972  s = "client-state";
973  goto astring;
974 
975  case expr_host_decl_name:
976  s = "host-decl-name";
977  goto astring;
978 
979  case expr_lease_time:
980  s = "lease-time";
981  goto astring;
982 
983  case expr_static:
984  s = "static";
985  goto astring;
986 
987  case expr_filename:
988  s = "filename";
989  goto astring;
990 
991  case expr_sname:
992  s = "server-name";
993  goto astring;
994 
995  case expr_reverse:
996  if (len > 11) {
997  rv = 13;
998  strcpy (buf, "(reverse ");
999  rv += print_subexpression (expr -> data.reverse.width,
1000  buf + rv, len - rv - 2);
1001  buf [rv++] = ' ';
1002  rv += print_subexpression (expr -> data.reverse.buffer,
1003  buf + rv, len - rv - 1);
1004  buf [rv++] = ')';
1005  buf [rv] = 0;
1006  return rv;
1007  }
1008  break;
1009 
1010  case expr_binary_to_ascii:
1011  if (len > 5) {
1012  rv = 9;
1013  strcpy (buf, "(b2a ");
1014  rv += print_subexpression (expr -> data.b2a.base,
1015  buf + rv, len - rv - 4);
1016  buf [rv++] = ' ';
1017  rv += print_subexpression (expr -> data.b2a.width,
1018  buf + rv, len - rv - 3);
1019  buf [rv++] = ' ';
1020  rv += print_subexpression (expr -> data.b2a.separator,
1021  buf + rv, len - rv - 2);
1022  buf [rv++] = ' ';
1023  rv += print_subexpression (expr -> data.b2a.buffer,
1024  buf + rv, len - rv - 1);
1025  buf [rv++] = ')';
1026  buf [rv] = 0;
1027  return rv;
1028  }
1029  break;
1030 
1031  case expr_dns_transaction:
1032  rv = 10;
1033  if (len < rv + 2) {
1034  buf [0] = '(';
1035  strcpy (&buf [1], "ns-update ");
1036  while (len < rv + 2) {
1037  rv += print_subexpression
1038  (expr -> data.dns_transaction.car,
1039  buf + rv, len - rv - 2);
1040  buf [rv++] = ' ';
1041  expr = expr -> data.dns_transaction.cdr;
1042  }
1043  buf [rv - 1] = ')';
1044  buf [rv] = 0;
1045  return rv;
1046  }
1047  return 0;
1048 
1049  case expr_ns_delete:
1050  s = "delete";
1051  left = 4;
1052  goto dodnsupd;
1053  case expr_ns_exists:
1054  s = "exists";
1055  left = 4;
1056  goto dodnsupd;
1057  case expr_ns_not_exists:
1058  s = "not_exists";
1059  left = 4;
1060  goto dodnsupd;
1061  case expr_ns_add:
1062  s = "update";
1063  left = 5;
1064  dodnsupd:
1065  rv = strlen (s);
1066  if (len > strlen (s) + 1) {
1067  buf [0] = '(';
1068  strcpy (buf + 1, s);
1069  rv++;
1070  buf [rv++] = ' ';
1071  s = print_dec_1 (expr -> data.ns_add.rrclass);
1072  if (len > rv + strlen (s) + left) {
1073  strcpy (&buf [rv], s);
1074  rv += strlen (&buf [rv]);
1075  }
1076  buf [rv++] = ' ';
1077  left--;
1078  s = print_dec_1 (expr -> data.ns_add.rrtype);
1079  if (len > rv + strlen (s) + left) {
1080  strcpy (&buf [rv], s);
1081  rv += strlen (&buf [rv]);
1082  }
1083  buf [rv++] = ' ';
1084  left--;
1085  rv += print_subexpression
1086  (expr -> data.ns_add.rrname,
1087  buf + rv, len - rv - left);
1088  buf [rv++] = ' ';
1089  left--;
1090  rv += print_subexpression
1091  (expr -> data.ns_add.rrdata,
1092  buf + rv, len - rv - left);
1093  buf [rv++] = ' ';
1094  left--;
1095  rv += print_subexpression
1096  (expr -> data.ns_add.ttl,
1097  buf + rv, len - rv - left);
1098  buf [rv++] = ')';
1099  buf [rv] = 0;
1100  return rv;
1101  }
1102  break;
1103 
1104  case expr_null:
1105  if (len > 6) {
1106  strcpy (buf, "(null)");
1107  return 6;
1108  }
1109  break;
1110  case expr_funcall:
1111  rv = 12 + strlen (expr -> data.funcall.name);
1112  if (len > rv + 1) {
1113  strcpy (buf, "(funcall ");
1114  strcpy (buf + 9, expr -> data.funcall.name);
1115  buf [rv++] = ' ';
1116  rv += print_subexpression
1117  (expr -> data.funcall.arglist, buf + rv,
1118  len - rv - 1);
1119  buf [rv++] = ')';
1120  buf [rv] = 0;
1121  return rv;
1122  }
1123  break;
1124 
1125  case expr_arg:
1126  rv = print_subexpression (expr -> data.arg.val, buf, len);
1127  if (expr -> data.arg.next && rv + 2 < len) {
1128  buf [rv++] = ' ';
1129  rv += print_subexpression (expr -> data.arg.next,
1130  buf, len);
1131  if (rv + 1 < len)
1132  buf [rv++] = 0;
1133  return rv;
1134  }
1135  break;
1136 
1137  case expr_function:
1138  rv = 9;
1139  if (len > rv + 1) {
1140  struct string_list *foo;
1141  strcpy (buf, "(function");
1142  for (foo = expr -> data.func -> args;
1143  foo; foo = foo -> next) {
1144  if (len > rv + 2 + strlen (foo -> string)) {
1145  buf [rv - 1] = ' ';
1146  strcpy (&buf [rv], foo -> string);
1147  rv += strlen (foo -> string);
1148  }
1149  }
1150  buf [rv++] = ')';
1151  buf [rv] = 0;
1152  return rv;
1153  }
1154  break;
1155 
1156  case expr_gethostname:
1157  if (len > 13) {
1158  strcpy(buf, "(gethostname)");
1159  return 13;
1160  }
1161  break;
1162 
1163  default:
1164  log_fatal("Impossible case at %s:%d (undefined expression "
1165  "%d).", MDL, expr->op);
1166  break;
1167  }
1168  return 0;
1169 }
1170 
1171 void print_expression (name, expr)
1172  const char *name;
1173  struct expression *expr;
1174 {
1175  char buf [1024];
1176 
1177  print_subexpression (expr, buf, sizeof buf);
1178  log_info ("%s: %s", name, buf);
1179 }
1180 
1181 int token_print_indent_concat (FILE *file, int col, int indent,
1182  const char *prefix,
1183  const char *suffix, ...)
1184 {
1185  va_list list;
1186  unsigned len;
1187  char *s, *t, *u;
1188 
1189  va_start (list, suffix);
1190  s = va_arg (list, char *);
1191  len = 0;
1192  while (s) {
1193  len += strlen (s);
1194  s = va_arg (list, char *);
1195  }
1196  va_end (list);
1197 
1198  t = dmalloc (len + 1, MDL);
1199  if (!t)
1200  log_fatal ("token_print_indent: no memory for copy buffer");
1201 
1202  va_start (list, suffix);
1203  s = va_arg (list, char *);
1204  u = t;
1205  while (s) {
1206  len = strlen (s);
1207  strcpy (u, s);
1208  u += len;
1209  s = va_arg (list, char *);
1210  }
1211  va_end (list);
1212 
1213  col = token_print_indent (file, col, indent,
1214  prefix, suffix, t);
1215  dfree (t, MDL);
1216  return col;
1217 }
1218 
1219 int token_indent_data_string (FILE *file, int col, int indent,
1220  const char *prefix, const char *suffix,
1221  struct data_string *data)
1222 {
1223  int i;
1224  char *buf;
1225  char obuf [3];
1226 
1227  /* See if this is just ASCII. */
1228  for (i = 0; i < data -> len; i++)
1229  if (!isascii (data -> data [i]) ||
1230  !isprint (data -> data [i]))
1231  break;
1232 
1233  /* If we have a purely ASCII string, output it as text. */
1234  if (i == data -> len) {
1235  buf = dmalloc (data -> len + 3, MDL);
1236  if (buf) {
1237  buf [0] = '"';
1238  memcpy (buf + 1, data -> data, data -> len);
1239  buf [data -> len + 1] = '"';
1240  buf [data -> len + 2] = 0;
1241  i = token_print_indent (file, col, indent,
1242  prefix, suffix, buf);
1243  dfree (buf, MDL);
1244  return i;
1245  }
1246  }
1247 
1248  for (i = 0; i < data -> len; i++) {
1249  sprintf (obuf, "%2.2x", data -> data [i]);
1250  col = token_print_indent (file, col, indent,
1251  i == 0 ? prefix : "",
1252  (i + 1 == data -> len
1253  ? suffix
1254  : ""), obuf);
1255  if (i + 1 != data -> len)
1256  col = token_print_indent (file, col, indent,
1257  prefix, suffix, ":");
1258  }
1259  return col;
1260 }
1261 
1262 int token_print_indent (FILE *file, int col, int indent,
1263  const char *prefix,
1264  const char *suffix, const char *buf)
1265 {
1266  int len = 0;
1267  if (prefix != NULL)
1268  len += strlen (prefix);
1269  if (buf != NULL)
1270  len += strlen (buf);
1271 
1272  if (col + len > 79) {
1273  if (indent + len < 79) {
1275  col = indent;
1276  } else {
1277  indent_spaces (file, col);
1278  col = len > 79 ? 0 : 79 - len - 1;
1279  }
1280  } else if (prefix && *prefix) {
1281  fputs (prefix, file);
1282  col += strlen (prefix);
1283  }
1284  if ((buf != NULL) && (*buf != 0)) {
1285  fputs (buf, file);
1286  col += strlen(buf);
1287  }
1288  if (suffix && *suffix) {
1289  if (col + strlen (suffix) > 79) {
1291  col = indent;
1292  } else {
1293  fputs (suffix, file);
1294  col += strlen (suffix);
1295  }
1296  }
1297  return col;
1298 }
1299 
1300 void indent_spaces (FILE *file, int indent)
1301 {
1302  int i;
1303  fputc ('\n', file);
1304  for (i = 0; i < indent; i++)
1305  fputc (' ', file);
1306 }
1307 
1308 /* Format the given time as "A; # B", where A is the format
1309  * used by the parser, and B is the local time, for humans.
1310  */
1311 const char *
1313 {
1314  static char buf[sizeof("epoch 9223372036854775807; "
1315  "# Wed Jun 30 21:49:08 2147483647")];
1316  static char buf1[sizeof("# Wed Jun 30 21:49:08 2147483647")];
1317  time_t since_epoch;
1318  /* The string: "6 2147483647/12/31 23:59:60;"
1319  * is smaller than the other, used to declare the buffer size, so
1320  * we can use one buffer for both.
1321  */
1322 
1323  if (t == MAX_TIME)
1324  return "never;";
1325 
1326  if (t < 0)
1327  return NULL;
1328 
1329  /* For those lucky enough to have a 128-bit time_t, ensure that
1330  * whatever (corrupt) value we're given doesn't exceed the static
1331  * buffer.
1332  */
1333 #if (MAX_TIME > 0x7fffffffffffffff)
1334  if (t > 0x7fffffffffffffff)
1335  return NULL;
1336 #endif
1337 
1339  since_epoch = mktime(localtime(&t));
1340  if ((strftime(buf1, sizeof(buf1),
1341  "# %a %b %d %H:%M:%S %Y",
1342  localtime(&t)) == 0) ||
1343  (snprintf(buf, sizeof(buf), "epoch %lu; %s",
1344  (unsigned long)since_epoch, buf1) >= sizeof(buf)))
1345  return NULL;
1346 
1347  } else {
1348  /* No bounds check for the year is necessary - in this case,
1349  * strftime() will run out of space and assert an error.
1350  */
1351  if (strftime(buf, sizeof(buf), "%w %Y/%m/%d %H:%M:%S;",
1352  gmtime(&t)) == 0)
1353  return NULL;
1354  }
1355 
1356  return buf;
1357 }
1358 
1359 /* !brief Return the given data as a string of hex digits "xx:xx:xx ..."
1360  *
1361  * Converts the given data into a null-terminated, string of hex digits,
1362  * stored in an allocated buffer. It is the caller's responsiblity to free
1363  * the buffer.
1364  *
1365  * \param s - pointer to the data to convert
1366  * \param len - length of the data to convert
1367  * \param file - source file of invocation
1368  * \param line - line number of invocation
1369  *
1370  * \return Returns an allocated buffer containing the hex string
1371 */
1372 char *buf_to_hex (const unsigned char *s, unsigned len,
1373  const char *file, int line)
1374 {
1375  unsigned nulen = 0;
1376  char *buf;
1377 
1378  /* If somebody hands us length of zero, we'll give them
1379  * back an empty string */
1380  if (!len) {
1381  buf = dmalloc (1, MDL);
1382  if (buf) {
1383  *buf = 0x0;
1384  }
1385 
1386  return (buf);
1387  }
1388 
1389 
1390  /* Figure out how big it needs to be. print_to_hex uses
1391  * "%02x:" per character. Note since there's no trailing colon
1392  * we'll have room for the null */
1393  nulen = (len * 3);
1394 
1395  /* Allocate our buffer */
1396  buf = dmalloc (nulen, MDL);
1397 
1398  /* Hex-ify it */
1399  if (buf) {
1400  print_hex_only (len, s, nulen, buf);
1401  }
1402 
1403  return buf;
1404 }
1405 
1406 /* !brief Formats data into a string based on a lease id format
1407  *
1408  * Takes the given data and returns an allocated string whose contents are
1409  * the string version of that data, formatted according to the output lease
1410  * id format. Note it is the caller's responsiblity to delete the string.
1411  *
1412  * Currently two formats are supported:
1413  *
1414  * OCTAL - Default or "legacy" CSL format enclosed in quotes '"'.
1415  *
1416  * HEX - Bytes represented as string colon seperated of hex digit pairs
1417  * (xx:xx:xx...)
1418  *
1419  * \param s - data to convert
1420  * \param len - length of the data to convert
1421  * \param format - desired format of the result
1422  * \param file - source file of invocation
1423  * \param line - line number of invocation
1424  *
1425  * \return A pointer to the allocated, null-terminated string
1426 */
1427 char *format_lease_id(const unsigned char *s, unsigned len,
1428  int format, const char *file, int line) {
1429  char *idstr = NULL;
1430 
1431  switch (format) {
1432  case TOKEN_HEX:
1433  idstr = buf_to_hex(s, len, MDL);
1434  break;
1435  case TOKEN_OCTAL:
1436  default:
1437  idstr = quotify_buf(s, len, '"', MDL);
1438  break;
1439  }
1440  return (idstr);
1441 }
1442 
1443 /*
1444  * Convert a relative path name to an absolute path name
1445  *
1446  * Not all versions of realpath() support NULL for
1447  * the second parameter and PATH_MAX isn't defined
1448  * on all systems. For the latter, we'll make what
1449  * ought to be a big enough buffer and let it fly.
1450  * If passed an absolute path it should return it
1451  * an allocated buffer.
1452  */
1453 char *absolute_path(const char *orgpath) {
1454  char *abspath = NULL;
1455  if (orgpath) {
1456 #ifdef PATH_MAX
1457  char buf[PATH_MAX];
1458 #else
1459  char buf[2048];
1460 #endif
1461  errno = 0;
1462  if (realpath(orgpath, buf) == NULL) {
1463  const char* errmsg = strerror(errno);
1464  log_fatal("Failed to get realpath for %s: %s",
1465  orgpath, errmsg);
1466  }
1467 
1468  /* dup the result into an allocated buffer */
1469  abspath = dmalloc(strlen(buf) + 1, MDL);
1470  if (abspath == NULL) {
1471  log_fatal("No memory for filename:%s\n",
1472  buf);
1473  }
1474 
1475  memcpy (abspath, buf, strlen(buf));
1476  abspath[strlen(buf)] = 0x0;
1477  }
1478 
1479  return (abspath);
1480 }
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1339
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
Definition: options.c:1793
void option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
Definition: options.c:3789
char * quotify_buf(const unsigned char *s, unsigned len, char enclose_char, const char *file, int line)
Definition: print.c:71
int token_indent_data_string(FILE *file, int col, int indent, const char *prefix, const char *suffix, struct data_string *data)
Definition: print.c:1219
int token_print_indent_concat(FILE *file, int col, int indent, const char *prefix, const char *suffix,...)
Definition: print.c:1181
void print_expression(char *name, struct expression *expr) const
Definition: print.c:1171
char * quotify_string(const char *s, const char *file, int line)
Definition: print.c:33
char * print_dec_2(unsigned long val)
Definition: print.c:532
const char * print_time(TIME t)
Definition: print.c:1312
char * print_dec_1(unsigned long val)
Definition: print.c:524
#define DQLEN
Definition: print.c:491
void indent_spaces(FILE *file, int indent)
Definition: print.c:1300
void hash_dump(struct hash_table *table)
Definition: print.c:344
char * format_lease_id(const unsigned char *s, unsigned len, int format, const char *file, int line)
Definition: print.c:1427
char * print_hex(unsigned len, const u_int8_t *data, unsigned limit, unsigned buf_num)
Definition: print.c:456
void print_lease(struct lease *lease)
Definition: print.c:194
void print_hex_or_string(unsigned len, const u_int8_t *data, unsigned limit, char *buf)
Definition: print.c:419
#define HBLEN
Definition: print.c:455
char * print_dotted_quads(unsigned len, const u_int8_t *data)
Definition: print.c:493
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
Definition: print.c:171
char * buf_to_hex(const unsigned char *s, unsigned len, const char *file, int line)
Definition: print.c:1372
char * absolute_path(const char *orgpath)
Definition: print.c:1453
int token_print_indent(FILE *file, int col, int indent, const char *prefix, const char *suffix, const char *buf)
Definition: print.c:1262
int db_time_format
Definition: print.c:31
void print_hex_only(unsigned len, const u_int8_t *data, unsigned limit, char *buf)
Definition: print.c:380
void dump_raw(unsigned char *buf, unsigned len) const
Definition: print.c:293
char * print_base64(const unsigned char *buf, unsigned len, const char *file, int line)
Definition: print.c:121
struct in_addr giaddr
Definition: dhclient.c:77
#define DEFAULT_TIME_FORMAT
Definition: dhcpd.h:2614
time_t TIME
Definition: dhcpd.h:85
void indent(int)
void dump_packet_option(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)
void dump_packet(struct packet *)
#define MAX_TIME
Definition: dhcpd.h:1626
#define LOCAL_TIME_FORMAT
Definition: dhcpd.h:2615
struct universe dhcp_universe
const char int line
Definition: dhcpd.h:3793
const char * file
Definition: dhcpd.h:3793
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2633
@ TOKEN_OCTAL
Definition: dhctoken.h:378
@ TOKEN_HEX
Definition: dhctoken.h:377
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:63
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
#define MDL
Definition: omapip.h:567
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
void dfree(void *, const char *, int)
Definition: alloc.c:145
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
const unsigned char * data
Definition: tree.h:78
unsigned len
Definition: tree.h:79
struct in_addr siaddr
Definition: dhcp.h:57
u_int16_t flags
Definition: dhcp.h:54
u_int32_t xid
Definition: dhcp.h:52
struct in_addr ciaddr
Definition: dhcp.h:55
unsigned char options[DHCP_MAX_OPTION_LEN]
Definition: dhcp.h:62
u_int8_t op
Definition: dhcp.h:48
u_int8_t htype
Definition: dhcp.h:49
struct in_addr yiaddr
Definition: dhcp.h:56
u_int16_t secs
Definition: dhcp.h:53
u_int8_t hlen
Definition: dhcp.h:50
unsigned char chaddr[16]
Definition: dhcp.h:59
char sname[DHCP_SNAME_LEN]
Definition: dhcp.h:60
u_int8_t hops
Definition: dhcp.h:51
union expression::expr_union data
enum expr_op op
Definition: tree.h:199
unsigned len
Definition: hash.h:53
struct hash_bucket * next
Definition: hash.h:51
const unsigned char * name
Definition: hash.h:52
Definition: dhcpd.h:560
Definition: tree.h:345
Definition: dhcpd.h:405
struct string_list * next
Definition: dhcpd.h:348
Definition: tree.h:301
int universe_count
Definition: tables.c:973
struct universe ** universes
Definition: tables.c:972
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2699
struct binding_scope * global_scope
Definition: tree.c:38
@ expr_ucase
Definition: tree.h:188
@ expr_funcall
Definition: tree.h:177
@ expr_gethostname
Definition: tree.h:192
@ expr_extract_int8
Definition: tree.h:147
@ expr_ns_not_exists
Definition: tree.h:169
@ expr_host_lookup
Definition: tree.h:139
@ expr_option
Definition: tree.h:143
@ expr_encode_int32
Definition: tree.h:152
@ expr_static
Definition: tree.h:165
@ expr_binary_and
Definition: tree.h:184
@ expr_encode_int16
Definition: tree.h:151
@ expr_regex_match
Definition: tree.h:190
@ expr_equal
Definition: tree.h:135
@ expr_check
Definition: tree.h:134
@ expr_none
Definition: tree.h:132
@ expr_lease_time
Definition: tree.h:163
@ expr_extract_int16
Definition: tree.h:148
@ expr_filename
Definition: tree.h:174
@ expr_binary_or
Definition: tree.h:185
@ expr_pick_first_value
Definition: tree.h:162
@ expr_encapsulate
Definition: tree.h:155
@ expr_ns_add
Definition: tree.h:166
@ expr_remainder
Definition: tree.h:183
@ expr_config_option
Definition: tree.h:160
@ expr_not
Definition: tree.h:142
@ expr_add
Definition: tree.h:179
@ expr_const_int
Definition: tree.h:153
@ expr_sname
Definition: tree.h:175
@ expr_divide
Definition: tree.h:182
@ expr_hardware
Definition: tree.h:144
@ expr_concat
Definition: tree.h:138
@ expr_or
Definition: tree.h:141
@ expr_and
Definition: tree.h:140
@ expr_null
Definition: tree.h:171
@ expr_dns_transaction
Definition: tree.h:164
@ expr_host_decl_name
Definition: tree.h:161
@ expr_known
Definition: tree.h:156
@ expr_leased_address
Definition: tree.h:158
@ expr_lcase
Definition: tree.h:189
@ expr_exists
Definition: tree.h:154
@ expr_const_data
Definition: tree.h:146
@ expr_binary_to_ascii
Definition: tree.h:159
@ expr_ns_delete
Definition: tree.h:167
@ expr_extract_int32
Definition: tree.h:149
@ expr_substring
Definition: tree.h:136
@ expr_multiply
Definition: tree.h:181
@ expr_suffix
Definition: tree.h:137
@ expr_function
Definition: tree.h:178
@ expr_packet
Definition: tree.h:145
@ expr_encode_int8
Definition: tree.h:150
@ expr_variable_exists
Definition: tree.h:172
@ expr_match
Definition: tree.h:133
@ expr_subtract
Definition: tree.h:180
@ expr_binary_xor
Definition: tree.h:186
@ expr_arg
Definition: tree.h:176
@ expr_not_equal
Definition: tree.h:170
@ expr_client_state
Definition: tree.h:187
@ expr_reverse
Definition: tree.h:157
@ expr_variable_reference
Definition: tree.h:173
@ expr_ns_exists
Definition: tree.h:168
unsigned rrclass
Definition: tree.h:255
struct expression * cdr
Definition: tree.h:248
unsigned long const_int
Definition: tree.h:231
struct expression * rrname
Definition: tree.h:257
struct dns_host_entry * host_lookup
Definition: tree.h:233
struct expression::expr_union::@22 dns_transaction
struct expression * next
Definition: tree.h:270
struct expression * not
Definition: tree.h:209
struct expression * extract_int
Definition: tree.h:229
struct expression * ucase
Definition: tree.h:221
struct expression::expr_union::@25 arg
struct expression * rrdata
Definition: tree.h:258
struct collection * check
Definition: tree.h:215
struct expression * arglist
Definition: tree.h:274
struct expression * len
Definition: tree.h:204
struct expression::expr_union::@19 b2a
struct expression * encode_int
Definition: tree.h:230
struct expression * val
Definition: tree.h:269
struct expression::expr_union::@20 reverse
struct data_string encapsulate
Definition: tree.h:235
struct expression * and[2]
Definition: tree.h:207
struct expression * separator
Definition: tree.h:239
struct expression * expr
Definition: tree.h:202
struct expression * ttl
Definition: tree.h:259
struct option * option
Definition: tree.h:222
struct expression::expr_union::@17 suffix
struct expression * base
Definition: tree.h:237
unsigned rrtype
Definition: tree.h:256
struct expression::expr_union::@16 substring
struct expression * lcase
Definition: tree.h:220
struct expression::expr_union::@18 packet
struct expression::expr_union::@21 pick_first_value
struct data_string const_data
Definition: tree.h:228
struct expression::expr_union::@23 ns_add
struct expression * offset
Definition: tree.h:203
struct expression * width
Definition: tree.h:238
struct expression * buffer
Definition: tree.h:240
struct expression * concat[2]
Definition: tree.h:232
struct expression * car
Definition: tree.h:247
struct expression * equal[2]
Definition: tree.h:206
struct expression::expr_union::@26 funcall