[comp.lang.perl] gnu awk extended to speak SNMP

emv@math.lsa.umich.edu (Edward Vielmetti) (03/07/90)

In article <16053.636724600@cheetah.nyser.net> in
comp.protocols.iso.dev-environ, Marshall Rose
<mrose@CHEETAH.NYSER.NET> describes modifications to GNU Awk that
speak to the ISODE 6.0 SNMP agent.  I enclose a snippet and refer you
to the actual article for more info.

You'll have to ask Marshall about availability of these modifications
-- I wouldn't be altogether opposed to seeing them put into my
favorite rapid prototyping language for Unix....

From the article:

    >> GNU Awk

    A month back, I saw an announcement of the CMU SNMP package, which had a
    really neat idea.  They took the popular netstat program and modified it
    to use SNMP iteractions to read information rather than just groking the
    kernel.  I liked this idea so much that I decided to steal it!

    But, the CMU people did a lot more work than I thought they needed: they
    actually modified the netstat source.  Instead, I thought, what one
    needed was a rapid-prototyping language for SNMP.  Well, the
    rapid-prototyping language for UNIX is called awk, and the version of
    awk which is easiest for the most people to get the source to is GNU
    Awk.  So, I modified my copy of GNU Awk (2.11 beta) to know about SNMP.
    The idea is that I now write awk scripts that read, process, and display
    SNMP variables from whatever agents I am interested in.  For example,
    here is how I produce the output of "netstat -i":
    ///////
    BEGIN {
	    printf "%-4s %-5s %-14s %-14s %-7s %-5s %-7s %-5s %-4s %-5s\n",
		    "Name",
			 "Mtu",
			      "Net/Dest",
				    "Address",
					  "Ipkts",
					      "Ierrs",
						   "Opkts",
							 "Oerrs",
							      "Drop",
								   "Queue";

	    didone = 0;
	    for (i in ifIndex) {
		didone = 1;

		dest = "";
		addr = "";
		for (j in ipAdEntAddr) {
		    if (ipAdEntIfIndex == ifIndex) {
			split(addr = ipAdEntAddr, a, ".");
			split(ipAdEntNetMask, b, ".");
			dest = bit_and(a[1],b[1]) "." \
			       bit_and(a[2],b[2]) "." \
			       bit_and(a[3],b[3]) "." \
			       bit_and(a[4],b[4]);
			break;
		    }
		}

		printf (length(ifDescr) <= 4 ? "%-4s " : "%s\n     "),
		    ifDescr;
		printf      "%-5d %-14s %-14s %-7d %-5d %-7d %-5d %-4d %-5d\n",
			     ifMtu,
				  dest,
					addr,
					      ifInUcastPkts+ifInNUcastPkts,
						   ifInErrors,
							ifOutUcastPkts+ifOutNUcastPkts,
							     ifOutErrors,
								  ifOutDiscards,
								       ifOutQLen;
		if (oflag)
		    for (j in clnpAdEntAddr) {
			if (clnpAdEntIfIndex == ifIndex) {
			    printf "%-4s %-5s %-14s NS+%s\n",
				   "",  "",  "",   clnpAdEntAddr;
			    break;
			}
		    }
	    }
	    if (!didone && DIAGNOSTIC)
		printf "ifTable: %s\n", DIAGNOSTIC;

	  }
    ///////

    So, I wrote a shell script which parses a command line to netstat, and
    invokes gawk on the write awk script.  I then modified the SNMP agent to
    know about UNIX-specific MIB variables that are useful in making the
    netstat output appear more UNIX-like.  So, when I run gawk and talk to a
    UNIX box, I get all the columns of output I want.  When I talk to some
    other box, I get the subset of the information provided by MIB-I/II.

    The output of the shell script above looks like this:
    ///////
% s-netstat -i
Name Mtu   Net/Dest       Address        Ipkts   Ierrs Opkts   Oerrs Drop Queue
le0  1500  192.52.180.0   192.52.180.1   357417  35    327444  0     0    0    
lo0  1536  127.0.0.0      127.0.0.1      35709   0     35709   0     0    0    
    ///////

(me again)

--Ed
Edward Vielmetti, U of Michigan perl dept. 

louie@sayshell.umd.edu (Louis A. Mamakos) (03/07/90)

The modifications to GNU AWK for the the SNMP stuff are now available.  I
think that Marshall Rose sent out a message with a pointer to them on 
nisc.nyser.net, along with the original release.

I spoke to Marshall Rose at the last IETF meeting and pointed him at perl
as the tool of choice for this sort of thing.  He mentioned to me that the
guts of perl were a bit more complicated the the guts of GAWK, which is why
its in GAWK now and not perl. 

I'd love to have this capability in perl.  Of course, since perl already has
sockets, you can already cobble up SNMP packets and send them off, and process
the replies.  A bit more complicated than support directly in perl mind you,
but it doesn't require any changes to perl.

I was thinking that you could pervert associative arrays to support SNMP
queries, much the same way that they're used to hook into DBM files.  But
hey, what do I know?

louie

<<no fancy one liner, but a LISTSERV in perl is under construction!>>