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