I'm trying to forward PDU's to another master snmp agent after handling them in 
the usual master agent (or before or instead of handling them, all under 
program control).

I haven't found anything like this in the archives.  Is this really weird?

I've cobbled together code from some of the apps, and it seems to work for GET 
and GETNEXT, but I'm not sure how to handle GETBULK.  Looks like the handler 
gets called once per varbind in a GETBULK response, and requests->repeat 
decrements, while requests->orig_repeat is non-zero and constant.

I think I should be able to tell when the handler is called for the last time, 
and call snmp_synch_response with a PDU containing the varbinds, then somehow 
update the varbinds that the caller of the handler receives.

Or perhaps I could call snmp_synch_response when the handler is called for the 
first time, and update the varbinds that the caller of the handler receives, 
but I haven't figured out how.

Question: Should I call snmp_add_var on each call, or can I do all varbinds at 
once, ie, when are they valid?

Question: How can I update the varbinds that the caller of the handler receives?

One problem is that I'm confused as to the meaning of request versus reqinfo 
versus the varbinds in request->requestvb, and when they're valid for GETBULK.  
Are there any docs on this?  Sign me up for Robert's upcoming book!

Best question: Can anyone point me to existing code that does something 
similar?  

Anyway, here's my very na�ve code so far.  It's very sketchy, but does it look 
like it's in the right direction?

/* Forward PDU's to another Master Agent.  Call this from a handler.
*/

int forward(netsnmp_mib_handler *handler,
                     netsnmp_handler_registration *reginfo,
                     netsnmp_agent_request_info *reqinfo,
                     netsnmp_request_info *requests)
{
    netsnmp_request_info *request;
    netsnmp_pdu     *response;
    static netsnmp_pdu    *pdu = NULL;
    netsnmp_variable_list *var;


        long ll;
        char buf[100];
        if(noForward)
                return 0;
        ++calls;
        printf("calls %d\n", ++calls);
        fflush(stdout);  

// forward the pdu for first (or should it be the last?) repeat only
         request = requests;
         if( request->orig_repeat > 0 && request->repeat != 
request->orig_repeat ) {
                return 0;
         }

         // create a PDU to be forwarded
        if( pdu == NULL ){
        switch (reqinfo->mode) {
        case MODE_GETNEXT:
                    pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
                        break;
        case MODE_GETBULK:
                    pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
                        break;
                case MODE_GET:
                    pdu = snmp_pdu_create(SNMP_MSG_GET);
                        break;
        case MODE_SET_RESERVE1:
                    pdu = snmp_pdu_create(SNMP_MSG_SET);
            break;

        default:               /* == the other SET modes */
 
                    pdu = snmp_pdu_create(SNMP_MSG_GET);
           break;

        }
    }

// build the pdu to be forwarded

        printf("requests->repeat %d\n", requests->repeat );
        fflush(stdout);  
    for (var = requests->requestvb; var; var = var->next_variable) {
 
        if (request->processed != 0)
            continue;

                sprintf(buf, "%ld", *(var->val.integer) );
                ll = var->name_length ;
        if (snmp_add_var(pdu, var->name, ll , 'i' , buf ) != 0) {
                        snmp_perror( "Can't snmp_add_var");
                        failures++;
                        }
    }           // end for 

     if (failures) {
        return SNMP_ERR_RESOURCEUNAVAILABLE;  // for now...
    }


        snmp_synch_response ( mySession, pdu, & response );
        if (response){
                                                // clear and update the 
request's varbinds
                request = requests;
                for (var = response->variables ; var; var = var->next_variable, 
request = request->next ) {
                        // we assume request is the same varbind as var.
                        // FIX LATER, we really need to check this.
                        // FIX LATER, what do we do if it's not???
                        
                        if (request->requestvb->val_len  != var->val_len){
                                free((void*)request->requestvb->val.integer );
                                request->requestvb->val.integer = 
malloc(var->val_len);
                        }
                        memcpy(request->requestvb->val.integer 
,var->val.integer , var->val_len);

                        }
                if(request != NULL) {   // mismatch!
                                return SNMP_ERR_RESOURCEUNAVAILABLE;  // for 
now...
                }
                snmp_free_pdu(response);
                }
        pdu = NULL;     // reset PDU so we re-alloc it next time.

        return 0;
}

Thanks,

Phil Gillis



-------------------------------------------------------
This SF.Net email is sponsored by: InterSystems CACHE
FREE OODBMS DOWNLOAD - A multidimensional database that combines
robust object and relational technologies, making it a perfect match
for Java, C++,COM, XML, ODBC and JDBC. www.intersystems.com/match8
_______________________________________________
Net-snmp-coders mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to