draft SNMP Script Language 9/1/94 SNMP Script Language August 16, 1993 Jeff D. Case David B. Levi SNMP Research, Inc. case@snmp.com levi@snmp.com Status of this Memo This document is an Internet Draft. Internet Drafts are working documents of the Internet Engineering Task Force (IETF), its Areas, and its Working Groups. Note that other groups may also distribute working documents as Internet Drafts. Internet Drafts are valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet Drafts as reference material or to cite them other than as a "work in progress". Expires 3/1/95 [Page 1] draft SNMP Script Language 9/1/94 1. Introduction The development of sophisticated network management applications based on the Simple Network Management Protocol (SNMP) often requires automation of complex series of SNMP requests. Writing code for performing these requests can become a considerable burden. Programmers must write code for building VarBind lists, Pdu structures, and Authentication structures, and for parsing these structures. Programmers must deal with multiplexing multiple SNMP requests along with any other I/O that the application must handle. In particular, applications which use a Graphical User Interface (GUI) must be able to perform asynchronous SNMP requests. In such an application, performing asynchronous SNMP requests in the proper sequence can become a difficult task. GUIs are event driven, and usually use callback functions to respond to events. Thus programmers must write a callback function to handle the response to each request in a series of SNMP requests, and for handling timeouts. Each of these callbacks must perform the next SNMP request depending on the results of previous queries. Also, the status and data retrieved from previous queries must be passed to each callback. This 'chaining' of callbacks can quickly lead to extremely complex and cumbersome programs. The SNMP script language is an attempt to provide a simpler, more intuitive interface for performing series of SNMP requests. The language allows programmers to specify complex series of SNMP requests, and to have a single callback function be invoked when the requests have completed. 1.1. SNMP Script Language Features The script language provides an easy to use interface for performing SNMP requests, including get, get-next, set, get-bulk, trap-send and m2m inform-request. The list of MIB variables resulting from a get, get-next, get-bulk, or set request can be assigned to a script variable, and the contents can be manipulated with mathematical expressions, logical expressions, comparisons, etc. Looping and branching structures are available based on expressions of script variables. Scripts may call other scripts, transfer control to other scripts, or execute a shell command (which can be any program available to the user). Scripts can currently send output to stdout (mainly for debugging purposes), or can redirect output to a file. The script language is also extensible. An application can provide C functions which can be called from within a script. Such a function is called a Registered Function. Expires 3/1/95 [Page 2] draft SNMP Script Language 9/1/94 1.2. Applications Of The Script Language There are a number of applications for the script language. It can be used as a stand-alone program, in which case scripts are run from the UNIX command line. The script language can be integrated into other applications as well. In SNMP Research's implementation of the script language, facilities are provided for compiling scripts from within a program, caching the compiled/tokenized scripts for memory and performance savings, and for executing scripts. Applications can run scripts synchronously or asynchronously. Some of the applications which have used the script language are: o Customization of node polling with Xnetmon (SNMP Research's network management software), including display of front panel and LED indicators of managed network devices and gathering MIB variables for display and analysis. o Downloading scripts to an agent and having the agent execute the script. This is the mid-level manager, and is useful for distributed management. o Management of nodes without a graphical interface. Scripts can be run periodically by cron, or just executed as a background process, and when an interesting event occurs on an agent, the script can start up any application desired, such as a graphical popup to notify a network operator that something is wrong. o Command line version of scripts used for script development, which can also be used to easily create command line utilities for manually managing agents. Expires 3/1/95 [Page 3] draft SNMP Script Language 9/1/94 2. Writing Scripts The following sections describe the semantics of writing SNMP scripts. 2.1. Varbind and Value Types The script language is designed to allow easy manipulation of MIB variables. To facilitate this, the script language provides two basic 'types' of objects, values and varbinds. A value consists of a data type and a piece of data. A varbind consists of an ASN.1 object identifier and a value. There is no specific relationship between the object identifier and value contained within a varbind. In particular, the object identifier need not be restricted to instances of MIB variables, and the value may contain any data type and data, regardless of the value of the object identifier. The script language distinguishes between value expressions and varbind expressions. A value expression evaluates to a single value, while a varbind expressions evaluates to a (possibly empty) list of varbinds. The semantics for combining value and varbind expressions is discussed in the following sections. Registered functions can also return either a value or a varbind list. Applications which register functions should specify which is returned by the function when it is registered. This will affect how calls to the function within a script parse (as value or varbind expressions). 2.2. Variables All variables in the script language are varbind lists. Variables are referred to using an identifier, which is a string of upper- or lower-case letters, numbers, or underscore characters. The first character cannot be a number. Since there is only one type of variable, there is no need to declare variables. Variables are always initialized to an empty varbind list. However, if a script is not recompiled between executions, all variables will retain the values from the previous execution. 2.2.1. Accessing Variables There are several ways to access the contents of a variable. When referring to the complete varbind list, just the identifier is used. To refer to an individual varbind in the list, an array subscript is used, as follows: Expires 3/1/95 [Page 4] draft SNMP Script Language 9/1/94 varname[3] Array indices start at 0, so the above example references the fourth varbind in the list called 'varname'. A range of varbinds can also be generated using array subscript ranges, as follows: varname[2..7] varname[..5] varname[3..] The first example generates a varbind list consisting of the third through eighth elements of varname. If the list does not contain enough varbinds, a list containing all the varbinds available is created. This list could possibly be an empty varbind list. The second example generates a list of all varbinds up to the sixth varbind. The final example generates a list of all varbinds from the fourth to the end of the list. A reference to a variable always parses as a varbind expression. 2.3. Types And Type Casting There is considerable flexibility in the script language for generating varbinds. In particular, there is no restriction placed on matching a particular OID and VALUE/TYPE. So, for example, the OID for sysName.0 could be placed in the name of a varbind, and an integer value could be placed in the value of the same varbind. Normally this does not make sense, since sysName is defined as an OCTET STRING in mib2. However, having this restriction would greatly reduce the flexibility of the script language. A varbind is not required to contain an OID and a value. If an OID is not provided, the script interpreter will provide "0.0" as the OID. If a value is not provided, the value is set to NULL_TYPE, with a NULL value. The script language will attempt to cast the type of a value to the necessary type in order to perform a particular operation. In general, values are cast to the type of the argument to the left of an operator. So, for example: "7" + 3 -> "73" 5 + "6" -> 11 Expires 3/1/95 [Page 5] draft SNMP Script Language 9/1/94 The first example would produce the string "73", while the second example would produce the integer value 11. It is possible to explicitly cast a varbind's value to a particular type by using the varbind_literal syntax (described later). Type casting also applies to object types. Operators may take value or varbind objects as arguments. The general semantics for combining value and varbind objects using operators are as follows. When the object on the left is a varbind or varbind list and the object on the right is a value, the operator will apply the value to each varbind in the list. Usually the operator will perform an operation on the value part of the varbinds, and generate a new varbind list with the new values and unchanged object identifiers. When the object on the left is a value and the object on the right is a varbind or varbind list, the varbind (list) will be converted to a value. This is done by extracting the value contained in the first varbind in the list, or by creating a NULL value if the varbind list is empty. Some operators use different semantics for combining value and varbind objects. This is discussed in the sections for the particular operators. Type casting is also performed in most places where the for the script language. The specific type-casting performed depends on context. However, in most cases a varbind expression will be converted to a value as described above. The three exceptions to this are when a varbind expression occurs as a complete statement, when a varbind expression is part of an argument list, and when a varbind expression is assigned to a variable. In these cases, no type casting is performed. For other occurences of value_or_varbind_expression, the resulting value is cast as follows: o When used in flow control statements as a branch condition, the value is cast to an integer. In this case, a value of 0 is considered 'false', and a non-zero value is considered 'true'. o When used in a 'ping' or 'icmp_echo' statement, the value is cast to an integer. o When used in a 'to_clause' for a network request, the value is cast to an ip-address, octet-string, or integer, respectively, for the three parameters of the to_clause. Expires 3/1/95 [Page 6] draft SNMP Script Language 9/1/94 o When used for redirection of a 'print' action to a file, the value is cast to an octet-string. o When used in a 'call' or 'transfer' action, the value is cast to an octet-string. o When used in a 'varbind_list', the values are cast to integers. o When used in a 'varbind_literal', the first two parameters are cast to an object-identifier and an integer, respectively. The third parameter is cast to the type specified in the second parameter if it exists, otherwise it is not cast. 2.4. Varbind Literals Varbind literals are used to create a varbind. The syntax of a varbind literal is as follows. { object-identifier : data-type : data } Any of the three fields in a varbind literal may be omitted. The fields of a varbind created by a literal varbind are initialized as follows. o If the object identifier is omitted, it will be initialized to "0.0". o If the data-type is omitted, it will be initialized to the type of the data as specified in the program text. Currently only data of type INTEGER or OctetString can be specified in the program text. o If the data is omitted, it will be initialized to be the equivalent of a NULL value whose type is specified by the data type field. For integer types, this would be the value zero (0). For types with a length, such as OctetStrings or OBJECT IDENTIFIERs, this would be a zero length value. o If both the data-type and data are omitted, the data-type will be initialized to NULL_TYPE, and the data will be empty. o If both the data-type and data are present, the data will be cast to the type specified by the data-type. Varbind literals parse as varbind expressions. Expires 3/1/95 [Page 7] draft SNMP Script Language 9/1/94 2.5. SNMP Requests An SNMP request may be performed using a single command in the script language. The syntax for performing a request is as follows. request-type ( argument-list ) request-type ( argument-list ) send request-type ( argument-list ) send request-type ( argument-list ) Where is: to ( destination : handle : port ) 2.5.1. Request Types The request-type specifies the type of request. Normally an SNMP request parses as a varbind expression, and the script blocks until a reply is received. However, if the send keyword is used, the request parses as a value, returns a unique request-id to identify the request, and the script continues execution. For requests that do not require a reply (such as traps), the send keyword only changes how the request parses. Such requests will not block the script, and will return either an empty varbind list, or an INTEGER value. Request types are listed in the following table. Request type Requires reply ------------------------- -------------- get, get_request Yes get_next, get_next_request Yes get_bulk, get_bulk_request Yes get_table, get_table_request Yes set, set_request Yes inform, inform_request Yes trap No snmpv2_trap No ping, icmp_echo Yes 2.5.2. Request Argument List The contents of the argument list in an SNMP request depends on the type of request. The syntax for an argument list will be discussed in a later section. Expires 3/1/95 [Page 8] draft SNMP Script Language 9/1/94 The get, get_next, and set requests require that all members of the argument list be varbind lists. These varbind lists will be concatenated and used as the varbind list in the request. The get-bulk request requires that the first two members of the argument list be INTEGER values. These two values are used for the non-repeater and max-repetition counts. The remainder of the argument list must be varbind lists as for the get, get_next, and set requests. The inform request has the same requirements as the get, get_next, and set requests. However, the varbind list which is sent will be prefixed with a varbind containing the OID for sysUpTime.0 and the current value of sysUpTime.0. The trap request requires that the first member of the argument list be a COUNTER value specifying the type of SNMPv1 trap to be sent. If the type of trap is an enterprise specific trap, the second member of the argument list must be the specific trap type, and the third member must be the enterprise OID for the trap. The snmpv2_trap request must requires that the first member of the argument list be an OBJECT IDENTIFIER specifying the snmpTrapOID of the trap. The varbind list which is sent in the trap will consist of a varbind containing sysUpTime.0, a varbind containing the snmpTrapOID, followed by the remainder of the argument list. The icmp_echo request does not require any arguments. A single COUNTER argument may be provided, which is taken as the number of bytes of data to be placed in the ICMP echo packet. The default number of bytes is 8. The get_table request takes three arguments, an integer and two object-identifiers. This request type is not a real SNMP request type, but uses SNMP get-next or get-bulk requests for its operation. The first argument specifies how many rows of a table to retreive, the second argument specifies the table, and the third argument (which is optional) specifies the row from which to begin retrieval. If the instance is omitted, retrieval starts at the beginning of the table. The result of a get_table request should be a varbind list containing the table rows concatentated together. Variables in a row which don't exist (i.e. holes) should have place holders whose type is NO_SUCH_INSTANCE_EXCEPTION. Note that a manager must have some knowledge of the MIB containing the table to be retrieved, and the object-identifier specified for the table must be an aggregate type (e.g. ifTable or atEntry). Expires 3/1/95 [Page 9] draft SNMP Script Language 9/1/94 2.5.3. Request To Clause The to keyword is used to explicitly specify the destination, handle, and port to be used in a request. Any or all of these may be specified. Each running script contains a default destination, handle, and port. These are used when the to clause is omitted, and when any part of a to clause is omitted. It is a syntax error to provide a to clause with all three parameters omitted. 2.5.4. Receiving Responses When the send keyword is used to send a get, get_next, set, inform, or ping request, a unique request id is returned. This request id can then be used to explicitly request the results of this request, as follows. receive request-id The request operation always parses as a varbind list. Currently, if there is no such request or if the request has not yet completed, an empty varbind list is returned. Note that this behavior may change in the future. 2.5.5. Error Lists If a request fails for some reason, the varbind list returned by the request or the receive operation will be an empty list. In this case, the special variable error_list will be set to reflect the cause of the error. The first element of this list will contain a code indicating the cause of the error. This code will either be the error_status from the received packet, or one of the following codes. These are stored as INTEGER values. o SNMP_REQUEST_FAIL_ERROR (0x80) means that the request could not be sent for some reason. This may mean that the destination was not a valid IP address, or any of several other reasons. o SNMP_SYNC_FAIL_ERROR (0x81) means that the clocks could not be synchronized in an SNMPv2 request. o SNMP_TIMEOUT_ERROR (0x82) means that there was no response. o SNMP_REQUEST_PENDING (0x83) means that a receive operation was attempted on a request which has not yet completed. o ICMP_REQUEST_FAIL_ERROR (0x84) means that an icmp echo could not be sent for some reason. Expires 3/1/95 [Page 10] draft SNMP Script Language 9/1/94 o ICMP_TIMEOUT_ERROR (0x85) means that there was no response. o ICMP_REQUEST_PENDING (0x86) means that a receive operation was attempted on an icmp echo request which has not yet completed. o TRAP_REQUEST_FAIL_ERROR (0x8A) means a trap could not be sent. This can occur for the same reasons as an SNMP_REQUEST_FAIL_ERROR. If the error code is the error_status from the received packet, the second element of the error_list will be the error_index from the packet, and the remainder of the error_list will contain the varbind list from the received packet. 2.5.6. Request Handlers A request handler is a default action which is taken when an SNMP or ICMP request times out or fails. When a request handler completes execution, the script immediately exits. Request handlers can be set for timeouts, SNMPv2 clock synchronization failures, general request failures, and for specific request errors. The syntax for a request handler is as follows: handler-type { code . . . }; Where handler-type can be one of: syncfail timeout request_fail icmp_timeout icmp_fail error The is the error code returned in a response packet. 2.6. Argument Lists Argument lists are used in SNMP requests, as the operand of a registered function call, or as the operand of some of the built- in actions of the script language. An argument list is simply a comma separated list of values or varbind lists. Restrictions on the sequence of values and varbind lists in an argument list are determined by the particular use of the list. If an argument list which does not obey these restrictions is used, a warning may be generated, and the function or action will most likely fail. Expires 3/1/95 [Page 11] draft SNMP Script Language 9/1/94 2.7. Operators Most operators in the script language can take any combination of value and varbind list objects as operands. In general, the object resulting from evaluation of an operator is the same object type as the left hand operand. The following sections describe most of the operators which are available. Remember that the type of the operand on the right will be cast to the type of the operand on the left. Unless otherwise noted, when both operands of a binary operator are varbind lists, the operator pairs the varbinds in the lists, and performs the operation on the values of each varbind. The result of each operation along with the object identifier from the varbind in the left operand are used to create a new varbind list whose length is the length of the shorter operand. o The '&&' operator performs a logical AND operation. The result is an integer value of 1 or 0, representing true or false. Operands which are integers are considered true if non-zero, otherwise false. Operands which are length-typed are considered true if they have length > 0, otherwise false. o The '||' operator performs a logical OR operation. Operands are treated the same as by the '&&' operator. o The '>' operator compares its operands to see which is greater. For operands with length, each element of the operand is compared up to the length of the shorter operand. The result is a boolean value as for the '&&' operator. o The '<' operator compares its operands to see which is smaller. o The '>=' operator compares its operand to see which is greater, or if the operands are equal. o The '<=' operator compares its operand to see which is smaller, or if the operands are equal. o The '==' operator compares its operands to see if they are equal. o The '!=' operator compares its operands to see if they are not equal. o The '.=' operator compares two values whose type is OBJECT IDENTIFIER to determine if they are in the same MIB family. Expires 3/1/95 [Page 12] draft SNMP Script Language 9/1/94 o The '.!=' operator compares two values whose type is OBJECT IDENTIFIER to determine if they are not in the same MIB family. o The '|' operator performs a mathematical OR operation. For operands which are length-typed, each element is OR'ed up to the length of the shorter operand. The length of the result is the length of the shorter operand. o The '&' operator performs a mathematical AND operation. Operands are treated as by the '|' operator. o The '^' operator performs a mathematical XOR operation. Operands are treated as by the '|' operator. o The '*' operator performs multiplication between integer operands. If the operands are length-typed a NULL value is generated. o The '/' operator performs division between integer operands. If the operands are length-typed a NULL value is generated. o The '+' operator performs addition or concatenation, depending on the type of its arguments. When the operands are values with integer types, the values are added, and the result is an integer type. When the operands are values whose types have length, the values are concatenated. The '+' operator can also be used as a unary operator, in which case its operand is returned unchanged. o The '.' operator performs OID concatenation. This operands will first convert both its operands to OBJECT IDENTIFIERs. o The '-' operator performs subtraction between integer operands. If the operands are length-typed a NULL value is generated. The '-' operator can also be used as a unary operator. In this case, if its operand is an integer type, the negative of the operand is returned, otherwise the operand is returned unchanged. o The '!' operator is a unary operator, and returns a boolean value as the '&&' operator. Its operand are treated as boolean values as for the '&&' operator, and it returns the negation of its operand. o The '++' operator requires both operands to be varbind lists. It concatenates the varbind lists and returns the result. Expires 3/1/95 [Page 13] draft SNMP Script Language 9/1/94 2.7.1. Assignment The assignment operator (=) requires the left hand operator be a varbind list constructed only from a variable. This may be just the variable name, or may contain a subscript to specify a range within the variable. The value returned by the assignment operator is always a copy of the varbind list which was affected by the assignment. The effect of the assignment operator depends on the syntax of the right hand operand. If the right hand operand evaluates to a value expression, the value in each varbind in the left hand operand is replaced by the right handle operand. If the left hand operand contains a subscript which references varbinds which do not exist, the left hand operand is padded with empty varbinds before the operation is performed. If the left hand operand does not contain a subscript, and the referenced variable does not contain any varbinds, the variable is assigned a single varbind whose OID is "0.0" and whose value is the right hand operand. If the right hand operand is a single varbind literal, the fields which are specified in the literal are used to replace the fields in each varbind of the left hand operand. If the left hand operand contains a subscript which references varbinds which do not exist, the left hand operand is padded with empty varbinds before the operation is performed. If the left hand operand does not contain a subscript, and the referenced variable is empty, the varbind literal is assigned directly to the variable. If the right hand operand evaluates to a varbind list, the left hand operand is replaced by the right hand operand. The left hand operand will be padded with empty varbinds if necessary. 2.8. Flow Control The script language provides three flow control structures. These are the if/else structure, the while loop, and the until loop. The syntax for these structure are as follows. if ( expression ) code-block if ( expression ) code-block else code-block while ( expression ) code-block Expires 3/1/95 [Page 14] draft SNMP Script Language 9/1/94 until ( expression ) code-block The expression is executed before the code block in a while structure, and after the code block in an until structure. This expression can be either a value expression or a varbind expression. The result will be interpreted as a boolean whether or not it is a varbind expression. For a varbind expression, the value of the first varbind in the list will be used. 2.9. Actions The script language provides five 'built-in' actions. These actions are not implemented as extensions either for performance reasons, or to simplify script programming. o return ( argument-list ) Terminates the script, and returns the argument-list as a varbind-list to the application. o print ( argument-list ) o print ( argument-list ) > value-or-varbind-expression o print ( argument-list ) >> value-or-varbind-expression Prints the argument list. The output may be redirected to a file by using '>' to overwrite the file, or '>>' to append to the file. The value-or-varbind-expression must evaluate to an OctetString. Members of the argument list which are varbinds are printed as OID = value, followed by a newline character. o exec ( argument-list ) Performs a system call. The members of the argument list are converted to OctetString, and concatenated with space separators. Only the value part of varbinds is used. The result is then passed to the 'system' function. Note that if the '&' character is not passed at the end of the argument list, the application will block until the system call completes. o call value-or-varbind-expression ( argument-list ) variable Executes another script, passing varbind-list as arguments. the varbind list returned from the called script is assigned to variable. The value-or-varbind- expression specifies the name of the script to be run. Expires 3/1/95 [Page 15] draft SNMP Script Language 9/1/94 o transfer value-or-varbind-expression ( argument-list ) Transfer execution from current script to another script, passing varbind-list as arguments. The original script is actually blocked until the called script completes execution, at which time the calling script terminates. 2.10. Accessing Varbind Elements In previous versions of the script language, the OID, type, and value of a varbind could be accessed and assigned to by using the OID(), TYPE(), and VAL() operators. These have been replaced in the new version of the language. To assign to individual parts of a varbind, simply assign a varbind literal (as described in the section on varbind literals). In order to access the individual parts of a varbind, registered functions must be used. These functions should be called OID, TYPE, and VAL, corresponding to the names of the older operators. These changes provide a more consistent and flexible programming interface. Expires 3/1/95 [Page 16] draft SNMP Script Language 9/1/94 3. Script Language Syntax Specification The following grammar provides a syntax specification for the SNMP script language. This grammar is suitable for parsing with yacc with a few minor changes and with the inclusion of a lex scanner. Terminals are specified with single quotes, or in upper-case letters. The valid values for terminals specified with upper-case letters are as follows: ID Specifies a variable name. A variable name may contain lower-case and upper-case letters, the numerals 0 through 9, and the underscore character. The first character may not be a numeral. STRING Specifies a string of single byte characters, delimited by double quote marks. Characters within the string may be escaped using the backslash character in the same manner as in the C programming language. CONSTANT Specifies a numeric constant. Currently, constants may only be specified in a decimal format. There are three groups of built-in constants. These are variable types, error codes, and exception codes. These are listed along with their values at the end of this section. VALUE_FUNCTION This is an ID which specifies the name of a registered function which returns a value. VARBIND_FUNCTION This is an ID which specifies the name of a registered function which returns a varbind list. Although variable and function names may be specified using the same sets of characters, the following conventions should be followed to prevent ambiguities: - Variable names should not contain any upper-case letters. - Registered function names should not contain any lower-case letters, and words within a registered function name should be separated by underscore characters (for example, DO_THIS, not DoThis or do_THIS). Expires 3/1/95 [Page 17] draft SNMP Script Language 9/1/94 3.1. Script Language Grammar /* TOP LEVEL RULES AND FLOW CONTROL */ start:: statement_list | '{' statement_list '}' code_block:: ';' | statement | '{' statement_list '}' statement_list:: statement | statement_list statement statement:: action ';' | value_or_varbind_expression ';' | branch_statement | error ';' branch_statement:: 'if' '(' value_or_varbind_expression ')' code_block | 'if' '(' value_or_varbind_expression ')' code_block 'else' code_block | 'while' '(' value_or_varbind_expression ')' code_block | 'until' '(' value_or_varbind_expression ')' code_block /* RULES FOR NETWORK REQUESTS */ snmp_request:: request_type '(' argument_list ')' | request_type '(' argument_list ')' to_clause local_request:: 'local' snmp_request icmp_request:: 'ping' '(' ')' | 'ping' '(' ')' to_clause | 'icmp_echo' '(' ')' | 'icmp_echo' '(' ')' to_clause | 'ping' '(' value_or_varbind_expression ')' | 'ping' '(' value_or_varbind_expression ')' to_clause | 'icmp_echo' '(' value_or_varbind_expression ')' Expires 3/1/95 [Page 18] draft SNMP Script Language 9/1/94 | 'icmp_echo' '(' value_or_varbind_expression ')' to_clause to_clause:: 'to' '(' value_or_varbind_expression ':' ':' ')' | 'to' '(' ':' value_or_varbind_expression ':' ')' | 'to' '(' ':' ':' value_or_varbind_expression ')' | 'to' '(' value_or_varbind_expression ':' value_or_varbind_expression ':' ')' | 'to' '(' value_or_varbind_expression ':' ':' value_or_varbind_expression ')' | 'to' '(' ':' value_or_varbind_expression ':' value_or_varbind_expression ')' | 'to' '(' value_or_varbind_expression ':' value_or_varbind_expression ':' value_or_varbind_expression ')' request_type:: 'get' | 'get_request' | 'get_next' | 'get_next_request; | 'get_bulk' | 'get_bulk_request' | 'get_table' | 'get_table_request' | 'set' | 'set_request' | 'inform' | 'inform_request' | 'trap' | 'snmpv2_trap' /* RULES FOR ACTIONS */ action:: 'return' '(' argument_list ')' | 'print' '(' argument_list ')' | 'print' '(' argument_list ')' '>' value_or_varbind_expression | 'print' '(' argument_list ')' '>>' value_or_varbind_expression | 'exec' '(' argument_list ')' | 'call' value_or_varbind_expression '(' argument_list ')' ID | 'call' value_or_varbind_expression '(' argument_list ')' | 'transfer' value_or_varbind_expression '(' argument_list ')' | 'syncfail' code_block | 'timeout' code_block | 'request_fail' code_block | 'error' CONSTANT code_block Expires 3/1/95 [Page 19] draft SNMP Script Language 9/1/94 | 'ping_timeout' code_block | 'icmp_timeout' code_block | 'ping_fail' code_block | 'icmp_fail' code_block argument_list:: value_or_varbind_expression | argument_list ',' value_or_varbind_expression /* RULES FOR EXPRESSION/ASSIGNMENT */ paren_value_expression:: STRING | CONSTANT | 'send' snmp_request | 'send' local_request | 'send' icmp_request | '(' value_expression ')' | VALUE_FUNCTION '(' ')' | VALUE_FUNCTION '(' argument_list ')' unary_value_expression:: paren_value_expression | '+' paren_value_expression | '-' paren_value_expression | '!' paren_value_expression | '+' paren_varbind_expression | '-' paren_varbind_expression | '!' paren_varbind_expression multiply_value_expression:: unary_value_expression | multiply_value_expression '*' unary_value_expression | multiply_value_expression '/' unary_value_expression | multiply_value_expression '*' paren_varbind_expression | multiply_value_expression '/' paren_varbind_expression plus_value_expression:: multiply_value_expression | plus_value_expression '+' multiply_value_expression | plus_value_expression '.' multiply_value_expression | plus_value_expression '-' multiply_value_expression | plus_value_expression '+' paren_varbind_expression | plus_value_expression '.' paren_varbind_expression | plus_value_expression '-' paren_varbind_expression compare_value_expression:: Expires 3/1/95 [Page 20] draft SNMP Script Language 9/1/94 plus_value_expression | compare_value_expression '>' plus_value_expression | compare_value_expression '<' plus_value_expression | compare_value_expression '>=' plus_value_expression | compare_value_expression '<=' plus_value_expression | compare_value_expression '>' paren_varbind_expression | compare_value_expression '<' paren_varbind_expression | compare_value_expression '>=' paren_varbind_expression | compare_value_expression '<=' paren_varbind_expression equal_value_expression:: compare_value_expression | equal_value_expression '==' compare_value_expression | equal_value_expression '!=' compare_value_expression | equal_value_expression '.=' compare_value_expression | equal_value_expression '.!=' compare_value_expression | equal_value_expression '==' paren_varbind_expression | equal_value_expression '!=' paren_varbind_expression | equal_value_expression '.=' paren_varbind_expression | equal_value_expression '.!=' paren_varbind_expression logic_and_value_expression:: equal_value_expression | logic_and_value_expression '&' equal_value_expression | logic_and_value_expression '&' paren_varbind_expression logic_eor_value_expression:: logic_and_value_expression | logic_eor_value_expression '^' logic_and_value_expression | logic_eor_value_expression '^' paren_varbind_expression logic_or_value_expression:: logic_eor_value_expression | logic_or_value_expression '|' logic_eor_value_expression | logic_or_value_expression '|' paren_varbind_expression logical_and_value_expression:: logic_or_value_expression | logical_and_value_expression '&&' logic_or_value_expression | logical_and_value_expression '&&' paren_varbind_expression logical_or_value_expression:: logical_and_value_expression | logical_or_value_expression '||' logical_and_value_expression | logical_or_value_expression '||' paren_varbind_expression value_expression:: logical_or_value_expression varbind_list:: ID Expires 3/1/95 [Page 21] draft SNMP Script Language 9/1/94 | ID '[' value_or_varbind_expression ']' | ID '[' value_or_varbind_expression '..' value_or_varbind_expression ']' | ID '[' '..' value_or_varbind_expression ']' | ID '[' value_or_varbind_expression '..' ']' varbind_literal:: '{' value_or_varbind_expression ':' ':' '}' | '{' ':' value_or_varbind_expression ':' '}' | '{' ':' ':' value_or_varbind_expression '}' | '{' ':' value_or_varbind_expression ':' value_or_varbind_expression '}' | '{' value_or_varbind_expression ':' ':' value_or_varbind_expression '}' | '{' value_or_varbind_expression ':' value_or_varbind_expression ':' value_or_varbind_expression '}' paren_varbind_expression:: varbind_list | varbind_literal | snmp_request | local_request | icmp_request | 'receive' paren_value_expression | '(' varbind_expression ')' | VARBIND_FUNCTION '(' ')' | VARBIND_FUNCTION '(' argument_list ')' concat_varbind_expression:: paren_varbind_expression | concat_varbind_expression '++' paren_varbind_expression multiply_varbind_expression:: concat_varbind_expression | multiply_varbind_expression '*' concat_varbind_expression | multiply_varbind_expression '/' concat_varbind_expression | multiply_varbind_expression '*' paren_value_expression | multiply_varbind_expression '/' paren_value_expression plus_varbind_expression:: multiply_varbind_expression | plus_varbind_expression '+' multiply_varbind_expression | plus_varbind_expression '.' multiply_varbind_expression | plus_varbind_expression '-' multiply_varbind_expression | plus_varbind_expression '+' paren_value_expression | plus_varbind_expression '.' paren_value_expression | plus_varbind_expression '-' paren_value_expression compare_varbind_expression:: plus_varbind_expression Expires 3/1/95 [Page 22] draft SNMP Script Language 9/1/94 | compare_varbind_expression '>' plus_varbind_expression | compare_varbind_expression '<' plus_varbind_expression | compare_varbind_expression '>=' plus_varbind_expression | compare_varbind_expression '<=' plus_varbind_expression | compare_varbind_expression '>' paren_value_expression | compare_varbind_expression '<' paren_value_expression | compare_varbind_expression '>=' paren_value_expression | compare_varbind_expression '<=' paren_value_expression equal_varbind_expression:: compare_varbind_expression | equal_varbind_expression '==' compare_varbind_expression | equal_varbind_expression '!=' compare_varbind_expression | equal_varbind_expression '.=' compare_varbind_expression | equal_varbind_expression '.!=' compare_varbind_expression | equal_varbind_expression '==' paren_value_expression | equal_varbind_expression '!=' paren_value_expression | equal_varbind_expression '.=' paren_value_expression | equal_varbind_expression '.!=' paren_value_expression logic_and_varbind_expression:: equal_varbind_expression | logic_and_varbind_expression '&' equal_varbind_expression | logic_and_varbind_expression '&' paren_value_expression logic_eor_varbind_expression:: logic_and_varbind_expression | logic_eor_varbind_expression '^' logic_and_varbind_expression | logic_eor_varbind_expression '^' paren_value_expression logic_or_varbind_expression:: logic_eor_varbind_expression | logic_or_varbind_expression '|' logic_eor_varbind_expression | logic_or_varbind_expression '|' paren_value_expression logical_and_varbind_expression:: logic_or_varbind_expression | logical_and_varbind_expression '&&' logic_or_varbind_expression | logical_and_varbind_expression '&&' paren_value_expression logical_or_varbind_expression:: logical_and_varbind_expression | logical_or_varbind_expression '||' logical_and_varbind_expression | logical_or_varbind_expression '||' logical_and_value_expression assignment:: varbind_list '=' value_or_varbind_expression Expires 3/1/95 [Page 23] draft SNMP Script Language 9/1/94 varbind_expression:: assignment | logical_or_varbind_expression value_or_varbind_expression:: value_expression | varbind_expression 3.2. Constant Names and Values The script language provides a set of symbolic constants to aid in making scripts more readable. These constants are broken up into three groups, TYPE constants, ERROR constants, and EXCEPTION constants. In addition, an application can register its own symbolic constants. The spelling of symbolic constants should follow the rules for registered functions. Constants which are provided by an application should always be prefixed with the string "C_". Constants provided by the script language should have a suffix reflecting the type of the constant ("_TYPE", "_ERROR", "_EXCEPTION"). The listing below is a minimal list of constants which an implementation of the script language should provide. Note that although all the required constants have integer values, constants provided by an application may also have string values. The first five ERROR constants are returned in the error_list variable when a device cannot be polled or does not respond to an SNMP or ICMP request. SNMP_REQUEST_FAIL_ERROR 0x80 SNMP_TIMEOUT_ERROR 0x82 ICMP_REQUEST_FAIL_ERROR 0x84 ICMP_TIMEOUT_ERROR 0x85 TRAP_REQUEST_ERROR 0x8A NO_ERROR 0x00 TOO_BIG_ERROR 0x01 NO_SUCH_NAME_ERROR 0x02 BAD_VALUE_ERROR 0x03 READ_ONLY_ERROR 0x04 GEN_ERROR 0x05 NO_ACCESS_ERROR 0x06 WRONG_TYPE_ERROR 0x07 WRONG_ENCODING_ERROR 0x09 WRONG_VALUE_ERROR 0x0A NO_CREATION_ERROR 0x0B INCONSISTENT_VALUE_ERROR 0x0C RESOURCE_UNAVAILABLE_ERROR 0x0D COMMIT_FAILED_ERROR 0x0E UNDO_FAILED_ERROR 0x0F AUTHORIZATION_ERROR 0x10 NOT_WRITABLE_ERROR 0x11 INCONSISTENT_NAME_ERROR 0x12 Expires 3/1/95 [Page 24] draft SNMP Script Language 9/1/94 INTEGER_TYPE 0x02 OCTET_PRIM_TYPE 0x04 NULL_TYPE 0x05 OBJECT_ID_TYPE 0x06 SEQUENCE_TYPE 0x30 IP_ADDR_PRIM_TYPE 0x40 COUNTER_TYPE 0x41 GAUGE_TYPE 0x42 TIME_TICKS_TYPE 0x43 OPAQUE_PRIM_TYPE 0x44 BIT_STRING_TYPE 0x03 INTEGER_32_TYPE 0x02 COUNTER_32_TYPE 0x41 GAUGE_32_TYPE 0x42 NSAP_ADDR_TYPE 0x45 COUNTER_64_TYPE 0x46 U_INTEGER_32_TYPE 0x47 GET_REQUEST_TYPE 0xA0 GET_NEXT_REQUEST_TYPE 0xA1 GET_RESPONSE_TYPE 0xA2 SET_REQUEST_TYPE 0xA3 TRAP_TYPE 0xA4 RESPONSE_TYPE 0xA2 GET_BULK_REQUEST_TYPE 0xA5 INFORM_REQUEST_TYPE 0xA6 SNMPv2_TRAP_TYPE 0xA7 NO_SUCH_OBJECT_EXCEPTION 0x80 NO_SUCH_INSTANCE_EXCEPTION 0x81 END_OF_MIB_VIEW_EXCEPTION 0x82 Expires 3/1/95 [Page 25] draft SNMP Script Language 9/1/94 4. Future Work SNMP Research's current implementation of the script language provides several sets of registered functions. For example, one set of functions provides facilities for reading and writing files. Another set provides facilities for manipulating OIDs. We refer to these as 'language extensions'. In the future, it might be useful to define standard sets of script language extensions which an implementation should provide. There are two additions to the script language which would be particularly useful. The first is to provided statement labels and a goto statement, similar to the C language goto statement. The second addition is to allow functions to be declared within a script. 5. Author's Address Jeff D. Case David B. Levi SNMP Research, Inc. 3001 Kimberlin Heights Road Knoxville, TN 37920-9716 Phone: (615)573-1434 Email: case@snmp.com levi@snmp.com Expires 3/1/95 [Page 26] draft SNMP Script Language 9/1/94 Table of Contents 1 Introduction .............................................. 2 1.1 SNMP Script Language Features ........................... 2 1.2 Applications Of The Script Language ..................... 3 2 Writing Scripts ........................................... 4 2.1 Varbind and Value Types ................................. 4 2.2 Variables ............................................... 4 2.2.1 Accessing Variables ................................... 4 2.3 Types And Type Casting .................................. 5 2.4 Varbind Literals ........................................ 7 2.5 SNMP Requests ........................................... 8 2.5.1 Request Types ......................................... 8 2.5.2 Request Argument List ................................. 8 2.5.3 Request To Clause ..................................... 10 2.5.4 Receiving Responses ................................... 10 2.5.5 Error Lists ........................................... 10 2.5.6 Request Handlers ...................................... 11 2.6 Argument Lists .......................................... 11 2.7 Operators ............................................... 12 2.7.1 Assignment ............................................ 14 2.8 Flow Control ............................................ 14 2.9 Actions ................................................. 15 2.10 Accessing Varbind Elements ............................. 16 3 Script Language Syntax Specification ...................... 17 3.1 Script Language Grammar ................................. 18 3.2 Constant Names and Values ............................... 24 4 Future Work ............................................... 26 5 Author's Address .......................................... 26 Expires 3/1/95 [Page 27]