SevOne SNMP Scripting (S3) is a scripting language developed by SevOne to enable the SNMP plugin to discover complex SNMP objects. The primary purpose of S3 is to describe an SNMP OID in relation to other SNMP OIDs. S3 creates text that relates to and is based on OIDs in order to create more user friendly SNMP object names and descriptions. S3 also relates OIDs to each other via logical and mathematical expressions to store the resultant value for later use such as to cross reference OIDs across a device SNMP tree and to gather descriptive information about a particular object.
The SNMP plugin uses S3 for the following:
Define an object name.
Define an object description.
Define an object type.
Determine which objects to include.
Define an indicator.
The SNMP plugin uses the following scoring formula to name a newly discovered object.
Assume that the best score to begin is 0.
Go through all of the objects for the device.
If the existing object’s object type is the wrong name, skip.
The best possible score is 5.
Assume that the new object description is valid.
If the new object description is the same as the Object Type name, then the object description is no good.
If two things that the SNMP plugin already found have the object description, then the object description is no good.
Assume that the old description is valid.
If the existing object description is the same as the Object Type name, then the object description is no good.
If two existing objects already have that object description, then the object description is no good.
If either object description is no good, then the best possible score is now 4.
The current score is 0.
If the object names are the same, then increase the current score by 3.
Otherwise, if the new object description is good and the existing object name is the same as the new object description, then increase the current score by 1.
If both object descriptions are good and the same, then increase the score by 1.
Otherwise, if the existing object description is good and the existing object description is the same as the new object name, then increase the current score by 1.
If the SNMP indexes are the same, then increase the current score by 1.
If the score is at least 2, and the score is better than the best score so far, consider the objects the same.
Human breakdown:
// Scoring analysis.
//
// Possible scores: / Current name matches existing name. [+3]
// 3,1,0 | Current description is good.
// \ Current description matches existing name. [+1]
//
// Possible scores: / Existing description is good.
// 1,0 | Current description is good.
// | Existing description matches current description. [+1]
// \ Existing description matches current name. [+1]
//
// Possible scores: / Current index matches existing index. [+1]
// 1,0 \
//
// So, when are things the same?
// 1. The names are the same.
// 2. The description (if good) matches an existing name AND the descriptions (if good) are the same.
// 3. The description (if good) matches an existing name AND the name is matches an existing description (if good).
// 4. The description (if good) matches an existing name AND the indexes are the same.
// 5. The name is matches an existing description (if good) AND the indexes are the same.
So what does this mean?
SevOne NMS discovers and polls a router with two network cards with two ports on each.
All objects belong to the Interfaces object type.
Each port is an object.
Object Name |
Object Description |
SNMP Index |
Note |
Score |
Eth0 |
Internet Access |
1 |
Existing object with poll data |
n/a |
Eth1 |
Interface |
2 |
Existing object with poll data |
n/a |
Eth2 |
Site One |
3 |
Existing object with poll data |
n/a |
Eth3 |
Back Link |
4 |
Existing object with poll data |
n/a |
You rename the ports on the router. Upon rediscovery the SNMP plugin continues to poll the objects with no change or data loss as long as you do not change the object description or the SNMP index.
Object Name |
Object Description |
SNMP Index |
Note |
Score |
Ethernet0 |
Internet Access |
1 |
No data lost, polled as if it were still Eth0 |
x |
Ethernet1 |
Interface |
2 |
No data lost, polled as if it were still Eth1 |
x |
Ethernet2 |
Site One |
3 |
No data lost, polled as if it were still Eth2 |
x |
Ethernet3 |
Back Link |
4 |
No data lost, polled as if it were still Eth3 |
x |
You remove the first card from the router. The router automatically renames each port. Upon rediscovery the SNMP plugin continues to polls the objects with no change or data loss as long as you do not change the description or the index.
Object Name |
Object Description |
SNMP Index |
Note |
Score |
|
|
|
Data stored for the number of Days Until Delete setting in the Cluster Manager |
x |
|
|
|
Data stored for the number of Days Until Delete setting in the Cluster Manager |
x |
Ethernet0 |
Site One |
3 |
No data lost, polled as if it were still Ethernet2 |
x |
Ethernet1 |
Back Link |
4 |
No data lost, polled as if it were still Ethernet3 |
x |
You add the card back to the router within the number of Days Until Delete setting in the Cluster Manager. The router automatically changes the object name.
Object Name |
Object Description |
SNMP Index |
Note |
Score |
Ethernet0 |
Internet Access |
1 |
Data gap for when the card was removed but otherwise no data lost, polled as if it were still Ethernet0 |
x |
Ethernet1 |
Interface |
2 |
Data gap for when the card was removed but otherwise no data lost, polled as if it were still Ethernet1 |
x |
Ethernet2 |
Site One |
3 |
No data lost, polled as if it were still Ethernet0 from previous discovery. |
x |
Ethernet3 |
Back Link |
4 |
No data lost, polled as if it were still Ethernet1 from previous discovery. |
x |
You decide to rename port four and change its description.
Object Name |
Object Description |
SNMP Index |
Note |
Score |
Ethernet0 |
Internet Access |
1 |
No data lost, polled as if it were still Ethernet0 from previous discovery. |
x |
Ethernet1 |
Interface |
2 |
No data lost, polled as if it were still Ethernet1 from previous discovery. |
x |
Ethernet2 |
Site One |
3 |
No data lost, polled as if it were still Ethernet2 from previous discovery. |
x |
Eth3 |
Site Three |
4 |
New object created and new poll data collected. Existing data stored for the number of Days Until Deleted setting in the Cluster Manager. |
x |
At an extraordinarily high level, SevOne NMS groups each SNMP object by an SNMP object type. Each object has indicators that are grouped by indicator type. SNMP Objects are composed of OIDs which in turn break down into MIBs.
Device manufacturers name SNMP OIDs by a series of numbers, (e.g., The OID sysDescr is .1.3.6.1.2.1.1.1). Everything that comes after a named OID is the OID index. System wide information is usually denoted as .0 information. The .0 generally means there is only one instance of the OID, (e.g., The sysDescr index is always .0). The OID ifDescr is indexed by a single number that is not 0, (e.g., The description of an Ethernet card in a server might be ifDescr.3). There is no limit to the count of numbers that follow an OID. Some manufacturers use integer indexes that have a constant amount of numbers that follow each OID and some manufacturers use string indexes for readability. A string index represents a piece of text (the string) as a series of characters where each character is represented as its ASCII value. String indexes are sometimes prefixed with the length of the string.
Integer - A single number of any size.
A simple integer that could be used for an interface index.
7
String (with length) - A string of text, prefixed with the number of characters and followed by the ASCII value of each character.
The text CPU is the number of characters followed by the ASCII value of each.
3.67.80.85
String (no length) - A string where the length is not prefixed.
The text CPU in ASCII values.
67.80.85
Number (with length) - A string index where the numbers do not have an ASCII meaning.
The IP address with its length before the octets.
4.192.158.0.1
Number (no length) - A string index with no length where the numbers do not have an ASCII meaning.
The IP address with no length information appears as a series of integer indexes. This is useful when there is no guaranteed how many numbers there could be.
192.168.0.1
S3 uses the full numeric OID representation (starting with .1) to remove the dependency on the MIBs and to remove potential ambiguity of the OID. This makes the object definition fully portable to another system because different MIBs can arbitrarily redefine OIDs.
Another S3 feature is that white space characters such as spaces, tabs, and new line characters are optional and exist for readability. All of the following are equivalent:
• 7+9
• 7 + 9
• 7
+9
• 7
+
9
An S3 script is a sequential evaluation of one or many statements. Each statement is executed in sequence. The only logic provided by S3 comes from flavors of the ternary operator which acts like an IF statement. The final result of the script is the result of the final statement in the script.
Example 1:
Statement 1
Example 2:
Statement 1
Statement 2
Statement 3
A statement is the atomic unit of a script. A statement can assign a value to a variable or a statement can be an expression that evaluates to some value. Each statement evaluates to some value upon execution, (e.g., For a variable assignment, the value of the statement is the value of the variable).
Statements are lists of expressions and expression chains may be very complex and long. All S3 statements must end in a semicolon <;>. The last statement in a script may omit the semicolon.
Simple statement:
Expression ;
List statement where the final value is the concatenation of both expressions:
Expression 1 Expression 2 ;
An expression is the atomic unit of a statement. S3 is an OID-evaluation language and a text creation language. Multiple expressions can lie next to each other and their results are concatenated together. This differs from more logical and mathematical languages.
Example: 1 + 2 3 + 4
In C there needs to be a joining operation between the 2 and the 3 because they are considered two disjointed expressions which results in a syntax error.
In S3 this is seen as two separate expressions next to each other: 1+ 2 and 3 + 4 and the result of the statement is 37. The white space does not matter unless enclosed in quotes.
An expression is anything that evaluates to a value. This value need not be numeric. A piece of text evaluates to itself. An expression might be the number 7, the word Hello, or a complex mathematical formula. Expressions can be chains of symbols and operators as long as the entire expression evaluates to a single value.
Number
7
String:
'Hello'
Complex Formula:
( ( 1 + 2 ) / 12 + 34 ) * 10
Variable or OID that evaluates to a number or string:
[INDEX]
.1.3.6.1.2.1.1.1.0
Multiple grouped expressions (enclosed within parentheses) concatenated together:
( 7 'Hello' ( ( 1 + 2 ) / 12 + 34 ) * 10 [INDEX] .1.3.6.1.2.1.1.1.0 )
Variables are evaluated as OIDs to store the value of an expression. S3 has two types of variables; scalars and vectors.
Scalar - Anything that is a single number or some text.
Vector - An array of things. Vectors in S3 are different from vectors in normal scripting languages. Vectors in S3 are geared toward OIDs because an individual OID is represented as .<number> and a full OID is a series of .<numbers>s one after another. S3 breaks down variables into vectors by the "." character.
Variables are a name surrounded by square brackets. Variable names consist of the following characters: a-z, A-Z, 0-9, and - .
[Variable Name]
A variable assignment is an expression. The evaluation of the assignment is the new variable value. A variable assignment uses the = operator.
[Variable name] = Expression
S3 uses the following conventions to differentiate SevOne system variables from user variables to prevent user variables from overwriting system variables. There is no rule to enforce this.
SevOne system variables use capital letters and underscores for spaces. [MY_VARIABLE]
User variables use lowercase letters, a capital letter in the next word, and no underscore for spaces. [myVariable]
S3 can treat and evaluate variables as OIDs. Each variable must be declared before use. There is no special declaration syntax, but a variable must have an assigned value before use in an expression. Both scalar variables and vector variables are evaluated and inserted raw into the expression. S3 does nothing special to scalar variables when scalar variables are evaluated.
When a vector variable is evaluated, each of the vector variable's components is written, separated by "."s. Elements in vector variables are zero-indexed numerically. The first element starts at 0, the second starts at 1, and so on. To access a particular element of a vector variable, surround the element index in curly braces after the variable.
[Variable Name ]{Index number }
A variable cannot be used as an index number. The index number must be an actual number.
Each element in a vector variable is usually a scalar variable. There are exceptions when an element in a vector variable is another vector variable.
Some variables should not be evaluated as an OID. Enclose the variable in back ticks to prevent the variable from being evaluated as an OID. If a variable simply contains a number, the variable is treated as a normal number if not back ticked; however, it is always safe to back tick a variable to prevent improper evaluation. Text evaluates to itself. Text is considered anything enclosed in quotes. Back ticks may be in a single quoted string and that single quote string may be in a back tick quoted string.
Single quotes (') - Single quotes are used for raw text. The content of the text is not processed in any way, e.g., 'Anything here'
Back Ticks (`) - Back ticks are used for variable interpolation. Any variables present in the text is evaluated, e.g., `Anything here, including variables`
OIDs are evaluated. Anything that is not text, a variable, an operator, a normal number, or otherwise special symbol is considered an OID. When an OID is evaluated, it evaluates to the value of the OID on the current device. If the OID is not present on the device, the OID, followed by the default SNMP index, is used instead. If the OID cannot be evaluated, it evaluates to the empty string.
It is critical to note here that a variable without back ticks around it is treated exactly as it would if the value of the variable were to be placed in its stead. This means that a variable that contains a string representation of an OID is evaluated as that OID when it is encountered.
The following example might not work as expected:
1 [test] = 'test';
2 [test1] = [test] 1;
One might expect the value of "[test1]" to be "test1"; however, since "[test]" is not back ticked, it is treated as if the text "test" were present. As such, S3 tries to get the value of the OID whose name is "test" naturally, there is not one, and it returns the empty string. Thus, the final value is actually "1".
The proper way to do this is:
1 [test] = 'test';
2 [test1] = `[test]` 1;
This example back ticks the variable to prevent it from being evaluated as an OID.
When an OID is encountered, S3 tries to evaluate it. If S3 cannot evaluate the OID, then S3 adds the value of the default index to the OID, which for SNMP discovery is [INDEX]. If S3 still cannot evaluate the OID, then the OID evaluates to the empty string. This allows for very human readable and human understandable definitions for objects and indicators. However, at the loss of stringent definitions.
If an OID already has .[INDEX] appended to it, then the OID saves S3 the step.
Symbols are special tokens (characters, or collections of characters) that have a special function in S3.
Parentheses ( and ) group expressions to define the sequence in which they are to be evaluated. This is commonly used in mathematical applications.
Example:
1 + 2 * 3
(which is 7)
Is not the same as:
( 1 + 2 ) * 3
(which is 9).
Parentheses can change two expressions into one expression.
Example:
( 1 + 2 3 + 4 )
Evaluates to the single value 37, which could be used by further expressions.
Operators are symbols. Operators are anything that act on an expression. There are three types of operators:
Unary operators act on one value only, (e.g., Not).
Binary operators act on two values, (e.g., Addition).
Ternary operators act on three values, (e.g., ... ? ... : ... is a ternary operator in C).
The common mathematical operators are applied with the usual precedence. Mathematical operators have full floating point support.
Multiplication (Standard multiplication)
Left expression * Right expression
Division (Standard division)
Left expression / Right expression
Addition (Standard addition)
Left expression + Right expression
Subtraction (Standard subtraction)
Left expression - Right expression
Note: Because MIB names can contain a dash -, which is the same as the minus symbol -, all subtraction mathematical operators must have a blank space before and after the minus symbol.
Comparison operators compare two expressions that return 1 if the comparison is true or return 0 if the comparison is false.
Equal to, Boolean == returns 1 if the left and right side are equal.
Left expression == Right expression
Not equal to, Boolean != returns 1 if the left and right side are not equal.
Left expression != Right expression
Less than, Boolean < returns 1 if the left side is less than the right side.
Left expression < Right expression
Less than or equal to, Boolean <= returns 1 if the left side is less than or equal to the right side.
Left expression <= Right expression
Greater than, Boolean > returns 1 if the left side is greater than the right side.
Left expression > Right expression
Greater than or equal to, Boolean >= returns 1 if the left side is greater than or equal to the right side.
Left expression >= Right expression
Logical operators generally perform true/false operations. S3 uses the following logical operators:
Binary
Binary logical operators operate on two expressions.
Logical AND, Boolean && returns 1 if the left and right side evaluate to true or returns 0 otherwise.
Left expression && Right expression
Logical OR, Boolean || returns 1 if the left side evaluates to true, the right side evaluates to true, or both evaluate to true; or returns 0 otherwise.
Left expression || Right expression
Bamboo, ||| is actually a shortcut for a particularly common case of the ?? ternary operator. It returns the value on the left if it is set; otherwise, it returns the value on the right regardless of its value.
Left expression ||| Right expression
This is equivalent to
Left expression ?? Left expression : Right expression
Ternary logical operators operate on three expressions and S3 has two ternary operators.
Logical ternary operator, ? evaluates the left expression for a test that is greater than 0 (numerically) or for a string that has length and is not 0. Otherwise, it evaluates the right expression. For this reason, the test is usually a logical Boolean expression that returns 0 or 1, guaranteed.
test ? Left expression : Right expression
Existential ternary operator, ?? evaluates the left expression for a test that has a value that is not the empty string. Otherwise, it evaluates the right expression.
test ?? Left expression : Right expression
Note:
test ?? test : Right expression
Is equivalent to:
test ||| Right expression
The results of a walk, #count walks the specified OID and returns the count of the occurrences of an OID . This does not resolve the OID in the manner that other naked OIDs are resolved to get the OID value. This #count resolves the OID count immediately, unlike the way an OID is resolved via an OID walk.
Example: To count the number of CPUs on a Linux device to determine what the maximum CPU utilization could be: net-snmp returns up to 800% utilization for a box with eight CPUs.
#count OID
Example:
#count .1.3.6.1.2.1.25.3.3.1.2
Can evaluate to 8.
Since OIDs may be indexed by numbers, strings, or variably-sized components, S3 uses conversion operators that operate on a single expression.
Conversion from OID
OID-to-ASCII-string (with length), $s converts the expression to an ASCII string.
$s Expression
The expression should be an OID with the following format:
n.ASCII 1.ASCII 2.....ASCII n
Example:
$s '5.72.101.108.108.111'
Evaluates to Hello.
OID-to-ASCII-string (no length), $S converts the expression to an ASCII string.
$S Expression
The expression should be an OID with the following format:
ASCII 1.ASCII 2
Example:
$S '72.101.108.108.111'
Evaluates to Hello.
OID-to-numbers (with length), $v converts the expression to a string.
$v Expression
The expression should be an OID with the following format:
n.Number 1.Number 2.....Number n
Example:
$v '4.192.168.0.1'
Evaluates to 192.168.0.1.
OID-to-numbers (no length), $V Identity operation; the value should be the same as the expression.
$V Expression
This converts the expression to a string. The expression should be an OID with the following format:
Number 1.Number 2.
Example:
$V '192.168.0.1'
Evaluates to 192.168.0.1.
String-to-OID (with length), #s converts the expression to an OID with the length prefixed. The expression should be ASCII text.
#s Expression
Example:
#s 'Hello'
Evaluates to 5.72.101.108.108.111.
String-to-OID (no length), $s converts the expression to a string with no length information. The expression should be ASCII text.
#S Expression
Example:
#S 'Hello'
Evaluates to 72.101.108.108.111.
Numbers-to-OID (with length), #v converts the expression to an OID with the length prefixed. The expression should be text consisting of numbers separated by "."s.
#v Expression
Example:
#v '192.168.0.1'
Evaluates to 4.192.168.0.1.
Numbers-to-OID (no length), #V Identity operation; the value should be the same as the expression converts the expression to an OID with no length information. The expression should be text consisting of numbers separated by "."s.
#V Expression
Example:
#V '192.168.0.1'
Evaluates to 192.168.0.1.
Parameters to the conversion operators should be enclosed in parentheses to avoid confusion.
To get the OID index representation of the text 37 (which is 2.51.55), you can try:
#s 1 + 2 3 + 4
However, the #s only applies to the 1 which yields 1.49. (49 is ASCII for 1); the value of that is added to 2 (1.49 + 2 = 3.49), which is then concatenated with 7 (to yield 3.497). You must use parentheses:
#s ( 1 + 2 3 + 4 )
Evaluates to 2.51.55 (which, as a string, is 37).
The precedence of operators and symbols is as follows. When given the choice (in other words, when parentheses are not used), S3 evaluates operations in the following sequence.
The normal mathematical operator precedence (* / + -) is preserved in this list.
'text' `text`
()
#s #S #v #V $s $S $v $V
* /
+ -
== != > >= < <=
&&
||
|||
:
? ??
=
The following examples assign the proper values to variables whose name should match their value.
[one] = 1;
[two] = 1 + 1;
[two] = `[one]` + `[one]` - 1 + 1;
[ten] = ( 2 + 1 ) * 3 + 1;
The following example sets all three variables equal to 12.
1 [x] = [y] = [z] = 12;
The following examples demonstrate Boolean logic.
[bothXandY] = `[x]` && `[y]`;
[eitherXorYorBoth] = `[x]` || `[y]`;
[eitherXorY] = ( `[x]` && (`[y]` ? 0 : 1) ) || ( `[y]` && (`[x]` ? 0 : 1) );
[notX] = `[x]` ? 0 : 1;
The following example selects the value of ifName if it is present, or the value of ifDescr otherwise.
[bamboo] = ifName ||| ifDescr;
The following examples demonstrate the use of the ternary operator.
[sevenOrEight1] = `[x]` ? 7 : 8;
[sevenOrEight2] = `[x]` ? 6 + 1 : 2 * 2 + 4;
The following examples convert the text CPU into an OID index. The ASCII value for C=67, P=80, and U=85.
#s 'CPU'
The result of this is "3.67.80.85".
#S 'CPU'
The result of this is 67.80.85 (no length prefix).
The following examples convert the OID indexes specified into strings.
$s '3.67.80.85'
The result of this is CPU.
$S '67.80.85'
The result of this is also CPU.
The Net-SNMP agent supports the NET-SNMP-VACM-MIB, which provides some information about Net-SNMP's View Access Control Model.
The following is a sample walk of nsVacmAccessEntry (.1.3.6.1.4.1.8072.1.9.1.1):
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpcomm1"."".0.noAuthNoPriv."read"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpcomm1"."".0.noAuthNoPriv."write"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpcomm1"."".0.noAuthNoPriv."notify"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpsnmpUser"."".3.authNoPriv."read"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpsnmpUser"."".3.authNoPriv."write"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmContextMatch."grpsnmpUser"."".3.authNoPriv."notify"
= INTEGER: prefix(2)
NET-SNMP-VACM-MIB::nsVacmViewName."grpcomm1"."".0.noAuthNoPriv."read"
= STRING: all
NET-SNMP-VACM-MIB::nsVacmViewName."grpcomm1"."".0.noAuthNoPriv."write"
= STRING: none
NET-SNMP-VACM-MIB::nsVacmViewName."grpcomm1"."".0.noAuthNoPriv."notify"
= STRING: none
NET-SNMP-VACM-MIB::nsVacmViewName."grpsnmpUser"."".3.authNoPriv."read"
= STRING: all
NET-SNMP-VACM-MIB::nsVacmViewName."grpsnmpUser"."".3.authNoPriv."write"
= STRING: all
NET-SNMP-VACM-MIB::nsVacmViewName."grpsnmpUser"."".3.authNoPriv."notify"
= STRING: all
NET-SNMP-VACM-MIB::nsVacmStorageType."grpcomm1"."".0.noAuthNoPriv."read"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStorageType."grpcomm1"."".0.noAuthNoPriv."write"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStorageType."grpcomm1"."".0.noAuthNoPriv."notify"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStorageType."grpsnmpUser"."".3.authNoPriv."read"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStorageType."grpsnmpUser"."".3.authNoPriv."write"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStorageType."grpsnmpUser"."".3.authNoPriv."notify"
= INTEGER: permanent(4)
NET-SNMP-VACM-MIB::nsVacmStatus."grpcomm1"."".0.noAuthNoPriv."read"
= INTEGER: active(1)
NET-SNMP-VACM-MIB::nsVacmStatus."grpcomm1"."".0.noAuthNoPriv."write"
= INTEGER: active(1)
NET-SNMP-VACM-MIB::nsVacmStatus."grpcomm1"."".0.noAuthNoPriv."notify"
= INTEGER: active(1)
NET-SNMP-VACM-MIB::nsVacmStatus."grpsnmpUser"."".3.authNoPriv."read"
= INTEGER: active(1)
NET-SNMP-VACM-MIB::nsVacmStatus."grpsnmpUser"."".3.authNoPriv."write"
= INTEGER: active(1)
NET-SNMP-VACM-MIB::nsVacmStatus."grpsnmpUser"."".3.authNoPriv."notify"
= INTEGER: active(1)
And with numeric OIDs:
.1.3.6.1.4.1.8072.1.9.1.1.2.8.103.114.112.99.111.109.109.49.0.0.1.4.114.101.97.100
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.2.8.103.114.112.99.111.109.109.49.0.0.1.5.119.114.105.116.101
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.2.8.103.114.112.99.111.109.109.49.0.0.1.6.110.111.116.105.102.121
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.2.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.4.114.101.97.100
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.2.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.5.119.114.105.116.101
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.2.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.6.110.111.116.105.102.121
= INTEGER: prefix(2)
.1.3.6.1.4.1.8072.1.9.1.1.3.8.103.114.112.99.111.109.109.49.0.0.1.4.114.101.97.100
= STRING: all
.1.3.6.1.4.1.8072.1.9.1.1.3.8.103.114.112.99.111.109.109.49.0.0.1.5.119.114.105.116.101
= STRING: none
.1.3.6.1.4.1.8072.1.9.1.1.3.8.103.114.112.99.111.109.109.49.0.0.1.6.110.111.116.105.102.121
= STRING: none
.1.3.6.1.4.1.8072.1.9.1.1.3.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.4.114.101.97.100
= STRING: all
.1.3.6.1.4.1.8072.1.9.1.1.3.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.5.119.114.105.116.101
= STRING: all
.1.3.6.1.4.1.8072.1.9.1.1.3.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.6.110.111.116.105.102.121
= STRING: all
.1.3.6.1.4.1.8072.1.9.1.1.4.8.103.114.112.99.111.109.109.49.0.0.1.4.114.101.97.100
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.4.8.103.114.112.99.111.109.109.49.0.0.1.5.119.114.105.116.101
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.4.8.103.114.112.99.111.109.109.49.0.0.1.6.110.111.116.105.102.121
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.4.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.4.114.101.97.100
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.4.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.5.119.114.105.116.101
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.4.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.6.110.111.116.105.102.121
= INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.9.1.1.5.8.103.114.112.99.111.109.109.49.0.0.1.4.114.101.97.100
= INTEGER: active(1)
.1.3.6.1.4.1.8072.1.9.1.1.5.8.103.114.112.99.111.109.109.49.0.0.1.5.119.114.105.116.101
= INTEGER: active(1)
.1.3.6.1.4.1.8072.1.9.1.1.5.8.103.114.112.99.111.109.109.49.0.0.1.6.110.111.116.105.102.121
= INTEGER: active(1)
.1.3.6.1.4.1.8072.1.9.1.1.5.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.4.114.101.97.100
= INTEGER: active(1)
.1.3.6.1.4.1.8072.1.9.1.1.5.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.5.119.114.105.116.101
= INTEGER: active(1)
.1.3.6.1.4.1.8072.1.9.1.1.5.11.103.114.112.115.110.109.112.85.115.101.114.0.3.2.6.110.111.116.105.102.121
= INTEGER: active(1)
The following entries use the "nsVacmStatus" OID.
S3 has two options to properly index entries.
S3 can choose a variable-length index (with no length prefix). However, this provides S3 no insight as to the components of the index. There are no OIDs available to determine a proper name for any of the entries to enter into the system as objects.
S3 can explicitly define each index component, which allows S3 to reference each component individually to properly name objects.
The index composed of the following types of fields.
Example:
"grpcomm1"."".0.noAuthNoPriv."read"
String, (e.g., grpcomm1) - According to the MIB, this is the name of the group for this entry.
String, (e.g., "") - According to the MIB, this is the prefix that a name must match to gain access rights.
Integer, (e.g., 0) - According to the MIB, this is the security model in use. This roughly corresponds with the SNMP version (where 0 = any).
Integer, (e.g., noAuthNoPriv, which is, 1) - According to the MIB, this is the minimum level of security required to gain access rights.
String, (e.g., read) - According to the MIB, this is the type of processing to which to apply the specified view.
S3 has the following information:
• [INDEX] is 8.103.114.112.99.111.109.109.49.0.0.1.4.114.101.97.100.
• [INDEX]{0} is 8.103.114.112.99.111.109.109.49.
• [INDEX]{1} is 0.
• [INDEX]{2} is 0.
• [INDEX]{3} is 1.
• [INDEX]{4} is 4.114.101.97.100.
S3 uses the following information to name an object for a VACM entry.
Group group name [ matching prefix ] using {any version|security model }with security level , providing processing
The security level is an enumeration. S3 creates a variable with the appropriate textual representation for its value.
Necessary S3:
[securityLevel] = ( `[INDEX]{3}` == 1 ? 'noAuthNoPriv' : ( `[INDEX]{3}` == 2
? 'authNoPriv' : ( `[INDEX]{3}` == 3 ? 'authPriv' : '(unknown)' ) ) );
Name:
'Group '( $s `[INDEX]{0}` )( ($s `[INDEX]{1}`) ?? (' matching '($s `[INDEX]{1}`)) : '')
'using'( `[INDEX]{2}` ? `v[INDEX]{2}` : 'any version' )` with [securityLevel], providing`
( $s `[INDEX]{4}` )
Evaluates to:
Group grpcomm1 uses any version with noAuthNoPriv, providing read
S3, revision 2
The first "Name" S3 is too long and is not very readable. In the second revision, S3 assigns various parts of the name to variables and links the names at the end.
Necessary S3:
[groupName] = ( $s `[INDEX]{0}` );
[matchText] = ( ($s `[INDEX]{1}`) ?? (' matching '($s `[INDEX]{1}`)) : '' );
[versionText] = ( `[INDEX]{2}` ? `v[INDEX]{2}` : 'any version' );
[securityLevel] = ( `[INDEX]{3}` == 1 ? 'noAuthNoPriv' : ( `[INDEX]{3}` == 2 ? 'authNoPriv' :
( `[INDEX]{3}` == 3 ? 'authPriv' : '(unknown)' ) ) );
[processingText] = ( $s `[INDEX]{4}` );
Name:
`Group [groupName][matchText] using [versionText] with [securityLevel], providing [processingText]`
Evaluates to:
Group grpcomm1 using any version with noAuthNoPriv, providing read
The end result is the same, but the name is easier to read and understand. The difference is that each component S3 is broken up into separate variables which allows the name to be a single interpolated string.
S3 evaluates OIDs. Evaluation must take place in the context of a certain SNMP agent.
S3 is used at the SNMP discover time for a particular device. All S3 statements are executed in the context of that device, meaning that every time an OID is encountered, the device is queried for its value, and that value is returned to the S3 statement.
The main purpose of S3 is to define ways to describe specific objects from a generic set of rules. As the SNMP discover script goes through the possible object types, for each one, it generates a list of individual object indexes for that object type. The rules for that object type are applied to each index that it encounters to generate a unique object per index.
The following SNMP Object Editor fields are evaluated, in order, for each object:
Variables
A mini S3 script generates variables for later use.
Variables generated:
(Any present)
Subtype expression
Determines the subtype of the object.
Variables generated:
[TYPE]: The numerical value of the subtype (if any).
[TYPE NAME]: The name of the subtype (if any).
[TYPE DESCRIPTION]: The description of the subtype (if any).
Assert expression
Skipped if an object does not pass the assert expression.
Should not define any variables.
Name expression
Uniquely identifies an object across the SNMP plugin for the device in question.
Should not define any variables.
Description expression
Should provide an informative description of the object. If not set then use the object type.
Should not define any variables.
Before any evaluation happens, the "[INDEX]" variable is set to the SNMP index of the current object. This is a vector variable; each index in the vector corresponds with each specific index key defined for this object type. Each of those could also be a vector. Because of the sequence in which the system variables are generated; S3 generates an error if a variable is used before it is generated.
The Expression field in the SNMP Indicator Editor for a particular indicator is also an S3 expression. Indicators should not set variables. The Maximum Value Expression field is also an S3 expression.
An indicator expression and maximum value expression can use any of the variables defined above for the object, including any user-defined variables in the Variables field.
This enables an indicator definition to get around any strange indexing (including out-of-order indexing) by using S3 to assemble the OID to poll as necessary.
Indicator expressions are unique because they are handled in a two pass system. The SNMP plugin does not implement S3; it implements a simple mathematical library. Any OIDs present in the data that is passed to the poller must be fully expanded with their index information. To accomplish this, two passes are used on the indicator expression.
The text-conversion functions of S3 does not work in either pass.
First Pass
The first pass is an expansion pass. It expands any OID encountered by adding the full index value to the end of it. This is equivalent to having every OID end in ".[INDEX]". The result of this pass is saved and no real values should be generated.
Second Pass
The second pass then evaluates (normally) the results of the first pass. If this pass results in a numeric value, then the indicator is presumed to exist. The results of the first pass are stored for use by the poller.
It is important to use standard mathematical expressions (and not the extra S3 operations) to perform indicator expressions. These expressions must conform to normal mathematical rules (for example, you cannot have two expressions next to each other with no joining operator). These expressions may include the following operators:
/ + -
And the following grouping symbols:
( )
Note: It is possible to get around the OID expansion in the first pass. The entire results of the evaluated first pass are passed to the second pass. Any text in the first pass does not have its quotes in the second pass. Thus, an OID may be quoted and used exactly as quoted in the second pass. The whole first pass could be quoted to prevent S3 from taking any intelligent action.
Example
To have every interface report, as an indicator, the total number of interfaces on the device (multiplied by 10), the following indicator expression does not work:
ifNumber.0 * 10
"ifNumber.0" is expanded with the default index, which in this case could be ".2", for example (yielding "ifNumber.0.2", which is not the desired outcome):
ifNumber.0.2 * 10
However, the following tricks the system into accepting the OID:
`ifNumber.0` * 10
This yields:
ifNumber.0 * 10
This is the desired outcome.
Pass 1
OIDs are expanded.
Text is unquoted.
Pass 2
Pass 1 is evaluated.
Notes:
Do not use text-conversion functions.
The following lists the first 128 ASCII values and their corresponding character value.