267 lines
8.4 KiB
C
267 lines
8.4 KiB
C
#include <net-snmp/net-snmp-config.h>
|
|
|
|
#include <ctype.h>
|
|
#if HAVE_STDDEF_H
|
|
#include <stddef.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#if HAVE_STRING_H
|
|
#include <string.h>
|
|
#else
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
#include "mibgroup/util_funcs.h"
|
|
#include "pass_common.h"
|
|
|
|
static int
|
|
netsnmp_internal_asc2bin(char *p)
|
|
{
|
|
char *r, *q = p;
|
|
char c;
|
|
int n = 0;
|
|
|
|
for (;;) {
|
|
c = (char) strtol(q, &r, 16);
|
|
if (r == q)
|
|
break;
|
|
*p++ = c;
|
|
q = r;
|
|
n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static int
|
|
netsnmp_internal_bin2asc(char *p, size_t n)
|
|
{
|
|
int i, flag = 0;
|
|
char buffer[SNMP_MAXBUF];
|
|
|
|
/* prevent buffer overflow */
|
|
if ((int)n > (sizeof(buffer) - 1))
|
|
n = sizeof(buffer) - 1;
|
|
|
|
for (i = 0; i < (int) n; i++) {
|
|
buffer[i] = p[i];
|
|
if (!isprint((unsigned char) (p[i])))
|
|
flag = 1;
|
|
}
|
|
if (flag == 0) {
|
|
p[n] = 0;
|
|
return n;
|
|
}
|
|
for (i = 0; i < (int) n; i++) {
|
|
sprintf(p, "%02x ", (unsigned char) (buffer[i] & 0xff));
|
|
p += 3;
|
|
}
|
|
*--p = 0;
|
|
return 3 * n - 1;
|
|
}
|
|
|
|
int
|
|
netsnmp_internal_pass_str_to_errno(const char *buf)
|
|
{
|
|
if (!strncasecmp(buf, "too-big", 7)) {
|
|
/* Shouldn't happen */
|
|
return SNMP_ERR_TOOBIG;
|
|
} else if (!strncasecmp(buf, "no-such-name", 12)) {
|
|
return SNMP_ERR_NOSUCHNAME;
|
|
} else if (!strncasecmp(buf, "bad-value", 9)) {
|
|
return SNMP_ERR_BADVALUE;
|
|
} else if (!strncasecmp(buf, "read-only", 9)) {
|
|
return SNMP_ERR_READONLY;
|
|
} else if (!strncasecmp(buf, "gen-error", 9)) {
|
|
return SNMP_ERR_GENERR;
|
|
} else if (!strncasecmp(buf, "no-access", 9)) {
|
|
return SNMP_ERR_NOACCESS;
|
|
} else if (!strncasecmp(buf, "wrong-type", 10)) {
|
|
return SNMP_ERR_WRONGTYPE;
|
|
} else if (!strncasecmp(buf, "wrong-length", 12)) {
|
|
return SNMP_ERR_WRONGLENGTH;
|
|
} else if (!strncasecmp(buf, "wrong-encoding", 14)) {
|
|
return SNMP_ERR_WRONGENCODING;
|
|
} else if (!strncasecmp(buf, "wrong-value", 11)) {
|
|
return SNMP_ERR_WRONGVALUE;
|
|
} else if (!strncasecmp(buf, "no-creation", 11)) {
|
|
return SNMP_ERR_NOCREATION;
|
|
} else if (!strncasecmp(buf, "inconsistent-value", 18)) {
|
|
return SNMP_ERR_INCONSISTENTVALUE;
|
|
} else if (!strncasecmp(buf, "resource-unavailable", 20)) {
|
|
return SNMP_ERR_RESOURCEUNAVAILABLE;
|
|
} else if (!strncasecmp(buf, "commit-failed", 13)) {
|
|
return SNMP_ERR_COMMITFAILED;
|
|
} else if (!strncasecmp(buf, "undo-failed", 11)) {
|
|
return SNMP_ERR_UNDOFAILED;
|
|
} else if (!strncasecmp(buf, "authorization-error", 19)) {
|
|
return SNMP_ERR_AUTHORIZATIONERROR;
|
|
} else if (!strncasecmp(buf, "not-writable", 12)) {
|
|
return SNMP_ERR_NOTWRITABLE;
|
|
} else if (!strncasecmp(buf, "inconsistent-name", 17)) {
|
|
return SNMP_ERR_INCONSISTENTNAME;
|
|
}
|
|
|
|
return SNMP_ERR_NOERROR;
|
|
}
|
|
|
|
unsigned char *
|
|
netsnmp_internal_pass_parse(char * buf,
|
|
char * buf2,
|
|
size_t * var_len,
|
|
struct variable *vp)
|
|
{
|
|
static long long_ret;
|
|
static in_addr_t addr_ret;
|
|
int newlen;
|
|
static oid objid[MAX_OID_LEN];
|
|
|
|
/*
|
|
* buf contains the return type, and buf2 contains the data
|
|
*/
|
|
if (!strncasecmp(buf, "string", 6)) {
|
|
buf2[strlen(buf2) - 1] = 0; /* zap the linefeed */
|
|
if (buf2[strlen(buf2) - 1] == '\r')
|
|
buf2[strlen(buf2) - 1] = 0; /* zap the carriage-return */
|
|
*var_len = strlen(buf2);
|
|
vp->type = ASN_OCTET_STR;
|
|
return ((unsigned char *) buf2);
|
|
}
|
|
#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
|
|
else if (!strncasecmp(buf, "integer64", 9)) {
|
|
static struct counter64 c64;
|
|
uint64_t v64 = strtoull(buf2, NULL, 10);
|
|
c64.high = (unsigned long)(v64 >> 32);
|
|
c64.low = (unsigned long)(v64 & 0xffffffff);
|
|
*var_len = sizeof(c64);
|
|
vp->type = ASN_OPAQUE_I64;
|
|
return ((unsigned char *) &c64);
|
|
}
|
|
#endif
|
|
else if (!strncasecmp(buf, "integer", 7)) {
|
|
*var_len = sizeof(long_ret);
|
|
long_ret = strtol(buf2, NULL, 10);
|
|
vp->type = ASN_INTEGER;
|
|
return ((unsigned char *) &long_ret);
|
|
} else if (!strncasecmp(buf, "unsigned", 8)) {
|
|
*var_len = sizeof(long_ret);
|
|
long_ret = strtoul(buf2, NULL, 10);
|
|
vp->type = ASN_UNSIGNED;
|
|
return ((unsigned char *) &long_ret);
|
|
}
|
|
else if (!strncasecmp(buf, "counter64", 9)) {
|
|
static struct counter64 c64;
|
|
uint64_t v64 = strtoull(buf2, NULL, 10);
|
|
c64.high = (unsigned long)(v64 >> 32);
|
|
c64.low = (unsigned long)(v64 & 0xffffffff);
|
|
*var_len = sizeof(c64);
|
|
vp->type = ASN_COUNTER64;
|
|
return ((unsigned char *) &c64);
|
|
}
|
|
else if (!strncasecmp(buf, "counter", 7)) {
|
|
*var_len = sizeof(long_ret);
|
|
long_ret = strtoul(buf2, NULL, 10);
|
|
vp->type = ASN_COUNTER;
|
|
return ((unsigned char *) &long_ret);
|
|
} else if (!strncasecmp(buf, "octet", 5)) {
|
|
*var_len = netsnmp_internal_asc2bin(buf2);
|
|
vp->type = ASN_OCTET_STR;
|
|
return ((unsigned char *) buf2);
|
|
} else if (!strncasecmp(buf, "opaque", 6)) {
|
|
*var_len = netsnmp_internal_asc2bin(buf2);
|
|
vp->type = ASN_OPAQUE;
|
|
return ((unsigned char *) buf2);
|
|
} else if (!strncasecmp(buf, "gauge", 5)) {
|
|
*var_len = sizeof(long_ret);
|
|
long_ret = strtoul(buf2, NULL, 10);
|
|
vp->type = ASN_GAUGE;
|
|
return ((unsigned char *) &long_ret);
|
|
} else if (!strncasecmp(buf, "objectid", 8)) {
|
|
newlen = parse_miboid(buf2, objid);
|
|
*var_len = newlen * sizeof(oid);
|
|
vp->type = ASN_OBJECT_ID;
|
|
return ((unsigned char *) objid);
|
|
} else if (!strncasecmp(buf, "timetick", 8)) {
|
|
*var_len = sizeof(long_ret);
|
|
long_ret = strtoul(buf2, NULL, 10);
|
|
vp->type = ASN_TIMETICKS;
|
|
return ((unsigned char *) &long_ret);
|
|
} else if (!strncasecmp(buf, "ipaddress", 9)) {
|
|
newlen = parse_miboid(buf2, objid);
|
|
if (newlen != 4) {
|
|
snmp_log(LOG_ERR, "invalid ipaddress returned: %s\n", buf2);
|
|
*var_len = 0;
|
|
return (NULL);
|
|
}
|
|
addr_ret =
|
|
(objid[0] << (8 * 3)) + (objid[1] << (8 * 2)) +
|
|
(objid[2] << 8) + objid[3];
|
|
addr_ret = htonl(addr_ret);
|
|
*var_len = sizeof(addr_ret);
|
|
vp->type = ASN_IPADDRESS;
|
|
return ((unsigned char *) &addr_ret);
|
|
}
|
|
*var_len = 0;
|
|
return (NULL);
|
|
}
|
|
|
|
void
|
|
netsnmp_internal_pass_set_format(char *buf,
|
|
const u_char *var_val,
|
|
u_char var_val_type,
|
|
size_t var_val_len)
|
|
{
|
|
char buf2[SNMP_MAXBUF];
|
|
long tmp;
|
|
unsigned long utmp;
|
|
|
|
switch (var_val_type) {
|
|
case ASN_INTEGER:
|
|
case ASN_COUNTER:
|
|
case ASN_GAUGE:
|
|
case ASN_TIMETICKS:
|
|
tmp = *((const long *) var_val);
|
|
switch (var_val_type) {
|
|
case ASN_INTEGER:
|
|
sprintf(buf, "integer %d\n", (int) tmp);
|
|
break;
|
|
case ASN_COUNTER:
|
|
sprintf(buf, "counter %d\n", (int) tmp);
|
|
break;
|
|
case ASN_GAUGE:
|
|
sprintf(buf, "gauge %d\n", (int) tmp);
|
|
break;
|
|
case ASN_TIMETICKS:
|
|
sprintf(buf, "timeticks %d\n", (int) tmp);
|
|
break;
|
|
}
|
|
break;
|
|
case ASN_IPADDRESS:
|
|
utmp = *((const u_long *) var_val);
|
|
utmp = ntohl(utmp);
|
|
sprintf(buf, "ipaddress %d.%d.%d.%d\n",
|
|
(int) ((utmp & 0xff000000) >> (8 * 3)),
|
|
(int) ((utmp & 0xff0000) >> (8 * 2)),
|
|
(int) ((utmp & 0xff00) >> (8)),
|
|
(int) ((utmp & 0xff)));
|
|
break;
|
|
case ASN_OCTET_STR:
|
|
memcpy(buf2, var_val, var_val_len);
|
|
if (var_val_len == 0)
|
|
sprintf(buf, "string \"\"\n");
|
|
else if (netsnmp_internal_bin2asc(buf2, var_val_len) ==
|
|
(int) var_val_len)
|
|
snprintf(buf, SNMP_MAXBUF, "string \"%s\"\n", buf2);
|
|
else
|
|
snprintf(buf, SNMP_MAXBUF, "octet \"%s\"\n", buf2);
|
|
buf[ SNMP_MAXBUF-1 ] = 0;
|
|
break;
|
|
case ASN_OBJECT_ID:
|
|
sprint_mib_oid(buf2, (const oid *) var_val, var_val_len/sizeof(oid));
|
|
snprintf(buf, SNMP_MAXBUF, "objectid \"%s\"\n", buf2);
|
|
buf[ SNMP_MAXBUF-1 ] = 0;
|
|
break;
|
|
}
|
|
}
|