in reply to Bad calculations?

I was going to try boiling your code down a bit, as per comments made previously, but I ran into some mysterious things, and I felt I'd have to ask...

Each of the three "snmpwalk" system calls at the top of the "for (;;;)" loop creates an output file in /tmp, and you read each whole file into an array; then you use only the last value (the last line) from each file. Is it true that you only need to use the last line of output from each run of "snmpwalk"?

If that's true (and if there weren't a better way to do this with a module -- which there probably is, I'm guessing), then you'd save yourself some trouble using a more suitable command line with backticks; something like:

my $cmdoutput = `snmpwalk blah blah blah | tail -1`; my $snmpval = substr( $cmdoutput, 54, 10 );
(and are you really sure that substr, with those parameter values, is always doing the right thing? Using the right module would avoid the risk of messing up on this.)

Then there's that funny arithmetic with $etime and $petime. Both start out as 0, but $etime gets set to current system time at the top of each iteration, then gets reset to that current system time minus $petime, then $petime gets set to the system time that used to be the value of $etime. Huh?? Have you actually gone through that step by step, and is that really what you want? Think about it.

loop iter. step etime= petime= ---------------------------------------- 1 at "#time" time1 0 at "#eth0in" time1 time1 2 at "#time" time2 time1 at "#eth0in" time2-time1 time2 3 at "#time" time3 time2 at "#eth0in" time3-time2 time3
and so on. I'm not sure about what you're really after, but I'd say that having $etime equal to system time (seconds since the epoch) will make the results of the first iteration very different from later ones, where $etime represents seconds elapsed since the previous iteration.

It might be best for you to step through this with the perl debugger, and watch what happens to the values to see whether it is what you expect and want.

As for reducing the code, think about a hash of hashes that stores the things you need to have for each ethernet interface:

%iface = ( eth0in => { param => 'InOctets.3', now => 0, prv => 0 }, eth0out=> { param => 'OutOctets.3', now => 0, prv => 0 }, loout => { param => 'OutOctets.1', now => 0, prv => 0 }, ); # use $iface{eth0in}{param} to run snmpwalk for that item, # use $iface{ethoin}{now} to store snmpwalk output, etc...
Then loop over the hash elements. This way, if you add another interface to track later on, you only need to add an item to the hash, and the rest of the code shouldn't need to change at all.