📄 master_admin.c
字号:
/* * AgentX Administrative request handling */#include <net-snmp/net-snmp-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# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# 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#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "agentx/protocol.h"#include "agentx/client.h"#include <net-snmp/agent/agent_index.h>#include <net-snmp/agent/agent_trap.h>#include "mibII/sysORTable.h"#include "master.h"extern struct timeval starttime;netsnmp_session *find_agentx_session(netsnmp_session * session, int sessid){ netsnmp_session *sp; for (sp = session->subsession; sp != NULL; sp = sp->next) { if (sp->sessid == sessid) return sp; } return NULL;}intopen_agentx_session(netsnmp_session * session, netsnmp_pdu *pdu){ netsnmp_session *sp; struct timeval now; DEBUGMSGTL(("agentx/master", "open %08p\n", session)); sp = (netsnmp_session *) malloc(sizeof(netsnmp_session)); if (sp == NULL) { session->s_snmp_errno = AGENTX_ERR_OPEN_FAILED; return -1; } memcpy(sp, session, sizeof(netsnmp_session)); sp->sessid = snmp_get_next_sessid(); sp->version = pdu->version; sp->timeout = pdu->time; /* * Be careful with fields: if these aren't zeroed, they will get free()d * more than once when the session is closed -- once in the main session, * and once in each subsession. Basically, if it's not being used for * some AgentX-specific purpose, it ought to be zeroed here. */ sp->community = NULL; sp->peername = NULL; sp->contextEngineID = NULL; sp->contextName = NULL; sp->securityEngineID = NULL; sp->securityPrivProto = NULL; /* * 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((char *) 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->flags &= ~AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER; sp->flags |= (pdu->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER); sp->next = session->subsession; session->subsession = sp; DEBUGMSGTL(("agentx/master", "opened %08p = %d with flags = %02x\n", sp, sp->sessid, sp->flags & AGENTX_MSG_FLAGS_MASK)); return sp->sessid;}intclose_agentx_session(netsnmp_session * session, int sessid){ netsnmp_session *sp, **prevNext; DEBUGMSGTL(("agentx/master", "close %08p, %d\n", session, sessid)); if (session != NULL && sessid == -1) { unregister_mibs_by_session(session); unregister_index_by_session(session); unregister_sysORTable_by_session(session); if (session->myvoid != NULL) { free(session->myvoid); } /* * The following is necessary to avoid locking up the agent when * a sugagent dies during a set request. We must clean up the * requests, so that the delegated request will be completed and * further requests can be processed */ netsnmp_remove_delegated_requests_for_session(session); if (session->subsession != NULL) { netsnmp_session *subsession = session->subsession; for(; subsession; subsession = subsession->next) { netsnmp_remove_delegated_requests_for_session(subsession); } } return AGENTX_ERR_NOERROR; } prevNext = &(session->subsession); for (sp = session->subsession; sp != NULL; sp = sp->next) { if (sp->sessid == sessid) { unregister_mibs_by_session(sp); unregister_index_by_session(sp); unregister_sysORTable_by_session(sp); *prevNext = sp->next; if (sp->securityAuthProto != NULL) { free(sp->securityAuthProto); } if (sp->securityName != NULL) { free(sp->securityName); } free(sp); sp = NULL; DEBUGMSGTL(("agentx/master", "closed %08p, %d okay\n", session, sessid)); return AGENTX_ERR_NOERROR; } prevNext = &(sp->next); } DEBUGMSGTL(("agentx/master", "sessid %d not found\n", sessid)); return AGENTX_ERR_NOT_OPEN;}intregister_agentx_list(netsnmp_session * session, netsnmp_pdu *pdu){ netsnmp_session *sp; char buf[128]; oid ubound = 0; u_long flags = 0; netsnmp_handler_registration *reg; int rc = 0; int cacheid; DEBUGMSGTL(("agentx/master", "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, session %8p, subsession %8p", sp->sessid, session, sp); /* * * TODO: registration timeout * * registration context */ if (pdu->range_subid) { ubound = pdu->variables->val.objid[pdu->range_subid - 1]; } if (pdu->flags & AGENTX_MSG_FLAG_INSTANCE_REGISTER) { flags = FULLY_QUALIFIED_INSTANCE; } reg = netsnmp_create_handler_registration(buf, agentx_master_handler, pdu->variables->name, pdu->variables->name_length, HANDLER_CAN_RWRITE | HANDLER_CAN_GETBULK); /* fake it */ if (!session->myvoid) { session->myvoid = malloc(sizeof(cacheid)); cacheid = netsnmp_allocate_globalcacheid(); *((int *) session->myvoid) = cacheid; } else { cacheid = *((int *) session->myvoid); } reg->handler->myvoid = session; reg->global_cacheid = cacheid; /* * register mib. Note that for failure cases, the registration info * (reg) will be freed, and thus is no longer a valid pointer. */ switch (netsnmp_register_mib(buf, NULL, 0, 1, pdu->variables->name, pdu->variables->name_length, pdu->priority, pdu->range_subid, ubound, sp, (char *) pdu->community, pdu->time, flags, reg, 1)) { case MIB_REGISTERED_OK: DEBUGMSGTL(("agentx/master", "registered ok\n")); return AGENTX_ERR_NOERROR; case MIB_DUPLICATE_REGISTRATION: DEBUGMSGTL(("agentx/master", "duplicate registration\n")); rc = AGENTX_ERR_DUPLICATE_REGISTRATION; break; case MIB_REGISTRATION_FAILED: default: rc = AGENTX_ERR_REQUEST_DENIED; DEBUGMSGTL(("agentx/master", "failed registration\n")); } return rc;}intunregister_agentx_list(netsnmp_session * session, netsnmp_pdu *pdu){ netsnmp_session *sp; int rc = 0; sp = find_agentx_session(session, pdu->sessid); if (sp == NULL) { return AGENTX_ERR_NOT_OPEN; } if (pdu->range_subid != 0) { oid ubound = pdu->variables->val.objid[pdu->range_subid - 1]; rc = netsnmp_unregister_mib_table_row(pdu->variables->name, pdu->variables->name_length, pdu->priority, pdu->range_subid, ubound, (char *) pdu->community); } else { rc = unregister_mib_context(pdu->variables->name, pdu->variables->name_length, pdu->priority, 0, 0, (char *) pdu->community); } switch (rc) { case MIB_UNREGISTERED_OK: return AGENTX_ERR_NOERROR; case MIB_NO_SUCH_REGISTRATION: return AGENTX_ERR_UNKNOWN_REGISTRATION; case MIB_UNREGISTRATION_FAILED:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -