DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Developing SMUX peers for SNMP agents

Events

When xselect indicates the SMUX file descriptor is ready for reading, the peer program calls the routine smux_wait to return the next event from the SNMP agent.

The event is filled-in from a static area. On the next call to smux_init, smux_close, or smux_wait, the value is overwritten.

On failure, smux_errno will be set to one of parameterMissing, invalidOperation, inProgress, or youLoseBig. See ``Error recovery'' for an explanation of these error codes. The peer program takes the appropriate action based on the error code returned.

struct type_SNMP_SMUX__PDUs *event;

if (smux_wait(&event, NOTOK) == NOTOK) { if (smux_errno == inProgress) return;

LIB_ERROR2("smux_wait: %s [%s]", smux_error(smux_errno), smux_info); smux_fd = NOTOK; return; }

Next, the peer program switches based on the actual event returned:
SMUX__PDUs_registerResponse
SMUX__PDUs_get__request
SMUX__PDUs_get__next__request
SMUX__PDUs_set__request
SMUX__PDUs_commitOrRollback
SMUX__PDUs_close
The actual code is fairly straightforward:
switch (event->offset) {
case SMUX__PDUs_registerResponse:
    if (!tc->t_name)
        goto unexpected;
    {
        struct type_SNMP_RRspPDU *rsp = event->un.registerResponse;

if (rsp->parm == RRspPDU_failure) LIB_ERROR1("SMUX registration of %s failed\n", tc->t_tree); else { if (debug) printf("SMUX register: %s out=%d\n", tc->t_tree, rsp->parm); got_at_least_one = 1; } } for (tc++; tc->t_tree; tc++) if (tc->t_name) { if (smux_register(tc->t_name, -1, tc->t_access) == NOTOK) { LIB_ERROR2("smux_register: %s [%s]\n", smux_error(smux_errno), smux_info); goto losing; } if (debug) printf("SMUX register: %s in=%d\n", tc->t_tree, -1); break; } if (!tc->t_tree) { if (!got_at_least_one) { dont_bother_anymore = 1; (void) smux_close(goingDown); goto losing; } if (smux_trap(trap_coldStart, 0, (struct type_SNMP_VarBindList *) 0) == NOTOK) { LIB_ERROR2("smux_trap: %s [%s]", smux_error(smux_errno), smux_info); goto losing; } } break;

case SMUX__PDUs_get__request: case SMUX__PDUs_get__next__request: case SMUX__PDUs_set__request: do_smux(event->un.get__request, event->offset); break;

case SMUX__PDUs_commitOrRollback:
    {
        register struct triple *tz;

for (tz = triples; tz->t_tree; tz++) if (tz->t_name) (void) (*tz->t_sync) (event->un.commitOrRollback->parm); } break;

case SMUX__PDUs_close: if (debug) printf("SMUX close: %s\n", smux_error(event->un.close->parm)); goto losing;

case SMUX__PDUs_simple: case SMUX__PDUs_registerRequest: case SMUX__PDUs_get__response: case SMUX__PDUs_trap: unexpected: ; LIB_ERROR1("unexpectedOperation: %d", event->offset); (void) smux_close(protocolError); goto losing;

default: LIB_ERROR1("badOperation: %d", event->offset); (void) smux_close(protocolError); goto losing; } free_SNMP_SMUX_PDU(event);

Note the use of the smux_trap routine to send a coldStart trap once the peer has successfully registered the MIB module it will be managing. The trap codes are:
trap_coldStart
trap_warmStart
trap_linkDown
trap_linkUp
trap_authenticationFailure
trap_egpNeighborLoss
trap_enterpriseSpecific
If this routine fails, smux_errno will be set to one of invalidOperation, congestion, or youLoseBig.
© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004