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 the section ``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; }

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.

Next topic: Get and set
Previous topic: Main loop

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003