Assignment 1

Write a script (in whatever scripting language you wish; I'd use unix shell scripting if you don't have an established favorite) to get ifInOctets and ifOutOctets from 10.38.2.42 (ulam3) every 15 minutes, for at least a couple hours. The community string futhark should work. Note that you cannot reach this machine from the Wi-Fi network.

Due: July 25, 2014

You will create a script and run it from one of the department's multi-user linux machines, knuth.cs.luc.edu and shannon.cs.luc.edu.

Here are some notes on shell scripting. Here is some information on using ssh at Loyola. Here's a cute ssh shortcut: go to https://ada.cs.luc.edu/shell/ and enter the specific username/password combination r****/b**** listed on Sakai. This gets you a login window, at which point you can type your own username/password combination. You thus bypass all that ssh-keygen stuff.
 
Every hour, at a certain number of minutes past the hour, ulam3 will transfer a large chunk of data across its "loopback" (lo) interface. Find the amount, and in which quarter-hour it occurs.
 
1.3.6.1.2.1: mib2
mib2.1: system
mib2.2: interfaces
system.2. iftable
iftable.1: ifentry
ifinoctets: ifentry.10 = 1.3.6.1.2.1.2.2.1.10
ifoutoctets: ifentry.16
 
Individual ifinoctet values for specific interfaces (2 on ulam3):
ifInOctets.1 (loopback),  ifInOctets.2 (ethernet 0, eth0), ifInOctets.2 (eth1)
 
Run this on knuth or shannon, via a command-line terminal.
 
The simplest command to get the information is snmpget.

Creating scripts

You just edit a file, with commands in it. There is no required extension, though I often use ".sh". To run your script, you will first need to make it executable:

    chmod +x myscriptfile.sh

Then you can run it via ./myscriptfile.sh

To edit, I recommend using nano for smaller edits. For larger edits, consider downloading the file, editing it on your own computer, and then uploading again.


To run something every 15 minutes, here are two general approaches:

crontab method  (This allows you to log out, and then log in again to collect your data)

Run "crontab -e" to open up an editor (probably nano), and create the 
following entry for your script:
(This runs it when the minutes part of the clock is 0, 15, 30, or 45)
 
     0,15,30,45 * * * *     $HOME/myscriptname.sh >> myfile.out 2>&1

You can also do the >> redirecting in the script file itself, rather than in the crontab entry. You must redirect one place or the other, but you do not need both.

There must be no spaces in the "0,15,30,45", followed by exactly four asterisks that are separated by spaces. These represent the five crontab time fields: the minutes, hours, day-of-month, day-of-week, and year. Asterisk means that the script is run every hour of every day of every year, at the minutes specified (0,15,30,45).

script method  (this requires you to remain logged in while data is accumulating)

Create a script file, and keep it running for several hours  (either from a home computer through a terminal session on random or infinity that's just quietly sitting there or using the "nohup" command)
 
Suppose the following is in foo.sh, and the file getscript.sh has the snmpget commands in it

    while true
    do
        ./getscript.sh >> myfile.out
        sleep 900   # 900 seconds = 15 minutes
    done
 
nohup foo.sh >/dev/null 2>&1
 
snmpget & snmpwalk are installed in standard places on {random,infinity}.

More notes on crontab

When crontab runs your script, it runs in your home directory, by default. If you need to go to a specific directory, use the cd command.

    cd $HOME/netmgmt
    snmpget -v 1 -c futhark 10.38.2.42 $IFTABLE.16.1 >>mydata.text

It is also sufficient to do the following, that is, using the relative path to the subdirectory:

    cd netmgmt
    snmpget ...

Here's a more or less full script (note that shell variable names, eg IFTABLE here, are case-sensitive, and uppercase by old tradition). You will probably need more snmpget lines.

IFTABLE=1.3.6.1.2.1.2.2.1
cd netmgmt
date >> mydata.text
snmpget -v 1 -c public ulam2.cs.luc.edu $IFTABLE.10.1 >>mydata.text

Also, in the crontab entry I needed to make this executable:

    chmod +x inoctets.sh



Perl

You don't have to do this in perl (and in fact I don't necessarily recommend it, but perl is certainly a popular scripting language. Here's a good overview site:
    http://search.cpan.org/~rgarcia/perl-5.9.2/pod/perlintro.pod
Here's more on working with hash references:
    http://www.cs.mcgill.ca/~abatko/computers/programming/perl/howto/hash/

Perl is a weird language. Things that should be transparent are not. Sigh.

In order to use the SNMP module, it has to be installed. It should generally be installed with the Net-SNMP package, using the --with-perl-modules directive or the winquivalent.

The Perl SNMP package typically entails creation of a basic session object at the outset.

simple_get.pl:

#!/usr/bin/perl

use SNMP;

$SNMP::use_sprint_value = 1;

my $host = "localhost";
my $community="public";

$sess = new SNMP::Session(
    'DestHost'    => $host,
    'Community'    => $community,
    'Version'    =>  2
    );

die "cannot create session: ${SNMP::ErrorStr}\n" unless defined $sess;

my $getvars = new SNMP::VarList(
    ['sysDescr',0],                   # this represents sysDescr.0  The 0 is needed for get
    ['sysContact',0],
    ['sysUpTime',0],
    ['ifNumber',0],
    ['ifSpeed',1],
    ['ifDescr',2],
    ['ifInOctets',2],
    ['ifOutOctets',2]
    );

my @response = $sess->get($getvars);       # try changing to getnext

print "start foreach\n";
foreach my $val (@response) {
    print "$val\n";
}
print "end foreach\n";
print "======================\n";

$ifname     = @response[5];
$ifinoctets = @response[6];
$ifoutoctets= @response[7];
$ifnumber   = @response[3];
print "there are $ifnumber interfaces\n";
print "$ifname ifinoctets = $ifinoctets\n";
print "$ifname ifoutoctets = $ifoutoctets\n";


out_octets.pl

#!/usr/bin/perl

# use strict;

use SNMP;

$SNMP::use_sprint_value = 1;

my $host = "localhost";
my $community="public";

$sess = new SNMP::Session(
    'DestHost'    => $host,
    'Community'    => $community,
    'Version'    =>  2
    );

die "cannot create session: ${SNMP::ErrorStr}\n" unless defined $sess;

my $getvars = new SNMP::VarList(
    ['ifDescr',2],                # note how we describe ifDescr.2
    ['ifInOctets',2],
    ['ifOutOctets',2]
    );

my $count = 0;
my $previnoctets = 0;
my $prevoutoctets = 0;

while ($count < 100) {
    $count++;

    my @response = $sess->get($getvars);

    my $ifname     = @response[0];
    my $ifinoctets = @response[1];
    my $ifoutoctets= @response[2];
    print "$ifname ifinoctets = $ifinoctets;";
    my $delta = $ifinoctets - $previnoctets;
    $previnoctets = $ifinoctets;
    print "\t\tdelta = $delta\n";
    sleep 10;
}

iftable.pl
Uses gettable()

#!/usr/bin/perl

use SNMP;
use Data::Dumper;

$SNMP::use_sprint_value = 1;

my $host = "localhost";
my $community="public";

$sess = new SNMP::Session(
    'DestHost'    => $host,
    'Community'    => $community,
    'Version'    =>  1
    );

die "cannot create session: ${SNMP::ErrorStr}\n" unless defined $sess;


my $response = $sess->gettable('ifTable');    # $response is a reference to hash
print "size of response is " . keys(%$response) . "\n";

@keys = keys(%$response);

print "keys are :";
foreach my $k (@keys) {
    print "$k ";
}
print "\n";

##================== print values??

my $eth0 = %{$response->{1}};        # weird use of $; this should be another hash.
my @eth0keys = keys %{$response->{1}};
print "eth0 keys: " . @eth0keys . "\n";
foreach my $k (@eth0keys) {
    print "$k ";
}
print "\n";

print("========================\n");

# from www.cs.mcgill.ca/~abatko/computers/programming/perl/howto/hash/
# goal: print everything in a two-level hash *reference*

for my $k1 ( sort keys %$response ) {
    print "key: $k1\n";
    for my $k2 ( keys %{$response->{ $k1 }} ) {
        print "    $k2 $response->{ $k1 }{ $k2 }\n";
    }
}

#=============================

# print Dumper(%$response);