X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/2028db4d8d4bae1a5e2a410d5eb9882da8ed6171..2075ea09c1535b547298fa47b51b2bfe41229032:/print-snmp.c diff --git a/print-snmp.c b/print-snmp.c index 735f0176..634ffdbe 100644 --- a/print-snmp.c +++ b/print-snmp.c @@ -1,16 +1,29 @@ /* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. + * John Robert LoVerso. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by John Robert LoVerso. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * This implementation has been influenced by the CMU SNMP release, * by Steve Waldbusser. However, this shares no code with that system. @@ -45,17 +58,15 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-snmp.c,v 1.45 2001-01-24 21:50:58 fenner Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-snmp.c,v 1.55 2002-08-01 08:53:30 risso Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include +#include -#include #include #include @@ -428,16 +439,11 @@ asn1_parse(register const u_char *p, u_int len, struct be *elem) elem->form = form; elem->class = class; elem->id = id; - if (vflag > 1) - printf("|%.2x", *p); p++; len--; hdr = 1; /* extended tag field */ if (id == ASN_ID_EXT) { - for (id = 0; *p & ASN_BIT8 && len > 0; len--, hdr++, p++) { - if (vflag > 1) - printf("|%.2x", *p); + for (id = 0; *p & ASN_BIT8 && len > 0; len--, hdr++, p++) id = (id << 7) | (*p & ~ASN_BIT8); - } if (len == 0 && *p & ASN_BIT8) { ifNotTruncated fputs("[Xtagfield?]", stdout); return -1; @@ -452,8 +458,6 @@ asn1_parse(register const u_char *p, u_int len, struct be *elem) return -1; } elem->asnlen = *p; - if (vflag > 1) - printf("|%.2x", *p); p++; len--; hdr++; if (elem->asnlen & ASN_BIT8) { int noct = elem->asnlen % ASN_BIT8; @@ -462,11 +466,8 @@ asn1_parse(register const u_char *p, u_int len, struct be *elem) ifNotTruncated printf("[asnlen? %d<%d]", len, noct); return -1; } - for (; noct-- > 0; len--, hdr++) { - if (vflag > 1) - printf("|%.2x", *p); + for (; noct-- > 0; len--, hdr++) elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++; - } } if (len < elem->asnlen) { if (!truncated) { @@ -556,7 +557,7 @@ asn1_parse(register const u_char *p, u_int len, struct be *elem) elem->type = BE_UNS64; high = 0, low = 0; for (i = elem->asnlen; i-- > 0; p++) { - high = (high << 8) | + high = (high << 8) | ((low & 0xFF000000) >> 24); low = (low << 8) | *p; } @@ -682,16 +683,20 @@ asn1_print(struct be *elem) o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); if (*p & ASN_LONGLEN) continue; - + /* * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) */ if (first < 0) { + int s; if (!nflag) objp = mibroot; first = 0; - OBJ_PRINT(o/OIDMUX, first); - o %= OIDMUX; + s = o / OIDMUX; + if (s > 2) s = 2; + OBJ_PRINT(s, first); + o -= s * OIDMUX; } OBJ_PRINT(o, first); if (--first < 0) @@ -718,9 +723,9 @@ asn1_print(struct be *elem) break; } d = elem->data.uns64.high * 4294967296.0; /* 2^32 */ - if (elem->data.uns64.high <= 0x1fffff) { + if (elem->data.uns64.high <= 0x1fffff) { d += elem->data.uns64.low; -#if 0 /*is looks illegal, but what is the intention???*/ +#if 0 /*is looks illegal, but what is the intention?*/ printf("%.f", d); #else printf("%f", d); @@ -728,7 +733,7 @@ asn1_print(struct be *elem) break; } d += (elem->data.uns64.low & 0xfffff000); -#if 0 /*is looks illegal, but what is the intention???*/ +#if 0 /*is looks illegal, but what is the intention?*/ snprintf(first, sizeof(first), "%.f", d); #else snprintf(first, sizeof(first), "%f", d); @@ -859,7 +864,7 @@ static struct smi2be smi2betab[] = { }; static void smi_decode_oid(struct be *elem, unsigned int *oid, - unsigned int *oidlen) + unsigned int oidsize, unsigned int *oidlen) { u_char *p = (u_char *)elem->data.raw; u_int32_t asnlen = elem->asnlen; @@ -869,16 +874,23 @@ static void smi_decode_oid(struct be *elem, unsigned int *oid, o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); if (*p & ASN_LONGLEN) continue; - + /* * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) */ if (first < 0) { first = 0; - oid[(*oidlen)++] = o/OIDMUX; - o %= OIDMUX; + if (*oidlen < oidsize) { + oid[*oidlen] = o / OIDMUX; + if (oid[*oidlen] > 2) oid[*oidlen] = 2; + } + o -= oid[*oidlen] * OIDMUX; + if (*oidlen < oidsize) (*oidlen)++; + } + if (*oidlen < oidsize) { + oid[(*oidlen)++] = o; } - oid[(*oidlen)++] = o; o = 0; } } @@ -900,7 +912,7 @@ 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: @@ -917,12 +929,12 @@ static int smi_check_a_range(SmiType *smiType, SmiRange *smiRange, 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; @@ -975,7 +987,7 @@ static SmiNode *smi_print_variable(struct be *elem) SmiNode *smiNode = NULL; int i; - smi_decode_oid(elem, oid, &oidlen); + smi_decode_oid(elem, oid, sizeof(oid)/sizeof(unsigned int), &oidlen); smiNode = smiGetNodeByOID(oidlen, oid); if (! smiNode) { asn1_print(elem); @@ -1042,7 +1054,7 @@ static void smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem) } if (! smi_check_range(smiType, elem)) { - fputs("[wrongLength]", stdout); + fputs("[outOfRange]", stdout); } /* resolve bits to named bits */ @@ -1052,13 +1064,15 @@ static void smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem) /* 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); + smi_decode_oid(elem, oid, + sizeof(oid)/sizeof(unsigned int), + &oidlen); smiNode = smiGetNodeByOID(oidlen, oid); if (smiNode) { if (vflag) { @@ -1067,7 +1081,7 @@ static void smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem) } fputs(smiNode->name, stdout); if (smiNode->oidlen < oidlen) { - for (i = smiNode->oidlen; + for (i = smiNode->oidlen; i < oidlen; i++) { printf(".%u", oid[i]); } @@ -1418,7 +1432,7 @@ pdu_print(const u_char *np, u_int length, int version) np = (u_char *)pdu.data.raw; if (version == SNMP_VERSION_1 && - (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || + (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || pdu.id == V2TRAP || pdu.id == REPORT)) { printf("[v2 PDU in v1 message]"); return; @@ -1446,7 +1460,7 @@ pdu_print(const u_char *np, u_int length, int version) } if (vflag) { - fputs("} ", stdout); + fputs(" } ", stdout); } } @@ -1521,8 +1535,9 @@ community_print(const u_char *np, u_int length, int version) return; } /* default community */ - if (strncmp((char *)elem.data.str, DEF_COMMUNITY, - sizeof(DEF_COMMUNITY) - 1)) + if (!(elem.asnlen == sizeof(DEF_COMMUNITY) - 1 && + strncmp((char *)elem.data.str, DEF_COMMUNITY, + sizeof(DEF_COMMUNITY) - 1) == 0)) /* ! "public" */ printf("C=%.*s ", (int)elem.asnlen, elem.data.str); length -= count; @@ -1570,7 +1585,7 @@ usm_print(const u_char *np, u_int length) asn1_print(&elem); return; } - if (vflag) + if (vflag) printf("B=%d ", elem.data.integer); length -= count; np += count; @@ -1583,7 +1598,7 @@ usm_print(const u_char *np, u_int length) asn1_print(&elem); return; } - if (vflag) + if (vflag) printf("T=%d ", elem.data.integer); length -= count; np += count; @@ -1690,7 +1705,7 @@ v3msg_print(const u_char *np, u_int length) return; } flags = elem.data.str[0]; - if (flags != 0x00 && flags != 0x01 && flags != 0x03 + if (flags != 0x00 && flags != 0x01 && flags != 0x03 && flags != 0x04 && flags != 0x05 && flags != 0x07) { printf("[msgFlags=0x%02X]", flags); return;