2. Very Brief SNMP Intro
• SNMP agent (daemon - responding to requests)
• SNMP management station (making of requests)
• UDP, port 161
• SNMP PDUs: SNMP GET , GET-NEXT, GETBULK,
notifications, SNMP-SET, etc
o Basic Encoding Rules (BER)
• Structure of Management Information (SMIv2, ASN.1
subset)
o Types (integer, string, etc)
o MIBs (standard, vendor-specific)
Managed Object Semantics
Managed Object Hierarchy
SNMP::Class
2
3. Very Brief SNMP Intro Example
Piece of knowledge:
.1.3.6.1.2.1.2.2.1.5.15 = 100000000 (k-v pair)
• Object ID (OID): .1.3.6.1.2.1.2.2.1.5.15
o Object: .1.3.6.1.2.1.2.2.1.5 or .iso(1).org(3).dod(6).internet
(1).mgmt(2).mib-2(1).interfaces(2).ifTable(2).ifEntry(1).ifSpeed(5) or
simply ifSpeed
Semantics: "the speed of an interface"
Type: Gauge32 (32-bit integer)
o Instance: .15 (row 15 in interface table)
• Value: 100.000.000 (100M) === 100Mbps for ifSpeed
SNMP::Class
3
4. Writing network management tools
Network management tools using SNMP:
• Small complexity, i.e. a nagios plugin
• Medium complexity, i.e. a topology discovery tool
• (Very) High complexity, i.e. a Network Management System
(NMS) (mostly commercial systems)
Burden of using SNMP properly for small or medium size
software
SNMP::Class
4
5. Problem Statement
• Perl : Availability of high performance, high quality libraries
for SNMP
o Net-SNMP: SNMP.pm (XS, very fast, used by
SNMP::Class)
o Net::SNMP (pure Perl)
• Usage of SNMP libraries for querying managed devices
(routers, switches, servers, etc)
• Typical network management tool:
1. retrieval of info from device(s) by library
2. organization of library returned data into suitable
structure
3. Conversions of data as necessary
4. Processing, calculations on data
SNMP::Class
5
6. Problem Statement (2)
Impedance mismatch between the programming language (not
just Perl) and the SNMP-SMI world
Issues:
• OIDs returned in various forms (ifType, .1.3.6...)
• Data types of values returned not always directly usable
o IP addresses, Mac addresses, Gauges, Enumerations
o Varying between libraries
• Error codes from library (end of mib, timeout, etc)
• SNMP agents
o Bugs in older implementations
missing OIDs
broken loops, etc
o Difference between GET-NEXT and GET-BULK
• Usability of structure of returned data (array, hash, etc) --->
considerable effort
SNMP::Class
6
7. Problem Statemement (3)
Some examples of cumbersomeness:
my ($instance) = ($key =~ /^ifSpeed.(d+)$/)
my ($instance) = ($key =~ /^.1.3.6.1.2.1.2.2.1.5.(d+)$/)
my $bridge_id = uc join(':',(unpack 'n(H2)*',$value)[1..6]);
for my $key (%kv) {
if ($key =~ /^ifDescr.(d+)$/) {
$descriptions{$1} = $kv{$key};
}
}
for my $key (%kv) {
if ($key =~ /^ifType.(d+)$/) {
say "interface ".$descriptions{$1}." is a ".$kv{$key}
}
}
SNMP::Class
7
8. SNMP::Class goals
• Usage of existing excellent libraries for Perl
• Minimization of programmer-required knowledge of SNMP
esoteric (and arcane) details
• Brief syntax for clarity and brevity, DWIM as much as
possible
• Easy connection setup with agents, provision of sensible
defaults
• Automatic optimization of communication with agents,
automatic handling of agent bugs
• Orthogonal error reporting, proper usage of exceptions
• Effortless navigation/querying of structure of returned data
from agents
• Automatic encapsulation of values, taking into account
OID semantics, type (MIB and PDU), display-hint
• Ultimately, complete encapsulation of SNMP
SNMP::Class
8
9. Library Overview - Connection Setup
my $c = SNMP::Class->new('myrouter.mydomain');
• Probing of SNMP version (try 2, then 1)
• Querying of sysName.0
SNMP::Class
9
10. Library Overview - OIDs
• OID: A series of integers
o representable by a label (example: 'ifType')
• Complete encapsulation of the OID (creation, addition,
comparing, etc)
my $oid1 = SNMP::Class::OID->new('.1.3.6.1.4.1');
my $oid2 = SNMP::Class::OID->new('interfaces');
$oid2->contains('ifDescr'); #true
my $oid3 = SNMP::Class::OID->new('ifDescr')->add(15); #ifDescr.15
• Also, automatic separation of instance when possible
$oid3->get_instance_oid; #returns a .15 oid
SNMP::Class
10
11. Library Overview - Varbinds
• Varbind: An OID with a value (SNMP::Class::Varbind)
• Value connected with the specific OID semantically!
• Attribute raw_value for all varbinds
o Just the bytes, completely unprocessed
• Method value for most varbinds
o What is expected by a human
• Varbind enhancement methods
• depending on OID semantics
• Automatically available
Examples:
$iftype->raw_value #6
$iftype->value #'ethernetCsmacd', enum of 6
$designated_bridge->raw_value; #8 bytes,unprintable
$bridge_id->value; # '80:00:00:06:28:84:D7:40'
$bridge_id->mac_address #'00:06:28:84:D7:40'
$bridge_id->priority #32768
SNMP::Class
11
12. Library Overview - Querying of agent
$c->add('system','interfaces');
• Walking of system and intefaces trees on agent
o If SNMPv2 available, usage of GETBULK
• Query result storage inside $c (separate result objects
possible as well)
o $c: connection object and result object
SNMP::Class
12
13. Library Overview - The ResultSet
ResultSet - a set of OID-value pairs (varbinds)
• Filtering of set through methods
$rs->filter_label('ifSpeed'); #keep only ifSpeed OIDs
• Method chaining (returning of new ResultSets)
$rs->filter_label('ifSpeed')->filter_instance(3)
• Method autoloading with OID label names
$rs->ifSpeed(3) #same as previous, more clear
• Generic filter (grep) available:
$rs->filter(sub {
return 1 if $_->get_label eq 'ifSpeed';
return
});
SNMP::Class
13
14. Library Overview - The ResultSet (2)
• More advanced filtering
#Find speed of interface 'eth0'
say $rs->filter_label('ifSpeed')->filter_instance($rs-
>filter_label('ifDescr')->filter_value('eth0')-
>get_instance_oid)->value;
#the same, much more clearly and briefly:
say $rs->find('ifDescr' => 'eth0')->ifSpeed->value;
#Keep the instance for which the ifDescr equals 'eth0', then
keep only the ifSpeed.
SNMP::Class
14
15. Library Overview - The ResultSet (3)
• Iteration over contents, detection of list context
#print the description of each interface
for($rs->ifDescr) {
say $_->value
}
• Filter and map methods
o Used exactly as list grep and map with BLOCK
my $new_rs = $rs->filter(sub { ..... });
my $new_rs = $rs->map(sub { ..... });
SNMP::Class
15
16. Library Overview - The ResultSet (4)
• Final touch: Resultset with 1 varbind:
$rs->ifDescr(3)->item(0)->value;
#the same:
$rs->ifDescr(3)->value;
Varbind methods valid on 1-item ResultSets.
• Overloading also possible, but:
o Awkward behavior when using list context
o Awkward behavior when using operators like '.'
SNMP::Class
16
17. Library Implementation (so far)
Built using Moose.pm
Class & Role Hierarchy:
• Classes:
o SNMP::Class - Session object (mostly empty, gaining functionality from
Role::ResultSet and Role::Implementation::Net-SNMP)
o SNMP::Class::ResultSet - Results object (ditto)
o SNMP::Class::OID - An OID
SNMP::Class::Varbind - A varbind (OID+value)
• Roles:
o SNMP::Class::Role::ResultSet - resultset behavior
o SNMP::Class::Role::Implementation - SNMP Instrumentation (abstract
part, not usable by itself)
SNMP::Class::Role::Implementation::NetSNMP - Instrumentation
lower part using Net-SNMP (applied to SNMP::Class objects)
SNMP::Class::Role::Implementation::Dummy - Another
instrumentation, dummy this time
o SNMP::Class::Varbind::XXXXX - Varbind enhancement roles, (application
to plain varbinds)
SNMP::Class
17
18. Library Roles (2)
SNMP::Class is-a:
• SNMP::Class::Role::Implementation::NetSNMP
• SNMP::Class::Role::ResultSet
Hence, full usability (SNMP Session + Result) available through
a single object.
my $s = SNMP::Class->new('myhost');
$s->add('system');
say $s->sysName->value;
#or
say SNMP::Class->new('myhost')->add('system')->sysName->value;
SNMP::Class
18
19. Varbind Enhancement Roles
Added functionality (new methods or override methods) for
SNMP::Class::Varbind objects through SNMP::Class::Varbind::
roles
Example:
#coming from SNMP::Class::Varbind
$bridge_id->raw_value; #8 bytes,unprintable
$bridge_id->value; # '80:00:00:06:28:84:D7:40'
#coming from SNMP::Class::Varbind::BridgeId
$bridge_id->mac_address #'00:06:28:84:D7:40'
$bridge_id->priority #32768
• Applying of role at runtime, trigger when OID and value of Varbind
are known
__PACKAGE__->meta->apply($_[0]);
• Applying of multiple roles possible
• Default Varbind 'value' method and other methods overridable by
roles
SNMP::Class
19
20. Code!
https://github.com/aduitsis/snmp-class
• Stuff in current presentation almost fully implemented
• Many many varbind enhancement roles missing
(implementation on a need basis)
• Only instrumentation so far from Net-SNMP
• MIB parsing also from Net-SNMP
• Obviously, bugs present
• Built with Moose
• Usage of Log::Log4Perl for logging
• Test suite - but not 100% coverage
SNMP::Class
20
21. Future Directions
• Second instrumentation wrapper from Net::SNMP (Pure
Perl)
• MIB parser other than from Net-SNMP
• More Varbind enhancement roles
• More performance fixes
• Fix any bugs observed
• Need to address snmpset functionality
• Encapsulation of entire MIBs, hide SNMP completely.
o (also see the very good SNMP::Info module on CPAN)
SNMP::Class
21