📄 print-snmp.c
字号:
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 voidasn1_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); fputs(a->prefix, stdout); 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 /*is looks illegal, but what is the intention???*/ printf("%.f", d);#else printf("%f", d);#endif break; } d += (elem->data.uns64.low & 0xfffff000);#if 0 /*is looks illegal, but what is the intention???*/ snprintf(first, sizeof(first), "%.f", d);#else snprintf(first, sizeof(first), "%f", d);#endif snprintf(last, sizeof(last), "%5.5d", 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'; } fputs(first, stdout); break; } case BE_STR: { register 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('"'); (void)fn_print(p, 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: fputs("[BE_ANY!?]", stdout); break; default: fputs("[be!?]", stdout); 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 voidasn1_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) { fputs(" ", stdout); asn1_print(&elem); if (elem.type == BE_SEQ || elem.type == BE_PDU) { fputs(" {", stdout); asn1_decode(elem.data.raw, elem.asnlen); fputs(" }", stdout); } length -= i; p += i; } }}#endif#ifdef LIBSMI#if (SMI_VERSION_MAJOR == 0 && SMI_VERSION_MINOR >= 2) || (SMI_VERSION_MAJOR > 0)#define LIBSMI_API_V2#else#define LIBSMI_API_V1#endif#ifdef LIBSMI_API_V1/* Some of the API revisions introduced new calls that can be * represented by macros. */#define smiGetNodeType(n) smiGetType((n)->typemodule, (n)->typename)#else/* These calls in the V1 API were removed in V2. */#define smiFreeRange(r)#define smiFreeType(r)#define smiFreeNode(r)#endifstruct smi2be { SmiBasetype basetype; int be;};static 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 = 1; 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: /* XXX */ break; /* case SMI_BASETYPE_INTEGER64: SMIng */ /* case SMI_BASETYPE_FLOAT32: SMIng */ /* case SMI_BASETYPE_FLOAT64: SMIng */ /* case SMI_BASETYPE_FLOAT128: SMIng */ case SMI_BASETYPE_ENUM: case SMI_BASETYPE_BITS: case SMI_BASETYPE_UNKNOWN: ok = 1; break; } return ok;}static int smi_check_range(SmiType *smiType, struct be *elem){ SmiRange *smiRange; int ok = 1;#ifdef LIBSMI_API_V1 for (smiRange = smiGetFirstRange(smiType->module, smiType->name);#else for (smiRange = smiGetFirstRange(smiType);#endif smiRange; smiRange = smiGetNextRange(smiRange)) { ok = smi_check_a_range(smiType, smiRange, elem); if (ok) { smiFreeRange(smiRange); break; } } if (ok#ifdef LIBSMI_API_V1 && smiType->parentmodule && smiType->parentname#endif ) { SmiType *parentType;#ifdef LIBSMI_API_V1 parentType = smiGetType(smiType->parentmodule, smiType->parentname);#else parentType = smiGetParentType(smiType);#endif if (parentType) { ok = smi_check_range(parentType, elem); smiFreeType(parentType); } } return ok;}static SmiNode *smi_print_variable(struct be *elem){ unsigned int oid[128], oidlen; SmiNode *smiNode = NULL; int i; smi_decode_oid(elem, oid, &oidlen); smiNode = smiGetNodeByOID(oidlen, oid); if (! smiNode) { asn1_print(elem); return NULL; } if (vflag) {#ifdef LIBSMI_API_V1 fputs(smiNode->module, stdout);#else fputs(smiGetNodeModule(smiNode)->name, stdout);#endif fputs("::", stdout); } fputs(smiNode->name, stdout); if (smiNode->oidlen < oidlen) { for (i = smiNode->oidlen; i < oidlen; i++) { printf(".%u", oid[i]); } } return smiNode;}static void smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem){ unsigned int oid[128], oidlen; SmiType *smiType; SmiNamedNumber *nn; int i, done = 0; if (! smiNode || ! (smiNode->nodekind & (SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN))) { asn1_print(elem); return; } if (elem->type == BE_NOSUCHOBJECT || elem->type == BE_NOSUCHINST || elem->type == BE_ENDOFMIBVIEW) { asn1_print(elem); return; } if (NOTIFY_CLASS(pduid) && smiNode->access < SMI_ACCESS_NOTIFY) { fputs("[notNotifyable]", stdout); } if (READ_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_ONLY) { fputs("[notReadable]", stdout); } if (WRITE_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_WRITE) { fputs("[notWritable]", stdout); } if (RESPONSE_CLASS(pduid) && smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE) { fputs("[noAccess]", stdout); }#ifdef LIBSMI_API_V1 smiType = smiGetType(smiNode->typemodule, smiNode->typename);#else smiType = smiGetNodeType(smiNode);#endif if (! smiType) { asn1_print(elem); return; }#ifdef LIBSMI_API_V1 if (! smi_check_type(smiNode->basetype, elem->type)) {#else if (! smi_check_type(smiType->basetype, elem->type)) {#endif fputs("[wrongType]", stdout); } if (! smi_check_range(smiType, elem)) { fputs("[wrongLength]", stdout); } /* resolve bits to named bits */ /* check whether instance identifier is valid */ /* apply display hints (integer, octetstring) */ /* convert instance identifier to index type values */ switch (elem->type) { case BE_OID: if (smiType->basetype == SMI_BASETYPE_BITS) { /* print bit labels */ } else { smi_decode_oid(elem, oid, &oidlen); smiNode = smiGetNodeByOID(oidlen, oid); if (smiNode) { if (vflag) {#ifdef LIBSMI_API_V1 fputs(smiNode->module, stdout);#else fputs(smiGetNodeModule(smiNode)->name, stdout);#endif fputs("::", stdout); } fputs(smiNode->name, stdout); if (smiNode->oidlen < oidlen) { for (i = smiNode->oidlen; i < oidlen; i++) { printf(".%u", oid[i]); } } done++; } } break; case BE_INT:#ifdef LIBSMI_API_V1 if (smiNode->basetype == SMI_BASETYPE_ENUM && smiNode->typemodule && smiNode->typename) { for (nn = smiGetFirstNamedNumber(smiNode->typemodule, smiNode->typename);#else if (smiType->basetype == SMI_BASETYPE_ENUM) { for (nn = smiGetFirstNamedNumber(smiType);#endif nn; nn = smiGetNextNamedNumber(nn)) { if (nn->value.value.integer32 == elem->data.integer) { fputs(nn->name, stdout); printf("(%d)", elem->data.integer); done++; break; } } } break; } if (! done) { asn1_print(elem); } if (smiType) { smiFreeType(smiType); }}#endif/* * General SNMP header * SEQUENCE { * version INTEGER {version-1(0)}, * community OCTET STRING, * data ANY -- PDUs * } * PDUs for all but Trap: (see rfc1157 from page 15 on) * SEQUENCE { * request-id INTEGER, * error-status INTEGER, * error-index INTEGER, * varbindlist SEQUENCE OF * SEQUENCE { * name ObjectName, * value ObjectValue * } * } * PDU for Trap: * SEQUENCE { * enterprise OBJECT IDENTIFIER, * agent-addr NetworkAddress, * generic-trap INTEGER, * specific-trap INTEGER, * time-stamp TimeTicks, * varbindlist SEQUENCE OF * SEQUENCE { * name ObjectName, * value ObjectValue * } * } *//* * Decode SNMP varBind */static voidvarbind_print(u_char pduid, const u_char *np, u_int length){ struct be elem; int count = 0, ind;#ifdef LIBSMI SmiNode *smiNode = NULL;#endif /* Sequence of varBind */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { fputs("[!SEQ of varbind]", stdout); asn1_print(&elem); return; } if (count < length) printf("[%d extra after SEQ of varbind]", length - count); /* descend */ length = elem.asnlen; np = (u_char *)elem.data.raw; for (ind = 1; length > 0; ind++) { const u_char *vbend; u_int vblength; fputs(" ", stdout); /* Sequence */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { fputs("[!varbind]", stdout); asn1_print(&elem); return; } vbend = np + count; vblength = length - count; /* descend */ length = elem.asnlen; np = (u_char *)elem.data.raw; /* objName (OID) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_OID) { fputs("[objName!=OID]", stdout); asn1_print(&elem); return; }#ifdef LIBSMI smiNode = smi_print_variable(&elem);#else asn1_print(&elem);#endif length -= count; np += count; if (pduid != GETREQ && pduid != GETNEXTREQ && pduid != GETBULKREQ) fputs("=", stdout); /* objVal (ANY) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (pduid == GETREQ || pduid == GETNEXTREQ || pduid == GETBULKREQ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -