📄 print-snmp.c
字号:
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 (!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 (; 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("%d", elem->data.uns); 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: { char sep; if (asnlen != ASNLEN_INETADDR) printf("[inetaddr len!=%d]", ASNLEN_INETADDR); sep='['; for (i = asnlen; i-- > 0; p++) { printf("%c%u", sep, *p); sep='.'; } putchar(']'); 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/* * 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, int error){ struct be elem; int count = 0, ind; /* 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; if (!error || ind == error) 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; } if (!error || ind == error) asn1_print(&elem); length -= count; np += count; if (pduid != GETREQ && pduid != GETNEXTREQ && !error) fputs("=", stdout); /* objVal (ANY) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (pduid == GETREQ || pduid == GETNEXTREQ) { if (elem.type != BE_NULL) { fputs("[objVal!=NULL]", stdout); asn1_print(&elem); } } else if (error && ind == error && elem.type != BE_NULL) fputs("[err objVal!=NULL]", stdout); if (!error || ind == error) asn1_print(&elem); length = vblength; np = vbend; }}/* * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, and SetRequest */static voidsnmppdu_print(u_char pduid, const u_char *np, u_int length){ struct be elem; int count = 0, error; /* reqId (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[reqId!=INT]", stdout); asn1_print(&elem); return; } /* ignore the reqId */ length -= count; np += count; /* errorStatus (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[errorStatus!=INT]", stdout); asn1_print(&elem); return; } error = 0; if ((pduid == GETREQ || pduid == GETNEXTREQ) && elem.data.integer != 0) { char errbuf[10]; printf("[errorStatus(%s)!=0]", DECODE_ErrorStatus(elem.data.integer)); } else if (elem.data.integer != 0) { char errbuf[10]; printf(" %s", DECODE_ErrorStatus(elem.data.integer)); error = elem.data.integer; } length -= count; np += count; /* errorIndex (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[errorIndex!=INT]", stdout); asn1_print(&elem); return; } if ((pduid == GETREQ || pduid == GETNEXTREQ) && elem.data.integer != 0) printf("[errorIndex(%d)!=0]", elem.data.integer); else if (elem.data.integer != 0) { if (!error) printf("[errorIndex(%d) w/o errorStatus]", elem.data.integer); else { printf("@%d", elem.data.integer); error = elem.data.integer; } } else if (error) { fputs("[errorIndex==0]", stdout); error = 0; } length -= count; np += count; varbind_print(pduid, np, length, error); return;}/* * Decode SNMP Trap PDU */static voidtrap_print(const u_char *np, u_int length){ struct be elem; int count = 0, generic; putchar(' '); /* enterprise (oid) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_OID) { fputs("[enterprise!=OID]", stdout); asn1_print(&elem); return; } asn1_print(&elem); length -= count; np += count; putchar(' '); /* agent-addr (inetaddr) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INETADDR) { fputs("[agent-addr!=INETADDR]", stdout); asn1_print(&elem); return; } asn1_print(&elem); length -= count; np += count; /* generic-trap (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[generic-trap!=INT]", stdout); asn1_print(&elem); return; } generic = elem.data.integer; { char buf[10]; printf(" %s", DECODE_GenericTrap(generic)); } length -= count; np += count; /* specific-trap (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[specific-trap!=INT]", stdout); asn1_print(&elem); return; } if (generic != GT_ENTERPRISE) { if (elem.data.integer != 0) printf("[specific-trap(%d)!=0]", elem.data.integer); } else printf(" s=%d", elem.data.integer); length -= count; np += count; putchar(' '); /* time-stamp (TimeTicks) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_UNS) { /* XXX */ fputs("[time-stamp!=TIMETICKS]", stdout); asn1_print(&elem); return; } asn1_print(&elem); length -= count; np += count; varbind_print (TRAP, np, length, 0); return;}/* * Decode SNMP header and pass on to PDU printing routines */voidsnmp_print(const u_char *np, u_int length){ struct be elem, pdu; int count = 0; truncated = 0; /* truncated packet? */ if (np + length > snapend) { truncated = 1; length = snapend - np; } putchar(' '); /* initial Sequence */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_SEQ) { fputs("[!init SEQ]", stdout); asn1_print(&elem); return; } if (count < length) printf("[%d extra after iSEQ]", length - count); /* descend */ length = elem.asnlen; np = (u_char *)elem.data.raw; /* Version (Integer) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_INT) { fputs("[version!=INT]", stdout); asn1_print(&elem); return; } /* only handle version==0 */ if (elem.data.integer != DEF_VERSION) { printf("[version(%d)!=0]", elem.data.integer); return; } length -= count; np += count; /* Community (String) */ if ((count = asn1_parse(np, length, &elem)) < 0) return; if (elem.type != BE_STR) { fputs("[comm!=STR]", stdout); asn1_print(&elem); return; } /* default community */ if (strncmp((char *)elem.data.str, DEF_COMMUNITY, sizeof(DEF_COMMUNITY) - 1)) /* ! "public" */ printf("C=%.*s ", (int)elem.asnlen, elem.data.str); length -= count; np += count; /* PDU (Context) */ if ((count = asn1_parse(np, length, &pdu)) < 0) return; if (pdu.type != BE_PDU) { fputs("[no PDU]", stdout); return; } if (count < length) printf("[%d extra after PDU]", length - count); asn1_print(&pdu); /* descend into PDU */ length = pdu.asnlen; np = (u_char *)pdu.data.raw; switch (pdu.id) { case TRAP: trap_print(np, length); break; case GETREQ: case GETNEXTREQ: case GETRESP: case SETREQ: snmppdu_print(pdu.id, np, length); break; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -