omapip/buffer.c

Go to the documentation of this file.
00001 /* buffer.c
00002 
00003    Buffer access functions for the object management protocol... */
00004 
00005 /*
00006  * Copyright (c) 2009,2012-2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
00008  * Copyright (c) 1999-2003 by Internet Software Consortium
00009  *
00010  * Permission to use, copy, modify, and distribute this software for any
00011  * purpose with or without fee is hereby granted, provided that the above
00012  * copyright notice and this permission notice appear in all copies.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00015  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00016  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00017  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00018  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00019  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00020  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00021  *
00022  *   Internet Systems Consortium, Inc.
00023  *   950 Charter Street
00024  *   Redwood City, CA 94063
00025  *   <info@isc.org>
00026  *   https://www.isc.org/
00027  *
00028  */
00029 
00030 #include "dhcpd.h"
00031 
00032 #include <omapip/omapip_p.h>
00033 #include <errno.h>
00034 
00035 #if defined (TRACING)
00036 static void trace_connection_input_input (trace_type_t *, unsigned, char *);
00037 static void trace_connection_input_stop (trace_type_t *);
00038 static void trace_connection_output_input (trace_type_t *, unsigned, char *);
00039 static void trace_connection_output_stop (trace_type_t *);
00040 static trace_type_t *trace_connection_input;
00041 static trace_type_t *trace_connection_output;
00042 static isc_result_t omapi_connection_reader_trace (omapi_object_t *,
00043                                                    unsigned, char *,
00044                                                    unsigned *);
00045 extern omapi_array_t *omapi_connections;
00046 
00047 void omapi_buffer_trace_setup ()
00048 {
00049         trace_connection_input =
00050                 trace_type_register ("connection-input",
00051                                      (void *)0,
00052                                      trace_connection_input_input,
00053                                      trace_connection_input_stop, MDL);
00054         trace_connection_output =
00055                 trace_type_register ("connection-output",
00056                                      (void *)0,
00057                                      trace_connection_output_input,
00058                                      trace_connection_output_stop, MDL);
00059 }
00060 
00061 static void trace_connection_input_input (trace_type_t *ttype,
00062                                           unsigned length, char *buf)
00063 {
00064         unsigned left, taken, cc = 0;
00065         char *s;
00066         int32_t connect_index;
00067         isc_result_t status;
00068         omapi_connection_object_t *c = (omapi_connection_object_t *)0;
00069 
00070         memcpy (&connect_index, buf, sizeof connect_index);
00071         connect_index = ntohl (connect_index);
00072 
00073         omapi_array_foreach_begin (omapi_connections,
00074                                    omapi_connection_object_t, lp) {
00075                 if (lp -> index == ntohl (connect_index)) {
00076                         omapi_connection_reference (&c, lp, MDL);
00077                         omapi_connection_dereference (&lp, MDL);
00078                         break;
00079                 }
00080         } omapi_array_foreach_end (omapi_connections,
00081                                    omapi_connection_object_t, lp);
00082 
00083         if (!c) {
00084                 log_error ("trace connection input: no connection index %ld",
00085                            (long int)connect_index);
00086                 return;
00087         }
00088 
00089         s = buf + sizeof connect_index;
00090         left = length - sizeof connect_index;
00091 
00092         while (left) {
00093                 taken = 0;
00094                 status = omapi_connection_reader_trace ((omapi_object_t *)c,
00095                                                         left, s, &taken);
00096                 if (status != ISC_R_SUCCESS) {
00097                         log_error ("trace connection input: %s",
00098                                    isc_result_totext (status));
00099                         break;
00100                 }
00101                 if (!taken) {
00102                         if (cc > 0) {
00103                                 log_error ("trace connection_input: %s",
00104                                            "input is not being consumed.");
00105                                 break;
00106                         }
00107                         cc++;
00108                 } else {
00109                         cc = 0;
00110                         left -= taken;
00111                 }
00112         }
00113         omapi_connection_dereference (&c, MDL);
00114 }
00115 
00116 static void trace_connection_input_stop (trace_type_t *ttype) { }
00117 
00118 static void trace_connection_output_input (trace_type_t *ttype,
00119                                           unsigned length, char *buf)
00120 {
00121         /* We *could* check to see if the output is correct, but for now
00122            we aren't going to do that. */
00123 }
00124 
00125 static void trace_connection_output_stop (trace_type_t *ttype) { }
00126 
00127 #endif
00128 
00129 /* Make sure that at least len bytes are in the input buffer, and if not,
00130    read enough bytes to make up the difference. */
00131 
00132 isc_result_t omapi_connection_reader (omapi_object_t *h)
00133 {
00134 #if defined (TRACING)
00135         return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)0);
00136 }
00137 
00138 static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
00139                                                    unsigned stuff_len,
00140                                                    char *stuff_buf,
00141                                                    unsigned *stuff_taken)
00142 {
00143 #endif
00144         omapi_buffer_t *buffer;
00145         isc_result_t status;
00146         unsigned read_len;
00147         int read_status;
00148         omapi_connection_object_t *c;
00149         unsigned bytes_to_read;
00150         
00151         if (!h || h -> type != omapi_type_connection)
00152                 return DHCP_R_INVALIDARG;
00153         c = (omapi_connection_object_t *)h;
00154 
00155         /* See if there are enough bytes. */
00156         if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
00157             c -> in_bytes > c -> bytes_needed)
00158                 return ISC_R_SUCCESS;
00159 
00160 
00161         if (c -> inbufs) {
00162                 for (buffer = c -> inbufs; buffer -> next;
00163                      buffer = buffer -> next)
00164                         ;
00165                 if (!BUFFER_BYTES_FREE (buffer)) {
00166                         status = omapi_buffer_new (&buffer -> next, MDL);
00167                         if (status != ISC_R_SUCCESS)
00168                                 return status;
00169                         buffer = buffer -> next;
00170                 }
00171         } else {
00172                 status = omapi_buffer_new (&c -> inbufs, MDL);
00173                 if (status != ISC_R_SUCCESS)
00174                         return status;
00175                 buffer = c -> inbufs;
00176         }
00177 
00178         bytes_to_read = BUFFER_BYTES_FREE (buffer);
00179 
00180         while (bytes_to_read) {
00181                 if (buffer -> tail > buffer -> head)
00182                         read_len = sizeof (buffer -> buf) - buffer -> tail;
00183                 else
00184                         read_len = buffer -> head - buffer -> tail;
00185 
00186 #if defined (TRACING)
00187                 if (trace_playback()) {
00188                         if (stuff_len) {
00189                                 if (read_len > stuff_len)
00190                                         read_len = stuff_len;
00191                                 if (stuff_taken)
00192                                         *stuff_taken += read_len;
00193                                 memcpy (&buffer -> buf [buffer -> tail],
00194                                         stuff_buf, read_len);
00195                                 stuff_len -= read_len;
00196                                 stuff_buf += read_len;
00197                                 read_status = read_len;
00198                         } else {
00199                                 break;
00200                         }
00201                 } else
00202 #endif
00203                 {
00204                         read_status = read (c -> socket,
00205                                             &buffer -> buf [buffer -> tail],
00206                                             read_len);
00207                 }
00208                 if (read_status < 0) {
00209                         if (errno == EWOULDBLOCK)
00210                                 break;
00211                         else if (errno == EIO)
00212                                 return ISC_R_IOERROR;
00213                         else if (errno == EINVAL)
00214                                 return DHCP_R_INVALIDARG;
00215                         else if (errno == ECONNRESET) {
00216                                 omapi_disconnect (h, 1);
00217                                 return ISC_R_SHUTTINGDOWN;
00218                         } else
00219                                 return ISC_R_UNEXPECTED;
00220                 }
00221 
00222                 /* If we got a zero-length read, as opposed to EWOULDBLOCK,
00223                    the remote end closed the connection. */
00224                 if (read_status == 0) {
00225                         omapi_disconnect (h, 0);
00226                         return ISC_R_SHUTTINGDOWN;
00227                 }
00228 #if defined (TRACING)
00229                 if (trace_record ()) {
00230                         trace_iov_t iov [2];
00231                         int32_t connect_index;
00232 
00233                         connect_index = htonl (c -> index);
00234 
00235                         iov [0].buf = (char *)&connect_index;
00236                         iov [0].len = sizeof connect_index;
00237                         iov [1].buf = &buffer -> buf [buffer -> tail];
00238                         iov [1].len = read_status;
00239 
00240                         status = (trace_write_packet_iov
00241                                   (trace_connection_input, 2, iov, MDL));
00242                         if (status != ISC_R_SUCCESS) {
00243                                 trace_stop ();
00244                                 log_error ("trace connection input: %s",
00245                                            isc_result_totext (status));
00246                         }
00247                 }
00248 #endif
00249                 buffer -> tail += read_status;
00250                 c -> in_bytes += read_status;
00251                 if (buffer -> tail == sizeof buffer -> buf)
00252                         buffer -> tail = 0;
00253                 if (read_status < read_len)
00254                         break;
00255                 bytes_to_read -= read_status;
00256         }
00257 
00258         if (c -> bytes_needed <= c -> in_bytes) {
00259                 omapi_signal (h, "ready", c);
00260         }
00261         return ISC_R_SUCCESS;
00262 }
00263 
00264 /* Put some bytes into the output buffer for a connection. */
00265 
00266 isc_result_t omapi_connection_copyin (omapi_object_t *h,
00267                                       const unsigned char *bufp,
00268                                       unsigned len)
00269 {
00270         omapi_buffer_t *buffer;
00271         isc_result_t status;
00272         int bytes_copied = 0;
00273         unsigned copy_len;
00274         int sig_flags = SIG_MODE_UPDATE;
00275         omapi_connection_object_t *c;
00276 
00277         /* no need to verify len as it's unsigned */
00278         if (!h || h -> type != omapi_type_connection)
00279                 return DHCP_R_INVALIDARG;
00280         c = (omapi_connection_object_t *)h;
00281 
00282         /* If the connection is closed, return an error if the caller
00283            tries to copy in. */
00284         if (c -> state == omapi_connection_disconnecting ||
00285             c -> state == omapi_connection_closed)
00286                 return ISC_R_NOTCONNECTED;
00287 
00288         if (c -> outbufs) {
00289                 for (buffer = c -> outbufs;
00290                      buffer -> next; buffer = buffer -> next)
00291                         ;
00292         } else {
00293                 status = omapi_buffer_new (&c -> outbufs, MDL);
00294                 if (status != ISC_R_SUCCESS)
00295                         goto leave;
00296                 buffer = c -> outbufs;
00297         }
00298 
00299         while (bytes_copied < len) {
00300                 /* If there is no space available in this buffer,
00301                    allocate a new one. */
00302                 if (!BUFFER_BYTES_FREE (buffer)) {
00303                         status = (omapi_buffer_new (&buffer -> next, MDL));
00304                         if (status != ISC_R_SUCCESS)
00305                                 goto leave;
00306                         buffer = buffer -> next;
00307                 }
00308 
00309                 if (buffer -> tail > buffer -> head)
00310                         copy_len = sizeof (buffer -> buf) - buffer -> tail;
00311                 else
00312                         copy_len = buffer -> head - buffer -> tail;
00313 
00314                 if (copy_len > (len - bytes_copied))
00315                         copy_len = len - bytes_copied;
00316 
00317                 if (c -> out_key) {
00318                         if (!c -> out_context)
00319                                 sig_flags |= SIG_MODE_INIT;
00320                         status = omapi_connection_sign_data
00321                                 (sig_flags, c -> out_key, &c -> out_context,
00322                                  &bufp [bytes_copied], copy_len,
00323                                  (omapi_typed_data_t **)0);
00324                         if (status != ISC_R_SUCCESS)
00325                                 goto leave;
00326                 }
00327 
00328                 memcpy (&buffer -> buf [buffer -> tail],
00329                         &bufp [bytes_copied], copy_len);
00330                 buffer -> tail += copy_len;
00331                 c -> out_bytes += copy_len;
00332                 bytes_copied += copy_len;
00333                 if (buffer -> tail == sizeof buffer -> buf)
00334                         buffer -> tail = 0;
00335         }
00336 
00337         status = ISC_R_SUCCESS;
00338 
00339  leave:
00340         /*
00341          * If we have any bytes to send and we have a proper io object
00342          * inform the socket code that we would like to know when we
00343          * can send more bytes.
00344          */
00345         if (c->out_bytes != 0) {
00346                 if ((c->outer != NULL) &&
00347                     (c->outer->type == omapi_type_io_object)) {
00348                         omapi_io_object_t *io = (omapi_io_object_t *)c->outer;
00349                         isc_socket_fdwatchpoke(io->fd,
00350                                                ISC_SOCKFDWATCH_WRITE);
00351                 }
00352         }
00353 
00354         return (status);
00355 }
00356 
00357 /* Copy some bytes from the input buffer, and advance the input buffer
00358    pointer beyond the bytes copied out. */
00359 
00360 isc_result_t omapi_connection_copyout (unsigned char *buf,
00361                                        omapi_object_t *h,
00362                                        unsigned size)
00363 {
00364         unsigned bytes_remaining;
00365         unsigned bytes_this_copy;
00366         unsigned first_byte;
00367         omapi_buffer_t *buffer;
00368         unsigned char *bufp;
00369         int sig_flags = SIG_MODE_UPDATE;
00370         omapi_connection_object_t *c;
00371         isc_result_t status;
00372 
00373         if (!h || h -> type != omapi_type_connection)
00374                 return DHCP_R_INVALIDARG;
00375         c = (omapi_connection_object_t *)h;
00376 
00377         if (size > c -> in_bytes)
00378                 return ISC_R_NOMORE;
00379         bufp = buf;
00380         bytes_remaining = size;
00381         buffer = c -> inbufs;
00382 
00383         while (bytes_remaining) {
00384                 if (!buffer)
00385                         return ISC_R_UNEXPECTED;
00386                 if (BYTES_IN_BUFFER (buffer)) {
00387                         if (buffer -> head == (sizeof buffer -> buf) - 1)
00388                                 first_byte = 0;
00389                         else
00390                                 first_byte = buffer -> head + 1;
00391 
00392                         if (first_byte > buffer -> tail) {
00393                                 bytes_this_copy = (sizeof buffer -> buf -
00394                                                    first_byte);
00395                         } else {
00396                                 bytes_this_copy =
00397                                         buffer -> tail - first_byte;
00398                         }
00399                         if (bytes_this_copy > bytes_remaining)
00400                                 bytes_this_copy = bytes_remaining;
00401                         if (bufp) {
00402                                 if (c -> in_key) {
00403                                         if (!c -> in_context)
00404                                                 sig_flags |= SIG_MODE_INIT;
00405                                         status = omapi_connection_sign_data
00406                                                 (sig_flags,
00407                                                  c -> in_key,
00408                                                  &c -> in_context,
00409                                                  (unsigned char *)
00410                                                  &buffer -> buf [first_byte],
00411                                                  bytes_this_copy,
00412                                                  (omapi_typed_data_t **)0);
00413                                         if (status != ISC_R_SUCCESS)
00414                                                 return status;
00415                                 }
00416 
00417                                 memcpy (bufp, &buffer -> buf [first_byte],
00418                                         bytes_this_copy);
00419                                 bufp += bytes_this_copy;
00420                         }
00421                         bytes_remaining -= bytes_this_copy;
00422                         buffer -> head = first_byte + bytes_this_copy - 1;
00423                         c -> in_bytes -= bytes_this_copy;
00424                 }
00425                         
00426                 if (!BYTES_IN_BUFFER (buffer))
00427                         buffer = buffer -> next;
00428         }
00429 
00430         /* Get rid of any input buffers that we emptied. */
00431         buffer = (omapi_buffer_t *)0;
00432         while (c -> inbufs &&
00433                !BYTES_IN_BUFFER (c -> inbufs)) {
00434                 if (c -> inbufs -> next) {
00435                         omapi_buffer_reference (&buffer,
00436                                                 c -> inbufs -> next, MDL);
00437                         omapi_buffer_dereference (&c -> inbufs -> next, MDL);
00438                 }
00439                 omapi_buffer_dereference (&c -> inbufs, MDL);
00440                 if (buffer) {
00441                         omapi_buffer_reference
00442                                 (&c -> inbufs, buffer, MDL);
00443                         omapi_buffer_dereference (&buffer, MDL);
00444                 }
00445         }
00446         return ISC_R_SUCCESS;
00447 }
00448 
00449 isc_result_t omapi_connection_writer (omapi_object_t *h)
00450 {
00451         unsigned bytes_this_write;
00452         int bytes_written;
00453         unsigned first_byte;
00454         omapi_buffer_t *buffer;
00455         omapi_connection_object_t *c;
00456 
00457         if (!h || h -> type != omapi_type_connection)
00458                 return DHCP_R_INVALIDARG;
00459         c = (omapi_connection_object_t *)h;
00460 
00461         /* Already flushed... */
00462         if (!c -> out_bytes)
00463                 return ISC_R_SUCCESS;
00464 
00465         buffer = c -> outbufs;
00466 
00467         while (c -> out_bytes) {
00468                 if (!buffer)
00469                         return ISC_R_UNEXPECTED;
00470                 if (BYTES_IN_BUFFER (buffer)) {
00471                         if (buffer -> head == (sizeof buffer -> buf) - 1)
00472                                 first_byte = 0;
00473                         else
00474                                 first_byte = buffer -> head + 1;
00475 
00476                         if (first_byte > buffer -> tail) {
00477                                 bytes_this_write = (sizeof buffer -> buf -
00478                                                    first_byte);
00479                         } else {
00480                                 bytes_this_write =
00481                                         buffer -> tail - first_byte;
00482                         }
00483                         bytes_written = write (c -> socket,
00484                                                &buffer -> buf [first_byte],
00485                                                bytes_this_write);
00486                         /* If the write failed with EWOULDBLOCK or we wrote
00487                            zero bytes, a further write would block, so we have
00488                            flushed as much as we can for now.   Other errors
00489                            are really errors. */
00490                         if (bytes_written < 0) {
00491                                 if (errno == EWOULDBLOCK || errno == EAGAIN)
00492                                         return ISC_R_INPROGRESS;
00493                                 else if (errno == EPIPE)
00494                                         return ISC_R_NOCONN;
00495 #ifdef EDQUOT
00496                                 else if (errno == EFBIG || errno == EDQUOT)
00497 #else
00498                                 else if (errno == EFBIG)
00499 #endif
00500                                         return ISC_R_NORESOURCES;
00501                                 else if (errno == ENOSPC)
00502                                         return ISC_R_NOSPACE;
00503                                 else if (errno == EIO)
00504                                         return ISC_R_IOERROR;
00505                                 else if (errno == EINVAL)
00506                                         return DHCP_R_INVALIDARG;
00507                                 else if (errno == ECONNRESET)
00508                                         return ISC_R_SHUTTINGDOWN;
00509                                 else
00510                                         return ISC_R_UNEXPECTED;
00511                         }
00512                         if (bytes_written == 0)
00513                                 return ISC_R_INPROGRESS;
00514 
00515 #if defined (TRACING)
00516                         if (trace_record ()) {
00517                                 isc_result_t status;
00518                                 trace_iov_t iov [2];
00519                                 int32_t connect_index;
00520                                 
00521                                 connect_index = htonl (c -> index);
00522                                 
00523                                 iov [0].buf = (char *)&connect_index;
00524                                 iov [0].len = sizeof connect_index;
00525                                 iov [1].buf = &buffer -> buf [buffer -> tail];
00526                                 iov [1].len = bytes_written;
00527                                 
00528                                 status = (trace_write_packet_iov
00529                                           (trace_connection_input, 2, iov,
00530                                            MDL));
00531                                 if (status != ISC_R_SUCCESS) {
00532                                         trace_stop ();
00533                                         log_error ("trace %s output: %s",
00534                                                    "connection",
00535                                                    isc_result_totext (status));
00536                                 }
00537                         }
00538 #endif
00539 
00540                         buffer -> head = first_byte + bytes_written - 1;
00541                         c -> out_bytes -= bytes_written;
00542 
00543                         /* If we didn't finish out the write, we filled the
00544                            O.S. output buffer and a further write would block,
00545                            so stop trying to flush now. */
00546                         if (bytes_written != bytes_this_write)
00547                                 return ISC_R_INPROGRESS;
00548                 }
00549                         
00550                 if (!BYTES_IN_BUFFER (buffer))
00551                         buffer = buffer -> next;
00552         }
00553                 
00554         /* Get rid of any output buffers we emptied. */
00555         buffer = (omapi_buffer_t *)0;
00556         while (c -> outbufs &&
00557                !BYTES_IN_BUFFER (c -> outbufs)) {
00558                 if (c -> outbufs -> next) {
00559                         omapi_buffer_reference (&buffer,
00560                                                 c -> outbufs -> next, MDL);
00561                         omapi_buffer_dereference (&c -> outbufs -> next, MDL);
00562                 }
00563                 omapi_buffer_dereference (&c -> outbufs, MDL);
00564                 if (buffer) {
00565                         omapi_buffer_reference (&c -> outbufs, buffer, MDL);
00566                         omapi_buffer_dereference (&buffer, MDL);
00567                 }
00568         }
00569         return ISC_R_SUCCESS;
00570 }
00571 
00572 isc_result_t omapi_connection_get_uint32 (omapi_object_t *c,
00573                                           u_int32_t *result)
00574 {
00575         u_int32_t inbuf;
00576         isc_result_t status;
00577 
00578         status = omapi_connection_copyout ((unsigned char *)&inbuf,
00579                                            c, sizeof inbuf);
00580         if (status != ISC_R_SUCCESS)
00581                 return status;
00582 
00583         *result = ntohl (inbuf);
00584         return ISC_R_SUCCESS;
00585 }
00586 
00587 isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
00588                                           u_int32_t value)
00589 {
00590         u_int32_t inbuf;
00591 
00592         inbuf = htonl (value);
00593         
00594         return omapi_connection_copyin (c, (unsigned char *)&inbuf,
00595                                         sizeof inbuf);
00596 }
00597 
00598 isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
00599                                           u_int16_t *result)
00600 {
00601         u_int16_t inbuf;
00602         isc_result_t status;
00603 
00604         status = omapi_connection_copyout ((unsigned char *)&inbuf,
00605                                            c, sizeof inbuf);
00606         if (status != ISC_R_SUCCESS)
00607                 return status;
00608 
00609         *result = ntohs (inbuf);
00610         return ISC_R_SUCCESS;
00611 }
00612 
00613 isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
00614                                           u_int32_t value)
00615 {
00616         u_int16_t inbuf;
00617 
00618         inbuf = htons (value);
00619         
00620         return omapi_connection_copyin (c, (unsigned char *)&inbuf,
00621                                         sizeof inbuf);
00622 }
00623 
00624 isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
00625                                                 omapi_typed_data_t *data)
00626 {
00627         isc_result_t status;
00628         omapi_handle_t handle;
00629 
00630         /* Null data is valid. */
00631         if (!data)
00632                 return omapi_connection_put_uint32 (c, 0);
00633 
00634         switch (data -> type) {
00635               case omapi_datatype_int:
00636                 status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
00637                 if (status != ISC_R_SUCCESS)
00638                         return status;
00639                 return omapi_connection_put_uint32 (c, ((u_int32_t)
00640                                                         (data -> u.integer)));
00641 
00642               case omapi_datatype_string:
00643               case omapi_datatype_data:
00644                 status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
00645                 if (status != ISC_R_SUCCESS)
00646                         return status;
00647                 if (data -> u.buffer.len)
00648                         return omapi_connection_copyin
00649                                 (c, data -> u.buffer.value,
00650                                  data -> u.buffer.len);
00651                 return ISC_R_SUCCESS;
00652 
00653               case omapi_datatype_object:
00654                 if (data -> u.object) {
00655                         status = omapi_object_handle (&handle,
00656                                                       data -> u.object);
00657                         if (status != ISC_R_SUCCESS)
00658                                 return status;
00659                 } else
00660                         handle = 0;
00661                 status = omapi_connection_put_uint32 (c, sizeof handle);
00662                 if (status != ISC_R_SUCCESS)
00663                         return status;
00664                 return omapi_connection_put_uint32 (c, handle);
00665 
00666         }
00667         return DHCP_R_INVALIDARG;
00668 }
00669 
00670 isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
00671 {
00672         isc_result_t status;
00673         unsigned len = strlen (name);
00674 
00675         status = omapi_connection_put_uint16 (c, len);
00676         if (status != ISC_R_SUCCESS)
00677                 return status;
00678         return omapi_connection_copyin (c, (const unsigned char *)name, len);
00679 }
00680 
00681 isc_result_t omapi_connection_put_string (omapi_object_t *c,
00682                                           const char *string)
00683 {
00684         isc_result_t status;
00685         unsigned len;
00686 
00687         if (string)
00688                 len = strlen (string);
00689         else
00690                 len = 0;
00691 
00692         status = omapi_connection_put_uint32 (c, len);
00693         if (status != ISC_R_SUCCESS)
00694                 return status;
00695         if (len)
00696                 return omapi_connection_copyin
00697                         (c, (const unsigned char *)string, len);
00698         return ISC_R_SUCCESS;
00699 }
00700 
00701 isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
00702 {
00703         isc_result_t status;
00704         omapi_handle_t handle;
00705 
00706         if (h) {
00707                 status = omapi_object_handle (&handle, h);
00708                 if (status != ISC_R_SUCCESS)
00709                         return status;
00710         } else
00711                 handle = 0;     /* The null handle. */
00712         status = omapi_connection_put_uint32 (c, sizeof handle);
00713         if (status != ISC_R_SUCCESS)
00714                 return status;
00715         return omapi_connection_put_uint32 (c, handle);
00716 }
00717 
00718 isc_result_t omapi_connection_put_named_uint32 (omapi_object_t *c,
00719                                                 const char *name,
00720                                                 u_int32_t value)
00721 {
00722         isc_result_t status;
00723 
00724         status = omapi_connection_put_name(c, name);
00725         if (status != ISC_R_SUCCESS)
00726                 return (status);
00727 
00728         status = omapi_connection_put_uint32(c, sizeof(u_int32_t));
00729         if (status != ISC_R_SUCCESS)
00730                 return (status);
00731 
00732         status = omapi_connection_put_uint32(c, value);
00733         return (status);
00734 }
00735 

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1