📄 master_request.c
字号:
/* * master_request.c * * Handle passing SNMP requests to and from AgentX clients */#include "config.h"#include <stdio.h>#include <sys/types.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#define SNMP_NEED_REQUEST_LIST#include "asn1.h"#include "mib.h"#include "snmp_api.h"#include "snmp_impl.h"#include "snmp_client.h"#include "snmp_debug.h"#include "snmp.h"#include "ds_agent.h"#include "default_store.h"#include "agentx/protocol.h"#include "agentx/client.h"#include "agentx/master.h"#include "snmp_agent.h"#include "snmp_vars.h"#include "var_struct.h"#include "mibII/sysORTable.h"#define MAX_VARS 64struct ax_variable_list { struct agent_snmp_session *asp; int num_vars;#ifdef ONE_IDEA { struct variable_list *entry; int index; } variables[MAX_VARS];#else struct variable_list* variables[MAX_VARS];#endif}; /* * Handle the response from an AgentX subagent, * merging the answers back into the original query */inthandle_agentx_response( int operation, struct snmp_session *session, int reqid, struct snmp_pdu *pdu, void *magic){ struct ax_variable_list *ax_vlist = (struct ax_variable_list *)magic; struct variable_list *vbp, *next; struct agent_snmp_session *asp = ax_vlist->asp; int i; struct ax_variable_list *retry_vlist; struct variable_list *vb_retry, *vbp2; struct subtree *retry_sub; int j; char buf[SPRINT_MAX_LEN]; asp->outstanding_requests = NULL; retry_vlist = NULL; vb_retry = NULL; vbp2 = NULL; DEBUGMSGTL(("agentx/master","handle_agentx_response() beginning...\n")); for ( i = 0, vbp = pdu->variables ; vbp && i < ax_vlist->num_vars ; i++, vbp = vbp->next_variable ) { if (vbp) { DEBUGMSGTL(("agentx/master"," handle_agentx_response: processing: ")); DEBUGMSGOID(("agentx/master",vbp->name, vbp->name_length)); DEBUGMSG(("agentx/master","\n")); } if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) ) { sprint_variable (buf, vbp->name, vbp->name_length, vbp); DEBUGMSGTL(("snmp_agent", " >> %s\n", buf)); } if ( !asp->exact && (vbp->type == SNMP_ENDOFMIBVIEW || in_a_view( vbp->name, &vbp->name_length, asp->pdu, vbp->type ))) { /* * Add unfulfilled requests to "retry" list */ retry_sub = find_subtree_next( vbp->name, vbp->name_length, NULL ); if ( retry_sub == NULL ) { next = ax_vlist->variables[i]->next_variable; snmp_clone_var( vbp, ax_vlist->variables[i] ); ax_vlist->variables[i]->next_variable = next; /* XXX - handle SNMPv1 */ ax_vlist->variables[i]->type = SNMP_ENDOFMIBVIEW; continue; } if (retry_vlist == NULL ) { retry_vlist = (struct ax_variable_list *) calloc( 1, sizeof( struct ax_variable_list)); if (retry_vlist == NULL) break; vb_retry = (struct variable_list *) calloc( 1, sizeof( struct variable_list)); if (vb_retry == NULL) { free(retry_vlist); break; } vbp2 = vb_retry; } else { vbp2->next_variable = (struct variable_list *) calloc( 1, sizeof( struct variable_list)); if (vbp2->next_variable == NULL) break; vbp2 = vbp2->next_variable; } j = retry_vlist->num_vars; retry_vlist->variables[ j ] = ax_vlist->variables[i]; retry_vlist->num_vars++; memcpy(vbp->name, retry_sub->name, retry_sub->namelen * sizeof(oid)); vbp->name_length = retry_sub->namelen; next = vbp2->next_variable; snmp_clone_var( vbp, vbp2 ); vbp2->next_variable = next; } else /* Got an answer, so use it */ if ( pdu->errstat != AGENTX_ERR_NOERROR ) { asp->status = pdu->errstat; } else { next = ax_vlist->variables[i]->next_variable; snmp_clone_var( vbp, ax_vlist->variables[i] ); ax_vlist->variables[i]->next_variable = next; } } if ( retry_vlist ) { /* * unfulfilled GETNEXT requests * * Need a new 'handle_getnext_request' routine * (parameters to be determined) */ asp->start = vb_retry; asp->end = vbp2; j = handle_var_list( asp ); if ( j != SNMP_ERR_NOERROR ) asp->status = j; else for ( i = 0, vbp2 = vb_retry ; i < retry_vlist->num_vars ; i++ , vbp2=vbp2->next_variable ) { /* * XXX - assumes success second time around * Needs to handle deferrals / failures */ next = retry_vlist->variables[i]->next_variable; snmp_clone_var( vbp2, retry_vlist->variables[i] ); retry_vlist->variables[i]->next_variable = next; } return j; } else DEBUGMSGTL(("agentx/master","handle_agentx_response() finishing...\n")); return handle_snmp_packet(operation, session, reqid, asp->pdu, (void*)asp);} /* * Return the request for this subagent transaction * (creating a new one if necessary) */struct request_list *get_agentx_request(struct agent_snmp_session *asp, struct snmp_session *ax_session, int transID ){ struct request_list *req; struct snmp_pdu *pdu; struct ax_variable_list *vlist; DEBUGMSGTL(("agentx/master","processing request...\n")); for (req = asp->outstanding_requests ; req != NULL ; req = req->next_request ) { if ( req->message_id == transID) return req; } /* * No existing request found, so create a new one */ req = (struct request_list *)calloc( 1, sizeof(struct request_list)); vlist = (struct ax_variable_list *)calloc( 1, sizeof(struct ax_variable_list)); pdu = snmp_pdu_create( 0 ); if ( req == NULL || pdu == NULL || vlist == NULL ) { free( pdu ); free( vlist ); free( req ); return NULL; } /* * Initialise the structures: * pdu, */ pdu->version = AGENTX_VERSION_1; pdu->reqid = snmp_get_next_transid(); pdu->transid = asp->pdu->transid; pdu->sessid = ax_session->sessid; switch (asp->pdu->command ) { case SNMP_MSG_GET: DEBUGMSGTL(("agentx/master","-> get\n")); pdu->command = AGENTX_MSG_GET; break; case SNMP_MSG_GETNEXT: case SNMP_MSG_GETBULK: DEBUGMSGTL(("agentx/master","-> getnext/bulk\n")); pdu->command = AGENTX_MSG_GETNEXT; break; case SNMP_MSG_SET: DEBUGMSGTL(("agentx/master","-> set\n")); switch ( asp->mode ) { /* * This is a provisional mapping of * UCD SET handling into the AgentX * protocol. * It is by no means definitive. */ case RESERVE1: case RESERVE2: pdu->command = AGENTX_MSG_TESTSET; break; case ACTION: pdu->command = AGENTX_MSG_COMMITSET; break; case UNDO: pdu->command = AGENTX_MSG_UNDOSET; break; case FREE: case COMMIT: pdu->command = AGENTX_MSG_CLEANUPSET; break; } break; default: DEBUGMSGTL(("agentx/master","-> unknown\n")); free( req ); free( pdu ); free( vlist ); return NULL; } /* callback data, */ vlist->asp = asp; vlist->num_vars = 0; /* and request */ req->request_id = pdu->reqid; req->message_id = pdu->transid; req->callback = handle_agentx_response; req->cb_data = vlist; req->pdu = pdu; req->session = ax_session; req->next_request = asp->outstanding_requests; asp->outstanding_requests = req; DEBUGMSGTL(("agentx/master","processing request... DONE\n")); return req;} /* * Delegate a request to an AgentX subagent * adding it to the list for that particular agent */intagentx_add_request( struct agent_snmp_session *asp, struct variable_list *vbp){ struct snmp_pdu *pdu = asp->pdu; struct snmp_session *ax_session; struct request_list *request; struct ax_variable_list *ax_vlist; struct subtree *sub; int sessid; if (asp->pdu->command == SNMP_MSG_SET && asp->mode == RESERVE1 ) return AGENTX_ERR_NOERROR; ax_session = get_session_for_oid( vbp->name, vbp->name_length ); sessid = ax_session->sessid; if ( ax_session->flags & SNMP_FLAGS_SUBSESSION ) ax_session = ax_session->subsession; request = get_agentx_request( asp, ax_session, pdu->transid ); request->pdu->sessid = sessid; /* Use the registered (sub)session's ID, not the main listening session ID */ ax_vlist = (struct ax_variable_list *)request->cb_data; ax_vlist->variables[ ax_vlist->num_vars ] = vbp; ax_vlist->num_vars++; if ( asp->exact ) snmp_pdu_add_variable( request->pdu, vbp->name, vbp->name_length, vbp->type, (u_char*)(vbp->val.string), vbp->val_len); else { sub = find_subtree_previous( vbp->name, vbp->name_length, NULL ); snmp_pdu_add_variable( request->pdu, vbp->name, vbp->name_length, ASN_PRIV_INCL_RANGE, (u_char*)sub->name, sub->namelen); } return AGENTX_ERR_NOERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -