client.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:13k
- /*
- * AgentX utility routines
- */
- #include <net-snmp/net-snmp-config.h>
- #include <stdio.h>
- #include <errno.h>
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <sys/types.h>
- #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_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/agent/net-snmp-agent-includes.h>
- #include <net-snmp/agent/agent_index.h>
- #include "agentx/protocol.h"
- #include "agentx/client.h"
- #include "agentx/subagent.h"
- extern struct timeval starttime;
- /*
- * AgentX handling utility routines
- *
- * Mostly wrappers round, or re-writes of
- * the SNMP equivalents
- */
- int
- agentx_synch_input(int op,
- netsnmp_session * session,
- int reqid, netsnmp_pdu *pdu, void *magic)
- {
- struct synch_state *state = (struct synch_state *) magic;
- struct timeval now, diff;
- if (reqid != state->reqid) {
- return handle_agentx_packet(op, session, reqid, pdu, magic);
- }
- DEBUGMSGTL(("agentx/subagent", "synching input, op 0x%02xn", op));
- state->waiting = 0;
- if (op == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
- if (pdu->command == AGENTX_MSG_RESPONSE) {
- state->pdu = snmp_clone_pdu(pdu);
- state->status = STAT_SUCCESS;
- session->s_snmp_errno = SNMPERR_SUCCESS;
- /*
- * Synchronise sysUpTime with the master agent
- */
- gettimeofday(&now, NULL);
- now.tv_sec--;
- now.tv_usec += 1000000L;
- diff.tv_sec = pdu->time / 100;
- diff.tv_usec = (pdu->time - (diff.tv_sec * 100)) * 10000;
- starttime.tv_sec = now.tv_sec - diff.tv_sec;
- starttime.tv_usec = now.tv_usec - diff.tv_usec;
- if (starttime.tv_usec > 1000000L) {
- starttime.tv_usec -= 1000000L;
- starttime.tv_sec++;
- }
- }
- } else if (op == NETSNMP_CALLBACK_OP_TIMED_OUT) {
- state->pdu = NULL;
- state->status = STAT_TIMEOUT;
- session->s_snmp_errno = SNMPERR_TIMEOUT;
- } else if (op == NETSNMP_CALLBACK_OP_DISCONNECT) {
- return handle_agentx_packet(op, session, reqid, pdu, magic);
- }
- return 1;
- }
- int
- agentx_synch_response(netsnmp_session * ss, netsnmp_pdu *pdu,
- netsnmp_pdu **response)
- {
- return snmp_synch_response_cb(ss, pdu, response, agentx_synch_input);
- }
- /*
- * AgentX PofE convenience functions
- */
- int
- agentx_open_session(netsnmp_session * ss)
- {
- netsnmp_pdu *pdu, *response;
- extern oid version_sysoid[];
- extern int version_sysoid_len;
- DEBUGMSGTL(("agentx/subagent", "opening session n"));
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_OPEN);
- if (pdu == NULL)
- return 0;
- pdu->time = 0;
- snmp_add_var(pdu, version_sysoid, version_sysoid_len,
- 's', "Net-SNMP AgentX sub-agent");
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return 0;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return 0;
- }
- ss->sessid = response->sessid;
- snmp_free_pdu(response);
- DEBUGMSGTL(("agentx/subagent", "open n"));
- return 1;
- }
- int
- agentx_close_session(netsnmp_session * ss, int why)
- {
- netsnmp_pdu *pdu, *response;
- DEBUGMSGTL(("agentx/subagent", "closing sessionn"));
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_CLOSE);
- if (pdu == NULL)
- return 0;
- pdu->time = 0;
- pdu->errstat = why;
- pdu->sessid = ss->sessid;
- (void) agentx_synch_response(ss, pdu, &response);
- snmp_free_pdu(response);
- DEBUGMSGTL(("agentx/subagent", "closedn"));
- return 1;
- }
- int
- agentx_register(netsnmp_session * ss, oid start[], size_t startlen,
- int priority, int range_subid, oid range_ubound,
- int timeout, u_char flags, const char *contextName)
- {
- netsnmp_pdu *pdu, *response;
- DEBUGMSGTL(("agentx/subagent", "registering: "));
- DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid,
- range_ubound));
- DEBUGMSG(("agentx/subagent", "n"));
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_REGISTER);
- if (pdu == NULL) {
- return 0;
- }
- pdu->time = timeout;
- pdu->priority = priority;
- pdu->sessid = ss->sessid;
- pdu->range_subid = range_subid;
- if (contextName) {
- pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
- pdu->community = strdup(contextName);
- pdu->community_len = strlen(contextName);
- }
- if (flags & FULLY_QUALIFIED_INSTANCE) {
- pdu->flags |= AGENTX_MSG_FLAG_INSTANCE_REGISTER;
- }
- if (range_subid) {
- snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID,
- (u_char *) start, startlen * sizeof(oid));
- pdu->variables->val.objid[range_subid - 1] = range_ubound;
- } else {
- snmp_add_null_var(pdu, start, startlen);
- }
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS) {
- DEBUGMSGTL(("agentx/subagent", "registering failed!n"));
- return 0;
- }
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_log(LOG_ERR,"registering pdu failed: %ld!n", response->errstat);
- snmp_free_pdu(response);
- return 0;
- }
- snmp_free_pdu(response);
- DEBUGMSGTL(("agentx/subagent", "registeredn"));
- return 1;
- }
- int
- agentx_unregister(netsnmp_session * ss, oid start[], size_t startlen,
- int priority, int range_subid, oid range_ubound,
- const char *contextName)
- {
- netsnmp_pdu *pdu, *response;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- DEBUGMSGTL(("agentx/subagent", "unregistering: "));
- DEBUGMSGOIDRANGE(("agentx/subagent", start, startlen, range_subid,
- range_ubound));
- DEBUGMSG(("agentx/subagent", "n"));
- pdu = snmp_pdu_create(AGENTX_MSG_UNREGISTER);
- if (pdu == NULL) {
- return 0;
- }
- pdu->time = 0;
- pdu->priority = priority;
- pdu->sessid = ss->sessid;
- pdu->range_subid = range_subid;
- if (contextName) {
- pdu->flags |= AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT;
- pdu->community = strdup(contextName);
- pdu->community_len = strlen(contextName);
- }
- if (range_subid) {
- snmp_pdu_add_variable(pdu, start, startlen, ASN_OBJECT_ID,
- (u_char *) start, startlen * sizeof(oid));
- pdu->variables->val.objid[range_subid - 1] = range_ubound;
- } else {
- snmp_add_null_var(pdu, start, startlen);
- }
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return 0;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return 0;
- }
- snmp_free_pdu(response);
- DEBUGMSGTL(("agentx/subagent", "unregisteredn"));
- return 1;
- }
- netsnmp_variable_list *
- agentx_register_index(netsnmp_session * ss,
- netsnmp_variable_list * varbind, int flags)
- {
- netsnmp_pdu *pdu, *response;
- netsnmp_variable_list *varbind2;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return NULL;
- }
- /*
- * Make a copy of the index request varbind
- * for the AgentX request PDU
- * (since the pdu structure will be freed)
- */
- varbind2 =
- (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
- if (varbind2 == NULL)
- return NULL;
- if (snmp_clone_var(varbind, varbind2)) {
- snmp_free_varbind(varbind2);
- return NULL;
- }
- if (varbind2->val.string == NULL)
- varbind2->val.string = varbind2->buf; /* ensure it points somewhere */
- pdu = snmp_pdu_create(AGENTX_MSG_INDEX_ALLOCATE);
- if (pdu == NULL) {
- snmp_free_varbind(varbind2);
- return NULL;
- }
- pdu->time = 0;
- pdu->sessid = ss->sessid;
- if (flags == ALLOCATE_ANY_INDEX)
- pdu->flags |= AGENTX_MSG_FLAG_ANY_INSTANCE;
- if (flags == ALLOCATE_NEW_INDEX)
- pdu->flags |= AGENTX_MSG_FLAG_NEW_INSTANCE;
- /*
- * Just send a single index request varbind.
- * Although the AgentX protocol supports
- * multiple index allocations in a single
- * request, the model used in the net-snmp agent
- * doesn't currently take advantage of this.
- * I believe this is our prerogative - just as
- * long as the master side Index request handler
- * can cope with multiple index requests.
- */
- pdu->variables = varbind2;
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return NULL;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return NULL;
- }
- /*
- * Unlink the (single) response varbind to return
- * to the main driving index request routine.
- *
- * This is a memory leak, as nothing will ever
- * release this varbind. If this becomes a problem,
- * we'll need to keep a list of these here, and
- * free the memory in the "index release" routine.
- * But the master side never frees these either (by
- * design, since it still needs them), so expecting
- * the subagent to is discrimination, pure & simple :-)
- */
- varbind2 = response->variables;
- response->variables = NULL;
- snmp_free_pdu(response);
- return varbind2;
- }
- int
- agentx_unregister_index(netsnmp_session * ss,
- netsnmp_variable_list * varbind)
- {
- netsnmp_pdu *pdu, *response;
- netsnmp_variable_list *varbind2;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return -1;
- }
- /*
- * Make a copy of the index request varbind
- * for the AgentX request PDU
- * (since the pdu structure will be freed)
- */
- varbind2 =
- (netsnmp_variable_list *) malloc(sizeof(netsnmp_variable_list));
- if (varbind2 == NULL)
- return -1;
- if (snmp_clone_var(varbind, varbind2)) {
- snmp_free_varbind(varbind2);
- return -1;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_INDEX_DEALLOCATE);
- if (pdu == NULL) {
- snmp_free_varbind(varbind2);
- return -1;
- }
- pdu->time = 0;
- pdu->sessid = ss->sessid;
- /*
- * Just send a single index release varbind.
- * (as above)
- */
- pdu->variables = varbind2;
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return -1;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return -1; /* XXX - say why */
- }
- snmp_free_pdu(response);
- return SNMP_ERR_NOERROR;
- }
- int
- agentx_add_agentcaps(netsnmp_session * ss,
- oid * agent_cap, size_t agent_caplen,
- const char *descr)
- {
- netsnmp_pdu *pdu, *response;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_ADD_AGENT_CAPS);
- if (pdu == NULL)
- return 0;
- pdu->time = 0;
- pdu->sessid = ss->sessid;
- snmp_add_var(pdu, agent_cap, agent_caplen, 's', descr);
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return 0;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return 0;
- }
- snmp_free_pdu(response);
- return 1;
- }
- int
- agentx_remove_agentcaps(netsnmp_session * ss,
- oid * agent_cap, size_t agent_caplen)
- {
- netsnmp_pdu *pdu, *response;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_REMOVE_AGENT_CAPS);
- if (pdu == NULL)
- return 0;
- pdu->time = 0;
- pdu->sessid = ss->sessid;
- snmp_add_null_var(pdu, agent_cap, agent_caplen);
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return 0;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return 0;
- }
- snmp_free_pdu(response);
- return 1;
- }
- int
- agentx_send_ping(netsnmp_session * ss)
- {
- netsnmp_pdu *pdu, *response;
- if (ss == NULL || !IS_AGENTX_VERSION(ss->version)) {
- return 0;
- }
- pdu = snmp_pdu_create(AGENTX_MSG_PING);
- if (pdu == NULL)
- return 0;
- pdu->time = 0;
- pdu->sessid = ss->sessid;
- if (agentx_synch_response(ss, pdu, &response) != STAT_SUCCESS)
- return 0;
- if (response->errstat != SNMP_ERR_NOERROR) {
- snmp_free_pdu(response);
- return 0;
- }
- snmp_free_pdu(response);
- return 1;
- }