ISC DHCP  4.3.4
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-2016 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
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  unsigned i;
387 
388  if ((buf == NULL) || (limit < 3))
389  return;
390 
391  for (i = 0; (i < limit / 3) && (i < len); i++) {
392  sprintf(&buf[i*3], "%02x:", data[i]);
393  }
394  buf[(i * 3) - 1] = 0;
395  return;
396 }
397 
398 /*
399  * print a string as either text if all the characters
400  * are printable or colon separated hex if they aren't
401  *
402  * len - length of data
403  * data - input data
404  * limit - length of buf to use
405  * buf - output buffer
406  */
407 void print_hex_or_string (len, data, limit, buf)
408  unsigned len;
409  const u_int8_t *data;
410  unsigned limit;
411  char *buf;
412 {
413  unsigned i;
414  if ((buf == NULL) || (limit < 3))
415  return;
416 
417  for (i = 0; (i < (limit - 3)) && (i < len); i++) {
418  if (!isascii(data[i]) || !isprint(data[i])) {
419  print_hex_only(len, data, limit, buf);
420  return;
421  }
422  }
423 
424  buf[0] = '"';
425  i = len;
426  if (i > (limit - 3))
427  i = limit - 3;
428  memcpy(&buf[1], data, i);
429  buf[i + 1] = '"';
430  buf[i + 2] = 0;
431  return;
432 }
433 
434 /*
435  * print a string as either hex or text
436  * using static buffers to hold the output
437  *
438  * len - length of data
439  * data - input data
440  * limit - length of buf
441  * buf_num - the output buffer to use
442  */
443 #define HBLEN 1024
444 char *print_hex(len, data, limit, buf_num)
445  unsigned len;
446  const u_int8_t *data;
447  unsigned limit;
448  unsigned buf_num;
449 {
450  static char hex_buf_1[HBLEN + 1];
451  static char hex_buf_2[HBLEN + 1];
452  static char hex_buf_3[HBLEN + 1];
453  char *hex_buf;
454 
455  switch(buf_num) {
456  case 0:
457  hex_buf = hex_buf_1;
458  if (limit >= sizeof(hex_buf_1))
459  limit = sizeof(hex_buf_1);
460  break;
461  case 1:
462  hex_buf = hex_buf_2;
463  if (limit >= sizeof(hex_buf_2))
464  limit = sizeof(hex_buf_2);
465  break;
466  case 2:
467  hex_buf = hex_buf_3;
468  if (limit >= sizeof(hex_buf_3))
469  limit = sizeof(hex_buf_3);
470  break;
471  default:
472  return(NULL);
473  }
474 
475  print_hex_or_string(len, data, limit, hex_buf);
476  return(hex_buf);
477 }
478 
479 #define DQLEN 80
480 
481 char *print_dotted_quads (len, data)
482  unsigned len;
483  const u_int8_t *data;
484 {
485  static char dq_buf [DQLEN + 1];
486  int i;
487  char *s;
488 
489  s = &dq_buf [0];
490 
491  i = 0;
492 
493  /* %Audit% Loop bounds checks to 21 bytes. %2004.06.17,Safe%
494  * The sprintf can't exceed 18 bytes, and since the loop enforces
495  * 21 bytes of space per iteration at no time can we exit the
496  * loop without at least 3 bytes spare.
497  */
498  do {
499  sprintf (s, "%u.%u.%u.%u, ",
500  data [i], data [i + 1], data [i + 2], data [i + 3]);
501  s += strlen (s);
502  i += 4;
503  } while ((s - &dq_buf [0] > DQLEN - 21) &&
504  i + 3 < len);
505  if (i == len)
506  s [-2] = 0;
507  else
508  strcpy (s, "...");
509  return dq_buf;
510 }
511 
512 char *print_dec_1 (val)
513  unsigned long val;
514 {
515  static char vbuf [32];
516  sprintf (vbuf, "%lu", val);
517  return vbuf;
518 }
519 
520 char *print_dec_2 (val)
521  unsigned long val;
522 {
523  static char vbuf [32];
524  sprintf (vbuf, "%lu", val);
525  return vbuf;
526 }
527 
528 static unsigned print_subexpression (struct expression *, char *, unsigned);
529 
530 static unsigned print_subexpression (expr, buf, len)
531  struct expression *expr;
532  char *buf;
533  unsigned len;
534 {
535  unsigned rv, left;
536  const char *s;
537 
538  switch (expr -> op) {
539  case expr_none:
540  if (len > 3) {
541  strcpy (buf, "nil");
542  return 3;
543  }
544  break;
545 
546  case expr_match:
547  if (len > 7) {
548  strcpy (buf, "(match)");
549  return 7;
550  }
551  break;
552 
553  case expr_check:
554  rv = 10 + strlen (expr -> data.check -> name);
555  if (len > rv) {
556  sprintf (buf, "(check %s)",
557  expr -> data.check -> name);
558  return rv;
559  }
560  break;
561 
562  case expr_equal:
563  if (len > 6) {
564  rv = 4;
565  strcpy (buf, "(eq ");
566  rv += print_subexpression (expr -> data.equal [0],
567  buf + rv, len - rv - 2);
568  buf [rv++] = ' ';
569  rv += print_subexpression (expr -> data.equal [1],
570  buf + rv, len - rv - 1);
571  buf [rv++] = ')';
572  buf [rv] = 0;
573  return rv;
574  }
575  break;
576 
577  case expr_not_equal:
578  if (len > 7) {
579  rv = 5;
580  strcpy (buf, "(neq ");
581  rv += print_subexpression (expr -> data.equal [0],
582  buf + rv, len - rv - 2);
583  buf [rv++] = ' ';
584  rv += print_subexpression (expr -> data.equal [1],
585  buf + rv, len - rv - 1);
586  buf [rv++] = ')';
587  buf [rv] = 0;
588  return rv;
589  }
590  break;
591 
592  case expr_regex_match:
593  if (len > 10) {
594  rv = 4;
595  strcpy(buf, "(regex ");
596  rv += print_subexpression(expr->data.equal[0],
597  buf + rv, len - rv - 2);
598  buf[rv++] = ' ';
599  rv += print_subexpression(expr->data.equal[1],
600  buf + rv, len - rv - 1);
601  buf[rv++] = ')';
602  buf[rv] = 0;
603  return rv;
604  }
605  break;
606 
607  case expr_substring:
608  if (len > 11) {
609  rv = 8;
610  strcpy (buf, "(substr ");
611  rv += print_subexpression (expr -> data.substring.expr,
612  buf + rv, len - rv - 3);
613  buf [rv++] = ' ';
614  rv += print_subexpression
615  (expr -> data.substring.offset,
616  buf + rv, len - rv - 2);
617  buf [rv++] = ' ';
618  rv += print_subexpression (expr -> data.substring.len,
619  buf + rv, len - rv - 1);
620  buf [rv++] = ')';
621  buf [rv] = 0;
622  return rv;
623  }
624  break;
625 
626  case expr_suffix:
627  if (len > 10) {
628  rv = 8;
629  strcpy (buf, "(suffix ");
630  rv += print_subexpression (expr -> data.suffix.expr,
631  buf + rv, len - rv - 2);
632  if (len > rv)
633  buf [rv++] = ' ';
634  rv += print_subexpression (expr -> data.suffix.len,
635  buf + rv, len - rv - 1);
636  if (len > rv)
637  buf [rv++] = ')';
638  buf [rv] = 0;
639  return rv;
640  }
641  break;
642 
643  case expr_lcase:
644  if (len > 9) {
645  rv = 7;
646  strcpy(buf, "(lcase ");
647  rv += print_subexpression(expr->data.lcase,
648  buf + rv, len - rv - 1);
649  buf[rv++] = ')';
650  buf[rv] = 0;
651  return rv;
652  }
653  break;
654 
655  case expr_ucase:
656  if (len > 9) {
657  rv = 7;
658  strcpy(buf, "(ucase ");
659  rv += print_subexpression(expr->data.ucase,
660  buf + rv, len - rv - 1);
661  buf[rv++] = ')';
662  buf[rv] = 0;
663  return rv;
664  }
665  break;
666 
667  case expr_concat:
668  if (len > 10) {
669  rv = 8;
670  strcpy (buf, "(concat ");
671  rv += print_subexpression (expr -> data.concat [0],
672  buf + rv, len - rv - 2);
673  buf [rv++] = ' ';
674  rv += print_subexpression (expr -> data.concat [1],
675  buf + rv, len - rv - 1);
676  buf [rv++] = ')';
677  buf [rv] = 0;
678  return rv;
679  }
680  break;
681 
683  if (len > 8) {
684  rv = 6;
685  strcpy (buf, "(pick1st ");
686  rv += print_subexpression
687  (expr -> data.pick_first_value.car,
688  buf + rv, len - rv - 2);
689  buf [rv++] = ' ';
690  rv += print_subexpression
691  (expr -> data.pick_first_value.cdr,
692  buf + rv, len - rv - 1);
693  buf [rv++] = ')';
694  buf [rv] = 0;
695  return rv;
696  }
697  break;
698 
699  case expr_host_lookup:
700  rv = 15 + strlen (expr -> data.host_lookup -> hostname);
701  if (len > rv) {
702  sprintf (buf, "(dns-lookup %s)",
703  expr -> data.host_lookup -> hostname);
704  return rv;
705  }
706  break;
707 
708  case expr_and:
709  s = "and";
710  binop:
711  rv = strlen (s);
712  if (len > rv + 4) {
713  buf [0] = '(';
714  strcpy (&buf [1], s);
715  rv += 1;
716  buf [rv++] = ' ';
717  rv += print_subexpression (expr -> data.and [0],
718  buf + rv, len - rv - 2);
719  buf [rv++] = ' ';
720  rv += print_subexpression (expr -> data.and [1],
721  buf + rv, len - rv - 1);
722  buf [rv++] = ')';
723  buf [rv] = 0;
724  return rv;
725  }
726  break;
727 
728  case expr_or:
729  s = "or";
730  goto binop;
731 
732  case expr_add:
733  s = "+";
734  goto binop;
735 
736  case expr_subtract:
737  s = "-";
738  goto binop;
739 
740  case expr_multiply:
741  s = "*";
742  goto binop;
743 
744  case expr_divide:
745  s = "/";
746  goto binop;
747 
748  case expr_remainder:
749  s = "%";
750  goto binop;
751 
752  case expr_binary_and:
753  s = "&";
754  goto binop;
755 
756  case expr_binary_or:
757  s = "|";
758  goto binop;
759 
760  case expr_binary_xor:
761  s = "^";
762  goto binop;
763 
764  case expr_not:
765  if (len > 6) {
766  rv = 5;
767  strcpy (buf, "(not ");
768  rv += print_subexpression (expr -> data.not,
769  buf + rv, len - rv - 1);
770  buf [rv++] = ')';
771  buf [rv] = 0;
772  return rv;
773  }
774  break;
775 
776  case expr_config_option:
777  s = "cfg-option";
778  goto dooption;
779 
780  case expr_option:
781  s = "option";
782  dooption:
783  rv = strlen (s) + 2 + (strlen (expr -> data.option -> name) +
784  strlen (expr -> data.option -> universe -> name));
785  if (len > rv) {
786  sprintf (buf, "(option %s.%s)",
787  expr -> data.option -> universe -> name,
788  expr -> data.option -> name);
789  return rv;
790  }
791  break;
792 
793  case expr_hardware:
794  if (len > 10) {
795  strcpy (buf, "(hardware)");
796  return 10;
797  }
798  break;
799 
800  case expr_packet:
801  if (len > 10) {
802  rv = 8;
803  strcpy (buf, "(substr ");
804  rv += print_subexpression (expr -> data.packet.offset,
805  buf + rv, len - rv - 2);
806  buf [rv++] = ' ';
807  rv += print_subexpression (expr -> data.packet.len,
808  buf + rv, len - rv - 1);
809  buf [rv++] = ')';
810  buf [rv] = 0;
811  return rv;
812  }
813  break;
814 
815  case expr_const_data:
816  s = print_hex_1 (expr -> data.const_data.len,
817  expr -> data.const_data.data, len);
818  rv = strlen (s);
819  if (rv >= len)
820  rv = len - 1;
821  strncpy (buf, s, rv);
822  buf [rv] = 0;
823  return rv;
824 
825  case expr_encapsulate:
826  rv = 13;
827  strcpy (buf, "(encapsulate ");
828  rv += expr -> data.encapsulate.len;
829  if (rv + 2 > len)
830  rv = len - 2;
831  strncpy (buf,
832  (const char *)expr -> data.encapsulate.data, rv - 13);
833  buf [rv++] = ')';
834  buf [rv++] = 0;
835  break;
836 
837  case expr_extract_int8:
838  if (len > 7) {
839  rv = 6;
840  strcpy (buf, "(int8 ");
841  rv += print_subexpression (expr -> data.extract_int,
842  buf + rv, len - rv - 1);
843  buf [rv++] = ')';
844  buf [rv] = 0;
845  return rv;
846  }
847  break;
848 
849  case expr_extract_int16:
850  if (len > 8) {
851  rv = 7;
852  strcpy (buf, "(int16 ");
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_int32:
862  if (len > 8) {
863  rv = 7;
864  strcpy (buf, "(int32 ");
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_encode_int8:
874  if (len > 7) {
875  rv = 6;
876  strcpy (buf, "(to-int8 ");
877  rv += print_subexpression (expr -> data.encode_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_int16:
886  if (len > 8) {
887  rv = 7;
888  strcpy (buf, "(to-int16 ");
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_int32:
898  if (len > 8) {
899  rv = 7;
900  strcpy (buf, "(to-int32 ");
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_const_int:
910  s = print_dec_1 (expr -> data.const_int);
911  rv = strlen (s);
912  if (len > rv) {
913  strcpy (buf, s);
914  return rv;
915  }
916  break;
917 
918  case expr_exists:
919  rv = 10 + (strlen (expr -> data.option -> name) +
920  strlen (expr -> data.option -> universe -> name));
921  if (len > rv) {
922  sprintf (buf, "(exists %s.%s)",
923  expr -> data.option -> universe -> name,
924  expr -> data.option -> name);
925  return rv;
926  }
927  break;
928 
930  rv = 10 + strlen (expr -> data.variable);
931  if (len > rv) {
932  sprintf (buf, "(defined %s)", expr -> data.variable);
933  return rv;
934  }
935  break;
936 
938  rv = strlen (expr -> data.variable);
939  if (len > rv) {
940  sprintf (buf, "%s", expr -> data.variable);
941  return rv;
942  }
943  break;
944 
945  case expr_known:
946  s = "known";
947  astring:
948  rv = strlen (s);
949  if (len > rv) {
950  strcpy (buf, s);
951  return rv;
952  }
953  break;
954 
955  case expr_leased_address:
956  s = "leased-address";
957  goto astring;
958 
959  case expr_client_state:
960  s = "client-state";
961  goto astring;
962 
963  case expr_host_decl_name:
964  s = "host-decl-name";
965  goto astring;
966 
967  case expr_lease_time:
968  s = "lease-time";
969  goto astring;
970 
971  case expr_static:
972  s = "static";
973  goto astring;
974 
975  case expr_filename:
976  s = "filename";
977  goto astring;
978 
979  case expr_sname:
980  s = "server-name";
981  goto astring;
982 
983  case expr_reverse:
984  if (len > 11) {
985  rv = 13;
986  strcpy (buf, "(reverse ");
987  rv += print_subexpression (expr -> data.reverse.width,
988  buf + rv, len - rv - 2);
989  buf [rv++] = ' ';
990  rv += print_subexpression (expr -> data.reverse.buffer,
991  buf + rv, len - rv - 1);
992  buf [rv++] = ')';
993  buf [rv] = 0;
994  return rv;
995  }
996  break;
997 
999  if (len > 5) {
1000  rv = 9;
1001  strcpy (buf, "(b2a ");
1002  rv += print_subexpression (expr -> data.b2a.base,
1003  buf + rv, len - rv - 4);
1004  buf [rv++] = ' ';
1005  rv += print_subexpression (expr -> data.b2a.width,
1006  buf + rv, len - rv - 3);
1007  buf [rv++] = ' ';
1008  rv += print_subexpression (expr -> data.b2a.separator,
1009  buf + rv, len - rv - 2);
1010  buf [rv++] = ' ';
1011  rv += print_subexpression (expr -> data.b2a.buffer,
1012  buf + rv, len - rv - 1);
1013  buf [rv++] = ')';
1014  buf [rv] = 0;
1015  return rv;
1016  }
1017  break;
1018 
1019  case expr_dns_transaction:
1020  rv = 10;
1021  if (len < rv + 2) {
1022  buf [0] = '(';
1023  strcpy (&buf [1], "ns-update ");
1024  while (len < rv + 2) {
1025  rv += print_subexpression
1026  (expr -> data.dns_transaction.car,
1027  buf + rv, len - rv - 2);
1028  buf [rv++] = ' ';
1029  expr = expr -> data.dns_transaction.cdr;
1030  }
1031  buf [rv - 1] = ')';
1032  buf [rv] = 0;
1033  return rv;
1034  }
1035  return 0;
1036 
1037  case expr_ns_delete:
1038  s = "delete";
1039  left = 4;
1040  goto dodnsupd;
1041  case expr_ns_exists:
1042  s = "exists";
1043  left = 4;
1044  goto dodnsupd;
1045  case expr_ns_not_exists:
1046  s = "not_exists";
1047  left = 4;
1048  goto dodnsupd;
1049  case expr_ns_add:
1050  s = "update";
1051  left = 5;
1052  dodnsupd:
1053  rv = strlen (s);
1054  if (len > strlen (s) + 1) {
1055  buf [0] = '(';
1056  strcpy (buf + 1, s);
1057  rv++;
1058  buf [rv++] = ' ';
1059  s = print_dec_1 (expr -> data.ns_add.rrclass);
1060  if (len > rv + strlen (s) + left) {
1061  strcpy (&buf [rv], s);
1062  rv += strlen (&buf [rv]);
1063  }
1064  buf [rv++] = ' ';
1065  left--;
1066  s = print_dec_1 (expr -> data.ns_add.rrtype);
1067  if (len > rv + strlen (s) + left) {
1068  strcpy (&buf [rv], s);
1069  rv += strlen (&buf [rv]);
1070  }
1071  buf [rv++] = ' ';
1072  left--;
1073  rv += print_subexpression
1074  (expr -> data.ns_add.rrname,
1075  buf + rv, len - rv - left);
1076  buf [rv++] = ' ';
1077  left--;
1078  rv += print_subexpression
1079  (expr -> data.ns_add.rrdata,
1080  buf + rv, len - rv - left);
1081  buf [rv++] = ' ';
1082  left--;
1083  rv += print_subexpression
1084  (expr -> data.ns_add.ttl,
1085  buf + rv, len - rv - left);
1086  buf [rv++] = ')';
1087  buf [rv] = 0;
1088  return rv;
1089  }
1090  break;
1091 
1092  case expr_null:
1093  if (len > 6) {
1094  strcpy (buf, "(null)");
1095  return 6;
1096  }
1097  break;
1098  case expr_funcall:
1099  rv = 12 + strlen (expr -> data.funcall.name);
1100  if (len > rv + 1) {
1101  strcpy (buf, "(funcall ");
1102  strcpy (buf + 9, expr -> data.funcall.name);
1103  buf [rv++] = ' ';
1104  rv += print_subexpression
1105  (expr -> data.funcall.arglist, buf + rv,
1106  len - rv - 1);
1107  buf [rv++] = ')';
1108  buf [rv] = 0;
1109  return rv;
1110  }
1111  break;
1112 
1113  case expr_arg:
1114  rv = print_subexpression (expr -> data.arg.val, buf, len);
1115  if (expr -> data.arg.next && rv + 2 < len) {
1116  buf [rv++] = ' ';
1117  rv += print_subexpression (expr -> data.arg.next,
1118  buf, len);
1119  if (rv + 1 < len)
1120  buf [rv++] = 0;
1121  return rv;
1122  }
1123  break;
1124 
1125  case expr_function:
1126  rv = 9;
1127  if (len > rv + 1) {
1128  struct string_list *foo;
1129  strcpy (buf, "(function");
1130  for (foo = expr -> data.func -> args;
1131  foo; foo = foo -> next) {
1132  if (len > rv + 2 + strlen (foo -> string)) {
1133  buf [rv - 1] = ' ';
1134  strcpy (&buf [rv], foo -> string);
1135  rv += strlen (foo -> string);
1136  }
1137  }
1138  buf [rv++] = ')';
1139  buf [rv] = 0;
1140  return rv;
1141  }
1142  break;
1143 
1144  case expr_gethostname:
1145  if (len > 13) {
1146  strcpy(buf, "(gethostname)");
1147  return 13;
1148  }
1149  break;
1150 
1151  default:
1152  log_fatal("Impossible case at %s:%d (undefined expression "
1153  "%d).", MDL, expr->op);
1154  break;
1155  }
1156  return 0;
1157 }
1158 
1159 void print_expression (name, expr)
1160  const char *name;
1161  struct expression *expr;
1162 {
1163  char buf [1024];
1164 
1165  print_subexpression (expr, buf, sizeof buf);
1166  log_info ("%s: %s", name, buf);
1167 }
1168 
1169 int token_print_indent_concat (FILE *file, int col, int indent,
1170  const char *prefix,
1171  const char *suffix, ...)
1172 {
1173  va_list list;
1174  unsigned len;
1175  char *s, *t, *u;
1176 
1177  va_start (list, suffix);
1178  s = va_arg (list, char *);
1179  len = 0;
1180  while (s) {
1181  len += strlen (s);
1182  s = va_arg (list, char *);
1183  }
1184  va_end (list);
1185 
1186  t = dmalloc (len + 1, MDL);
1187  if (!t)
1188  log_fatal ("token_print_indent: no memory for copy buffer");
1189 
1190  va_start (list, suffix);
1191  s = va_arg (list, char *);
1192  u = t;
1193  while (s) {
1194  len = strlen (s);
1195  strcpy (u, s);
1196  u += len;
1197  s = va_arg (list, char *);
1198  }
1199  va_end (list);
1200 
1201  col = token_print_indent (file, col, indent,
1202  prefix, suffix, t);
1203  dfree (t, MDL);
1204  return col;
1205 }
1206 
1207 int token_indent_data_string (FILE *file, int col, int indent,
1208  const char *prefix, const char *suffix,
1209  struct data_string *data)
1210 {
1211  int i;
1212  char *buf;
1213  char obuf [3];
1214 
1215  /* See if this is just ASCII. */
1216  for (i = 0; i < data -> len; i++)
1217  if (!isascii (data -> data [i]) ||
1218  !isprint (data -> data [i]))
1219  break;
1220 
1221  /* If we have a purely ASCII string, output it as text. */
1222  if (i == data -> len) {
1223  buf = dmalloc (data -> len + 3, MDL);
1224  if (buf) {
1225  buf [0] = '"';
1226  memcpy (buf + 1, data -> data, data -> len);
1227  buf [data -> len + 1] = '"';
1228  buf [data -> len + 2] = 0;
1229  i = token_print_indent (file, col, indent,
1230  prefix, suffix, buf);
1231  dfree (buf, MDL);
1232  return i;
1233  }
1234  }
1235 
1236  for (i = 0; i < data -> len; i++) {
1237  sprintf (obuf, "%2.2x", data -> data [i]);
1238  col = token_print_indent (file, col, indent,
1239  i == 0 ? prefix : "",
1240  (i + 1 == data -> len
1241  ? suffix
1242  : ""), obuf);
1243  if (i + 1 != data -> len)
1244  col = token_print_indent (file, col, indent,
1245  prefix, suffix, ":");
1246  }
1247  return col;
1248 }
1249 
1250 int token_print_indent (FILE *file, int col, int indent,
1251  const char *prefix,
1252  const char *suffix, const char *buf)
1253 {
1254  int len = 0;
1255  if (prefix != NULL)
1256  len += strlen (prefix);
1257  if (buf != NULL)
1258  len += strlen (buf);
1259 
1260  if (col + len > 79) {
1261  if (indent + len < 79) {
1262  indent_spaces (file, indent);
1263  col = indent;
1264  } else {
1265  indent_spaces (file, col);
1266  col = len > 79 ? 0 : 79 - len - 1;
1267  }
1268  } else if (prefix && *prefix) {
1269  fputs (prefix, file);
1270  col += strlen (prefix);
1271  }
1272  if ((buf != NULL) && (*buf != 0)) {
1273  fputs (buf, file);
1274  col += strlen(buf);
1275  }
1276  if (suffix && *suffix) {
1277  if (col + strlen (suffix) > 79) {
1278  indent_spaces (file, indent);
1279  col = indent;
1280  } else {
1281  fputs (suffix, file);
1282  col += strlen (suffix);
1283  }
1284  }
1285  return col;
1286 }
1287 
1288 void indent_spaces (FILE *file, int indent)
1289 {
1290  int i;
1291  fputc ('\n', file);
1292  for (i = 0; i < indent; i++)
1293  fputc (' ', file);
1294 }
1295 
1296 #if defined (NSUPDATE)
1297 #if defined (DEBUG_DNS_UPDATES)
1298 /*
1299  * direction outbound (messages to the dns server)
1300  * inbound (messages from the dns server)
1301  * ddns_cb is the control block associated with the message
1302  * result is the result from the dns code. For outbound calls
1303  * it is from the call to pass the message to the dns library.
1304  * For inbound calls it is from the event returned by the library.
1305  *
1306  * For outbound messages we print whatever we think is interesting
1307  * from the control block.
1308  * For inbound messages we only print the transaction id pointer
1309  * and the result and expect that the user will match them up as
1310  * necessary. Note well: the transaction information is opaque to
1311  * us so we simply print the pointer to it. This should be sufficient
1312  * to match requests and replys in a short sequence but is awkward
1313  * when trying to use it for longer sequences.
1314  */
1315 void
1316 print_dns_status (int direction,
1317  struct dhcp_ddns_cb *ddns_cb,
1318  isc_result_t result)
1319 {
1320  char obuf[1024];
1321  char *s = obuf, *end = &obuf[sizeof(obuf)-2];
1322  char *en;
1323  const char *result_str;
1324  char ddns_address[
1325  sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
1326 
1327  if (direction == DDNS_PRINT_INBOUND) {
1328  log_info("DDNS reply: id ptr %p, result: %s",
1329  ddns_cb->transaction, isc_result_totext(result));
1330  return;
1331  }
1332 
1333  /*
1334  * To avoid having to figure out if any of the strings
1335  * aren't NULL terminated, just 0 the whole string
1336  */
1337  memset(obuf, 0, 1024);
1338 
1339  en = "DDNS request: id ptr ";
1340  if (s + strlen(en) + 16 < end) {
1341  sprintf(s, "%s%p", en, ddns_cb->transaction);
1342  s += strlen(s);
1343  } else {
1344  goto bailout;
1345  }
1346 
1347  switch (ddns_cb->state) {
1349  en = " add forward ";
1350  break;
1352  en = " modify forward ";
1353  break;
1354 
1355  case DDNS_STATE_ADD_PTR:
1356  en = " add reverse ";
1357  break;
1358 
1360  en = " remove forward ";
1361  break;
1362 
1364  en = " remove rrset ";
1365  break;
1366 
1367  case DDNS_STATE_REM_PTR:
1368  en = " remove reverse ";
1369  break;
1370 
1371  case DDNS_STATE_CLEANUP:
1372  en = " cleanup ";
1373  break;
1374 
1375  default:
1376  en = " unknown state ";
1377  break;
1378  }
1379 
1380  switch (ddns_cb->state) {
1385  strcpy(ddns_address, piaddr(ddns_cb->address));
1386  if (s + strlen(en) + strlen(ddns_address) +
1387  ddns_cb->fwd_name.len + 5 < end) {
1388  sprintf(s, "%s%s for %.*s", en, ddns_address,
1389  ddns_cb->fwd_name.len,
1390  ddns_cb->fwd_name.data);
1391  s += strlen(s);
1392  } else {
1393  goto bailout;
1394  }
1395  break;
1396 
1397  case DDNS_STATE_ADD_PTR:
1398  case DDNS_STATE_REM_PTR:
1399  if (s + strlen(en) + ddns_cb->fwd_name.len +
1400  ddns_cb->rev_name.len + 5 < end) {
1401  sprintf(s, "%s%.*s for %.*s", en,
1402  ddns_cb->fwd_name.len,
1403  ddns_cb->fwd_name.data,
1404  ddns_cb->rev_name.len,
1405  ddns_cb->rev_name.data);
1406  s += strlen(s);
1407  } else {
1408  goto bailout;
1409  }
1410  break;
1411 
1412  case DDNS_STATE_CLEANUP:
1413  default:
1414  if (s + strlen(en) < end) {
1415  sprintf(s, "%s", en);
1416  s += strlen(s);
1417  } else {
1418  goto bailout;
1419  }
1420  break;
1421  }
1422 
1423  en = " zone: ";
1424  if (s + strlen(en) + strlen((char *)ddns_cb->zone_name) < end) {
1425  sprintf(s, "%s%s", en, ddns_cb->zone_name);
1426  s += strlen(s);
1427  } else {
1428  goto bailout;
1429  }
1430 
1431  en = " dhcid: ";
1432  if (ddns_cb->dhcid.len > 0) {
1433  if (s + strlen(en) + ddns_cb->dhcid.len-1 < end) {
1434  strcpy(s, en);
1435  s += strlen(s);
1436  strncpy(s, (char *)ddns_cb->dhcid.data+1,
1437  ddns_cb->dhcid.len-1);
1438  s += strlen(s);
1439  } else {
1440  goto bailout;
1441  }
1442  } else {
1443  en = " dhcid: <empty>";
1444  if (s + strlen(en) < end) {
1445  strcpy(s, en);
1446  s += strlen(s);
1447  } else {
1448  goto bailout;
1449  }
1450  }
1451 
1452  en = " ttl: ";
1453  if (s + strlen(en) + 10 < end) {
1454  sprintf(s, "%s%ld", en, ddns_cb->ttl);
1455  s += strlen(s);
1456  } else {
1457  goto bailout;
1458  }
1459 
1460  en = " result: ";
1461  result_str = isc_result_totext(result);
1462  if (s + strlen(en) + strlen(result_str) < end) {
1463  sprintf(s, "%s%s", en, result_str);
1464  s += strlen(s);
1465  } else {
1466  goto bailout;
1467  }
1468 
1469  bailout:
1470  /*
1471  * We either finished building the string or ran out
1472  * of space, print whatever we have in case it is useful
1473  */
1474  log_info("%s", obuf);
1475 
1476  return;
1477 }
1478 #endif
1479 #endif /* NSUPDATE */
1480 
1481 /* Format the given time as "A; # B", where A is the format
1482  * used by the parser, and B is the local time, for humans.
1483  */
1484 const char *
1486 {
1487  static char buf[sizeof("epoch 9223372036854775807; "
1488  "# Wed Jun 30 21:49:08 2147483647")];
1489  static char buf1[sizeof("# Wed Jun 30 21:49:08 2147483647")];
1490  time_t since_epoch;
1491  /* The string: "6 2147483647/12/31 23:59:60;"
1492  * is smaller than the other, used to declare the buffer size, so
1493  * we can use one buffer for both.
1494  */
1495 
1496  if (t == MAX_TIME)
1497  return "never;";
1498 
1499  if (t < 0)
1500  return NULL;
1501 
1502  /* For those lucky enough to have a 128-bit time_t, ensure that
1503  * whatever (corrupt) value we're given doesn't exceed the static
1504  * buffer.
1505  */
1506 #if (MAX_TIME > 0x7fffffffffffffff)
1507  if (t > 0x7fffffffffffffff)
1508  return NULL;
1509 #endif
1510 
1512  since_epoch = mktime(localtime(&t));
1513  if ((strftime(buf1, sizeof(buf1),
1514  "# %a %b %d %H:%M:%S %Y",
1515  localtime(&t)) == 0) ||
1516  (snprintf(buf, sizeof(buf), "epoch %lu; %s",
1517  (unsigned long)since_epoch, buf1) >= sizeof(buf)))
1518  return NULL;
1519 
1520  } else {
1521  /* No bounds check for the year is necessary - in this case,
1522  * strftime() will run out of space and assert an error.
1523  */
1524  if (strftime(buf, sizeof(buf), "%w %Y/%m/%d %H:%M:%S;",
1525  gmtime(&t)) == 0)
1526  return NULL;
1527  }
1528 
1529  return buf;
1530 }
1531 
1532 /* !brief Return the given data as a string of hex digits "xx:xx:xx ..."
1533  *
1534  * Converts the given data into a null-terminated, string of hex digits,
1535  * stored in an allocated buffer. It is the caller's responsiblity to free
1536  * the buffer.
1537  *
1538  * \param s - pointer to the data to convert
1539  * \param len - length of the data to convert
1540  * \param file - source file of invocation
1541  * \param line - line number of invocation
1542  *
1543  * \return Returns an allocated buffer containing the hex string
1544 */
1545 char *buf_to_hex (const unsigned char *s, unsigned len,
1546  const char *file, int line)
1547 {
1548  unsigned nulen = 0;
1549  char *buf;
1550 
1551  /* If somebody hands us length of zero, we'll give them
1552  * back an empty string */
1553  if (!len) {
1554  buf = dmalloc (1, MDL);
1555  if (buf) {
1556  *buf = 0x0;
1557  }
1558 
1559  return (buf);
1560  }
1561 
1562 
1563  /* Figure out how big it needs to be. print_to_hex uses
1564  * "%02x:" per character. Note since there's no trailing colon
1565  * we'll have room for the null */
1566  nulen = (len * 3);
1567 
1568  /* Allocate our buffer */
1569  buf = dmalloc (nulen, MDL);
1570 
1571  /* Hex-ify it */
1572  if (buf) {
1573  print_hex_only (len, s, nulen, buf);
1574  }
1575 
1576  return buf;
1577 }
1578 
1579 /* !brief Formats data into a string based on a lease id format
1580  *
1581  * Takes the given data and returns an allocated string whose contents are
1582  * the string version of that data, formatted according to the output lease
1583  * id format. Note it is the caller's responsiblity to delete the string.
1584  *
1585  * Currently two formats are supported:
1586  *
1587  * OCTAL - Default or "legacy" CSL format enclosed in quotes '"'.
1588  *
1589  * HEX - Bytes represented as string colon seperated of hex digit pairs
1590  * (xx:xx:xx...)
1591  *
1592  * \param s - data to convert
1593  * \param len - length of the data to convert
1594  * \param format - desired format of the result
1595  * \param file - source file of invocation
1596  * \param line - line number of invocation
1597  *
1598  * \return A pointer to the allocated, null-terminated string
1599 */
1600 char *format_lease_id(const unsigned char *s, unsigned len,
1601  int format, const char *file, int line) {
1602  char *idstr = NULL;
1603 
1604  switch (format) {
1605  case TOKEN_HEX:
1606  idstr = buf_to_hex(s, len, MDL);
1607  break;
1608  case TOKEN_OCTAL:
1609  default:
1610  idstr = quotify_buf(s, len, '"', MDL);
1611  break;
1612  }
1613  return (idstr);
1614 }
enum expr_op op
Definition: tree.h:200
const char int line
Definition: dhcpd.h:3717
char sname[DHCP_SNAME_LEN]
Definition: dhcp.h:61
#define DDNS_PRINT_INBOUND
Definition: dhcpd.h:1758
struct binding_scope * global_scope
Definition: tree.c:38
unsigned char zone_name[DHCP_MAXDNS_WIRE]
Definition: dhcpd.h:1775
Definition: tree.h:142
Definition: dhcpd.h:556
unsigned len
Definition: tree.h:80
struct expression * val
Definition: tree.h:270
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
#define DDNS_STATE_ADD_FW_NXDOMAIN
Definition: dhcpd.h:1747
struct expression::expr_union::@25 arg
struct expression * equal[2]
Definition: tree.h:207
struct hash_bucket * next
Definition: hash.h:51
struct data_string encapsulate
Definition: tree.h:236
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
struct expression::expr_union::@21 pick_first_value
u_int16_t secs
Definition: dhcp.h:54
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:63
#define MDL
Definition: omapip.h:568
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2568
#define DDNS_STATE_REM_PTR
Definition: dhcpd.h:1753
u_int8_t hlen
Definition: dhcp.h:51
unsigned long const_int
Definition: tree.h:232
struct expression * lcase
Definition: tree.h:221
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
struct expression * arglist
Definition: tree.h:275
struct expression::expr_union::@16 substring
struct universe dhcp_universe
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:1676
struct expression * concat[2]
Definition: tree.h:233
Definition: tree.h:141
void print_dns_status(int, struct dhcp_ddns_cb *, isc_result_t)
struct expression * offset
Definition: tree.h:204
struct in_addr siaddr
Definition: dhcp.h:58
Definition: tree.h:177
void dump_packet(struct packet *)
#define DDNS_STATE_REM_FW_YXDHCID
Definition: dhcpd.h:1751
struct expression * rrdata
Definition: tree.h:259
struct data_string fwd_name
Definition: dhcpd.h:1767
struct expression * not
Definition: tree.h:210
u_int16_t flags
Definition: dhcp.h:55
#define LOCAL_TIME_FORMAT
Definition: dhcpd.h:2550
struct iaddr address
Definition: dhcpd.h:1770
unsigned long ttl
Definition: dhcpd.h:1773
Definition: tree.h:302
struct expression::expr_union::@17 suffix
void log_fatal(const char *,...) __attribute__((__format__(__printf__
unsigned len
Definition: hash.h:53
struct data_string dhcid
Definition: dhcpd.h:1769
struct data_string rev_name
Definition: dhcpd.h:1768
union expression::expr_union data
struct expression * encode_int
Definition: tree.h:231
u_int8_t htype
Definition: dhcp.h:50
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
Definition: tree.h:346
unsigned char chaddr[16]
Definition: dhcp.h:60
u_int32_t xid
Definition: dhcp.h:53
struct expression::expr_union::@20 reverse
struct expression * width
Definition: tree.h:239
#define DDNS_STATE_ADD_PTR
Definition: dhcpd.h:1749
struct expression::expr_union::@22 dns_transaction
Definition: dhcpd.h:405
struct expression * next
Definition: tree.h:271
struct expression * expr
Definition: tree.h:203
struct in_addr yiaddr
Definition: dhcp.h:57
struct in_addr giaddr
Definition: dhclient.c:74
void dfree(void *, const char *, int)
Definition: alloc.c:131
struct expression * buffer
Definition: tree.h:241
#define DEFAULT_TIME_FORMAT
Definition: dhcpd.h:2549
const unsigned char * name
Definition: hash.h:52
struct expression * and[2]
Definition: tree.h:208
struct expression * base
Definition: tree.h:238
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct expression::expr_union::@19 b2a
struct expression * extract_int
Definition: tree.h:230
struct option * option
Definition: tree.h:223
unsigned rrclass
Definition: tree.h:256
Definition: tree.h:143
struct universe ** universes
Definition: tables.c:963
struct data_string const_data
Definition: tree.h:229
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:3632
void indent(int)
struct expression * len
Definition: tree.h:205
unsigned rrtype
Definition: tree.h:257
struct string_list * next
Definition: dhcpd.h:348
time_t TIME
Definition: dhcpd.h:85
struct expression * ucase
Definition: tree.h:222
int state
Definition: dhcpd.h:1783
#define DDNS_STATE_ADD_FW_YXDHCID
Definition: dhcpd.h:1748
struct expression::expr_union::@23 ns_add
struct collection * check
Definition: tree.h:216
u_int8_t hops
Definition: dhcp.h:52
struct expression * ttl
Definition: tree.h:260
#define MAX_TIME
Definition: dhcpd.h:1591
void * transaction
Definition: dhcpd.h:1792
struct expression * cdr
Definition: tree.h:249
struct expression * rrname
Definition: tree.h:258
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 *)
struct dns_host_entry * host_lookup
Definition: tree.h:234
const char * file
Definition: dhcpd.h:3717
struct expression * car
Definition: tree.h:248
const unsigned char * data
Definition: tree.h:79
struct in_addr ciaddr
Definition: dhcp.h:56
struct expression::expr_union::@26 funcall
#define DDNS_STATE_CLEANUP
Definition: dhcpd.h:1745
#define DDNS_STATE_REM_FW_NXRR
Definition: dhcpd.h:1752
u_int8_t op
Definition: dhcp.h:49
struct expression::expr_union::@18 packet
int universe_count
Definition: tables.c:964
unsigned char options[DHCP_MAX_OPTION_LEN]
Definition: dhcp.h:63
struct expression * separator
Definition: tree.h:240
Definition: tree.h:180