OSSP CVS Repository

ossp - Difference in ossp-pkg/snmpdx/snmpdx versions 1.5 and 1.6
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/snmpdx/snmpdx 1.5 -> 1.6

--- snmpdx       2003/09/02 12:39:20     1.5
+++ snmpdx       2003/09/02 15:36:18     1.6
@@ -476,7 +476,7 @@
 package main;
 
 #   find path to ourself
-my $myroot    = "$FindBin::Bin";
+my $myroot = "$FindBin::Bin";
 
 #   parameters (defaults)
 my $opt = {
@@ -493,6 +493,7 @@
     'mibname'   => "snmpdx",
     'logfile'   => "$myroot/snmpdx.log",
     'loglevel'  => 9,
+    'strict'    => 0,
 };
 
 #   command line parsing
@@ -510,6 +511,7 @@
     'm|mibname=s'   => \$opt->{'mibname'},
     'l|logfile=s'   => \$opt->{'logfile'},
     'L|loglevel=i'  => \$opt->{'loglevel'},
+    's|strict'      => \$opt->{'strict'},
 );
 Getopt::Long::Configure("bundling");
 my $result = GetOptions(%options) || die "option parsing failed";
@@ -528,7 +530,8 @@
           " -M,--mibdir=PATH    path to MIB directory\n" .
           " -m,--mibname=MIB    the name of the MIB to act under\n" .
           " -l,--logfile=PATH   path to daemon logfile\n" .
-          " -L,--loglevel=NUM   logging level (0...9)\n";
+          " -L,--loglevel=NUM   logging level (0...9)\n" .
+          " -s,--strict         strict processing of unknown values\n";
     exit(0);
 }
 if ($opt->{'version'}) {
@@ -604,6 +607,7 @@
 #   load probes and determine their handled OIDs
 my $oidtable   = [];
 my $oidhandler = {};
+my $oidprobe   = {};
 my $oidtype    = {
     'DisplayString'      => [ 'string',    'N.A.'    ],
     'Integer32'          => [ 'integer',   '-1'      ],
@@ -630,12 +634,13 @@
         die if ($@);
     };
     if ($@) {
-        die "invalid probe \"$probe\"";
+        die "invalid probe \"$probe\": $@";
     }
     $ctx->{-log}->printf(2, "Probe: \"%s\"", $probe);
     foreach my $oid (sort(@{$p->oids()})) {
         push(@{$oidtable}, $oid);
         $oidhandler->{$oid} = $p;
+        $oidprobe->{$oid} = $probe;
         $ctx->{-log}->printf(1, "MIB OID: %s [%s] ::= %s (%s)",
             $oid, $ctx->{-mib}->oid2name($oid),
             $ctx->{-mib}->oid2type($oid),
@@ -665,111 +670,219 @@
     $ctx->{-log}->printf(4, "IO: recv: << \"%s\\n\"", $cmd);
 
     if ($cmd =~ m/^PING$/i) {
+        #
         #   the PING/PONG protocol part
+        #
         $ctx->{-log}->printf(4, "IO: send: >> \"PONG\\n\"");
         $stdout->printf("PONG\n");
     }
+
     elsif ($cmd =~ m/^GET$/i or $cmd =~ m/^GETNEXT$/i) {
+        #
         #   the GET/GETNEXT protocol part
+        #
+
+        #   read requested OID
         my $error = 1;
-        my $oid = $stdin->getline;
-        if (not defined($oid)) {
+        my $oid_request = $stdin->getline;
+        if (not defined($oid_request)) {
             $ctx->{-log}->printf(1, "ERROR: EOF instead of OID");
             goto ERROR;
         }
-        $oid =~ s|\n?$||s;
-        $ctx->{-log}->printf(4, "IO: recv: << \"%s\\n\"", $oid);
-        if ($oid !~ m/^(\.\d+)+$/) {
-            $ctx->{-log}->printf(1, "ERROR: invalid query OID \"%s\"", $oid);
+        $oid_request =~ s|\n?$||s;
+        $ctx->{-log}->printf(4, "IO: recv: << \"%s\\n\"", $oid_request);
+        if ($oid_request !~ m/^(\.\d+)+$/) {
+            $ctx->{-log}->printf(1, "ERROR: invalid query OID \"%s\"", $oid_request);
             goto ERROR;
         }
-        my $oid_table = undef;
-        if ($cmd =~ m/^GETNEXT$/i) {
-            my $oid_parent = $oid;
-            $oid_parent =~ s|(\.\d+)$||s;
+
+        #  re-entry point for OID processing
+        my $oid_search = $oid_request;
+        RETRY:
+
+        #   determine acted/handled OID
+        my $oid_action  = undef;
+        my $oid_handled = undef;
+        my $oid_handler = undef;
+        my $oid_next    = undef;
+        if ($cmd =~ m/^GET$/i) {
+            #   search for explicitly handled OID
             for (my $i = 0; defined($oidtable->[$i]); $i++) {
-                if ($oidtable->[$i] =~ m|^\Q$oid\E(\.\d+)+$|) {
-                    #   OID start with requested OID prefix, so use this OID
-                    $oid = $oidtable->[$i];
+                if ($oidtable->[$i] eq $oid_search) {
+                    $oid_action  = $oidtable->[$i];
+                    $oid_handled = $oidtable->[$i];
                     last;
                 }
-                elsif ($oidtable->[$i] eq $oid) {
+            }
+            #   search for implicitly handled OID (sequence element)
+            if (not defined($oid_handled)) {
+                my $oid_parent = $oid_search;
+                $oid_parent =~ s|(\.\d+)$||s;
+                for (my $i = 0; defined($oidtable->[$i]); $i++) {
+                    if ($oidtable->[$i] =~ m|^\Q$oid_parent\E\.#$|) {
+                        $oid_action  = $oid_search;
+                        $oid_handled = $oidtable->[$i];
+                        last;
+                    }
+                }
+            }
+        }
+        elsif ($cmd =~ m/^GETNEXT$/i) {
+            #   search for explicitly handled OID
+            for (my $i = 0; defined($oidtable->[$i]); $i++) {
+                if ($oidtable->[$i] =~ m|^\Q$oid_search\E(\.\d+)+$|) {
+                    #   OID starts with requested OID prefix, so use this OID
+                    $oid_action  = $oidtable->[$i];
+                    $oid_handled = $oidtable->[$i];
+                    $oid_next    = $oidtable->[$i+1];
+                    last;
+                }
+                elsif ($oidtable->[$i] eq $oid_search) {
                     #   OID is the requested OID exactly, so use next OID
                     if (defined($oidtable->[$i+1])) {
-                        $oid = $oidtable->[$i+1];
+                        $oid_action  = $oidtable->[$i+1];
+                        $oid_action  =~ s|\.#$|.1|s;
+                        $oid_handled = $oidtable->[$i+1];
+                        $oid_next    = $oidtable->[$i+2];
                         last;
                     }
                     else {
-                        goto ERROR; # end-of-MIB case
+                        goto ERROR; # end-of-MIB
                     }
                 }
-                elsif ($oidtable->[$i] =~ m|^\Q$oid\E(\.\d+)*(\.#)$|) {
-                    #   OID start with requested OID prefix, so use this OID (special case of table)
-                    $oid = $oidtable->[$i];
-                    $oid =~ s|\.#$|.1|s;
-                    last;
-                }
-                elsif ($oidtable->[$i] =~ m|^\Q$oid_parent\E\.#$|) {
-                    #   OID is the a requested OID of a table, so use next OID in table
-                    $oid = s|\.(\d+)$|".".($1+1)|se;
-                    $oid_table = $oidtable->[$i+1];
-                    $oid =~ s|\.#$|.1|s;
-                    last;
+            }
+            #   search for implicitly handled OID (sequence element)
+            if (not defined($oid_handled)) {
+                my $oid_parent = $oid_search;
+                $oid_parent =~ s|(\.\d+)$||s;
+                for (my $i = 0; defined($oidtable->[$i]); $i++) {
+                    #   search for implicitly handled OID (sequence element)
+                    if ($oidtable->[$i] =~ m|^\Q$oid_search\E(\.\d+)*\.#$|) {
+                        #   OID start with requested OID prefix, so use first OID in sequence
+                        $oid_action  = $oidtable->[$i];
+                        $oid_action  =~ s|\.#$|.1|s;
+                        $oid_handled = $oidtable->[$i];
+                        $oid_next    = $oidtable->[$i+1];
+                        last;
+                    }
+                    elsif ($oidtable->[$i] =~ m|^\Q$oid_parent\E\.#$|) {
+                        #   OID is the requested OID of a sequence exactly, so use next OID in sequence
+                        $oid_action  = $oid_search;
+                        $oid_action  =~ s|\.(\d+)$|".".($1+1)|se;
+                        $oid_handled = $oidtable->[$i];
+                        $oid_next    = $oidtable->[$i+1];
+                        last;
+                    }
                 }
             }
         }
-        TABLE_NEXT:
-        my $oid_wild = $oid;
-        my $handler = $oidhandler->{$oid};
-        if (not defined($handler)) {
-            $oid_wild =~ s|(\.\d+)$|.#|s;
-            $handler = $oidhandler->{$oid_wild};
+        if (defined($oid_handled)) {
+            $oid_handler = $oidhandler->{$oid_handled};
         }
-        if (not defined($handler)) {
-            $ctx->{-log}->printf(1, "ERROR: no handler found for OID \"%s\"", $oid);
-            goto ERROR;
+        else {
+            $ctx->{-log}->printf(1, "ERROR: no handler found for OID \"%s\"", $oid_request);
+            goto ERROR; # end-of-MIB
         }
+
+        #   prepare probe request object
         my $obj = {
-            -oid   => $oid,
-            -name  => $ctx->{-mib}->oid2name($oid_wild),
-            -type  => $ctx->{-mib}->oid2type($oid_wild),
+            -oid   => $oid_action,
+            -name  => $ctx->{-mib}->oid2name($oid_handled),
+            -type  => $ctx->{-mib}->oid2type($oid_handled),
             -value => undef
         };
-        $handler->probe($obj);
+
+        #   provide mixed name/OID for sequence index
+        if ($obj->{-name} =~ m|\.#$|) {
+            my ($idx) = ($obj->{-oid} =~ m|\.(\d+)$|);
+            $obj->{-name} =~ s|\.#$|.$idx|;
+        }
+
+        #   probe value of OID
+        $ctx->{-log}->printf(2, "probing \"%s\" for OID \"%s\"", $oidprobe->{$oid_handled}, $oid_action);
+        $oid_handler->probe($obj);
+
+        #   handle special "end of sequence" situation
+        #if (not defined($obj->{-value}) and $oid_handled =~ m|\.#$|) {
+        #    if (defined($oid_next)) {
+        #        $oid_search = $oid_next;
+        #        $oid_search =~ s|\.#$||s;
+        #        goto RETRY;
+        #    }
+        #    else {
+        #        goto ERROR; # end-of-MIB
+        #    }
+        #}
+
+        #   handle special "unknown OID value" situation
         if (not defined($obj->{-value})) {
-            if (defined($oid_table)) {
-                #   end of table entry
-                $oid = $oid_table;
-                goto TABLE_NEXT;
+            $ctx->{-log}->printf(1, "WARNING: handler was unable to provide probe value for OID \"%s\"", $oid_request);
+            if ($opt->{'strict'}) {
+                #   strict processing: return ERROR on unknown value
+                #   for GET request and skip unknown OIDs on GETNEXT.
+                if ($cmd =~ m/^GET$/i) {
+                    goto ERROR; # no-value
+                }
+                else { # GETNEXT
+                    if (defined($oid_next)) {
+                        $oid_search = $oid_next;
+                        $oid_search =~ s|\.#$||s;
+                        goto RETRY;
+                    }
+                    else {
+                        goto ERROR; # no-value
+                    }
+                }
+            }
+            else {
+                #   non-strict processing: return a reasonable default value
+                if ($oid_handled =~ m|\.#$|) {
+                    if ($oid_action =~ m|\.1$|) {
+                        $obj->{-value} = $oidtype->{$obj->{-type}}->[1];
+                    }
+                    else {
+                        if (defined($oid_next)) {
+                            $oid_search = $oid_next;
+                            $oid_search =~ s|\.#$||s;
+                            goto RETRY;
+                        }
+                        else {
+                            goto ERROR; # end-of-MIB
+                        }
+                    }
+                }
+                else {
+                    $obj->{-value} = $oidtype->{$obj->{-type}}->[1];
+                }
             }
-            #$ctx->{-log}->printf(1, "ERROR: handler was unable to provide probe value for OID \"%s\"", $oid);
-            #goto ERROR;
-            $ctx->{-log}->printf(1, "WARNING: handler was unable to provide probe value for OID \"%s\"", $oid);
-            $obj->{-value} = $oidtype->{$obj->{-type}}->[1];
         }
+
+        #   optionally encode value to conform to snmpd(8) protocol
         if ($oidtype->{$obj->{-type}}->[0] =~ m/^(octet|opaque)$/) {
             $obj->{-value} = $ctx->{-enc}->octet_encode($obj->{-value});
         }
+
+        #   return result
         $ctx->{-log}->printf(1, "QUERY: %s [%s] ::= %s \"%s\"",
             $obj->{-name}, $obj->{-oid}, $obj->{-type}, $obj->{-value});
         $stdout->printf("%s\n%s\n%s\n",
             $obj->{-oid}, $oidtype->{$obj->{-type}}->[0], $obj->{-value});
         $ctx->{-log}->printf(4, "IO: send: >> \"%s\\n%s\\n%s\\n\"",
             $obj->{-oid}, $oidtype->{$obj->{-type}}->[0], $obj->{-value});
-        $error = 0;
 
+        #   end-of-MIB or no-value handling
+        $error = 0;
         if ($error) {
-            #   end-of-MIB or error
             ERROR:
             $ctx->{-log}->printf(4, "IO: send: >> \"NONE\\n\"");
             $stdout->printf("NONE\n");
         }
     }
     else {
-        #   for anything else (not expected) just send 
-        #   something in case snmpd expects something.
-        $ctx->{-log}->printf(4, "IO: send: >> \"\"");
-        $stdout->printf("\n");
+        #   for anything else (not expected) just send at least
+        #   "NONE" in case snmpd(8) expects something.
+        $ctx->{-log}->printf(4, "IO: send: >> \"NONE\\n\"");
+        $stdout->printf("NONE\n");
     }
 }
 

CVSTrac 2.0.1