ISC DHCP  4.3.2
A reference DHCPv4 and DHCPv6 implementation
protocol.c
Go to the documentation of this file.
1 /* protocol.c
2 
3  Functions supporting the object management protocol... */
4 
5 /*
6  * Copyright (c) 2009,2012,2014 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1999-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Internet Systems Consortium, Inc.
23  * 950 Charter Street
24  * Redwood City, CA 94063
25  * <info@isc.org>
26  * https://www.isc.org/
27  *
28  */
29 
30 #include "dhcpd.h"
31 
32 #include <omapip/omapip_p.h>
33 
38 
39 isc_result_t omapi_protocol_connect (omapi_object_t *h,
40  const char *server_name,
41  unsigned port,
42  omapi_object_t *a)
43 {
44  isc_result_t rstatus, status;
46 
47 #ifdef DEBUG_PROTOCOL
48  log_debug ("omapi_protocol_connect(%s port=%d)", server_name, port);
49 #endif
50 
51  obj = (omapi_protocol_object_t *)0;
52  status = omapi_protocol_allocate (&obj, MDL);
53  if (status != ISC_R_SUCCESS)
54  return status;
55 
56  rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port);
57  if (rstatus != ISC_R_SUCCESS && rstatus != DHCP_R_INCOMPLETE) {
58  omapi_protocol_dereference (&obj, MDL);
59  return rstatus;
60  }
61  status = omapi_object_reference (&h -> outer,
62  (omapi_object_t *)obj, MDL);
63  if (status != ISC_R_SUCCESS) {
64  omapi_protocol_dereference (&obj, MDL);
65  return status;
66  }
67  status = omapi_object_reference (&obj -> inner, h, MDL);
68  if (status != ISC_R_SUCCESS) {
69  omapi_protocol_dereference (&obj, MDL);
70  return status;
71  }
72 
73  /* If we were passed a default authenticator, store it now. We'll
74  open it once we're connected. */
75  if (a) {
76  obj -> default_auth =
77  dmalloc (sizeof(omapi_remote_auth_t), MDL);
78  if (!obj -> default_auth) {
79  omapi_protocol_dereference (&obj, MDL);
80  return ISC_R_NOMEMORY;
81  }
82 
83  obj -> default_auth -> next = (omapi_remote_auth_t *)0;
84  status = omapi_object_reference (&obj -> default_auth -> a,
85  a, MDL);
86  if (status != ISC_R_SUCCESS) {
87  dfree (obj -> default_auth, MDL);
88  omapi_protocol_dereference (&obj, MDL);
89  return status;
90  }
91 
92  obj -> insecure = 0;
93  rstatus = DHCP_R_INCOMPLETE;
94  } else {
95  obj -> insecure = 1;
96 #if 0
97  status = ISC_R_SUCCESS;
98 #endif
99  }
100 
101  omapi_protocol_dereference (&obj, MDL);
102  return rstatus;
103 }
104 
105 /* Send the protocol introduction message. */
107  unsigned ver,
108  unsigned hsize)
109 {
110  isc_result_t status;
112 
113 #ifdef DEBUG_PROTOCOL
114  log_debug ("omapi_protocol_send_intro()");
115 #endif
116 
117  if (h -> type != omapi_type_protocol)
118  return DHCP_R_INVALIDARG;
119  p = (omapi_protocol_object_t *)h;
120 
121  if (!h -> outer || h -> outer -> type != omapi_type_connection)
122  return ISC_R_NOTCONNECTED;
123 
124  status = omapi_connection_put_uint32 (h -> outer, ver);
125  if (status != ISC_R_SUCCESS)
126  return status;
127 
128  status = omapi_connection_put_uint32 (h -> outer, hsize);
129 
130  if (status != ISC_R_SUCCESS)
131  return status;
132 
133  /* Require the other end to send an intro - this kicks off the
134  protocol input state machine. */
135  p -> state = omapi_protocol_intro_wait;
136  status = omapi_connection_require (h -> outer, 8);
137  if (status != ISC_R_SUCCESS && status != DHCP_R_NOTYET)
138  return status;
139 
140  /* Make up an initial transaction ID for this connection. */
141  p -> next_xid = random ();
142  return ISC_R_SUCCESS;
143 }
144 
145 #ifdef DEBUG_PROTOCOL
146 extern const char *omapi_message_op_name(int);
147 #endif /* DEBUG_PROTOCOL */
148 
150  omapi_object_t *id,
151  omapi_object_t *mo,
152  omapi_object_t *omo)
153 {
155  omapi_object_t *c;
156  omapi_message_object_t *m, *om;
158  omapi_value_t *signature;
159  isc_result_t status;
160  unsigned auth_len;
161 
162  if (po -> type != omapi_type_protocol ||
163  !po -> outer || po -> outer -> type != omapi_type_connection ||
164  mo -> type != omapi_type_message)
165  return DHCP_R_INVALIDARG;
166  if (omo && omo -> type != omapi_type_message)
167  return DHCP_R_INVALIDARG;
168  p = (omapi_protocol_object_t *)po;
169  c = (omapi_object_t *)(po -> outer);
170  m = (omapi_message_object_t *)mo;
171  om = (omapi_message_object_t *)omo;
172 
173 #ifdef DEBUG_PROTOCOL
174  log_debug ("omapi_protocol_send_message(): "
175  "op=%s handle=%#lx id=%#lx rid=%#lx",
176  omapi_message_op_name (m->op),
177  (long)(m -> object ? m -> object -> handle : m -> handle),
178  (long)p -> next_xid, (long)m -> rid);
179 #endif
180 
181  /* Find the authid to use for this message. */
182  if (id) {
183  for (ra = p -> remote_auth_list; ra; ra = ra -> next) {
184  if (ra -> a == id) {
185  break;
186  }
187  }
188 
189  if (!ra)
190  return DHCP_R_KEY_UNKNOWN;
191  } else if (p -> remote_auth_list) {
192  ra = p -> default_auth;
193  } else {
194  ra = (omapi_remote_auth_t *)0;
195  }
196 
197  if (ra) {
198  m -> authid = ra -> remote_handle;
199  status = omapi_object_reference (&m -> id_object,
200  ra -> a, MDL);
201  if (status != ISC_R_SUCCESS)
202  return status;
203  }
204 
205  /* Write the ID of the authentication key we're using. */
206  status = omapi_connection_put_uint32 (c, ra ? ra -> remote_handle : 0);
207  if (status != ISC_R_SUCCESS) {
208  omapi_disconnect (c, 1);
209  return status;
210  }
211 
212  /* Activate the authentication key on the connection. */
213  auth_len = 0;
214  if (ra) {
215  status = omapi_set_object_value (c, (omapi_object_t *)0,
216  "output-authenticator",
217  ra -> a);
218  if (status != ISC_R_SUCCESS) {
219  omapi_disconnect (c, 1);
220  return status;
221  }
222 
223  status = omapi_connection_output_auth_length (c, &auth_len);
224  if (status != ISC_R_SUCCESS) {
225  omapi_disconnect (c, 1);
226  return status;
227  }
228  }
229 
230  /* Write the authenticator length */
231  status = omapi_connection_put_uint32 (c, auth_len);
232  if (status != ISC_R_SUCCESS) {
233  omapi_disconnect (c, 1);
234  return status;
235  }
236 
237  /* Write the opcode. */
238  status = omapi_connection_put_uint32 (c, m -> op);
239  if (status != ISC_R_SUCCESS) {
240  omapi_disconnect (c, 1);
241  return status;
242  }
243 
244  /* Write the handle. If we've been given an explicit handle, use
245  that. Otherwise, use the handle of the object we're sending.
246  The caller is responsible for arranging for one of these handles
247  to be set (or not). */
248  status = omapi_connection_put_uint32 (c, (m -> h
249  ? m -> h
250  : (m -> object
251  ? m -> object -> handle
252  : 0)));
253  if (status != ISC_R_SUCCESS) {
254  omapi_disconnect (c, 1);
255  return status;
256  }
257 
258  /* Set and write the transaction ID. */
259  m -> id = p -> next_xid++;
260  status = omapi_connection_put_uint32 (c, m -> id);
261  if (status != ISC_R_SUCCESS) {
262  omapi_disconnect (c, 1);
263  return status;
264  }
265 
266  /* Write the transaction ID of the message to which this is a
267  response, if there is such a message. */
268  status = omapi_connection_put_uint32 (c, om ? om -> id : m -> rid);
269  if (status != ISC_R_SUCCESS) {
270  omapi_disconnect (c, 1);
271  return status;
272  }
273 
274  /* Stuff out the name/value pairs specific to this message. */
275  status = omapi_stuff_values (c, id, (omapi_object_t *)m);
276  if (status != ISC_R_SUCCESS) {
277  omapi_disconnect (c, 1);
278  return status;
279  }
280 
281  /* Write the zero-length name that terminates the list of name/value
282  pairs specific to the message. */
283  status = omapi_connection_put_uint16 (c, 0);
284  if (status != ISC_R_SUCCESS) {
285  omapi_disconnect (c, 1);
286  return status;
287  }
288 
289  /* Stuff out all the published name/value pairs in the object that's
290  being sent in the message, if there is one. */
291  if (m -> object) {
292  status = omapi_stuff_values (c, id, m -> object);
293  if (status != ISC_R_SUCCESS) {
294  omapi_disconnect (c, 1);
295  return status;
296  }
297  }
298 
299  /* Write the zero-length name that terminates the list of name/value
300  pairs for the associated object. */
301  status = omapi_connection_put_uint16 (c, 0);
302  if (status != ISC_R_SUCCESS) {
303  omapi_disconnect (c, 1);
304  return status;
305  }
306 
307  if (ra) {
308  /* Calculate the message signature. */
309  signature = (omapi_value_t *)0;
310  status = omapi_get_value_str (c, (omapi_object_t *)0,
311  "output-signature", &signature);
312  if (status != ISC_R_SUCCESS) {
313  omapi_disconnect (c, 1);
314  return status;
315  }
316 
317  /* Write the authenticator... */
318  status = (omapi_connection_copyin
319  (c, signature -> value -> u.buffer.value,
320  signature -> value -> u.buffer.len));
321  omapi_value_dereference (&signature, MDL);
322  if (status != ISC_R_SUCCESS) {
323  omapi_disconnect (c, 1);
324  return status;
325  }
326 
327  /* Dectivate the authentication key on the connection. */
328  status = omapi_set_value_str (c, (omapi_object_t *)0,
329  "output-authenticator",
330  (omapi_typed_data_t *)0);
331  if (status != ISC_R_SUCCESS) {
332  omapi_disconnect (c, 1);
333  return status;
334  }
335  }
336 
337  if (!omo) {
338  omapi_protocol_reference (&m -> protocol_object, p, MDL);
339  }
340  return ISC_R_SUCCESS;
341 }
342 
343 
345  const char *name, va_list ap)
346 {
347  isc_result_t status;
349  omapi_object_t *c;
351  omapi_value_t *signature = NULL;
352  u_int16_t nlen;
353  u_int32_t vlen;
354  u_int32_t th;
355 #if defined (DEBUG_MEMORY_LEAKAGE)
356  unsigned long previous_outstanding = 0xDEADBEEF;
357  unsigned long connect_outstanding = 0xDEADBEEF;
358 #endif
359 
360  if (h -> type != omapi_type_protocol) {
361  /* XXX shouldn't happen. Put an assert here? */
362  return ISC_R_UNEXPECTED;
363  }
364  p = (omapi_protocol_object_t *)h;
365 
366  if (!strcmp (name, "connect")) {
367 #if defined (DEBUG_MEMORY_LEAKAGE)
368  connect_outstanding = dmalloc_outstanding;
369 #endif
370  /* Send the introductory message. */
373  sizeof (omapi_protocol_header_t));
374  if (status != ISC_R_SUCCESS) {
375  omapi_disconnect (p -> outer, 1);
376  return status;
377  }
378  return ISC_R_SUCCESS;
379  }
380 
381  /* Should only receive these when opening the initial authenticator. */
382  if (!strcmp (name, "status")) {
383  status = va_arg (ap, isc_result_t);
384  if (status != ISC_R_SUCCESS) {
385  omapi_signal_in (h -> inner, "status", status,
386  (omapi_object_t *)0);
387  omapi_disconnect (p -> outer, 1);
388  return status;
389  } else {
390  return omapi_signal_in (h -> inner, "ready");
391  }
392  }
393 
394  /* If we get a disconnect, dump memory usage. */
395  if (!strcmp (name, "disconnect")) {
396 #if defined (DEBUG_MEMORY_LEAKAGE)
397  if (connect_outstanding != 0xDEADBEEF) {
398  log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
399  dmalloc_generation,
400  dmalloc_outstanding - previous_outstanding,
401  dmalloc_outstanding, dmalloc_longterm, " long-term");
402  }
403 #endif
404 #if defined (DEBUG_MEMORY_LEAKAGE)
405  dmalloc_dump_outstanding ();
406 #endif
407 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
408  dump_rc_history (h);
409 #endif
410  for (m = omapi_registered_messages; m; m = m -> next) {
411  if (m -> protocol_object == p) {
412  if (m -> object)
413  omapi_signal (m -> object, "disconnect");
414  }
415  }
416 
417  /* XXX */
418  return ISC_R_SUCCESS;
419  }
420 
421  /* Not a signal we recognize? */
422  if (strcmp (name, "ready")) {
423  if (p -> inner && p -> inner -> type -> signal_handler)
424  return (*(p -> inner -> type -> signal_handler)) (h,
425  name,
426  ap);
427  return ISC_R_NOTFOUND;
428  }
429 
430  if (!p -> outer || p -> outer -> type != omapi_type_connection)
431  return DHCP_R_INVALIDARG;
432  c = p -> outer;
433 
434  /* We get here because we requested that we be woken up after
435  some number of bytes were read, and that number of bytes
436  has in fact been read. */
437  switch (p -> state) {
439  /* Get protocol version and header size in network
440  byte order. */
441  omapi_connection_get_uint32 (c, &p -> protocol_version);
442  omapi_connection_get_uint32 (c, &p -> header_size);
443 
444  /* We currently only support the current protocol version. */
445  if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
446  omapi_disconnect (c, 1);
447  return DHCP_R_VERSIONMISMATCH;
448  }
449 
450  if (p -> header_size < sizeof (omapi_protocol_header_t)) {
451  omapi_disconnect (c, 1);
452  return DHCP_R_PROTOCOLERROR;
453  }
454 
455  if (p -> default_auth) {
456  status = omapi_protocol_send_open
457  (h, (omapi_object_t *)0, "authenticator",
458  p -> default_auth -> a,
460  if (status != ISC_R_SUCCESS) {
461  omapi_disconnect (c, 1);
462  return status;
463  }
464  } else {
465  status = omapi_signal_in (h -> inner, "ready");
466  }
467 
468  to_header_wait:
469  /* The next thing we're expecting is a message header. */
470  p -> state = omapi_protocol_header_wait;
471 
472  /* Register a need for the number of bytes in a
473  header, and if we already have that many, process
474  them immediately. */
475  if ((omapi_connection_require (c, p -> header_size)) !=
476  ISC_R_SUCCESS)
477  break;
478  /* If we already have the data, fall through. */
479 
481 #if defined (DEBUG_MEMORY_LEAKAGE)
482  if (previous_outstanding != 0xDEADBEEF) {
483  log_info ("%s %ld: %ld new, %ld outstanding, %ld%s",
484  "generation", dmalloc_generation,
485  dmalloc_outstanding - previous_outstanding,
486  dmalloc_outstanding, dmalloc_longterm,
487  " long-term");
488 #endif
489 #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
490  dmalloc_dump_outstanding ();
491 #endif
492 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
493  dump_rc_history (h);
494 #endif
495 #if defined (DEBUG_MEMORY_LEAKAGE)
496  }
497  previous_outstanding = dmalloc_outstanding;
498 #endif
499  status = omapi_message_new ((omapi_object_t **)&p -> message,
500  MDL);
501  if (status != ISC_R_SUCCESS) {
502  omapi_disconnect (c, 1);
503  return status;
504  }
505 
506  p -> verify_result = ISC_R_SUCCESS;
507 
508  /* Swap in the header... */
509  omapi_connection_get_uint32 (c, &p -> message -> authid);
510 
511  /* Bind the authenticator to the message object. */
512  if (p -> message -> authid) {
514  (&p -> message -> id_object, h,
515  p -> message -> authid));
516  if (status != ISC_R_SUCCESS)
517  p -> verify_result = status;
518 
519  /* Activate the authentication key. */
520  status = omapi_set_object_value
521  (c, (omapi_object_t *)0, "input-authenticator",
522  p -> message -> id_object);
523  if (status != ISC_R_SUCCESS) {
524  omapi_disconnect (c, 1);
525  return status;
526  }
527  }
528 
529  omapi_connection_get_uint32 (c, &p -> message -> authlen);
530  omapi_connection_get_uint32 (c, &p -> message -> op);
532  p -> message -> h = th;
533  omapi_connection_get_uint32 (c, &p -> message -> id);
534  omapi_connection_get_uint32 (c, &p -> message -> rid);
535 
536  /* If there was any extra header data, skip over it. */
537  if (p -> header_size > sizeof (omapi_protocol_header_t)) {
539  (0, c, (p -> header_size -
540  sizeof (omapi_protocol_header_t)));
541  }
542 
543  /* XXX must compute partial signature across the
544  XXX preceding bytes. Also, if authenticator
545  specifies encryption as well as signing, we may
546  have to decrypt the data on the way in. */
547 
548  /* First we read in message-specific values, then object
549  values. */
550  p -> reading_message_values = 1;
551 
552  need_name_length:
553  /* The next thing we're expecting is length of the
554  first name. */
555  p -> state = omapi_protocol_name_length_wait;
556 
557  /* Wait for a 16-bit length. */
558  if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
559  break;
560  /* If it's already here, fall through. */
561 
563  omapi_connection_get_uint16 (c, &nlen);
564  /* A zero-length name means that we're done reading name+value
565  pairs. */
566  if (nlen == 0) {
567  /* If we've already read in the object, we are
568  done reading the message, but if we've just
569  finished reading in the values associated
570  with the message, we need to read the
571  object. */
572  if (p -> reading_message_values) {
573  p -> reading_message_values = 0;
574  goto need_name_length;
575  }
576 
577  /* If the authenticator length is zero, there's no
578  signature to read in, so go straight to processing
579  the message. */
580  if (p -> message -> authlen == 0)
581  goto message_done;
582 
583  /* The next thing we're expecting is the
584  message signature. */
585  p -> state = omapi_protocol_signature_wait;
586 
587  /* Wait for the number of bytes specified for
588  the authenticator. If we already have it,
589  go read it in. */
591  (c, p -> message -> authlen) == ISC_R_SUCCESS)
592  goto signature_wait;
593  break;
594  }
595 
596  /* Allocate a buffer for the name. */
597  status = (omapi_data_string_new (&p -> name, nlen, MDL));
598  if (status != ISC_R_SUCCESS) {
599  omapi_disconnect (c, 1);
600  return ISC_R_NOMEMORY;
601  }
602  p -> state = omapi_protocol_name_wait;
603  if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
604  break;
605  /* If it's already here, fall through. */
606 
608  omapi_connection_copyout (p -> name -> value, c,
609  p -> name -> len);
610  /* Wait for a 32-bit length. */
612  if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
613  break;
614  /* If it's already here, fall through. */
615 
617  omapi_connection_get_uint32 (c, &vlen);
618 
619  /* Zero-length values are allowed - if we get one, we
620  don't have to read any data for the value - just
621  get the next one, if there is a next one. */
622  if (!vlen)
623  goto insert_new_value;
624 
625  status = omapi_typed_data_new (MDL, &p -> value,
627  vlen);
628  if (status != ISC_R_SUCCESS) {
629  omapi_disconnect (c, 1);
630  return ISC_R_NOMEMORY;
631  }
632 
633  p -> state = omapi_protocol_value_wait;
634  if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
635  break;
636  /* If it's already here, fall through. */
637 
639  omapi_connection_copyout (p -> value -> u.buffer.value, c,
640  p -> value -> u.buffer.len);
641 
642  insert_new_value:
643  if (p -> reading_message_values) {
644  status = (omapi_set_value
645  ((omapi_object_t *)p -> message,
646  p -> message -> id_object,
647  p -> name, p -> value));
648  } else {
649  if (!p -> message -> object) {
650  /* We need a generic object to hang off of the
651  incoming message. */
652  status = (omapi_generic_new
653  (&p -> message -> object, MDL));
654  if (status != ISC_R_SUCCESS) {
655  omapi_disconnect (c, 1);
656  return status;
657  }
658  }
659  status = (omapi_set_value
660  ((omapi_object_t *)p -> message -> object,
661  p -> message -> id_object,
662  p -> name, p -> value));
663  }
664  if (status != ISC_R_SUCCESS) {
665  omapi_disconnect (c, 1);
666  return status;
667  }
668  omapi_data_string_dereference (&p -> name, MDL);
669  if (p -> value)
670  omapi_typed_data_dereference (&p -> value, MDL);
671  goto need_name_length;
672 
673  signature_wait:
675  if (p -> message -> id_object) {
676  /* Compute the signature of the message. */
677  status = omapi_get_value_str (c, (omapi_object_t *)0,
678  "input-signature",
679  &signature);
680  if (status != ISC_R_SUCCESS) {
681  omapi_disconnect (c, 1);
682  return status;
683  }
684 
685  /* Disable the authentication key on the connection. */
686  status = omapi_set_value_str (c, (omapi_object_t *)0,
687  "input-authenticator",
688  (omapi_typed_data_t *)0);
689  if (status != ISC_R_SUCCESS) {
690  omapi_value_dereference (&signature, MDL);
691  omapi_disconnect (c, 1);
692  return status;
693  }
694  }
695 
696  /* Read the authenticator. */
697  status = omapi_typed_data_new (MDL,
698  &p -> message -> authenticator,
700  p -> message -> authlen);
701 
702  if (status != ISC_R_SUCCESS) {
703  if (signature != NULL) {
704  omapi_value_dereference (&signature, MDL);
705  }
706  omapi_disconnect (c, 1);
707  return ISC_R_NOMEMORY;
708  }
710  (p -> message -> authenticator -> u.buffer.value, c,
711  p -> message -> authlen);
712 
713  /* Verify the signature. */
714  if (p -> message -> id_object &&
715  ((signature -> value -> u.buffer.len !=
716  p -> message -> authlen) ||
717  (memcmp (signature -> value -> u.buffer.value,
718  p -> message -> authenticator -> u.buffer.value,
719  p -> message -> authlen) != 0))) {
720  /* Invalid signature. */
722  }
723 
724  if (signature != NULL) {
725  omapi_value_dereference (&signature, MDL);
726  }
727 
728  /* Process the message. */
729  message_done:
730  if (p -> verify_result != ISC_R_SUCCESS) {
732  (h, (omapi_object_t *)0, p -> verify_result,
733  p -> message -> id, (char *)0);
734  } else {
735  status = omapi_message_process
736  ((omapi_object_t *)p -> message, h);
737  }
738  if (status != ISC_R_SUCCESS) {
739  omapi_disconnect (c, 1);
740  return ISC_R_NOMEMORY;
741  }
742 
743  omapi_message_dereference (&p -> message, MDL);
744 #if defined (DEBUG_MEMORY_LEAKAGE)
745  log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
746  dmalloc_generation,
747  dmalloc_outstanding - previous_outstanding,
748  dmalloc_outstanding, dmalloc_longterm, " long-term");
749 #endif
750 #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
751  dmalloc_dump_outstanding ();
752 #endif
753 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
754  dump_rc_history (h);
755 #endif
756 #if defined (DEBUG_MEMORY_LEAKAGE)
757  previous_outstanding = 0xDEADBEEF;
758 #endif
759  /* Now wait for the next message. */
760  goto to_header_wait;
761 
762  default:
763  /* XXX should never get here. Assertion? */
764  break;
765  }
766  return ISC_R_SUCCESS;
767 }
768 
770  omapi_object_t *ao,
771  omapi_handle_t handle)
772 {
775  isc_result_t status;
776 
777  if (ao -> type != omapi_type_auth_key &&
778  (!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
779  return DHCP_R_INVALIDARG;
780 
781  if (po -> type != omapi_type_protocol)
782  return DHCP_R_INVALIDARG;
783  p = (omapi_protocol_object_t *)po;
784 
785 #ifdef DEBUG_PROTOCOL
786  log_debug ("omapi_protocol_add_auth(name=%s)",
787  ((omapi_auth_key_t *)ao) -> name);
788 #endif
789 
790  if (p -> verify_auth) {
791  status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao);
792  if (status != ISC_R_SUCCESS)
793  return status;
794  }
795 
796  /* If omapi_protocol_connect() was called with a default
797  authenticator, p -> default_auth will already be set,
798  but p -> remote_auth_list will not yet be initialized. */
799  if (p -> default_auth && !p -> remote_auth_list) {
800  if (p -> default_auth -> a != ao) {
801  /* Something just went horribly wrong. */
802  omapi_disconnect (p -> outer, 1);
803  return ISC_R_UNEXPECTED;
804  }
805 
806  p -> remote_auth_list = p -> default_auth;
807  p -> default_auth -> remote_handle = handle;
808 
809  return omapi_signal_in (p -> inner, "ready");
810  }
811 
812  r = dmalloc (sizeof(*r), MDL);
813  if (!r)
814  return ISC_R_NOMEMORY;
815 
816  status = omapi_object_reference (&r -> a, ao, MDL);
817  if (status != ISC_R_SUCCESS) {
818  dfree (r, MDL);
819  return status;
820  }
821 
822  r -> remote_handle = handle;
823  r -> next = p -> remote_auth_list;
824  p -> remote_auth_list = r;
825 
826  return ISC_R_SUCCESS;
827 }
828 
830  omapi_object_t *po,
831  omapi_handle_t handle)
832 {
835 
836  if (po -> type != omapi_type_protocol)
837  return DHCP_R_INVALIDARG;
838  p = (omapi_protocol_object_t *)po;
839 
840  for (r = p -> remote_auth_list; r; r = r -> next)
841  if (r -> remote_handle == handle)
842  return omapi_object_reference (a, r -> a, MDL);
843 
844  return DHCP_R_KEY_UNKNOWN;
845 }
846 
848  omapi_object_t *id,
849  omapi_data_string_t *name,
850  omapi_typed_data_t *value)
851 {
854 
855  if (h -> type != omapi_type_protocol)
856  return DHCP_R_INVALIDARG;
857  p = (omapi_protocol_object_t *)h;
858 
859  if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
860  if (!value || value -> type != omapi_datatype_object)
861  return DHCP_R_INVALIDARG;
862 
863  if (!value -> u.object) {
864  p -> default_auth = (omapi_remote_auth_t *)0;
865  } else {
866  for (r = p -> remote_auth_list; r; r = r -> next)
867  if (r -> a == value -> u.object)
868  break;
869 
870  if (!r)
871  return DHCP_R_KEY_UNKNOWN;
872 
873  p -> default_auth = r;
874  }
875 
876  return ISC_R_SUCCESS;
877  }
878 
879  if (h -> inner && h -> inner -> type -> set_value)
880  return (*(h -> inner -> type -> set_value))
881  (h -> inner, id, name, value);
882  return ISC_R_NOTFOUND;
883 }
884 
886  omapi_object_t *id,
887  omapi_data_string_t *name,
888  omapi_value_t **value)
889 {
891 
892  if (h -> type != omapi_type_protocol)
893  return DHCP_R_INVALIDARG;
894  p = (omapi_protocol_object_t *)h;
895 
896  if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
897  if (!p -> default_auth)
898  return ISC_R_NOTFOUND;
899 
900  return omapi_make_object_value (value, name,
901  p -> default_auth -> a, MDL);
902  }
903 
904  if (h -> inner && h -> inner -> type -> get_value)
905  return (*(h -> inner -> type -> get_value))
906  (h -> inner, id, name, value);
907  return ISC_R_NOTFOUND;
908 }
909 
911  const char *file, int line)
912 {
914  if (h -> type != omapi_type_protocol)
915  return DHCP_R_INVALIDARG;
916  p = (omapi_protocol_object_t *)h;
917  if (p -> message)
918  omapi_message_dereference (&p -> message, file, line);
919 
920  /* This will happen if: 1) A default authenticator is supplied to
921  omapi_protocol_connect(), and 2) something goes wrong before
922  the authenticator can be opened. */
923  if (p -> default_auth && !p -> remote_auth_list)
924  dfree (p -> default_auth, file, line);
925 
926  while (p -> remote_auth_list) {
927  omapi_remote_auth_t *r = p -> remote_auth_list;
928  p -> remote_auth_list = p -> remote_auth_list -> next;
929  omapi_object_dereference (&r -> a, file, line);
930  dfree (r, file, line);
931  }
932  return ISC_R_SUCCESS;
933 }
934 
935 /* Write all the published values associated with the object through the
936  specified connection. */
937 
939  omapi_object_t *id,
940  omapi_object_t *p)
941 {
942  if (p -> type != omapi_type_protocol)
943  return DHCP_R_INVALIDARG;
944 
945  if (p -> inner && p -> inner -> type -> stuff_values)
946  return (*(p -> inner -> type -> stuff_values)) (c, id,
947  p -> inner);
948  return ISC_R_SUCCESS;
949 }
950 
951 /* Returns a boolean indicating whether this protocol requires that
952  messages be authenticated or not. */
953 
955 {
956  if (h -> type != omapi_type_protocol)
957  return isc_boolean_false;
958  if (((omapi_protocol_object_t *)h) -> insecure)
959  return isc_boolean_false;
960  else
961  return isc_boolean_true;
962 }
963 
964 /* Sets the address and authenticator verification callbacks. The handle
965  is to a listener object, not a protocol object. */
966 
968  isc_result_t (*verify_addr)
969  (omapi_object_t *,
970  omapi_addr_t *),
971  isc_result_t (*verify_auth)
972  (omapi_object_t *,
973  omapi_auth_key_t *))
974 {
976 
977  if (h -> outer && h -> outer -> type == omapi_type_protocol_listener)
978  h = h -> outer;
979 
980  if (h -> type != omapi_type_protocol_listener)
981  return DHCP_R_INVALIDARG;
983 
984  l -> verify_auth = verify_auth;
985  l -> insecure = 0;
986 
987  if (h -> outer != NULL) {
988  return omapi_listener_configure_security (h -> outer, verify_addr);
989  } else {
990  return DHCP_R_INVALIDARG;
991  }
992 }
993 
994 
995 /* Set up a listener for the omapi protocol. The handle stored points to
996  a listener object, not a protocol object. */
997 
999  unsigned port,
1000  int max)
1001 {
1002  isc_result_t status;
1004 
1006  status = omapi_protocol_listener_allocate (&obj, MDL);
1007  if (status != ISC_R_SUCCESS)
1008  return status;
1009 
1010  status = omapi_object_reference (&h -> outer,
1011  (omapi_object_t *)obj, MDL);
1012  if (status != ISC_R_SUCCESS) {
1013  omapi_protocol_listener_dereference (&obj, MDL);
1014  return status;
1015  }
1016  status = omapi_object_reference (&obj -> inner, h, MDL);
1017  if (status != ISC_R_SUCCESS) {
1018  omapi_protocol_listener_dereference (&obj, MDL);
1019  return status;
1020  }
1021 
1022  /* What a terrible default. */
1023  obj -> insecure = 1;
1024 
1025  status = omapi_listen ((omapi_object_t *)obj, port, max);
1026  omapi_protocol_listener_dereference (&obj, MDL);
1027  return status;
1028 }
1029 
1030 /* Signal handler for protocol listener - if we get a connect signal,
1031  create a new protocol connection, otherwise pass the signal down. */
1032 
1034  const char *name, va_list ap)
1035 {
1036  isc_result_t status;
1037  omapi_object_t *c;
1040 
1041  if (!o || o -> type != omapi_type_protocol_listener)
1042  return DHCP_R_INVALIDARG;
1044 
1045  /* Not a signal we recognize? */
1046  if (strcmp (name, "connect")) {
1047  if (p -> inner && p -> inner -> type -> signal_handler)
1048  return (*(p -> inner -> type -> signal_handler))
1049  (p -> inner, name, ap);
1050  return ISC_R_NOTFOUND;
1051  }
1052 
1053  c = va_arg (ap, omapi_object_t *);
1054  if (!c || c -> type != omapi_type_connection)
1055  return DHCP_R_INVALIDARG;
1056 
1057  obj = (omapi_protocol_object_t *)0;
1058  status = omapi_protocol_allocate (&obj, MDL);
1059  if (status != ISC_R_SUCCESS)
1060  return status;
1061 
1062  obj -> verify_auth = p -> verify_auth;
1063  obj -> insecure = p -> insecure;
1064 
1065  status = omapi_object_reference (&obj -> outer, c, MDL);
1066  if (status != ISC_R_SUCCESS) {
1067  lose:
1068  omapi_protocol_dereference (&obj, MDL);
1069  omapi_disconnect (c, 1);
1070  return status;
1071  }
1072 
1073  status = omapi_object_reference (&c -> inner,
1074  (omapi_object_t *)obj, MDL);
1075  if (status != ISC_R_SUCCESS)
1076  goto lose;
1077 
1078  /* Send the introductory message. */
1079  status = omapi_protocol_send_intro ((omapi_object_t *)obj,
1081  sizeof (omapi_protocol_header_t));
1082  if (status != ISC_R_SUCCESS)
1083  goto lose;
1084 
1085  omapi_protocol_dereference (&obj, MDL);
1086  return status;
1087 }
1088 
1090  omapi_object_t *id,
1091  omapi_data_string_t *name,
1092  omapi_typed_data_t *value)
1093 {
1094  if (h -> type != omapi_type_protocol_listener)
1095  return DHCP_R_INVALIDARG;
1096 
1097  if (h -> inner && h -> inner -> type -> set_value)
1098  return (*(h -> inner -> type -> set_value))
1099  (h -> inner, id, name, value);
1100  return ISC_R_NOTFOUND;
1101 }
1102 
1104  omapi_object_t *id,
1105  omapi_data_string_t *name,
1106  omapi_value_t **value)
1107 {
1108  if (h -> type != omapi_type_protocol_listener)
1109  return DHCP_R_INVALIDARG;
1110 
1111  if (h -> inner && h -> inner -> type -> get_value)
1112  return (*(h -> inner -> type -> get_value))
1113  (h -> inner, id, name, value);
1114  return ISC_R_NOTFOUND;
1115 }
1116 
1118  const char *file, int line)
1119 {
1120  if (h -> type != omapi_type_protocol_listener)
1121  return DHCP_R_INVALIDARG;
1122  return ISC_R_SUCCESS;
1123 }
1124 
1125 /* Write all the published values associated with the object through the
1126  specified connection. */
1127 
1129  omapi_object_t *id,
1130  omapi_object_t *p)
1131 {
1132  if (p -> type != omapi_type_protocol_listener)
1133  return DHCP_R_INVALIDARG;
1134 
1135  if (p -> inner && p -> inner -> type -> stuff_values)
1136  return (*(p -> inner -> type -> stuff_values)) (c, id,
1137  p -> inner);
1138  return ISC_R_SUCCESS;
1139 }
1140 
1142  omapi_object_t *id,
1143  isc_result_t waitstatus,
1144  unsigned rid, const char *msg)
1145 {
1146  isc_result_t status;
1148  omapi_object_t *mo;
1149 
1150  if (po -> type != omapi_type_protocol)
1151  return DHCP_R_INVALIDARG;
1152 
1153  status = omapi_message_new ((omapi_object_t **)&message, MDL);
1154  if (status != ISC_R_SUCCESS)
1155  return status;
1156  mo = (omapi_object_t *)message;
1157 
1158  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1159  "op", OMAPI_OP_STATUS);
1160  if (status != ISC_R_SUCCESS) {
1161  omapi_message_dereference (&message, MDL);
1162  return status;
1163  }
1164 
1165  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1166  "rid", (int)rid);
1167  if (status != ISC_R_SUCCESS) {
1168  omapi_message_dereference (&message, MDL);
1169  return status;
1170  }
1171 
1172  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1173  "result", (int)waitstatus);
1174  if (status != ISC_R_SUCCESS) {
1175  omapi_message_dereference (&message, MDL);
1176  return status;
1177  }
1178 
1179  /* If a message has been provided, send it. */
1180  if (msg) {
1181  status = omapi_set_string_value (mo, (omapi_object_t *)0,
1182  "message", msg);
1183  if (status != ISC_R_SUCCESS) {
1184  omapi_message_dereference (&message, MDL);
1185  return status;
1186  }
1187  }
1188 
1189  status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
1190  omapi_message_dereference (&message, MDL);
1191  return status;
1192 }
1193 
1194 /* The OMAPI_NOTIFY_PROTOCOL flag will cause the notify-object for the
1195  message to be set to the protocol object. This is used when opening
1196  the default authenticator. */
1197 
1199  omapi_object_t *id,
1200  const char *type,
1201  omapi_object_t *object,
1202  unsigned flags)
1203 {
1204  isc_result_t status;
1206  omapi_object_t *mo;
1207 
1208  if (po -> type != omapi_type_protocol)
1209  return DHCP_R_INVALIDARG;
1210 
1211  status = omapi_message_new ((omapi_object_t **)&message, MDL);
1212  mo = (omapi_object_t *)message;
1213 
1214  if (status == ISC_R_SUCCESS)
1215  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1216  "op", OMAPI_OP_OPEN);
1217 
1218  if (status == ISC_R_SUCCESS)
1219  status = omapi_set_object_value (mo, (omapi_object_t *)0,
1220  "object", object);
1221 
1222  if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
1223  status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1224  "create", 1);
1225 
1226  if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
1227  status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1228  "update", 1);
1229 
1230  if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
1231  status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1232  "exclusive", 1);
1233 
1234  if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
1235  status = omapi_set_object_value (mo, (omapi_object_t *)0,
1236  "notify-object", po);
1237 
1238  if (type && (status == ISC_R_SUCCESS))
1239  status = omapi_set_string_value (mo, (omapi_object_t *)0,
1240  "type", type);
1241 
1242  if (status == ISC_R_SUCCESS)
1243  status = omapi_message_register (mo);
1244 
1245  if (status == ISC_R_SUCCESS) {
1246  status = omapi_protocol_send_message (po, id, mo,
1247  (omapi_object_t *)0);
1248  if (status != ISC_R_SUCCESS)
1250  }
1251 
1252  if (message)
1253  omapi_message_dereference (&message, MDL);
1254 
1255  return status;
1256 }
1257 
1259  omapi_object_t *id,
1260  unsigned rid,
1261  omapi_object_t *object)
1262 {
1263  isc_result_t status;
1265  omapi_object_t *mo;
1266 
1267  if (po -> type != omapi_type_protocol)
1268  return DHCP_R_INVALIDARG;
1269 
1270  status = omapi_message_new ((omapi_object_t **)&message, MDL);
1271  if (status != ISC_R_SUCCESS)
1272  return status;
1273  mo = (omapi_object_t *)message;
1274 
1275  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1276  "op", OMAPI_OP_UPDATE);
1277  if (status != ISC_R_SUCCESS) {
1278  omapi_message_dereference (&message, MDL);
1279  return status;
1280  }
1281 
1282  if (rid) {
1283  omapi_handle_t handle;
1284  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1285  "rid", (int)rid);
1286  if (status != ISC_R_SUCCESS) {
1287  omapi_message_dereference (&message, MDL);
1288  return status;
1289  }
1290 
1291  status = omapi_object_handle (&handle, object);
1292  if (status != ISC_R_SUCCESS) {
1293  omapi_message_dereference (&message, MDL);
1294  return status;
1295  }
1296  status = omapi_set_int_value (mo, (omapi_object_t *)0,
1297  "handle", (int)handle);
1298  if (status != ISC_R_SUCCESS) {
1299  omapi_message_dereference (&message, MDL);
1300  return status;
1301  }
1302  }
1303 
1304  status = omapi_set_object_value (mo, (omapi_object_t *)0,
1305  "object", object);
1306  if (status != ISC_R_SUCCESS) {
1307  omapi_message_dereference (&message, MDL);
1308  return status;
1309  }
1310 
1311  status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
1312  omapi_message_dereference (&message, MDL);
1313  return status;
1314 }
#define OMAPI_CREATE
Definition: omapip.h:156
#define OMAPI_PROTOCOL_VERSION
Definition: omapip_p.h:87
isc_result_t omapi_typed_data_new(const char *, int, omapi_typed_data_t **, omapi_datatype_t,...)
Definition: alloc.c:789
isc_result_t omapi_set_string_value(omapi_object_t *, omapi_object_t *, const char *, const char *)
Definition: support.c:444
const char int line
Definition: dhcpd.h:3615
omapi_message_object_t * omapi_registered_messages
isc_result_t omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
Definition: protocol.c:344
omapi_object_type_t * omapi_type_connection
Definition: support.c:34
isc_result_t omapi_message_new(omapi_object_t **, const char *, int)
isc_result_t omapi_object_reference(omapi_object_t **, omapi_object_t *, const char *, int)
Definition: alloc.c:557
#define DHCP_R_PROTOCOLERROR
Definition: result.h:47
#define OMAPI_OP_UPDATE
Definition: omapip_p.h:91
isc_result_t omapi_data_string_dereference(omapi_data_string_t **, const char *, int)
Definition: alloc.c:974
isc_result_t omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id, unsigned rid, omapi_object_t *object)
Definition: protocol.c:1258
isc_result_t omapi_message_register(omapi_object_t *)
Definition: message.c:267
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
isc_result_t omapi_connection_copyin(omapi_object_t *, const unsigned char *, unsigned)
Definition: buffer.c:266
#define MDL
Definition: omapip.h:568
#define DHCP_R_NOTYET
Definition: result.h:49
#define OMAPI_OP_OPEN
Definition: omapip_p.h:89
#define DHCP_R_INVALIDARG
Definition: result.h:48
omapi_typed_data_t * value
Definition: omapip.h:91
isc_result_t omapi_set_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)
Definition: support.c:304
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_protocol_stuff_values(omapi_object_t *c, omapi_object_t *id, omapi_object_t *p)
Definition: protocol.c:938
isc_result_t omapi_signal_in(omapi_object_t *, const char *,...)
Definition: support.c:286
isc_result_t omapi_protocol_add_auth(omapi_object_t *po, omapi_object_t *ao, omapi_handle_t handle)
Definition: protocol.c:769
isc_result_t omapi_set_object_value(omapi_object_t *, omapi_object_t *, const char *, omapi_object_t *)
Definition: support.c:420
isc_result_t verify_result
Definition: omapip_p.h:148
OMAPI_OBJECT_ALLOC(omapi_protocol, omapi_protocol_object_t, omapi_type_protocol)
Definition: protocol.c:34
isc_result_t omapi_protocol_listen(omapi_object_t *h, unsigned port, int max)
Definition: protocol.c:998
isc_result_t omapi_message_unregister(omapi_object_t *)
Definition: message.c:295
#define DHCP_R_INVALIDKEY
Definition: result.h:56
omapi_object_t * object
Definition: omapip.h:63
isc_result_t omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id, isc_result_t waitstatus, unsigned rid, const char *msg)
Definition: protocol.c:1141
isc_result_t omapi_connection_output_auth_length(omapi_object_t *, unsigned *)
Definition: connection.c:895
#define OMAPI_UPDATE
Definition: omapip.h:157
#define DHCP_R_KEY_UNKNOWN
Definition: result.h:55
isc_result_t omapi_connection_put_uint32(omapi_object_t *, u_int32_t)
Definition: buffer.c:587
omapi_object_type_t * omapi_type_protocol
Definition: support.c:39
isc_result_t omapi_get_value_str(omapi_object_t *, omapi_object_t *, const char *, omapi_value_t **)
Definition: support.c:483
isc_result_t omapi_connection_require(omapi_object_t *, unsigned)
Definition: connection.c:559
isc_result_t omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id, omapi_object_t *mo, omapi_object_t *omo)
Definition: protocol.c:149
isc_result_t omapi_stuff_values(omapi_object_t *, omapi_object_t *, omapi_object_t *)
Definition: support.c:509
#define DHCP_R_VERSIONMISMATCH
Definition: result.h:46
isc_result_t omapi_set_boolean_value(omapi_object_t *, omapi_object_t *, const char *, int)
Definition: support.c:372
isc_result_t omapi_protocol_configure_security(omapi_object_t *h, isc_result_t(*verify_addr)(omapi_object_t *, omapi_addr_t *), isc_result_t(*verify_auth)(omapi_object_t *, omapi_auth_key_t *))
Definition: protocol.c:967
isc_result_t omapi_protocol_send_open(omapi_object_t *po, omapi_object_t *id, const char *type, omapi_object_t *object, unsigned flags)
Definition: protocol.c:1198
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition: alloc.c:579
isc_result_t omapi_signal(omapi_object_t *, const char *,...)
Definition: support.c:268
isc_result_t omapi_set_value_str(omapi_object_t *, omapi_object_t *, const char *, omapi_typed_data_t *)
Definition: support.c:353
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
omapi_typed_data_t * value
Definition: omapip_p.h:147
isc_result_t omapi_protocol_lookup_auth(omapi_object_t **a, omapi_object_t *po, omapi_handle_t handle)
Definition: protocol.c:829
omapi_object_type_t * omapi_type_protocol_listener
Definition: support.c:40
void dfree(void *, const char *, int)
Definition: alloc.c:131
isc_result_t omapi_protocol_get_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value)
Definition: protocol.c:885
isc_result_t omapi_connection_get_uint32(omapi_object_t *, u_int32_t *)
Definition: buffer.c:572
isc_result_t omapi_listener_configure_security(omapi_object_t *, isc_result_t(*)(omapi_object_t *, omapi_addr_t *))
Definition: listener.c:398
isc_result_t omapi_protocol_listener_stuff(omapi_object_t *c, omapi_object_t *id, omapi_object_t *p)
Definition: protocol.c:1128
int int log_info(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_protocol_connect(omapi_object_t *, const char *, unsigned, omapi_object_t *)
isc_result_t omapi_object_handle(omapi_handle_t *, omapi_object_t *)
Definition: handle.c:73
isc_result_t omapi_connect(omapi_object_t *, const char *, unsigned)
unsigned int omapi_handle_t
Definition: omapip.h:37
isc_result_t omapi_listen(omapi_object_t *, unsigned, int)
isc_result_t omapi_protocol_send_intro(omapi_object_t *h, unsigned ver, unsigned hsize)
Definition: protocol.c:106
isc_result_t omapi_value_dereference(omapi_value_t **, const char *, int)
Definition: alloc.c:1046
isc_result_t omapi_message_process(omapi_object_t *, omapi_object_t *)
Definition: message.c:358
#define OMAPI_EXCL
Definition: omapip.h:158
isc_result_t omapi_protocol_listener_get_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value)
Definition: protocol.c:1103
isc_result_t omapi_protocol_listener_signal(omapi_object_t *o, const char *name, va_list ap)
Definition: protocol.c:1033
int omapi_ds_strcmp(omapi_data_string_t *, const char *)
Definition: support.c:582
isc_result_t omapi_connection_put_uint16(omapi_object_t *, u_int32_t)
Definition: buffer.c:613
isc_result_t omapi_data_string_new(omapi_data_string_t **, unsigned, const char *, int)
Definition: alloc.c:936
omapi_object_type_t * omapi_type_message
Definition: support.c:43
isc_result_t omapi_protocol_listener_set_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_typed_data_t *value)
Definition: protocol.c:1089
isc_result_t omapi_connection_copyout(unsigned char *, omapi_object_t *, unsigned)
Definition: buffer.c:360
isc_result_t omapi_set_int_value(omapi_object_t *, omapi_object_t *, const char *, int)
Definition: support.c:396
#define DHCP_R_INCOMPLETE
Definition: result.h:57
const char * file
Definition: dhcpd.h:3615
isc_result_t omapi_connection_get_uint16(omapi_object_t *, u_int16_t *)
Definition: buffer.c:598
isc_result_t omapi_disconnect(omapi_object_t *, int)
Definition: connection.c:454
isc_result_t omapi_protocol_listener_destroy(omapi_object_t *h, const char *file, int line)
Definition: protocol.c:1117
isc_result_t omapi_protocol_set_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_typed_data_t *value)
Definition: protocol.c:847
omapi_object_type_t * omapi_type_auth_key
Definition: support.c:44
#define OMAPI_OP_STATUS
Definition: omapip_p.h:93
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **, const char *, int)
Definition: alloc.c:887
#define OMAPI_NOTIFY_PROTOCOL
Definition: omapip.h:159
isc_boolean_t omapi_protocol_authenticated(omapi_object_t *h)
Definition: protocol.c:954
isc_result_t omapi_protocol_destroy(omapi_object_t *h, const char *file, int line)
Definition: protocol.c:910
isc_result_t omapi_make_object_value(omapi_value_t **, omapi_data_string_t *, omapi_object_t *, const char *, int)
Definition: support.c:743