⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subagent.c

📁 非常不错的网管开发包
💻 C
字号:
/* *  AgentX sub-agent */#include "config.h"#include <sys/types.h>#ifdef HAVE_STDLIB_H#include <stdlib.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#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <sys/errno.h>#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#include "asn1.h"#include "snmp_api.h"#include "snmp_impl.h"#include "snmp_client.h"#include "snmp.h"#include "snmp_vars.h"#include "snmp_agent.h"#include "var_struct.h"#include "snmpd.h"#include "agentx/protocol.h"#include "agentx/client.h"#include "default_store.h"#include "ds_agent.h"#include "callback.h"#include "agent_registry.h"#include "agent_callbacks.h"#include "agent_trap.h"#include "snmp_debug.h"#include "mib_module_config.h"#ifdef USING_MIBII_SYSORTABLE_MODULE#include "mibII/sysORTable.h"#endif#include "system.h"struct agent_set_info {    int			  transID;    int			  mode;    time_t		  uptime;    struct snmp_session  *sess;    struct variable_list *var_list;    struct agent_set_info *next;};static struct agent_set_info *Sets;voidsave_set_vars( struct snmp_session *ss, struct snmp_pdu *pdu ){    struct agent_set_info *ptr;    struct timeval now;    struct snmp_pdu *pdu2;    extern struct timeval starttime;    ptr = (struct agent_set_info *)malloc(sizeof(struct agent_set_info));    if (ptr == NULL )	return;	/*	 * Save the important information	 */    ptr->transID = pdu->transid;    ptr->sess    = ss;    ptr->mode    = RESERVE1;    gettimeofday(&now, NULL);    ptr->uptime = calculate_time_diff(&now, &starttime);		/* Lazy way to copy the variables! */    pdu2 = snmp_clone_pdu( pdu );    if ( pdu2 == NULL ) {	free( ptr );	return;    }    ptr->var_list = pdu2->variables;	    pdu2->variables = NULL;    snmp_free_pdu( pdu2 );    ptr->next = Sets;    Sets = ptr;}voidrestore_set_vars( struct agent_snmp_session *asp ){    struct agent_set_info *ptr;    for ( ptr=Sets ; ptr != NULL ; ptr=ptr->next )	if ( ptr->sess == asp->session && ptr->transID == asp->pdu->transid ) {	    if ( ptr->var_list == NULL )		return;	    asp->rw      	= WRITE;	    asp->pdu->variables = ptr->var_list;	    asp->start		= ptr->var_list;	    asp->end		= ptr->var_list;	    while ( asp->end->next_variable )		asp->end = asp->end->next_variable;	    ptr->mode		= asp->mode;	    return;	}    return;}intset_mode( struct snmp_session *ss, struct snmp_pdu *pdu ){    struct agent_set_info *ptr;    for ( ptr=Sets ; ptr != NULL ; ptr=ptr->next )	if ( ptr->sess == ss && ptr->transID == pdu->transid )	    return ptr->mode;    return -1;}voidfree_set_vars( struct snmp_session *ss, struct snmp_pdu *pdu ){    struct agent_set_info *ptr, *prev=NULL;    for ( ptr=Sets ; ptr != NULL ; ptr=ptr->next )	if ( ptr->sess == ss && ptr->transID == pdu->transid ) {	    if ( prev )		prev->next = ptr->next;	    else		Sets = ptr->next;	    snmp_free_varbind(ptr->var_list);	    free(ptr);	    return;	}}inthandle_agentx_packet(int operation, struct snmp_session *session, int reqid,                   struct snmp_pdu *pdu, void *magic){    struct agent_snmp_session  *asp;    int status, allDone, i;    struct variable_list *var_ptr, *var_ptr2;    asp = init_agent_snmp_session( session, snmp_clone_pdu(pdu) );    DEBUGMSGTL(("agentx/subagent","handling agentx request....\n"));    switch (pdu->command) {    case AGENTX_MSG_GET:        DEBUGMSGTL(("agentx/subagent","  -> get\n"));	status = handle_next_pass( asp );	break;    case AGENTX_MSG_GETBULK:        DEBUGMSGTL(("agentx/subagent","  -> getbulk\n"));	    /*	     * GETBULKS require multiple passes. The first pass handles the	     * explicitly requested varbinds, and subsequent passes append	     * to the existing var_op_list.  Each pass (after the first)	     * uses the results of the preceeding pass as the input list	     * (delimited by the start & end pointers.	     * Processing is terminated if all entries in a pass are	     * EndOfMib, or the maximum number of repetitions are made.	     */	asp->exact   = FALSE;		/*		 * Limit max repetitions to something reasonable		 *	XXX: We should figure out what will fit somehow...		 */	if ( asp->pdu->errindex > 100 )	    asp->pdu->errindex = 100;	status = handle_next_pass( asp );	/* First pass */	if ( status != SNMP_ERR_NOERROR )	    break;	while ( asp->pdu->errstat-- > 0 )	/* Skip non-repeaters */	    asp->start = asp->start->next_variable;	asp->pdu->errindex--;           /* First repetition was handled above */	while ( asp->pdu->errindex-- > 0 ) {	/* Process repeaters */		/*		 * Add new variable structures for the		 * repeating elements, ready for the next pass.		 * Also check that these are not all EndOfMib		 */	    allDone = TRUE;		/* Check for some content */	    for ( var_ptr = asp->start;		  var_ptr != asp->end->next_variable;		  var_ptr = var_ptr->next_variable ) {				/* XXX: we don't know the size of the next					OID, so assume the maximum length */		var_ptr2 = snmp_add_null_var(asp->pdu, var_ptr->name, MAX_OID_LEN);		for ( i=var_ptr->name_length ; i<MAX_OID_LEN ; i++)		    var_ptr2->name[i] = '\0';		var_ptr2->name_length = var_ptr->name_length;		if ( var_ptr->type != SNMP_ENDOFMIBVIEW )		    allDone = FALSE;	    }	    if ( allDone )		break;	    asp->start = asp->end->next_variable;	    while ( asp->end->next_variable != NULL )		asp->end = asp->end->next_variable;	    	    status = handle_next_pass( asp );	    if ( status != SNMP_ERR_NOERROR )		break;	}	break;    case AGENTX_MSG_GETNEXT:        DEBUGMSGTL(("agentx/subagent","  -> getnext\n"));	asp->exact   = FALSE;	status = handle_next_pass( asp );	break;    case AGENTX_MSG_TESTSET:        DEBUGMSGTL(("agentx/subagent","  -> testset\n"));    	    /*	     * In the UCD architecture the first two passes through var_op_list	     * verify that all types, lengths, and values are valid	     * and may reserve resources.	     * These correspond to the first AgentX pass - TESTSET	     */	asp->rw      = WRITE;        asp->mode = RESERVE1;	save_set_vars( session, pdu );	status = handle_next_pass( asp );	if ( status != SNMP_ERR_NOERROR ) {	    asp->mode = FREE;	    (void) handle_next_pass( asp );	    free_set_vars( session, pdu );	    break;	}        asp->mode = RESERVE2;	status = handle_next_pass( asp );	if ( status != SNMP_ERR_NOERROR ) {	    asp->mode = FREE;	    (void) handle_next_pass( asp );	    free_set_vars( session, pdu );	}	break;	    /*	     * The third and fourth passes in the UCD architecture	     *   correspond to distinct AgentX passes,	     *   as does the "undo" pass, in case of errors elsewhere	     */    case AGENTX_MSG_COMMITSET:        DEBUGMSGTL(("agentx/subagent","  -> commitset\n"));        asp->mode = ACTION;        restore_set_vars( asp );        if ( asp->pdu->variables == NULL )            status = AGENTX_ERR_PROCESSING_ERROR;        else	    status = handle_next_pass( asp );	if ( status != SNMP_ERR_NOERROR ) {	    asp->mode = UNDO;	    (void) handle_next_pass( asp );	    free_set_vars( session, pdu );	}        asp->pdu->variables = NULL;	break;    case AGENTX_MSG_CLEANUPSET:        DEBUGMSGTL(("agentx/subagent","  -> cleanupset\n"));        switch ( set_mode( session, pdu )) {            case RESERVE1:             case RESERVE2:             case UNDO:                 asp->mode = FREE;                break;            case ACTION:                asp->mode = COMMIT;                break;        }        restore_set_vars( asp );        if ( asp->pdu->variables == NULL )            status = AGENTX_ERR_PROCESSING_ERROR;        else	    status = handle_next_pass( asp );	free_set_vars( session, pdu );        asp->pdu->variables = NULL;	break;    case AGENTX_MSG_UNDOSET:        DEBUGMSGTL(("agentx/subagent","  -> undoset\n"));        asp->mode = UNDO;        restore_set_vars( asp );        if ( asp->pdu->variables == NULL )            status = AGENTX_ERR_PROCESSING_ERROR;        else	    status = handle_next_pass( asp );	free_set_vars( session, pdu );        asp->pdu->variables = NULL;	break;    case AGENTX_MSG_RESPONSE:        DEBUGMSGTL(("agentx/subagent","  -> response\n"));	free( asp );	return 0;    default:        DEBUGMSGTL(("agentx/subagent","  -> unknown (%d)\n", pdu->command ));	free( asp );	return 0;    }	    	    if ( asp->outstanding_requests == NULL ) {	asp->pdu->command = AGENTX_MSG_RESPONSE;	asp->pdu->errstat = status;	snmp_send( asp->session, asp->pdu );	free( asp );    }    DEBUGMSGTL(("agentx/subagent","  FINISHED\n\n"));    return 1;}extern struct snmp_session *main_session;	/* from snmp_agent.c */intagentx_registration_callback(int majorID, int minorID, void *serverarg,                         void *clientarg) {  struct register_parameters *reg_parms =    (struct register_parameters *) serverarg;  struct snmp_session *agentx_ss =    (struct snmp_session *) clientarg;  if (minorID == SNMPD_CALLBACK_REGISTER_OID)    return agentx_register(agentx_ss,		    reg_parms->name, reg_parms->namelen,		    reg_parms->priority,		    reg_parms->range_subid, reg_parms->range_ubound);  else    return agentx_unregister(agentx_ss,		    reg_parms->name, reg_parms->namelen,		    reg_parms->priority,		    reg_parms->range_subid, reg_parms->range_ubound);}#ifdef USING_MIBII_SYSORTABLE_MODULEintagentx_sysOR_callback(int majorID, int minorID, void *serverarg,                         void *clientarg) {  struct register_sysOR_parameters *reg_parms =    (struct register_sysOR_parameters *) serverarg;  struct snmp_session *agentx_ss =    (struct snmp_session *) clientarg;  if (minorID == SNMPD_CALLBACK_REG_SYSOR)    return agentx_add_agentcaps(agentx_ss,		    reg_parms->name, reg_parms->namelen,		    reg_parms->descr);  else    return agentx_remove_agentcaps(agentx_ss,		    reg_parms->name, reg_parms->namelen);}#endifstatic intsubagent_shutdown(int majorID, int minorID, void *serverarg, void *clientarg) {  struct snmp_session *thesession = (struct snmp_session *) clientarg;  DEBUGMSGTL(("agentx/subagent","shutting down session....\n"));  if (thesession == NULL) {    DEBUGMSGTL(("agentx/subagent","Empty session to shutdown\n"));    return 0;  }  agentx_close_session(thesession, AGENTX_CLOSE_SHUTDOWN);  snmp_close(thesession);  free(thesession);  DEBUGMSGTL(("agentx/subagent","shut down finished.\n"));  return 1;}static intsubagent_register_for_traps(int majorID, int minorID, void *serverarg, void *clientarg) {  struct snmp_session *thesession = (struct snmp_session *) clientarg;  DEBUGMSGTL(("agentx/subagent","registering trap session....\n"));  if (thesession == NULL) {    DEBUGMSGTL(("agentx/subagent","No session to register\n"));    return 0;  }  if (add_trap_session( thesession, AGENTX_MSG_NOTIFY, AGENTX_VERSION_1) == 0){    DEBUGMSGTL(("agentx/subagent","Trap session registration failed\n"));    return 0;  }  DEBUGMSGTL(("agentx/subagent","Trap session registered OK\n"));  return 1;}voidsubagent_pre_init( void ){    struct snmp_session sess;    DEBUGMSGTL(("agentx/subagent","initializing....\n"));    if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) != SUB_AGENT )	return;    snmp_sess_init( &sess );    sess.version = AGENTX_VERSION_1;    sess.peername = strdup(AGENTX_SOCKET);    sess.retries = SNMP_DEFAULT_RETRIES;    sess.timeout = SNMP_DEFAULT_TIMEOUT;    sess.flags  |= SNMP_FLAGS_STREAM_SOCKET;         sess.local_port = 0;	/* client */    sess.callback = handle_agentx_packet;    sess.authenticator = NULL;    main_session = snmp_open_ex( &sess, 0, agentx_parse, 0, agentx_build,                                   agentx_check_packet );    if ( main_session == NULL ) {      /* diagnose snmp_open errors with the input struct snmp_session pointer */	snmp_sess_perror("subagent_pre_init", &sess);	exit(1);    }    if ( agentx_open_session( main_session ) < 0 ) {	snmp_close( main_session );	exit(1);    }    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_PREMIB_READ_CONFIG,                           subagent_register_for_traps, main_session);    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,                           subagent_shutdown, main_session);    snmp_register_callback(SNMP_CALLBACK_APPLICATION,                           SNMPD_CALLBACK_REGISTER_OID,                           agentx_registration_callback, main_session);    snmp_register_callback(SNMP_CALLBACK_APPLICATION,                           SNMPD_CALLBACK_UNREGISTER_OID,                           agentx_registration_callback, main_session);#ifdef USING_MIBII_SYSORTABLE_MODULE    snmp_register_callback(SNMP_CALLBACK_APPLICATION,                           SNMPD_CALLBACK_REG_SYSOR,                           agentx_sysOR_callback, main_session);    snmp_register_callback(SNMP_CALLBACK_APPLICATION,                           SNMPD_CALLBACK_UNREG_SYSOR,                           agentx_sysOR_callback, main_session);#endif    DEBUGMSGTL(("agentx/subagent","initializing....  DONE\n"));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -