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

📄 master_admin.c

📁 非常不错的网管开发包
💻 C
字号:
/* *  AgentX Administrative request handling */#include "config.h"#include <sys/types.h>#ifdef HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#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_NETINET_IN_H#include <netinet/in.h>#endif#include "asn1.h"#include "snmp_api.h"#include "snmp_client.h"#include "snmp_impl.h"#include "snmp.h"#include "system.h"#include "agentx/protocol.h"#include "agentx/client.h"#include "snmp_agent.h"#include "snmp_vars.h"#include "var_struct.h"#include "agent_registry.h"#include "agent_trap.h"#include "mibII/sysORTable.h"#include "snmp_debug.h"extern struct variable2 agentx_varlist[];extern struct timeval   starttime;struct snmp_session *find_agentx_session( struct snmp_session *session, int sessid){    struct snmp_session *sp;        for ( sp = session->subsession ; sp != NULL ; sp = sp->next ) {        if ( sp->sessid == sessid )	    return sp;    }    return NULL;}intopen_agentx_session(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    struct timeval now;    sp = (struct snmp_session *)malloc( sizeof( struct snmp_session ));    if ( sp == NULL ) {        session->s_snmp_errno = AGENTX_ERR_OPEN_FAILED;	return -1;    }    memcpy( sp, session, sizeof(struct snmp_session));        sp->sessid     = snmp_get_next_sessid();    sp->version    = pdu->version;    sp->timeout    = pdu->time;	/*	 * This next bit utilises unused SNMPv3 fields	 *   to store the subagent OID and description.	 * This really ought to use AgentX-specific fields,	 *   but it hardly seems worth it for a one-off use.	 *	 * But I'm willing to be persuaded otherwise....	 */    sp->securityAuthProto =	snmp_duplicate_objid(pdu->variables->name, pdu->variables->name_length);    sp->securityAuthProtoLen = pdu->variables->name_length;    sp->securityName = strdup( pdu->variables->val.string );    gettimeofday(&now, NULL);    sp->engineTime = calculate_time_diff( &now, &starttime );    sp->subsession = session;			/* link back to head */    sp->flags     |= SNMP_FLAGS_SUBSESSION;    sp->next       = session->subsession;    session->subsession = sp;    return sp->sessid;}intclose_agentx_session(struct snmp_session *session, int sessid){    struct snmp_session *sp, *prev = NULL;        for ( sp = session->subsession ; sp != NULL ; prev = sp, sp = sp->next ) {        if ( sp->sessid == sessid ) {	    unregister_mibs_by_session( sp );	    unregister_index_by_session( sp );	    unregister_sysORTable_by_session( sp );	    if ( prev )	        prev->next = sp->next;	    else	    	session->subsession = sp->next;	    free( sp );	    	    return AGENTX_ERR_NOERROR;	}    }        return AGENTX_ERR_NOT_OPEN;}intregister_agentx_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    char buf[32];    oid ubound = 0;    DEBUGMSGTL(("agentx:register","in register_agentx_list\n"));        sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    sprintf(buf, "AgentX subagent %ld", sp->sessid );    		 /*		* TODO: registration timeout		*	registration context		*/     if ( pdu->range_subid )	ubound = pdu->variables->val.objid[ pdu->range_subid-1 ];    switch (register_mib_range(buf, (struct variable *)agentx_varlist,			 sizeof(agentx_varlist[0]), 1,			 pdu->variables->name, pdu->variables->name_length,			 pdu->priority, pdu->range_subid, ubound, sp)) {	case MIB_REGISTERED_OK:				DEBUGMSGTL(("agentx:register",                                            "registered ok\n"));				return AGENTX_ERR_NOERROR;	case MIB_DUPLICATE_REGISTRATION:				DEBUGMSGTL(("agentx:register",                                            "duplicate registration\n"));				return AGENTX_ERR_DUPLICATE_REGISTRATION;	case MIB_REGISTRATION_FAILED:	default:				DEBUGMSGTL(("agentx:register",                                            "failed registration\n"));				return AGENTX_ERR_REQUEST_DENIED;    }}intunregister_agentx_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    oid ubound = 0;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    switch (unregister_mib_range(pdu->variables->name,    		       pdu->variables->name_length,		       pdu->priority, pdu->range_subid, ubound)) {	case MIB_UNREGISTERED_OK:				return AGENTX_ERR_NOERROR;	case MIB_NO_SUCH_REGISTRATION:				return AGENTX_ERR_UNKNOWN_REGISTRATION;	case MIB_UNREGISTRATION_FAILED:	default:				return AGENTX_ERR_REQUEST_DENIED;    }}intallocate_idx_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    struct variable_list *vp, *vp2, *next, *res;    int flags = 0;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    if ( pdu->flags & AGENTX_MSG_FLAG_ANY_INSTANCE )	flags |= ALLOCATE_ANY_INDEX;    if ( pdu->flags & AGENTX_MSG_FLAG_NEW_INSTANCE )	flags |= ALLOCATE_NEW_INDEX;		/*		 * XXX - what about errors?		 *		 *  If any allocations fail, then we need to		 *    *fully* release the earlier ones.		 *  (i.e. remove them completely from the index registry,		 *    not simply mark them as available for re-use)		 *		 * For now - assume they all succeed.		 */    for ( vp = pdu->variables ; vp != NULL; vp = next ) {	next = vp->next_variable;	res = register_index( vp, flags, session );	if ( res == NULL ) {		/*		 *  If any allocations fail, we need to *fully* release		 *	all previous ones (i.e. remove them completely		 *	from the index registry)		 */	    for ( vp2 = pdu->variables ; vp2 != vp ; vp2=vp2->next_variable )		remove_index( vp2, session );	    return AGENTX_ERR_INDEX_NONE_AVAILABLE;	/* XXX */	}	(void)snmp_clone_var( res, vp );	vp->next_variable = next;    }    return AGENTX_ERR_NOERROR;}intrelease_idx_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    struct variable_list *vp, *vp2;    int res;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    for ( vp = pdu->variables ; vp != NULL; vp = vp->next_variable ) {	res = unregister_index( vp, TRUE, session );		/*		 *  If any releases fail,		 *	we need to reinstate all previous ones.		 */	if ( res != SNMP_ERR_NOERROR ) {	    for ( vp2 = pdu->variables ; vp2 != vp; vp2 = vp2->next_variable )		(void) register_index( vp2, ALLOCATE_THIS_INDEX, session );	    return AGENTX_ERR_INDEX_NOT_ALLOCATED;	/* Probably */	}    }    return AGENTX_ERR_NOERROR;}intadd_agent_caps_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    register_sysORTable_sess(pdu->variables->name,    			pdu->variables->name_length,			(char *)pdu->variables->val.string, sp);    return AGENTX_ERR_NOERROR;}intremove_agent_caps_list(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    if ( unregister_sysORTable_sess(pdu->variables->name,    			       pdu->variables->name_length, sp) < 0 )        return AGENTX_ERR_UNKNOWN_AGENTCAPS;    else        return AGENTX_ERR_NOERROR;}intagentx_notify(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    struct variable_list *var;    int got_sysuptime = 0;    struct timeval now;    extern oid sysuptime_oid[], snmptrap_oid[];    extern size_t sysuptime_oid_len, snmptrap_oid_len;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    var = pdu->variables;    if (!var)	return AGENTX_ERR_PROCESSING_ERROR;    if ( snmp_oid_compare( var->name, var->name_length, 		sysuptime_oid, sysuptime_oid_len) == 0 ) {	got_sysuptime = 1;	var = var->next_variable;    }    if (!var || snmp_oid_compare( var->name, var->name_length, 			snmptrap_oid, snmptrap_oid_len) != 0 )	return AGENTX_ERR_PROCESSING_ERROR;		/*		 *  If sysUptime isn't the first varbind, don't worry.  		 *     send_trap_vars() will add it if necessary.		 *		 *  Note that if this behaviour is altered, it will		 *     be necessary to add sysUptime here,		 *     as this is valid AgentX syntax.		 */    send_trap_vars( -1, -1, pdu->variables );    return AGENTX_ERR_NOERROR;}intagentx_ping_response(struct snmp_session *session, struct snmp_pdu *pdu){    struct snmp_session *sp;    sp = find_agentx_session( session, pdu->sessid );    if ( sp == NULL )        return AGENTX_ERR_NOT_OPEN;    else        return AGENTX_ERR_NOERROR;}inthandle_master_agentx_packet(int operation,			    struct snmp_session *session,			    int reqid,			    struct snmp_pdu *pdu,			    void *magic){    struct agent_snmp_session  *asp;    struct timeval now;        if ( magic )        asp = (struct agent_snmp_session *)magic;    else    	asp = init_agent_snmp_session(session, snmp_clone_pdu(pdu) );    switch (pdu->command) {        case AGENTX_MSG_OPEN:		asp->pdu->sessid = open_agentx_session( session, pdu );		if ( asp->pdu->sessid == -1 )		    asp->status = session->s_snmp_errno;		break;        case AGENTX_MSG_CLOSE:		asp->status = close_agentx_session( session, pdu->sessid );		break;	case AGENTX_MSG_REGISTER:		asp->status = register_agentx_list( session, pdu );		break;	case AGENTX_MSG_UNREGISTER:		asp->status = unregister_agentx_list( session, pdu );		break;	case AGENTX_MSG_INDEX_ALLOCATE:		asp->status = allocate_idx_list( session, asp->pdu );		if ( asp->status != AGENTX_ERR_NOERROR) {		    snmp_free_pdu( asp->pdu );    		    asp->pdu = snmp_clone_pdu(pdu);		}		break;	case AGENTX_MSG_INDEX_DEALLOCATE:		asp->status = release_idx_list( session, pdu );		break;	case AGENTX_MSG_ADD_AGENT_CAPS:		asp->status = add_agent_caps_list( session, pdu );		break;	case AGENTX_MSG_REMOVE_AGENT_CAPS:		asp->status = remove_agent_caps_list( session, pdu );		break;	case AGENTX_MSG_NOTIFY:		asp->status = agentx_notify( session, pdu );		break;	case AGENTX_MSG_PING:		asp->status = agentx_ping_response( session, pdu );		break;	/* TODO: Other admin packets */		case AGENTX_MSG_GET:	case AGENTX_MSG_GETNEXT:	case AGENTX_MSG_GETBULK:	case AGENTX_MSG_TESTSET:	case AGENTX_MSG_COMMITSET:	case AGENTX_MSG_UNDOSET:	case AGENTX_MSG_CLEANUPSET:	case AGENTX_MSG_RESPONSE:		/* Shouldn't be handled here */		break;			default:		asp->status = AGENTX_ERR_PARSE_FAILED;		break;    }        if ( asp->outstanding_requests == NULL ) {        gettimeofday(&now, NULL);	asp->pdu->time    = calculate_time_diff( &now, &starttime );        asp->pdu->command = AGENTX_MSG_RESPONSE;	asp->pdu->errstat = asp->status;	snmp_send( asp->session, asp->pdu );	free(asp);    }    return 1;}

⌨️ 快捷键说明

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