📄 _snmp.c
字号:
{
if (vflag)
PRINTF ("|%.2x", *p);
elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++;
}
}
if (len < elem->asnlen)
{
if (!truncated)
{
PRINTF ("[len%d<asnlen%u]", len, elem->asnlen);
return -1;
}
/* maybe should check at least 4? */
elem->asnlen = len;
}
if (form >= DIM(Form))
{
ifNotTruncated PRINTF ("[form?%d]", form);
return -1;
}
if (class >= DIM(Class))
{
ifNotTruncated PRINTF ("[class?%c/%d]", *Form[form], class);
return -1;
}
if ((int) id >= Class[class].numIDs)
{
ifNotTruncated PRINTF ("[id?%c/%s/%d]", *Form[form], Class[class].name, id);
return -1;
}
switch (form)
{
case PRIMITIVE:
switch (class)
{
case UNIVERSAL:
switch (id)
{
case STRING:
elem->type = BE_STR;
elem->data.str = p;
break;
case INTEGER:
{
int32_t data;
elem->type = BE_INT;
data = 0;
if (*p & ASN_BIT8) /* negative */
data = -1;
for (i = elem->asnlen; i-- > 0; p++)
data = (data << ASN_SHIFT8) | *p;
elem->data.integer = data;
break;
}
case OBJECTID:
elem->type = BE_OID;
elem->data.raw = (caddr_t) p;
break;
case ASN_NULL:
elem->type = BE_NULL;
elem->data.raw = (caddr_t)0;
break;
default:
elem->type = BE_OCTET;
elem->data.raw = (caddr_t) p;
PRINTF ("[P/U/%s]", Class[class].Id[id]);
break;
}
break;
case APPLICATION:
switch (id)
{
case IPADDR:
elem->type = BE_INETADDR;
elem->data.raw = (caddr_t) p;
break;
case COUNTER:
case GAUGE:
case TIMETICKS:
{
u_int32_t data;
elem->type = BE_UNS;
data = 0;
for (i = elem->asnlen; i-- > 0; p++)
data = (data << 8) + *p;
elem->data.uns = data;
break;
}
case COUNTER64:
{
u_int32_t high, low;
elem->type = BE_UNS64;
high = 0, low = 0;
for (i = elem->asnlen; i-- > 0; p++)
{
high = (high << 8) | ((low & 0xFF000000) >> 24);
low = (low << 8) | *p;
}
elem->data.uns64.high = high;
elem->data.uns64.low = low;
break;
}
default:
elem->type = BE_OCTET;
elem->data.raw = (caddr_t) p;
PRINTF ("[P/A/%s]", Class[class].Id[id]);
break;
}
break;
case CONTEXT:
switch (id)
{
case NOSUCHOBJECT:
elem->type = BE_NOSUCHOBJECT;
elem->data.raw = (caddr_t)0;
break;
case NOSUCHINSTANCE:
elem->type = BE_NOSUCHINST;
elem->data.raw = (caddr_t)0;
break;
case ENDOFMIBVIEW:
elem->type = BE_ENDOFMIBVIEW;
elem->data.raw = (caddr_t)0;
break;
}
break;
default:
elem->type = BE_OCTET;
elem->data.raw = (caddr_t) p;
PRINTF ("[P/%s/%s]", Class[class].name, Class[class].Id[id]);
break;
}
break;
case CONSTRUCTED:
switch (class)
{
case UNIVERSAL:
switch (id)
{
case SEQUENCE:
elem->type = BE_SEQ;
elem->data.raw = (caddr_t) p;
break;
default:
elem->type = BE_OCTET;
elem->data.raw = (caddr_t) p;
PRINTF ("C/U/%s", Class[class].Id[id]);
break;
}
break;
case CONTEXT:
elem->type = BE_PDU;
elem->data.raw = (caddr_t) p;
break;
default:
elem->type = BE_OCTET;
elem->data.raw = (caddr_t) p;
PRINTF ("C/%s/%s", Class[class].name, Class[class].Id[id]);
break;
}
break;
}
p += elem->asnlen;
len -= elem->asnlen;
return elem->asnlen + hdr;
}
/*
* Display the ASN.1 object represented by the BE object.
* This used to be an integral part of asn1_parse() before the intermediate
* BE form was added.
*/
static void asn1_print (struct be *elem)
{
u_char *p = (u_char *) elem->data.raw;
u_int32_t asnlen = elem->asnlen;
int i;
switch (elem->type)
{
case BE_OCTET:
for (i = asnlen; i-- > 0; p++) ;
PRINTF ("_%.2x", *p);
break;
case BE_NULL:
break;
case BE_OID:
{
int o = 0, first = -1, i = asnlen;
if (!sflag && !nflag && asnlen > 2)
{
struct obj_abrev *a = &obj_abrev_list[0];
for (; a->node; a++)
{
if (!memcmp (a->oid, (char *) p, strlen (a->oid)))
{
objp = a->node->child;
i -= strlen (a->oid);
p += strlen (a->oid);
PUTS (a->prefix);
first = 1;
break;
}
}
}
for (; !sflag && i-- > 0; p++)
{
o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
if (*p & ASN_LONGLEN)
continue;
/*
* first subitem encodes two items with 1st*OIDMUX+2nd
*/
if (first < 0)
{
if (!nflag)
objp = mibroot;
first = 0;
OBJ_PRINT (o / OIDMUX, first);
o %= OIDMUX;
}
OBJ_PRINT (o, first);
if (--first < 0)
first = 0;
o = 0;
}
break;
}
case BE_INT:
PRINTF ("%d", elem->data.integer);
break;
case BE_UNS:
PRINTF ("%u", elem->data.uns);
break;
case BE_UNS64:
{ /* idea borrowed from by Marshall Rose */
double d;
int j, carry;
char *cpf, *cpl, last[6], first[30];
if (elem->data.uns64.high == 0)
{
PRINTF ("%u", elem->data.uns64.low);
break;
}
d = elem->data.uns64.high * 4294967296.0; /* 2^32 */
if (elem->data.uns64.high <= 0x1fffff)
{
d += elem->data.uns64.low;
#if 0 /* it looks illegal, but what is the intention??? */
PRINTF ("%.f", d);
#else
PRINTF ("%f", d);
#endif
break;
}
d += (elem->data.uns64.low & 0xfffff000);
#if 0 /* it looks illegal, but what is the intention??? */
sprintf (first, "%.f", d);
#else
sprintf (first, "%f", d);
#endif
sprintf (last, "%5.5ld", elem->data.uns64.low & 0xfff);
for (carry = 0, cpf = first + strlen (first) - 1, cpl = last + 4; cpl >= last; cpf--, cpl--)
{
j = carry + (*cpf - '0') + (*cpl - '0');
if (j > 9)
{
j -= 10;
carry = 1;
}
else
{
carry = 0;
}
*cpf = j + '0';
}
PUTS (first);
break;
}
case BE_STR:
{
int printable = 1, first = 1;
const u_char *p = elem->data.str;
for (i = asnlen; printable && i-- > 0; p++)
printable = isprint (*p) || isspace (*p);
p = elem->data.str;
if (printable)
{
PUTCHAR ('"');
fn_print ((char*)p, (char*)(p+asnlen));
PUTCHAR ('"');
}
else
for (i = asnlen; i-- > 0; p++)
{
PRINTF (first ? "%.2x" : "_%.2x", *p);
first = 0;
}
break;
}
case BE_SEQ:
PRINTF ("Seq(%u)", elem->asnlen);
break;
case BE_INETADDR:
if (asnlen != ASNLEN_INETADDR)
PRINTF ("[inetaddr len!=%d]", ASNLEN_INETADDR);
for (i = asnlen; i-- > 0; p++)
PRINTF ((i == asnlen - 1) ? "%u" : ".%u", *p);
break;
case BE_NOSUCHOBJECT:
case BE_NOSUCHINST:
case BE_ENDOFMIBVIEW:
PRINTF ("[%s]", Class[EXCEPTIONS].Id[elem->id]);
break;
case BE_PDU:
PRINTF ("%s(%u)", Class[CONTEXT].Id[elem->id], elem->asnlen);
break;
case BE_ANY:
PUTS ("[BE_ANY!?]");
break;
default:
PUTS ("[be!?]");
break;
}
}
#ifdef notdef
/*
* This is a brute force ASN.1 printer: recurses to dump an entire structure.
* This will work for any ASN.1 stream, not just an SNMP PDU.
*
* By adding newlines and spaces at the correct places, this would print in
* Rose-Normal-Form.
*
* This is not currently used.
*/
static void asn1_decode (u_char * p, u_int length)
{
struct be elem;
int i = 0;
while (i >= 0 && length > 0)
{
i = asn1_parse (p, length, &elem);
if (i >= 0)
{
PUTCHAR (' ');
asn1_print (&elem);
if (elem.type == BE_SEQ || elem.type == BE_PDU)
{
PUTS (" {");
asn1_decode (elem.data.raw, elem.asnlen);
PUTS (" }");
}
length -= i;
p += i;
}
}
}
#endif
#ifdef LIBSMI
struct smi2be {
SmiBasetype basetype;
int be;
};
struct smi2be smi2betab[] = {
{SMI_BASETYPE_INTEGER32, BE_INT},
{SMI_BASETYPE_OCTETSTRING, BE_STR},
{SMI_BASETYPE_OCTETSTRING, BE_INETADDR},
{SMI_BASETYPE_OBJECTIDENTIFIER, BE_OID},
{SMI_BASETYPE_UNSIGNED32, BE_UNS},
{SMI_BASETYPE_INTEGER64, BE_NONE},
{SMI_BASETYPE_UNSIGNED64, BE_UNS64},
{SMI_BASETYPE_FLOAT32, BE_NONE},
{SMI_BASETYPE_FLOAT64, BE_NONE},
{SMI_BASETYPE_FLOAT128, BE_NONE},
{SMI_BASETYPE_ENUM, BE_INT},
{SMI_BASETYPE_BITS, BE_STR},
{SMI_BASETYPE_UNKNOWN, BE_NONE}
};
static void smi_decode_oid (struct be *elem, unsigned int *oid, unsigned int *oidlen)
{
u_char *p = (u_char *) elem->data.raw;
u_int32_t asnlen = elem->asnlen;
int o = 0, first = -1, i = asnlen;
for (*oidlen = 0; sflag && i-- > 0; p++)
{
o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
if (*p & ASN_LONGLEN)
continue;
/*
* first subitem encodes two items with 1st*OIDMUX+2nd
*/
if (first < 0)
{
first = 0;
oid[(*oidlen)++] = o / OIDMUX;
o %= OIDMUX;
}
oid[(*oidlen)++] = o;
o = 0;
}
}
static int smi_check_type (SmiBasetype basetype, int be)
{
int i;
for (i = 0; smi2betab[i].basetype != SMI_BASETYPE_UNKNOWN; i++)
{
if (smi2betab[i].basetype == basetype && smi2betab[i].be == be)
return 1;
}
return 0;
}
static int smi_check_a_range (SmiType * smiType, SmiRange * smiRange, struct be *elem)
{
int ok;
switch (smiType->basetype)
{
case SMI_BASETYPE_OBJECTIDENTIFIER:
case SMI_BASETYPE_OCTETSTRING:
if (smiRange->minValue.value.unsigned32 == smiRange->maxValue.value.unsigned32)
ok = (elem->asnlen == smiRange->minValue.value.unsigned32);
else ok = (elem->asnlen >= smiRange->minValue.value.unsigned32 &&
elem->asnlen <= smiRange->maxValue.value.unsigned32);
break;
case SMI_BASETYPE_INTEGER32:
ok = (elem->data.integer >= smiRange->minValue.value.integer32 &&
elem->data.integer <= smiRange->maxValue.value.integer32);
break;
case SMI_BASETYPE_UNSIGNED32:
ok = (elem->data.uns >= smiRange->minValue.value.unsigned32 &&
elem->data.uns <= smiRange->maxValue.value.unsigned32);
break;
case SMI_BASETYPE_UNSIGNED64:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -