[BACK]Return to protocol.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / dhcp / dist / omapip

Annotation of src/external/mpl/dhcp/dist/omapip/protocol.c, Revision 1.1.1.1

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

CVSweb <webmaster@jp.NetBSD.org>