|
Packit Service |
b38f0b |
/* Portions of this file are subject to the following copyright(s). See
|
|
Packit Service |
b38f0b |
* the Net-SNMP's COPYING file for more details and other copyrights
|
|
Packit Service |
b38f0b |
* that may apply:
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Portions of this file are copyrighted by:
|
|
Packit Service |
b38f0b |
* Copyright @ 2009 Sun Microsystems, Inc. All rights reserved.
|
|
Packit Service |
b38f0b |
* Use is subject to license terms specified in the COPYING file
|
|
Packit Service |
b38f0b |
* distributed with the Net-SNMP package.
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* Portions of this file are copyrighted by:
|
|
Packit Service |
b38f0b |
* Copyright (c) 2016 VMware, Inc. All rights reserved.
|
|
Packit Service |
b38f0b |
* Use is subject to license terms specified in the COPYING file
|
|
Packit Service |
b38f0b |
* distributed with the Net-SNMP package.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-config.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-features.h>
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include <sys/types.h>
|
|
Packit Service |
b38f0b |
#if HAVE_STRING_H
|
|
Packit Service |
b38f0b |
#include <string.h>
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
#ifdef HAVE_NETINET_IN_H
|
|
Packit Service |
b38f0b |
#include <netinet/in.h>
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include "proxy.h"
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_feature_require(handler_mark_requests_as_delegated)
|
|
Packit Service |
b38f0b |
netsnmp_feature_require(request_set_error_idx)
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
static struct simple_proxy *proxies = NULL;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* this must be standardized somewhere, right?
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
#define MAX_ARGS 128
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
char *context_string;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
static void
|
|
Packit Service |
b38f0b |
proxyOptProc(int argc, char *const *argv, int opt)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
switch (opt) {
|
|
Packit Service |
b38f0b |
case 'C':
|
|
Packit Service |
b38f0b |
while (*optarg) {
|
|
Packit Service |
b38f0b |
switch (*optarg++) {
|
|
Packit Service |
b38f0b |
case 'n':
|
|
Packit Service |
b38f0b |
optind++;
|
|
Packit Service |
b38f0b |
if (optind < argc) {
|
|
Packit Service |
b38f0b |
context_string = argv[optind - 1];
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
config_perror("No context name passed to -Cn");
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
case 'c':
|
|
Packit Service |
b38f0b |
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit Service |
b38f0b |
NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY, 1);
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
default:
|
|
Packit Service |
b38f0b |
config_perror("unknown argument passed to -C");
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
default:
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* shouldn't get here
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
proxy_parse_config(const char *token, char *line)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* proxy args [base-oid] [remap-to-remote-oid]
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_session session, *ss;
|
|
Packit Service |
b38f0b |
struct simple_proxy *newp, **listpp;
|
|
Packit Service |
b38f0b |
char *argv[MAX_ARGS];
|
|
Packit Service |
b38f0b |
int argn, arg;
|
|
Packit Service |
b38f0b |
char *cp;
|
|
Packit Service |
b38f0b |
char *buff;
|
|
Packit Service |
b38f0b |
netsnmp_handler_registration *reg;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
context_string = NULL;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_config", "entering\n"));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* Put the first string into the array */
|
|
Packit Service |
b38f0b |
argv[0] = strdup("snmpd-proxy");
|
|
Packit Service |
b38f0b |
if (!argv[0]) {
|
|
Packit Service |
b38f0b |
config_perror("could not allocate memory for argv[0]");
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* create the argv[] like array
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
/* Allocates memory to store the parameters value */
|
|
Packit Service |
b38f0b |
buff = (char *) malloc (strlen(line)+1);
|
|
Packit Service |
b38f0b |
if (!buff) {
|
|
Packit Service |
b38f0b |
config_perror("could not allocate memory for buff");
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[0]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
for (argn = 1, cp = line; cp && argn < MAX_ARGS;) {
|
|
Packit Service |
b38f0b |
/* Copy a parameter into the buff */
|
|
Packit Service |
b38f0b |
cp = copy_nword(cp, buff, strlen(cp)+1);
|
|
Packit Service |
b38f0b |
argv[argn] = strdup(buff);
|
|
Packit Service |
b38f0b |
if (!argv[argn]) {
|
|
Packit Service |
b38f0b |
config_perror("could not allocate memory for argv[n]");
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
SNMP_FREE(buff);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
argn++;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
SNMP_FREE(buff);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
for (arg = 0; arg < argn; arg++) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_args", "final args: %d = %s\n", arg,
|
|
Packit Service |
b38f0b |
argv[arg]));
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_config", "parsing args: %d\n", argn));
|
|
Packit Service |
b38f0b |
/* Call special parse_args that allows for no specified community string */
|
|
Packit Service |
b38f0b |
arg = netsnmp_parse_args(argn, argv, &session, "C:", proxyOptProc,
|
|
Packit Service |
b38f0b |
NETSNMP_PARSE_ARGS_NOLOGGING |
|
|
Packit Service |
b38f0b |
NETSNMP_PARSE_ARGS_NOZERO);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* reset this in case we modified it */
|
|
Packit Service |
b38f0b |
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit Service |
b38f0b |
NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY, 0);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (arg < 0) {
|
|
Packit Service |
b38f0b |
config_perror("failed to parse proxy args");
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_config", "done parsing args\n"));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (arg >= argn) {
|
|
Packit Service |
b38f0b |
config_perror("missing base oid");
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* usm_set_reportErrorOnUnknownID(0);
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* hack, stupid v3 ASIs.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* XXX: on a side note, we don't really need to be a reference
|
|
Packit Service |
b38f0b |
* platform any more so the proper thing to do would be to fix
|
|
Packit Service |
b38f0b |
* snmplib/snmpusm.c to pass in the pdu type to usm_process_incoming
|
|
Packit Service |
b38f0b |
* so this isn't needed.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
ss = snmp_open(&session);
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* usm_set_reportErrorOnUnknownID(1);
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (ss == NULL) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* diagnose snmp_open errors with the input netsnmp_session pointer
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
snmp_sess_perror("snmpget", &session);
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
newp = (struct simple_proxy *) calloc(1, sizeof(struct simple_proxy));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
newp->sess = ss;
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_init", "name = %s\n", argv[arg]));
|
|
Packit Service |
b38f0b |
newp->name_len = MAX_OID_LEN;
|
|
Packit Service |
b38f0b |
if (!snmp_parse_oid(argv[arg++], newp->name, &newp->name_len)) {
|
|
Packit Service |
b38f0b |
snmp_perror("proxy");
|
|
Packit Service |
b38f0b |
config_perror("illegal proxy oid specified\n");
|
|
Packit Service |
b38f0b |
/*deallocate the memory previously allocated*/
|
|
Packit Service |
b38f0b |
SNMP_FREE(newp);
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (arg < argn) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_init", "base = %s\n", argv[arg]));
|
|
Packit Service |
b38f0b |
newp->base_len = MAX_OID_LEN;
|
|
Packit Service |
b38f0b |
if (!snmp_parse_oid(argv[arg++], newp->base, &newp->base_len)) {
|
|
Packit Service |
b38f0b |
snmp_perror("proxy");
|
|
Packit Service |
b38f0b |
config_perror("illegal variable name specified (base oid)\n");
|
|
Packit Service |
b38f0b |
SNMP_FREE(newp);
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
if ( context_string )
|
|
Packit Service |
b38f0b |
newp->context = strdup(context_string);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_init", "registering at: "));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy_init", newp->name, newp->name_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(("proxy_init", "\n"));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* add to our chain
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* must be sorted!
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
listpp = &proxies;
|
|
Packit Service |
b38f0b |
while (*listpp &&
|
|
Packit Service |
b38f0b |
snmp_oid_compare(newp->name, newp->name_len,
|
|
Packit Service |
b38f0b |
(*listpp)->name, (*listpp)->name_len) > 0) {
|
|
Packit Service |
b38f0b |
listpp = &((*listpp)->next);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* listpp should be next in line from us.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (*listpp) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* make our next in the link point to the current link
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
newp->next = *listpp;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* replace current link with us
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
*listpp = newp;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
reg = netsnmp_create_handler_registration("proxy",
|
|
Packit Service |
b38f0b |
proxy_handler,
|
|
Packit Service |
b38f0b |
newp->name,
|
|
Packit Service |
b38f0b |
newp->name_len,
|
|
Packit Service |
b38f0b |
HANDLER_CAN_RWRITE);
|
|
Packit Service |
b38f0b |
reg->handler->myvoid = newp;
|
|
Packit Service |
b38f0b |
if (context_string)
|
|
Packit Service |
b38f0b |
reg->contextName = strdup(context_string);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_register_handler(reg);
|
|
Packit Service |
b38f0b |
/* Free the memory allocated */
|
|
Packit Service |
b38f0b |
while(argn--)
|
|
Packit Service |
b38f0b |
SNMP_FREE(argv[argn]);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
proxy_free_config(void)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
struct simple_proxy *rm;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy_free_config", "Free config\n"));
|
|
Packit Service |
b38f0b |
while (proxies) {
|
|
Packit Service |
b38f0b |
rm = proxies;
|
|
Packit Service |
b38f0b |
proxies = rm->next;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(( "proxy_free_config", "freeing "));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy_free_config", rm->name, rm->name_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(( "proxy_free_config", " (%s)\n", rm->context));
|
|
Packit Service |
b38f0b |
unregister_mib_context(rm->name, rm->name_len,
|
|
Packit Service |
b38f0b |
DEFAULT_MIB_PRIORITY, 0, 0,
|
|
Packit Service |
b38f0b |
rm->context);
|
|
Packit Service |
b38f0b |
SNMP_FREE(rm->variables);
|
|
Packit Service |
b38f0b |
SNMP_FREE(rm->context);
|
|
Packit Service |
b38f0b |
snmp_close(rm->sess);
|
|
Packit Service |
b38f0b |
SNMP_FREE(rm);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Configure special parameters on the session.
|
|
Packit Service |
b38f0b |
* Currently takes the parameter configured and changes it if something
|
|
Packit Service |
b38f0b |
* was configured. It becomes "-c" if the community string from the pdu
|
|
Packit Service |
b38f0b |
* is placed on the session.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
proxy_fill_in_session(netsnmp_mib_handler *handler,
|
|
Packit Service |
b38f0b |
netsnmp_agent_request_info *reqinfo,
|
|
Packit Service |
b38f0b |
void **configured)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
netsnmp_session *session;
|
|
Packit Service |
b38f0b |
struct simple_proxy *sp;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
sp = (struct simple_proxy *) handler->myvoid;
|
|
Packit Service |
b38f0b |
if (!sp) {
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
session = sp->sess;
|
|
Packit Service |
b38f0b |
if (!session) {
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
|
|
Packit Service |
b38f0b |
if (
|
|
Packit Service |
b38f0b |
#ifndef NETSNMP_DISABLE_SNMPV1
|
|
Packit Service |
b38f0b |
((session->version == SNMP_VERSION_1) &&
|
|
Packit Service |
b38f0b |
!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit Service |
b38f0b |
NETSNMP_DS_LIB_DISABLE_V1)) ||
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
#ifndef NETSNMP_DISABLE_SNMPV2C
|
|
Packit Service |
b38f0b |
((session->version == SNMP_VERSION_2c) &&
|
|
Packit Service |
b38f0b |
!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit Service |
b38f0b |
NETSNMP_DS_LIB_DISABLE_V2c)) ||
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
0 ) { /* 0 to terminate '||' above */
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Check if session has community string defined for it.
|
|
Packit Service |
b38f0b |
* If not, need to extract community string from the pdu.
|
|
Packit Service |
b38f0b |
* Copy to session and set 'configured' to indicate this.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (session->community_len == 0) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "session has no community string\n"));
|
|
Packit Service |
b38f0b |
if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL ||
|
|
Packit Service |
b38f0b |
reqinfo->asp->pdu->community_len == 0) {
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
*configured = strdup("-c");
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "pdu has community string\n"));
|
|
Packit Service |
b38f0b |
session->community_len = reqinfo->asp->pdu->community_len;
|
|
Packit Service |
b38f0b |
session->community = malloc(session->community_len + 1);
|
|
Packit Service |
b38f0b |
sprintf((char *)session->community, "%.*s",
|
|
Packit Service |
b38f0b |
(int) session->community_len,
|
|
Packit Service |
b38f0b |
(const char *)reqinfo->asp->pdu->community);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return 1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Free any specially configured parameters used on the session.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
proxy_free_filled_in_session_args(netsnmp_session *session, void **configured)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* Only do comparisions, etc., if something was configured */
|
|
Packit Service |
b38f0b |
if (*configured == NULL) {
|
|
Packit Service |
b38f0b |
return;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* If used community string from pdu, release it from session now */
|
|
Packit Service |
b38f0b |
if (strcmp((const char *)(*configured), "-c") == 0) {
|
|
Packit Service |
b38f0b |
free(session->community);
|
|
Packit Service |
b38f0b |
session->community = NULL;
|
|
Packit Service |
b38f0b |
session->community_len = 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
free((u_char *)(*configured));
|
|
Packit Service |
b38f0b |
*configured = NULL;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
init_proxy(void)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
snmpd_register_config_handler("proxy", proxy_parse_config,
|
|
Packit Service |
b38f0b |
proxy_free_config,
|
|
Packit Service |
b38f0b |
"[snmpcmd args] host oid [remoteoid]");
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
shutdown_proxy(void)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
proxy_free_config();
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
proxy_handler(netsnmp_mib_handler *handler,
|
|
Packit Service |
b38f0b |
netsnmp_handler_registration *reginfo,
|
|
Packit Service |
b38f0b |
netsnmp_agent_request_info *reqinfo,
|
|
Packit Service |
b38f0b |
netsnmp_request_info *requests)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_pdu *pdu;
|
|
Packit Service |
b38f0b |
struct simple_proxy *sp;
|
|
Packit Service |
b38f0b |
oid *ourname;
|
|
Packit Service |
b38f0b |
size_t ourlength;
|
|
Packit Service |
b38f0b |
netsnmp_request_info *request = requests;
|
|
Packit Service |
b38f0b |
u_char *configured = NULL;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n",
|
|
Packit Service |
b38f0b |
reqinfo->mode));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
switch (reqinfo->mode) {
|
|
Packit Service |
b38f0b |
case MODE_GET:
|
|
Packit Service |
b38f0b |
case MODE_GETNEXT:
|
|
Packit Service |
b38f0b |
case MODE_GETBULK: /* WWWXXX */
|
|
Packit Service |
b38f0b |
pdu = snmp_pdu_create(reqinfo->mode);
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#ifndef NETSNMP_NO_WRITE_SUPPORT
|
|
Packit Service |
b38f0b |
case MODE_SET_ACTION:
|
|
Packit Service |
b38f0b |
pdu = snmp_pdu_create(SNMP_MSG_SET);
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
case MODE_SET_UNDO:
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* If we set successfully (status == NOERROR),
|
|
Packit Service |
b38f0b |
* we can't back out again, so need to report the fact.
|
|
Packit Service |
b38f0b |
* If we failed to set successfully, then we're fine.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
for (request = requests; request; request=request->next) {
|
|
Packit Service |
b38f0b |
if (request->status == SNMP_ERR_NOERROR) {
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(reqinfo, requests,
|
|
Packit Service |
b38f0b |
SNMP_ERR_UNDOFAILED);
|
|
Packit Service |
b38f0b |
return SNMP_ERR_UNDOFAILED;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
case MODE_SET_RESERVE1:
|
|
Packit Service |
b38f0b |
case MODE_SET_RESERVE2:
|
|
Packit Service |
b38f0b |
case MODE_SET_FREE:
|
|
Packit Service |
b38f0b |
case MODE_SET_COMMIT:
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Nothing to do in this pass
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
default:
|
|
Packit Service |
b38f0b |
snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n",
|
|
Packit Service |
b38f0b |
reqinfo->mode);
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
sp = (struct simple_proxy *) handler->myvoid;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (!pdu || !sp) {
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
|
|
Packit Service |
b38f0b |
if (pdu)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
while (request) {
|
|
Packit Service |
b38f0b |
ourname = request->requestvb->name;
|
|
Packit Service |
b38f0b |
ourlength = request->requestvb->name_length;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (sp->base_len &&
|
|
Packit Service |
b38f0b |
reqinfo->mode == MODE_GETNEXT &&
|
|
Packit Service |
b38f0b |
(snmp_oid_compare(ourname, ourlength,
|
|
Packit Service |
127f7a |
sp->name, sp->name_len) < 0)) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(( "proxy", "request is out of registered range\n"));
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Create GETNEXT request with an OID so the
|
|
Packit Service |
b38f0b |
* master returns the first OID in the registered range.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
memcpy(ourname, sp->base, sp->base_len * sizeof(oid));
|
|
Packit Service |
b38f0b |
ourlength = sp->base_len;
|
|
Packit Service |
b38f0b |
if (ourname[ourlength-1] <= 1) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* The registered range ends with x.y.z.1
|
|
Packit Service |
b38f0b |
* -> ask for the next of x.y.z
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
ourlength--;
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* The registered range ends with x.y.z.A
|
|
Packit Service |
b38f0b |
* -> ask for the next of x.y.z.A-1.MAX_SUBID
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
ourname[ourlength-1]--;
|
|
Packit Service |
b38f0b |
ourname[ourlength] = MAX_SUBID;
|
|
Packit Service |
b38f0b |
ourlength++;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
} else if (sp->base_len > 0) {
|
|
Packit Service |
b38f0b |
if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* too large
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (pdu)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR,
|
|
Packit Service |
b38f0b |
"proxy oid request length is too long\n");
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* suffix appended?
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n",
|
|
Packit Service |
b38f0b |
(int)ourlength, (int)sp->base_len, (int)sp->name_len));
|
|
Packit Service |
b38f0b |
if (ourlength > sp->name_len)
|
|
Packit Service |
b38f0b |
memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]),
|
|
Packit Service |
b38f0b |
sizeof(oid) * (ourlength - sp->name_len));
|
|
Packit Service |
b38f0b |
ourlength = ourlength - sp->name_len + sp->base_len;
|
|
Packit Service |
b38f0b |
ourname = sp->base;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
snmp_pdu_add_variable(pdu, ourname, ourlength,
|
|
Packit Service |
b38f0b |
request->requestvb->type,
|
|
Packit Service |
b38f0b |
request->requestvb->val.string,
|
|
Packit Service |
b38f0b |
request->requestvb->val_len);
|
|
Packit Service |
b38f0b |
request->delegated = 1;
|
|
Packit Service |
b38f0b |
request = request->next;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Customize session parameters based on request information
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) {
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
|
|
Packit Service |
b38f0b |
if (pdu)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* send the request out
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "sending pdu\n"));
|
|
Packit Service |
b38f0b |
snmp_async_send(sp->sess, pdu, proxy_got_response,
|
|
Packit Service |
b38f0b |
netsnmp_create_delegated_cache(handler, reginfo,
|
|
Packit Service |
b38f0b |
reqinfo, requests,
|
|
Packit Service |
b38f0b |
(void *) sp));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* Free any special parameters generated on the session */
|
|
Packit Service |
b38f0b |
proxy_free_filled_in_session_args(sp->sess, (void **)&configured);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
proxy_got_response(int operation, netsnmp_session * sess, int reqid,
|
|
Packit Service |
b38f0b |
netsnmp_pdu *pdu, void *cb_data)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) cb_data;
|
|
Packit Service |
b38f0b |
netsnmp_request_info *requests, *request = NULL;
|
|
Packit Service |
b38f0b |
netsnmp_variable_list *vars, *var = NULL;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
struct simple_proxy *sp;
|
|
Packit Service |
b38f0b |
oid myname[MAX_OID_LEN];
|
|
Packit Service |
b38f0b |
size_t myname_len = MAX_OID_LEN;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
cache = netsnmp_handler_check_cache(cache);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (!cache) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n"));
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
requests = cache->requests;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
sp = (struct simple_proxy *) cache->localinfo;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (!sp) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n"));
|
|
Packit Service |
b38f0b |
return SNMP_ERR_NOERROR;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
switch (operation) {
|
|
Packit Service |
b38f0b |
case NETSNMP_CALLBACK_OP_TIMED_OUT:
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* WWWXXX: don't leave requests delayed if operation is
|
|
Packit Service |
b38f0b |
* something like TIMEOUT
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "got timed out... requests = %8p\n", requests));
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_handler_mark_requests_as_delegated(requests,
|
|
Packit Service |
b38f0b |
REQUEST_IS_NOT_DELEGATED);
|
|
Packit Service |
b38f0b |
if(cache->reqinfo->mode != MODE_GETNEXT) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", " ignoring timeout\n"));
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(cache->reqinfo, requests, /* XXXWWW: should be index = 0 */
|
|
Packit Service |
b38f0b |
SNMP_ERR_GENERR);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
netsnmp_free_delegated_cache(cache);
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:
|
|
Packit Service |
b38f0b |
vars = pdu->variables;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (pdu->errstat != SNMP_ERR_NOERROR) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* If we receive an error from the proxy agent, pass it on up.
|
|
Packit Service |
b38f0b |
* The higher-level processing seems to Do The Right Thing.
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* 2005/06 rks: actually, it doesn't do the right thing for
|
|
Packit Service |
b38f0b |
* a get-next request that returns NOSUCHNAME. If we do nothing,
|
|
Packit Service |
b38f0b |
* it passes that error back to the comman initiator. What it should
|
|
Packit Service |
b38f0b |
* do is ignore the error and move on to the next tree. To
|
|
Packit Service |
b38f0b |
* accomplish that, all we need to do is clear the delegated flag.
|
|
Packit Service |
b38f0b |
* Not sure if any other error codes need the same treatment. Left
|
|
Packit Service |
b38f0b |
* as an exercise to the reader...
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "got error response (%ld)\n", pdu->errstat));
|
|
Packit Service |
b38f0b |
if((cache->reqinfo->mode == MODE_GETNEXT) &&
|
|
Packit Service |
b38f0b |
(SNMP_ERR_NOSUCHNAME == pdu->errstat)) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", " ignoring error response\n"));
|
|
Packit Service |
b38f0b |
netsnmp_handler_mark_requests_as_delegated(requests,
|
|
Packit Service |
b38f0b |
REQUEST_IS_NOT_DELEGATED);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#ifndef NETSNMP_NO_WRITE_SUPPORT
|
|
Packit Service |
b38f0b |
else if (cache->reqinfo->mode == MODE_SET_ACTION) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* In order for netsnmp_wrap_up_request to consider the
|
|
Packit Service |
b38f0b |
* SET request complete,
|
|
Packit Service |
b38f0b |
* there must be no delegated requests pending.
|
|
Packit Service |
b38f0b |
* https://sourceforge.net/tracker/
|
|
Packit Service |
b38f0b |
* ?func=detail&atid=112694&aid=1554261&group_id=12694
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy",
|
|
Packit Service |
b38f0b |
"got SET error %s, index %ld\n",
|
|
Packit Service |
b38f0b |
snmp_errstring(pdu->errstat), pdu->errindex));
|
|
Packit Service |
b38f0b |
netsnmp_handler_mark_requests_as_delegated(
|
|
Packit Service |
b38f0b |
requests, REQUEST_IS_NOT_DELEGATED);
|
|
Packit Service |
b38f0b |
netsnmp_request_set_error_idx(requests, pdu->errstat,
|
|
Packit Service |
b38f0b |
pdu->errindex);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
|
|
Packit Service |
b38f0b |
else {
|
|
Packit Service |
b38f0b |
netsnmp_handler_mark_requests_as_delegated( requests,
|
|
Packit Service |
b38f0b |
REQUEST_IS_NOT_DELEGATED);
|
|
Packit Service |
b38f0b |
netsnmp_request_set_error_idx(requests, pdu->errstat,
|
|
Packit Service |
b38f0b |
pdu->errindex);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* update the original request varbinds with the results
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
} else for (var = vars, request = requests;
|
|
Packit Service |
b38f0b |
request && var;
|
|
Packit Service |
b38f0b |
request = request->next, var = var->next_variable) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* XXX - should this be done here?
|
|
Packit Service |
b38f0b |
* Or wait until we know it's OK?
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
snmp_set_var_typed_value(request->requestvb, var->type,
|
|
Packit Service |
b38f0b |
var->val.string, var->val_len);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "got response... "));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy", var->name, var->name_length));
|
|
Packit Service |
b38f0b |
DEBUGMSG(("proxy", "\n"));
|
|
Packit Service |
b38f0b |
request->delegated = 0;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Check the response oid is legitimate,
|
|
Packit Service |
b38f0b |
* and discard the value if not.
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* XXX - what's the difference between these cases?
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (sp->base_len &&
|
|
Packit Service |
b38f0b |
(var->name_length < sp->base_len ||
|
|
Packit Service |
b38f0b |
snmp_oid_compare(var->name, sp->base_len, sp->base,
|
|
Packit Service |
b38f0b |
sp->base_len) != 0)) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(( "proxy", "out of registered range... "));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy", var->name, sp->base_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(( "proxy", " (%d) != ", (int)sp->base_len));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy", sp->base, sp->base_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(( "proxy", "\n"));
|
|
Packit Service |
b38f0b |
snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
continue;
|
|
Packit Service |
b38f0b |
} else if (!sp->base_len &&
|
|
Packit Service |
b38f0b |
(var->name_length < sp->name_len ||
|
|
Packit Service |
b38f0b |
snmp_oid_compare(var->name, sp->name_len, sp->name,
|
|
Packit Service |
b38f0b |
sp->name_len) != 0)) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(( "proxy", "out of registered base range... "));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy", var->name, sp->name_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(( "proxy", " (%d) != ", (int)sp->name_len));
|
|
Packit Service |
b38f0b |
DEBUGMSGOID(("proxy", sp->name, sp->name_len));
|
|
Packit Service |
b38f0b |
DEBUGMSG(( "proxy", "\n"));
|
|
Packit Service |
b38f0b |
snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0);
|
|
Packit Service |
b38f0b |
continue;
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* If the returned OID is legitimate, then update
|
|
Packit Service |
b38f0b |
* the original request varbind accordingly.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (sp->base_len) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* XXX: oid size maxed?
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
memcpy(myname, sp->name, sizeof(oid) * sp->name_len);
|
|
Packit Service |
b38f0b |
myname_len =
|
|
Packit Service |
b38f0b |
sp->name_len + var->name_length - sp->base_len;
|
|
Packit Service |
b38f0b |
if (myname_len > MAX_OID_LEN) {
|
|
Packit Service |
b38f0b |
snmp_log(LOG_WARNING,
|
|
Packit Service |
b38f0b |
"proxy OID return length too long.\n");
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(cache->reqinfo, requests,
|
|
Packit Service |
b38f0b |
SNMP_ERR_GENERR);
|
|
Packit Service |
b38f0b |
if (pdu)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
netsnmp_free_delegated_cache(cache);
|
|
Packit Service |
b38f0b |
return 1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (var->name_length > sp->base_len)
|
|
Packit Service |
b38f0b |
memcpy(&myname[sp->name_len],
|
|
Packit Service |
b38f0b |
&var->name[sp->base_len],
|
|
Packit Service |
b38f0b |
sizeof(oid) * (var->name_length -
|
|
Packit Service |
b38f0b |
sp->base_len));
|
|
Packit Service |
b38f0b |
snmp_set_var_objid(request->requestvb, myname,
|
|
Packit Service |
b38f0b |
myname_len);
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
snmp_set_var_objid(request->requestvb, var->name,
|
|
Packit Service |
b38f0b |
var->name_length);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (request || var) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* ack, this is bad. The # of varbinds don't match and
|
|
Packit Service |
b38f0b |
* there is no way to fix the problem
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (pdu)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR,
|
|
Packit Service |
b38f0b |
"response to proxy request illegal. We're screwed.\n");
|
|
Packit Service |
b38f0b |
netsnmp_set_request_error(cache->reqinfo, requests,
|
|
Packit Service |
b38f0b |
SNMP_ERR_GENERR);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* fix bulk_to_next operations */
|
|
Packit Service |
b38f0b |
if (cache->reqinfo->mode == MODE_GETBULK)
|
|
Packit Service |
b38f0b |
netsnmp_bulk_to_next_fix_requests(requests);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* free the response
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (pdu && 0)
|
|
Packit Service |
b38f0b |
snmp_free_pdu(pdu);
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
default:
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("proxy", "no response received: op = %d\n",
|
|
Packit Service |
b38f0b |
operation));
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_free_delegated_cache(cache);
|
|
Packit Service |
b38f0b |
return 1;
|
|
Packit Service |
b38f0b |
}
|