#include #include #if HAVE_STDDEF_H #include #endif #include #if HAVE_STRING_H #include #else #include #endif #include #include #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; } }