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

Get and set

When xselect indicates the SMUX file descriptor is ready for reading, the reference peer program calls the routine smux_wait to return the next event from the SNMP agent. The peer program invoked The routine do_smux, which implements the SNMP ``get'', ``get-next'' and ``set'' operations. The routine looks like this:

static
do_smux(pdu, offset)
    register struct type_SNMP_GetRequest__PDU *pdu;
    int             offset;
{
    int             idx, status;
    object_instance ois;
    register struct type_SNMP_VarBindList *vp;
    IFP             method;

quantum = pdu->request__id; idx = 0; for (vp = pdu->variable__bindings; vp; vp = vp->next) { register OI oi; register OT ot; register struct type_SNMP_VarBind *v = vp->VarBind;

idx++;

if (offset == SMUX__PDUs_get__next__request) { if ((oi = name2inst(v->name)) == NULLOI && (oi = next2inst(v->name)) == NULLOI) goto no_name;

if ((ot = oi->oi_type)->ot_getfnx == NULLIFP) goto get_next; } else { if ((oi = name2inst(v->name)) == NULLOI) goto no_name; ot = oi->oi_type; if ((offset == SMUX__PDUs_get__request ? ot->ot_getfnx : ot->ot_setfnx) == NULLIFP) { no_name: ; pdu->error__status = error__status_noSuchName; goto out; } }

try_again:    ;
        switch (offset) {
        case SMUX__PDUs_get__request:
            if (!(method = ot->ot_getfnx))
                goto no_name;
            break;

case SMUX__PDUs_get__next__request: if (!(method = ot->ot_getfnx)) goto get_next; break;

case SMUX__PDUs_set__request: if (!(method = ot->ot_setfnx)) goto no_name; break;

default: goto no_name; }

        switch (status = (method) (oi, v, offset)) {
        case NOTOK:    /* get-next wants a bump */
    get_next:    ;
            oi = &ois ;
            for (;;) {
                if ((ot = ot->ot_next) == NULLOT) {
                    pdu->error__status = error__status_noSuchName;
                    goto out;
                }
                oi->oi_name = (oi->oi_type = ot)->ot_name;
                if (ot->ot_getfnx)
                    goto try_again;
            }

        case error__status_noError:
            break;

default: pdu->error__status = status; goto out; } } idx = 0;

out: ; pdu->error__index = idx;

if (smux_response(pdu) == NOTOK) { LIB_ERROR2("smux_response: %s [%s]", smux_error(smux_errno), smux_info); smux_fd = NOTOK; } }

The actual code is fairly straightforward. First, the variable quantum is set to the request ID for this transaction. The SMUX protocol requires that this number increment for each SNMP operation that the agent handles, so the peer program can use it to see when it should re-read its local variables. (A single SNMP operation received by the agent might result in multiple SMUX protocol transactions with the program.)

Next, the code loops through the list of variables requested. The object instance is determined and loaded into oin and the corresponding object type is loaded into ot, and the access is checked.

Finally, the user-defined routine is invoked. This routine returns one of these values:

NOTOK
error__status_noError
error__status_tooBig
error__status_noSuchName
error__status_badValue
error__status_readOnly
error__status_genErr
The first value is returned only if the get-next operator is being invoked and the routine did not have any more object instances for the object type in question. The remainder are similar to the error codes returned by the SNMP agent and are self-explanatory.

Once an answer is returned, the loop either continues or is broken and a response is written back using the smux_response routine. On failure, smux_error will be set to one of parameterMissing, invalidOperation, or youLoseBig.


© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005