home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.perl:5041 comp.protocols.snmp:523
- Newsgroups: comp.lang.perl,comp.protocols.snmp
- Path: sparky!uunet!infonode!ingr!b30!guy!guy
- From: guy@guy.b11.ingr.com (Guy Streeter)
- Subject: PERL interface to CMU-SNMP
- Message-ID: <guy.712515964@guy>
- Keywords: perl,snmp,CMU
- Sender: usenet@b30.ingr.com (Usenet Feed)
- Reply-To: guy@guy.b11.ingr.com
- Organization: evidently not
- Date: Thu, 30 Jul 1992 17:06:04 GMT
- Lines: 1636
-
- I was planning to hold off releasing this in order to port it to the
- new CMU release. But it looks like it may be a while before I can get
- to that, so here it is.
-
- What is it? It is snmperl, an interface from perl to the API of the
- CMU SNMP implementation. See the README file for more information.
-
- I'll be glad to hear feedback about problems with this package, and
- about how useful/useless it is, but I don't guarantee support for it
- and I don't warantee it at all.
-
- I'll also be glad to hear from Mr. Wall or anyone else familiar with
- the user-supplied subroutine code about how well (or not) I did the
- implementation.
-
- have fun,
- Guy Streeter
- guy@guy.b30.ingr.com
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 07/30/1992 17:03 UTC by guy@guy.b30.ingr.com
- # Source directory /usr2/perl/snmp
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 3407 -rw-rw-r-- README
- # 495 -rw-r--r-- Makefile
- # 9601 -rw-rw-r-- snmp.c
- # 16738 -rw-r--r-- mib.c
- # 1754 -rw-rw-rw- snmp.pl
- # 4584 -rwxr-xr-x snmp-tracer
- #
- # ============= README ==============
- if test -f 'README' -a X"$1" != X"-c"; then
- echo 'x - skipping README (File already exists)'
- else
- echo 'x - extracting README (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'README' &&
- XThis directory contains the source code to add callable C subroutines
- Xto perl. The subroutines implement the SNMP functions "get",
- X"getnext", and "set". They use the freely-distributable SNMP package
- X(version 1.1b) from CMU.
- X
- XThis file tells how to build and use this package. The following
- Xfiles should be present:
- X
- XREADME -- This file.
- X
- Xsnmp.c -- The callable interface to perl.
- X
- Xmib.c -- The only file from the CMU SNMP package which has been
- X modified for use here.
- X
- XMakefile -- The Makefile (You'll need to edit this).
- X
- Xsnmp.pl -- A small package of useful routines.
- X
- Xsnmp-tracer -- An incomplete attempt to implement trace-route.
- X Supplied as an example of the interface.
- X
- XSETUP:
- X These files should be in a subdirectory of the main perl source
- Xdirectory. If not, you must change the SRC variable in the Makefile
- Xto point to the perl source directory. Perl should be built.
- XSpecifically, "uperl.o" should be present in the perl directory.
- X
- X You must have the CMU SNMP package. This can be retrieved from
- Xlancaster.andrew.cmu.edu as pub/snmp1.1b.tar, via anonymous FTP. You
- Xdon't have to build all the applications (some of them won't work
- Xunless you are a BSD system), you just need to build libsnmp.a.
- X
- XBUILD:
- X Once you have perl and the CMU SNMP package:
- X1) Copy libsnmp.a from the CMU package to this directory (we will
- Xmodify it).
- X2) Edit "Makefile". See especially the CC and INCS variables.
- X3) make.
- X
- XMake should compile mib.c and replace mib.o in libsnmp.a, compile
- Xsnmp.c, and create an executable called "snmperl". Installation is
- Xleft to the user.
- X
- XUSE:
- X There are four subroutines defined in the callable interface:
- Xsnmp_get, snmp_next, snmp_set, and snmp_error.
- X
- X snmp_get and snmp_next implement the GET and GETNEXT operations,
- Xrespectively. The first two calling arguments are the hostname and
- XCommunity string. The IP address of the host, as a dotted-quad ASCII
- Xstring, may be used as the hostname. The rest of the calling
- Xarguments are a list of variables. See the CMU package documentation
- Xfor how variables may be specified.
- X snmp_set also takes hostname and Community string as arguments. The
- Xremaining arguments are a list of triples consisting of variable name,
- Xvariable type, and value. The variable type is a string, such as
- X"INTEGER" or "IpAddress".
- X snmp_get, snmp_next, and snmp_set return a list containing
- Xalternating variables and values. snmp_get and snmp_next will simply
- Xomit non-existent variables on return. snmp_set will fail completely
- Xif one of the specified variables does not exist (or is read-only).
- X snmp_error will return a text string containing some error
- Xinformation about the most recent snmp_get|next|set call, if it had an
- Xerror.
- X
- XOTHER NOTES:
- X I didn't find all the places where the CMU library writes to stderr
- Xor calls exit() directly.
- X The changes I made to mib.c involve the formatting of variable values
- Xfor return to the caller. I took out the descriptive prefix so the
- Xstring contains only the value.
- X Enumerated types are returned as a string containing the symbolic
- Xrepresentation followed in parentheses by the numeric.
- X
- XDISTRIBUTION and OWNERSHIP
- X perl and the CMU SNMP package have their own statements. Read them.
- XThe work I've done is free and clear. Just don't say you wrote it if
- Xyou didn't, and don't say I wrote it if you change it.
- X
- XGuy Streeter
- Xstreeter@ingr.com
- XApril 1, 1992 (not a joke!)
- SHAR_EOF
- chmod 0664 README ||
- echo 'restore of README failed'
- Wc_c="`wc -c < 'README'`"
- test 3407 -eq "$Wc_c" ||
- echo 'README: original size 3407, current size' "$Wc_c"
- fi
- # ============= Makefile ==============
- if test -f 'Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping Makefile (File already exists)'
- else
- echo 'x - extracting Makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
- X# define your C compiler command here
- XCC = gcc -mc300 -O -s -fwritable-strings -fstrength-reduce -fpcc-struct-return
- X
- X# point this to the "include" directory of the CMU SNMP source.
- XINCS=-I/usr2/guy/src/cmu-snmp/include
- X
- XSRC = ..
- XLDLIBS = libsnmp.a `. $(SRC)/config.sh; echo $$libs`
- X
- Xsnmperl: $(SRC)/uperl.o snmp.o libsnmp.a
- X $(CC) $(SRC)/uperl.o snmp.o $(LDLIBS) -o snmperl
- X
- Xsnmp.o : snmp.c
- X $(CC) -c -I$(SRC) $(INCS) snmp.c
- X
- Xmib.o : mib.c
- X $(CC) -c $(INCS) mib.c
- X
- Xlibsnmp.a: libsnmp.a(mib.o)
- SHAR_EOF
- chmod 0644 Makefile ||
- echo 'restore of Makefile failed'
- Wc_c="`wc -c < 'Makefile'`"
- test 495 -eq "$Wc_c" ||
- echo 'Makefile: original size 495, current size' "$Wc_c"
- fi
- # ============= snmp.c ==============
- if test -f 'snmp.c' -a X"$1" != X"-c"; then
- echo 'x - skipping snmp.c (File already exists)'
- else
- echo 'x - extracting snmp.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'snmp.c' &&
- X/*
- X * Guy Streeter, 31-mar-92
- X *
- X * 15-may-92 Fix the handling of Octet Strings, so they come out unmodified.
- X *
- X * A lot of this code was derived by example from the CMU SNMP package,
- X * whose copyright notice follows:
- X */
- X/***********************************************************
- X Copyright 1988, 1989 by Carnegie Mellon University
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the name of CMU not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X******************************************************************/
- X#include "EXTERN.h"
- X#include "perl.h"
- X
- X#include <sys/types.h>
- X#include <netinet/in.h>
- X#include <sys/time.h>
- X#include "snmp.h"
- X#include "snmp_impl.h"
- X#include "asn1.h"
- X#include "snmp_api.h"
- X#include "snmp_client.h"
- X
- Xextern int snmp_errno;
- Xextern struct tree *Mib;
- X
- Xint snmp_dump_packet = 0;
- X
- Xstatic int last_status;
- Xstatic int last_errstat;
- Xstatic char err_text[1024];
- X
- Xenum usersubs {
- X US_snmp_get,
- X US_snmp_next,
- X US_snmp_set,
- X US_snmp_error,
- X};
- X
- Xint
- Xuserinit()
- X{
- X static void usersub();
- X static char *filename = "snmp.c";
- X
- X make_usub("snmp_get", US_snmp_get, usersub, filename);
- X make_usub("snmp_next", US_snmp_next, usersub, filename);
- X make_usub("snmp_set", US_snmp_set, usersub, filename);
- X make_usub("snmp_error", US_snmp_error, usersub, filename);
- X /* ../perl.h declares this routine as returning an int, but the
- X documentation doesn't define the return value, and the code
- X doesn't check it */
- X return 0;
- X}
- X
- X
- Xstatic char *
- Xsnmp_error()
- X{
- X if (err_text[0] != '\0') return err_text;
- X
- X if (last_status == STAT_SUCCESS) return snmp_errstring(last_errstat);
- X
- X if (last_status == STAT_TIMEOUT) return "Timeout ocurred";
- X
- X return "A general error ocurred";
- X}
- X
- X
- Xstatic int
- Xusersub(ix, sp, items)
- X int ix;
- X register int sp;
- X register int items;
- X{
- X STR **st = stack->ary_array + sp;
- X struct snmp_session session, *ss;
- X struct snmp_pdu *pdu, *response = NULL;
- X oid name[MAX_NAME_LEN];
- X int name_length;
- X char buf[1024];
- X int i;
- X
- X switch (ix)
- X {
- X case US_snmp_get:
- X case US_snmp_next:
- X case US_snmp_set:
- X {
- X char *host = (char *)str_get(st[1]);
- X char *community = (char *)str_get(st[2]);
- X
- X last_status = 0;
- X err_text[0] = '\0';
- X
- X if (Mib == (struct tree *)0) init_mib();
- X
- X bzero((char *)&session, sizeof(struct snmp_session));
- X session.peername = host;
- X session.community = community;
- X session.community_len = strlen(community);
- X session.retries = SNMP_DEFAULT_RETRIES;
- X session.timeout = SNMP_DEFAULT_TIMEOUT;
- X session.authenticator = NULL;
- X
- X snmp_synch_setup(&session);
- X ss = snmp_open(&session);
- X if (ss == NULL)
- X {
- X strcpy(err_text,"Couldn't open snmp");
- X return NULL;
- X }
- X
- X if (ix == US_snmp_set)
- X {
- X struct variable_list *vars = NULL;
- X
- X if (items < 5)
- X fatal(
- X "Usage: &snmp_set($host, $community, $variable, $type, $value...)");
- X pdu = snmp_pdu_create(SET_REQ_MSG);
- X
- X for (i = 3; i <= items; )
- X {
- X struct variable_list *vp;
- X char *type, *variable = (char *)str_get(st[i]);
- X
- X name_length = MAX_NAME_LEN;
- X if ( !read_objid(variable, name, &name_length))
- X {
- X sprintf(err_text,"Invalid object identifier: %s",
- X variable);
- X snmp_free_pdu(pdu);
- X snmp_close(ss);
- X return NULL;
- X }
- X
- X if ((vp = (struct variable_list *)malloc(sizeof *vp))
- X == NULL) fatal ("malloc() failed, line %d",__LINE__);
- X if (vars == NULL)
- X pdu->variables = vp;
- X else
- X vars->next_variable = vp;
- X vars = vp;
- X
- X vp->name_length = name_length;
- X if ((vp->name = (oid *)malloc(vp->name_length * sizeof(oid)))
- X == NULL) fatal("malloc() failed, line %d",__LINE__);
- X bcopy((char *)name, (char *)vp->name,
- X vp->name_length * sizeof(oid));
- X
- X type = (char *)str_get(st[++i]);
- X variable = (char *)str_get(st[++i]);
- X
- X if (strcmp(type, "INTEGER") == 0)
- X {
- X vp->type = INTEGER;
- X if ((vp->val.integer = (long *)malloc(sizeof(long)))
- X == NULL) fatal("malloc() failed");
- X vp->val_len = sizeof(long);
- X *(vp->val.integer) = atoi(variable);
- X }
- X else if (strcmp(type, "DisplayString") == 0)
- X {
- X vp->type = STRING;
- X if ((vp->val.string = strdup(variable)) == NULL)
- X fatal("strdup() failed");
- X vp->val_len = strlen(variable);
- X }
- X else if (strcmp(type, "OCTET STRING") == 0)
- X {
- X vp->type = STRING;
- X vp->val_len = st[i]->str_cur;
- X if ((vp->val.string = (char *)malloc(vp->val_len))
- X == NULL) fatal("malloc() failed");
- X bcopy(st[i]->str_ptr, vp->val.string, vp->val_len);
- X }
- X else if (strcmp(type, "NULL") == 0)
- X {
- X vp->type = NULLOBJ;
- X vp->val_len = 0;
- X vp->val.string = NULL;
- X }
- X else if (strcmp(type, "OBJECT IDENTIFIER") == 0)
- X {
- X vp->type = OBJID;
- X vp->val_len = MAX_NAME_LEN;
- X read_objid(variable, name, &vp->val_len);
- X vp->val_len *= sizeof(oid);
- X if ((vp->val.objid = (oid *)malloc(vp->val_len))
- X == NULL) fatal("malloc() failed");
- X bcopy((char *)name, (char *)vp->val.objid,
- X vp->val_len);
- X }
- X else if (strcmp(type, "TimeTicks") == 0)
- X {
- X vp->type = TIMETICKS;
- X if ((vp->val.integer = (long *)malloc(sizeof(long)))
- X == NULL) fatal("malloc() failed");
- X vp->val_len = sizeof(long);
- X *(vp->val.integer) = atoi(variable);
- X }
- X else if (strcmp(type, "IpAddress") == 0)
- X {
- X vp->type = IPADDRESS;
- X if ((vp->val.integer = (long *)malloc(sizeof(long)))
- X == NULL) fatal("malloc() failed");
- X vp->val_len = sizeof(long);
- X *(vp->val.integer) = inet_addr(variable);
- X }
- X else if (strcmp(type, "Counter") == 0)
- X {
- X vp->type = COUNTER;
- X if ((vp->val.integer = (long *)malloc(sizeof(long)))
- X == NULL) fatal("malloc() failed");
- X vp->val_len = sizeof(long);
- X *(vp->val.integer) = atoi(variable);
- X }
- X else if (strcmp(type, "Gauge") == 0)
- X {
- X vp->type = GAUGE;
- X if ((vp->val.integer = (long *)malloc(sizeof(long)))
- X == NULL) fatal("malloc() failed");
- X vp->val_len = sizeof(long);
- X *(vp->val.integer) = atoi(variable);
- X }
- X else if (strcmp(type, "Opaque") == 0)
- X {
- X vp->type = OPAQUE;
- X vp->val_len = st[i]->str_cur;
- X if ((vp->val.string = (char *)malloc(vp->val_len))
- X == NULL) fatal("malloc() failed");
- X bcopy(st[i]->str_ptr, vp->val.string, vp->val_len);
- X }
- X else
- X fatal(
- X "snmp_set() bad type: use one of INTEGER, Counter, etc.");
- X
- X i++;
- X }
- X }
- X else
- X {
- X if (items < 3)
- X fatal("Usage: &snmp_%s($host, $community, $variable, ...)",
- X ix == US_snmp_get ? "get" : "next");
- X pdu = snmp_pdu_create(ix == US_snmp_get
- X ? GET_REQ_MSG : GETNEXT_REQ_MSG);
- X
- X for (i = 3; i <= items; i++)
- X {
- X char *variable = (char *)str_get(st[i]);
- X
- X name_length = MAX_NAME_LEN;
- X if ( !read_objid(variable, name, &name_length))
- X {
- X sprintf(err_text,"Invalid object identifier: %s",
- X variable);
- X snmp_free_pdu(pdu);
- X snmp_close(ss);
- X return NULL;
- X }
- X
- X snmp_add_null_var(pdu, name, name_length);
- X }
- X }
- X
- Xretry:
- X last_status = snmp_synch_response(ss, pdu, &response);
- X
- X i = 0;
- X if (last_status == STAT_SUCCESS)
- X {
- X last_errstat = response->errstat;
- X if (response->errstat == SNMP_ERR_NOERROR)
- X {
- X struct variable_list *vars;
- X
- X for (vars = response->variables;
- X vars != NULL;
- X vars = vars->next_variable)
- X {
- X i++;
- X astore(stack, sp + i*2, Nullstr);
- X st = stack->ary_array + sp + (i-1)*2;
- X buf[0] = '.';
- X get_symbol(vars->name,vars->name_length, Mib, buf+1);
- X st[0] = str_2mortal(str_make(buf,strlen(buf)));
- X
- X if (vars->type == ASN_OCTET_STR)
- X {
- X if (vars->val_len == 0)
- X st[1] = str_2mortal(&str_undef);
- X else
- X st[1] = str_2mortal(str_make(vars->val.string,
- X vars->val_len));
- X }
- X else
- X {
- X sprint_value(buf, vars->name, vars->name_length,
- X vars);
- X if (buf[0] == '\0')
- X st[1] = str_2mortal(&str_undef);
- X else
- X st[1] = str_2mortal(str_make(buf,strlen(buf)));
- X }
- X }
- X
- X }
- X else
- X if (ix != US_snmp_set &&
- X (pdu = snmp_fix_pdu(response, ix == US_snmp_get
- X ? GET_REQ_MSG : GETNEXT_REQ_MSG))
- X != NULL)
- X goto retry;
- X }
- X
- X if (response) snmp_free_pdu(response);
- X
- X snmp_close(ss);
- X
- X err_text[0] = '\0';
- X
- X return sp + i*2 - 1;
- X }
- X
- X case US_snmp_error:
- X if (items != 0)
- X fatal("Usage: &snmp_error()");
- X else
- X str_set(st[0], (char*) snmp_error());
- X return sp;
- X }
- X fatal("Can't happen");
- X}
- SHAR_EOF
- chmod 0664 snmp.c ||
- echo 'restore of snmp.c failed'
- Wc_c="`wc -c < 'snmp.c'`"
- test 9601 -eq "$Wc_c" ||
- echo 'snmp.c: original size 9601, current size' "$Wc_c"
- fi
- # ============= mib.c ==============
- if test -f 'mib.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mib.c (File already exists)'
- else
- echo 'x - extracting mib.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'mib.c' &&
- X/*
- X * MODIFIED
- X *
- X * For use in callable subroutines in perl, I modified the sprint_<type>
- X * routines so the don't prepend "<type>: " to the strings they create.
- X * Guy Streeter, 2-20-1992
- X */
- X/***********************************************************
- X Copyright 1988, 1989 by Carnegie Mellon University
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the name of CMU not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XCMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XCMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X******************************************************************/
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <netinet/in.h>
- X#include <sys/time.h>
- X#include "asn1.h"
- X#include "snmp_impl.h"
- X#include "snmp_api.h"
- X#include "parse.h"
- X#include "snmp.h"
- X
- Xstatic void sprint_by_type();
- Xstatic set_functions(), parse_subtree(), lc_cmp();
- X
- Xoid RFC1066_MIB[] = { 1, 3, 6, 1, 2, 1 };
- Xunsigned char RFC1066_MIB_text[] = ".iso.org.dod.internet.mgmt.mib";
- Xstruct tree *Mib = 0;
- X
- X
- Xstatic char *uptimeString(timeticks, buf)
- X
- Xregister long timeticks;
- Xchar *buf;
- X
- X{
- X int seconds, minutes, hours, days;
- X
- X timeticks /= 100;
- X days = timeticks / (60 * 60 * 24);
- X timeticks %= (60 * 60 * 24);
- X
- X hours = timeticks / (60 * 60);
- X timeticks %= (60 * 60);
- X
- X minutes = timeticks / 60;
- X seconds = timeticks % 60;
- X
- X if (days == 0){
- X sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
- X } else if (days == 1) {
- X sprintf(buf, "%d day, %d:%02d:%02d", days, hours, minutes, seconds);
- X } else {
- X sprintf(buf, "%d days, %d:%02d:%02d", days, hours, minutes, seconds);
- X }
- X return buf;
- X}
- X
- X
- Xstatic sprint_hexstring(buf, cp, len)
- X
- Xchar *buf;
- Xu_char *cp;
- Xint len;
- X
- X{
- X
- X for(; len >= 16; len -= 16){
- X sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X ",
- X cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
- X buf += strlen(buf);
- X cp += 8;
- X sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
- X cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
- X buf += strlen(buf);
- X cp += 8;
- X }
- X
- X for(; len > 0; len--){
- X sprintf(buf, "%02X ", *cp++);
- X buf += strlen(buf);
- X }
- X *buf = '\0';
- X}
- X
- X
- Xstatic sprint_asciistring(buf, cp, len)
- X
- Xchar *buf;
- Xu_char *cp;
- Xint len;
- X
- X{
- X int x;
- X
- X for(x = 0; x < len; x++){
- X if (*cp){
- X *buf++ = *cp++;
- X } else {
- X *buf++ = '.';
- X cp++;
- X }
- X }
- X *buf = '\0';
- X}
- X
- X
- Xstatic void sprint_octet_string(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != ASN_OCTET_STR){
- X sprintf(buf, "Wrong Type (should be OCTET STRING): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprint_asciistring(buf, var->val.string, var->val_len);
- X}
- X
- X
- Xstatic void sprint_ascii_string(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X
- X if (var->type != ASN_OCTET_STR){
- X sprintf(buf, "Wrong Type (should be OCTET STRING): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprint_asciistring(buf, var->val.string, var->val_len);
- X}
- X
- X
- Xstatic void sprint_opaque(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X
- X if (var->type != OPAQUE){
- X sprintf(buf, "Wrong Type (should be Opaque): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprint_hexstring(buf, var->val.string, var->val_len);
- X}
- X
- X
- Xstatic void sprint_object_identifier(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != ASN_OBJECT_ID){
- X sprintf(buf, "Wrong Type (should be OBJECT IDENTIFIER): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprint_objid(buf, (oid *)(var->val.objid), var->val_len / sizeof(oid));
- X}
- X
- X
- Xstatic void sprint_timeticks(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X char timebuf[32];
- X
- X if (var->type != TIMETICKS){
- X sprintf(buf, "Wrong Type (should be Timeticks): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprintf(buf, "%d (%s)",
- X *(var->val.integer), uptimeString(*(var->val.integer), timebuf));
- X}
- X
- X
- Xstatic void sprint_integer(buf, var, enums)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- Xstruct enum_list *enums;
- X
- X{
- X char *enum_string = NULL;
- X
- X if (var->type != ASN_INTEGER){
- X sprintf(buf, "Wrong Type (should be INTEGER): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X for (; enums; enums = enums->next) {
- X if (enums->value == *var->val.integer){
- X enum_string = enums->label;
- X break;
- X }
- X }
- X
- X if (enum_string == NULL) {
- X sprintf(buf, "%d", *var->val.integer);
- X } else {
- X sprintf(buf, "%s(%d)", enum_string, *var->val.integer);
- X }
- X}
- X
- X
- Xstatic void sprint_gauge(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != GAUGE){
- X sprintf(buf, "Wrong Type (should be Gauge): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprintf(buf, "%lu", *var->val.integer);
- X}
- X
- X
- Xstatic void sprint_counter(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != COUNTER){
- X sprintf(buf, "Wrong Type (should be Counter): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprintf(buf, "%lu", *var->val.integer);
- X}
- X
- X
- Xstatic void sprint_networkaddress(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X int x, len;
- X u_char *cp;
- X
- X cp = var->val.string;
- X len = var->val_len;
- X for(x = 0; x < len; x++){
- X sprintf(buf, "%02X", *cp++);
- X buf += strlen(buf);
- X if (x < (len - 1)) {
- X *buf++ = ':';
- X }
- X }
- X}
- X
- X
- Xstatic void sprint_ipaddress(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X u_char *ip;
- X
- X if (var->type != IPADDRESS){
- X sprintf(buf, "Wrong Type (should be Ipaddress): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X ip = var->val.string;
- X sprintf(buf, "%d.%d.%d.%d",ip[0], ip[1], ip[2], ip[3]);
- X}
- X
- X
- Xstatic void sprint_unsigned_short(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != ASN_INTEGER){
- X sprintf(buf, "Wrong Type (should be INTEGER): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprintf(buf, "%lu", *var->val.integer);
- X}
- X
- X
- Xstatic void sprint_null(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X if (var->type != ASN_NULL){
- X sprintf(buf, "Wrong Type (should be NULL): ");
- X buf += strlen(buf);
- X sprint_by_type(buf, var, (struct enum_list *)NULL);
- X return;
- X }
- X sprintf(buf, "NULL");
- X}
- X
- X
- Xstatic void sprint_unknowntype(buf, var)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- X
- X{
- X /* sprintf(buf, "Variable has bad type"); */
- X sprint_by_type(buf, var, NULL);
- X}
- X
- X
- Xstatic void sprint_badtype(buf)
- X
- Xchar *buf;
- X
- X{
- X sprintf(buf, "Variable has bad type");
- X}
- X
- X
- Xstatic void sprint_by_type(buf, var, enums)
- X
- Xchar *buf;
- Xstruct variable_list *var;
- Xstruct enum_list *enums;
- X
- X{
- X switch (var->type){
- X case ASN_INTEGER:
- X sprint_integer(buf, var, enums);
- X break;
- X case ASN_OCTET_STR:
- X sprint_octet_string(buf, var);
- X break;
- X case OPAQUE:
- X sprint_opaque(buf, var);
- X break;
- X case ASN_OBJECT_ID:
- X sprint_object_identifier(buf, var);
- X break;
- X case TIMETICKS:
- X sprint_timeticks(buf, var);
- X break;
- X case GAUGE:
- X sprint_gauge(buf, var);
- X break;
- X case COUNTER:
- X sprint_counter(buf, var);
- X break;
- X case IPADDRESS:
- X sprint_ipaddress(buf, var);
- X break;
- X case ASN_NULL:
- X sprint_null(buf, var);
- X break;
- X default:
- X sprint_badtype(buf);
- X break;
- X }
- X}
- X
- X
- Xinit_mib()
- X{
- X char *file, *getenv();
- X
- X file = getenv("MIBFILE");
- X if (file) {
- X Mib = read_mib(file);
- X }
- X if (!Mib) {
- X Mib = read_mib("mib.txt");
- X }
- X if (!Mib) {
- X Mib = read_mib("/etc/mib.txt");
- X }
- X if (!Mib){
- X fprintf(stderr, "Couldn't find mib file\n");
- X exit(2);
- X }
- X set_functions(Mib);
- X}
- X
- X
- Xstatic set_functions(subtree)
- X
- Xstruct tree *subtree;
- X
- X{
- X for(; subtree; subtree = subtree->next_peer){
- X
- X switch(subtree->type){
- X case TYPE_OBJID:
- X subtree->printer = sprint_object_identifier;
- X break;
- X case TYPE_OCTETSTR:
- X subtree->printer = sprint_octet_string;
- X break;
- X case TYPE_INTEGER:
- X subtree->printer = sprint_integer;
- X break;
- X case TYPE_NETADDR:
- X subtree->printer = sprint_networkaddress;
- X break;
- X case TYPE_IPADDR:
- X subtree->printer = sprint_ipaddress;
- X break;
- X case TYPE_COUNTER:
- X subtree->printer = sprint_counter;
- X break;
- X case TYPE_GAUGE:
- X subtree->printer = sprint_gauge;
- X break;
- X case TYPE_TIMETICKS:
- X subtree->printer = sprint_timeticks;
- X break;
- X case TYPE_OPAQUE:
- X subtree->printer = sprint_opaque;
- X break;
- X case TYPE_NULL:
- X subtree->printer = sprint_null;
- X break;
- X case TYPE_DISPLAYSTR:
- X subtree->printer = sprint_ascii_string;
- X break;
- X case TYPE_OTHER:
- X default:
- X subtree->printer = sprint_unknowntype;
- X break;
- X }
- X set_functions(subtree->child_list);
- X }
- X}
- X
- X
- Xstatic struct tree *find_rfc1066_mib(root)
- X
- Xstruct tree *root;
- X
- X{
- X oid *op = RFC1066_MIB;
- X struct tree *tp;
- X int len;
- X
- X for(len = sizeof(RFC1066_MIB)/sizeof(oid); len; len--, op++){
- X for(tp = root; tp; tp = tp->next_peer){
- X if (tp->subid == *op){
- X root = tp->child_list;
- X break;
- X }
- X }
- X if (tp == NULL) {
- X return NULL;
- X }
- X }
- X return root;
- X}
- X
- X
- Xint read_objid(input, output, out_len)
- X
- Xchar *input;
- Xoid *output;
- Xint *out_len; /* number of subid's in "output" */
- X
- X{
- X struct tree *root = Mib;
- X oid *op = output;
- X int i;
- X
- X if (*input == '.') {
- X input++;
- X } else {
- X root = find_rfc1066_mib(root);
- X for (i = 0; i < sizeof (RFC1066_MIB)/sizeof(oid); i++) {
- X if ((*out_len)-- > 0) {
- X *output++ = RFC1066_MIB[i];
- X } else {
- X fprintf(stderr, "object identifier too long\n");
- X return (0);
- X }
- X }
- X }
- X
- X if (root == NULL){
- X fprintf(stderr, "Mib not initialized. Exiting.\n");
- X exit(1);
- X }
- X if ((*out_len = parse_subtree(root, input, output, out_len)) == 0) {
- X return (0);
- X }
- X
- X *out_len += output - op;
- X
- X return (1);
- X}
- X
- X
- Xstatic parse_subtree(subtree, input, output, out_len)
- X
- Xstruct tree *subtree;
- Xchar *input;
- Xoid *output;
- Xint *out_len; /* number of subid's */
- X
- X{
- X char buf[128], *to = buf;
- X u_long subid = 0;
- X struct tree *tp;
- X
- X /*
- X * No empty strings. Can happen if there is a trailing '.' or two '.'s
- X * in a row, i.e. "..".
- X */
- X
- X if ((*input == '\0') || (*input == '.')) {
- X return (0);
- X }
- X
- X if (isdigit(*input)) {
- X /*
- X * Read the number, then try to find it in the subtree.
- X */
- X while (isdigit(*input)) {
- X subid *= 10;
- X subid += *input++ - '0';
- X }
- X for (tp = subtree; tp; tp = tp->next_peer) {
- X if (tp->subid == subid)
- X goto found;
- X }
- X tp = NULL;
- X } else {
- X /*
- X * Read the name into a buffer.
- X */
- X while ((*input != '\0') && (*input != '.')) {
- X *to++ = *input++;
- X }
- X *to = '\0';
- X
- X /*
- X * Find the name in the subtree;
- X */
- X for (tp = subtree; tp; tp = tp->next_peer) {
- X if (lc_cmp(tp->label, buf) == 0) {
- X subid = tp->subid;
- X goto found;
- X }
- X }
- X
- X /*
- X * If we didn't find the entry, punt...
- X */
- X if (tp == NULL) {
- X fprintf(stderr, "sub-identifier not found: %s\n", buf);
- X return (0);
- X }
- X }
- X
- Xfound:
- X if(subid > (u_long)MAX_SUBID){
- X fprintf(stderr, "sub-identifier too large: %s\n", buf);
- X return (0);
- X }
- X
- X if ((*out_len)-- <= 0){
- X fprintf(stderr, "object identifier too long\n");
- X return (0);
- X }
- X *output++ = subid;
- X
- X if (*input != '.') {
- X return (1);
- X }
- X if ((*out_len = parse_subtree(tp ? tp->child_list : NULL,
- X ++input, output, out_len)) == 0) {
- X return (0);
- X }
- X return (++*out_len);
- X}
- X
- X
- Xstruct tree * get_symbol(objid, objidlen, subtree, buf)
- X
- Xoid *objid;
- Xint objidlen;
- Xstruct tree *subtree;
- Xchar *buf;
- X
- X{
- X struct tree *return_tree = NULL;
- X
- X for(; subtree; subtree = subtree->next_peer){
- X if (*objid == subtree->subid){
- X strcpy(buf, subtree->label);
- X goto found;
- X }
- X }
- X
- X /* subtree not found */
- X while(objidlen--){ /* output rest of name, uninterpreted */
- X sprintf(buf, "%u.", *objid++);
- X while(*buf) {
- X buf++;
- X }
- X }
- X *(buf - 1) = '\0'; /* remove trailing dot */
- X return NULL;
- X
- Xfound:
- X if (objidlen > 1){
- X while(*buf) {
- X buf++;
- X }
- X *buf++ = '.';
- X *buf = '\0';
- X return_tree = get_symbol(objid + 1, objidlen - 1,
- X subtree->child_list, buf);
- X }
- X if (return_tree != NULL) {
- X return return_tree;
- X } else {
- X return subtree;
- X }
- X}
- X
- X
- Xprint_objid(objid, objidlen)
- X
- Xoid *objid;
- Xint objidlen; /* number of subidentifiers */
- X
- X{
- X char buf[256];
- X struct tree *subtree = Mib;
- X
- X *buf = '.'; /* this is a fully qualified name */
- X get_symbol(objid, objidlen, subtree, buf + 1);
- X printf("%s\n", buf);
- X
- X}
- X
- X
- Xsprint_objid(buf, objid, objidlen)
- X
- Xchar *buf;
- Xoid *objid;
- Xint objidlen; /* number of subidentifiers */
- X
- X{
- X struct tree *subtree = Mib;
- X
- X *buf = '.'; /* this is a fully qualified name */
- X get_symbol(objid, objidlen, subtree, buf + 1);
- X}
- X
- X
- Xprint_variable(objid, objidlen, variable)
- X
- Xoid *objid;
- Xint objidlen;
- Xstruct variable_list *variable;
- X
- X{
- X char buf[512], *cp;
- X struct tree *subtree = Mib;
- X
- X *buf = '.'; /* this is a fully qualified name */
- X subtree = get_symbol(objid, objidlen, subtree, buf + 1);
- X cp = buf;
- X if ( (strlen(buf) >= strlen((char *)RFC1066_MIB_text)) &&
- X ! bcmp( buf, (char *)RFC1066_MIB_text,
- X strlen((char *)RFC1066_MIB_text))){
- X cp += sizeof(RFC1066_MIB_text);
- X }
- X printf("Name: %s\n", cp);
- X *buf = '\0';
- X if (subtree->printer) {
- X (*subtree->printer)(buf, variable, subtree->enums);
- X } else {
- X sprint_by_type(buf, variable, subtree->enums);
- X }
- X printf("%s\n", buf);
- X}
- X
- X
- Xsprint_variable(buf, objid, objidlen, variable)
- X
- Xchar *buf;
- Xoid *objid;
- Xint objidlen;
- Xstruct variable_list *variable;
- X
- X{
- X char tempbuf[512], *cp;
- X struct tree *subtree = Mib;
- X
- X *tempbuf = '.'; /* this is a fully qualified name */
- X subtree = get_symbol(objid, objidlen, subtree, tempbuf + 1);
- X cp = tempbuf;
- X if ( (strlen(tempbuf) >= strlen((char *)RFC1066_MIB_text)) &&
- X ! bcmp(tempbuf, (char *)RFC1066_MIB_text,
- X strlen((char *)RFC1066_MIB_text))){
- X cp += sizeof(RFC1066_MIB_text);
- X }
- X sprintf(buf, "Name: %s\n", cp);
- X buf += strlen(buf);
- X if (subtree->printer) {
- X (*subtree->printer)(buf, variable, subtree->enums);
- X } else {
- X sprint_by_type(buf, variable, subtree->enums);
- X }
- X strcat(buf, "\n");
- X}
- X
- X
- Xsprint_value(buf, objid, objidlen, variable)
- X
- Xchar *buf;
- Xoid *objid;
- Xint objidlen;
- Xstruct variable_list *variable;
- X
- X{
- X char tempbuf[512];
- X struct tree *subtree = Mib;
- X
- X subtree = get_symbol(objid, objidlen, subtree, tempbuf);
- X if (subtree->printer) {
- X (*subtree->printer)(buf, variable, subtree->enums);
- X } else {
- X sprint_by_type(buf, variable, subtree->enums);
- X }
- X}
- X
- X
- Xprint_value(objid, objidlen, variable)
- X
- Xoid *objid;
- Xint objidlen;
- Xstruct variable_list *variable;
- X
- X{
- X char tempbuf[512];
- X struct tree *subtree = Mib;
- X
- X subtree = get_symbol(objid, objidlen, subtree, tempbuf);
- X if (subtree->printer) {
- X (*subtree->printer)(tempbuf, variable, subtree->enums);
- X } else {
- X sprint_by_type(tempbuf, variable, subtree->enums);
- X }
- X printf("%s\n", tempbuf);
- X}
- X
- X
- Xstatic int lc_cmp(s1, s2)
- Xchar *s1, *s2;
- X
- X{
- X char c1, c2;
- X
- X while(*s1 && *s2){
- X if (isupper(*s1)) {
- X c1 = tolower(*s1);
- X } else {
- X c1 = *s1;
- X }
- X if (isupper(*s2)) {
- X c2 = tolower(*s2);
- X } else {
- X c2 = *s2;
- X }
- X
- X if (c1 != c2) {
- X return ((c1 - c2) > 0 ? 1 : -1);
- X }
- X
- X s1++;
- X s2++;
- X }
- X
- X if (*s1) {
- X return -1;
- X }
- X if (*s2) {
- X return 1;
- X }
- X return 0;
- X}
- X
- SHAR_EOF
- chmod 0644 mib.c ||
- echo 'restore of mib.c failed'
- Wc_c="`wc -c < 'mib.c'`"
- test 16738 -eq "$Wc_c" ||
- echo 'mib.c: original size 16738, current size' "$Wc_c"
- fi
- # ============= snmp.pl ==============
- if test -f 'snmp.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping snmp.pl (File already exists)'
- else
- echo 'x - extracting snmp.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'snmp.pl' &&
- X#
- X# a few useful routines. Guy Streeter, 3/31/92
- X#
- Xpackage SNMP;
- X
- X# not much debug output here, but it can be turned on by setting
- X# $SNMP'debug to a positive value.
- X
- X$debug = 0;
- X
- X# &inet_addr takes an IP address in ASCII dotted quad form (0.0.0.0) and
- X# returns an integer in network byte-order.
- X
- Xsub main'inet_addr { # @_ = (dotted quad)
- X return unpack("N",pack("C4",split(/\./,$_[0])));
- X}
- X
- X# &inet_ntoa takes an integer IP address in network byte-order and returns
- X# an ASCII string in dotted decimal notation.
- X
- Xsub main'inet_ntoa { # @_ = (integer)
- X return join('.',unpack('C4',pack('N',$_[0])));
- X}
- X
- X# &dottedquad takes a hostname or dotted-quad IP address and returns
- X# a dotted-quad address.
- X
- Xsub main'dottedquad { # @_ = (hostname or dotted quad)
- X if ($_[0] =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
- X return $_[0];
- X } else {
- X $saddr = (gethostbyname($_[0]))[4] || return undef;
- X return join('.',unpack("C4",$saddr));
- X }
- X}
- X
- X# $SNMP'communityFile specifies the location of a DBM file that associates
- X# a host with a Community string.
- X
- X$communityFile = "/etc/mib.commun";
- X
- X# &communityString returns the Community string associated with a given
- X# key. For simplicity the key should be the dotted-decimal ASCII form
- X# of the address of the host, but the routine doesn't care what the key
- X# is. "public" is returned if the key or the file doesn't exist.
- X
- Xsub main'communityString { # @_ = (dotted quad)
- X if (undef %communityArray) {
- X warn "opening $communityFile for reading\n" if $debug;
- X dbmopen(%communityArray,$communityFile,undef)
- X || warn "somebody stole $communityFile!\n" if $debug;
- X }
- X warn "using default community\n" if $debug > 1
- X && ! $communityArray{@_[0]};
- X return "$communityArray{@_[0]}" || "public";
- X}
- SHAR_EOF
- chmod 0666 snmp.pl ||
- echo 'restore of snmp.pl failed'
- Wc_c="`wc -c < 'snmp.pl'`"
- test 1754 -eq "$Wc_c" ||
- echo 'snmp.pl: original size 1754, current size' "$Wc_c"
- fi
- # ============= snmp-tracer ==============
- if test -f 'snmp-tracer' -a X"$1" != X"-c"; then
- echo 'x - skipping snmp-tracer (File already exists)'
- else
- echo 'x - extracting snmp-tracer (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'snmp-tracer' &&
- X#!/usr/local/bin/snmperl
- X
- Xrequire 'snmp.pl';
- X
- Xsub subnet { # @_ = (dotted quad)
- X split(/\./,$destination);
- X
- X if ($_[1] < 128) {
- X return "255.0.0.0";
- X } else {
- X if ($_[1] < 192) {
- X return "255.255.0.0";
- X } else {
- X return "255.255.255.0";
- X }
- X }
- X}
- X
- Xsub findMask {
- X return $netmask{$start} if $netmask{$start};
- X local($dnum) = &inet_addr($destination);
- X local($ipAdEntAddr) = "ip.ipAddrTable.ipAddrEntry.ipAdEntAddr";
- X local($ipAdEntNetMask) = "ip.ipAddrTable.ipAddrEntry.ipAdEntNetMask";
- X local($nextAddr) = $ipAdEntAddr;
- X local($nextMask) = $ipAdEntNetMask;
- X local($addrValue,$maskValue,$mnum);
- X while ($nextMask) {
- X ($nextAddr,$addrValue,$nextMask,$maskValue) =
- X &snmp_next($start,&communityString($start),$nextAddr,$nextMask);
- X last unless $nextMask =~ /$ipAdEntNetMask/;
- X $mnum = &inet_addr($maskValue);
- X if (($dnum & $mnum) == (&inet_addr($addrValue) & $mnum)) {
- X return $netmask{$start} = $maskValue;
- X }
- X }
- X return $netmask{$start} = &subnet($destination);
- X}
- X
- Xwhile ($a=shift(ARGV)) {
- X $debug++, next if $a eq "-d";
- X die "Usage: $0 [-d] destination [start]\n" if $a =~ /-.*/;
- X $destination = $a, next unless $destination;
- X $start = $a, next unless $start;
- X die "Usage: $0 [-d] destination [start]\n";
- X}
- X
- X$SNMP'debug = $debug;
- X
- Xdie "Usage: $0 [-d] destination [start]\n" unless $destination;
- X
- Xchop($start = `uname -n`) unless $start;
- X
- Xprint "from $start to $destination:\n";
- X
- X$start = &dottedquad($start) || die "Address lookup failed for $start\n";
- X$destination = &dottedquad($destination)
- X || die "Address lookup failed for $destination\n";
- X
- X$dest_num = &inet_addr($destination);
- X
- X$ipRouteDest = "ip.ipRoutingTable.ipRouteEntry.ipRouteDest";
- X$ipRouteNextHop = "ip.ipRoutingTable.ipRouteEntry.ipRouteNextHop";
- X$ipRouteType = "ip.ipRoutingTable.ipRouteEntry.ipRouteType";
- X$ipRouteMask = "ip.ipRoutingTable.ipRouteEntry.ipRouteMask";
- X
- X$| = 1; # unbuffered stdout
- X$indent = " ";
- X%netmask = ();
- X
- Xwhile ($start && $start ne $destination) {
- X print $indent, "from $start";
- X $indent .= " ";
- X
- X $nextDest = $ipRouteDest;
- X $nextNextHop = $ipRouteNextHop;
- X $nextType = $ipRouteType;
- X $nextMask = $ipRouteMask;
- X undef $hop;
- X
- X $tryDest = &inet_ntoa(&inet_addr($destination) & &inet_addr(&findMask));
- X if (@result = &snmp_get($start,&communityString($start),
- X "$nextDest.$tryDest","$nextNextHop.$tryDest",
- X "$nextType.$tryDest")) {
- X undef $valueOfNextHop;
- X if ($result[0] =~ /$ipRouteDest/) {
- X shift(result);
- X shift(result);
- X }
- X if ($result[0] =~ /$ipRouteNextHop/) {
- X shift(result);
- X $valueOfNextHop = shift(result);
- X }
- X if ($result[0] =~ /$ipRouteType/) {
- X shift(result);
- X $valueOfType = shift(result);
- X }
- X if ($valueOfType &&
- X !($valueOfType =~ /invalid/ || $valueOfType == 2))
- X {
- X $hop = $valueOfNextHop;
- X undef $nextDest if $valueOfType;
- X }
- X }
- X
- X undef $default;
- X
- X while ($nextDest) {
- X @questions = ($nextDest,$nextNextHop,$nextType);
- X push(questions,$nextMask) if $nextMask;
- X if ($debug > 2) {
- X warn "asking @questions\nof $start ",
- X &communityString($start),"\n";
- X }
- X @result = &snmp_next($start,&communityString($start),@questions);
- X die "Something is foobar" unless @result;
- X
- X undef $nextDest;
- X undef $nextMask;
- X
- X if ($result[0] =~ /$ipRouteDest/) {
- X $nextDest = shift(result);
- X $valueOfDest = shift(result);
- X }
- X if ($result[0] =~ /$ipRouteNextHop/) {
- X $nextNextHop = shift(result);
- X $valueOfNextHop = shift(result);
- X }
- X if ($result[0] =~ /$ipRouteType/) {
- X $nextType = shift(result);
- X $valueOfType = shift(result);
- X }
- X if ($result[0] =~ /$ipRouteMask/) {
- X $nextMask = shift(result);
- X $valueOfMask = shift(result);
- X }
- X
- X last unless $nextDest;
- X
- X next if $valueOfType =~ /invalid/ || $valueOfType == 2;
- X
- X $valueOfMask = &findMask unless $nextMask;
- X
- X if ($debug) {
- X warn "mask is $valueOfMask\n";
- X warn "mask is from default\n" unless $nextMask;
- X }
- X
- X $thisdest = &inet_addr($valueOfDest);
- X if ($thisdest == 0) {
- X warn "default route discovered: $valueOfNextHop\n" if $debug;
- X $default = $valueOfNextHop;
- X next;
- X }
- X $thismask = &inet_addr($valueOfMask);
- X
- X printf(STDERR "comparing %lx and %lx, mask %lx\n", $dest_num,
- X $thisdest, $thismask) if $debug > 1;
- X if (($dest_num & $thismask) == ($thisdest & $thismask))
- X {
- X $hop = $valueOfNextHop;
- X last;
- X }
- X }
- X
- X $start = $hop ? $hop : $default;
- X print " to $start, type = $valueOfType\n";
- X
- X exit 0 if (($dest_num & $thismask) == ($thismask & &inet_addr($start)));
- X}
- X
- Xdie "I got to here somehow";
- SHAR_EOF
- chmod 0755 snmp-tracer ||
- echo 'restore of snmp-tracer failed'
- Wc_c="`wc -c < 'snmp-tracer'`"
- test 4584 -eq "$Wc_c" ||
- echo 'snmp-tracer: original size 4584, current size' "$Wc_c"
- fi
- exit 0
-