tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search

RFC 4011

 
 
 

Policy Based Management MIB

Part 2 of 4, p. 27 to 59
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 27 
6.  Index Information for 'this element'

   PolicyScript code needs a convenient way to get the components of the
   index for 'this element' so that they can perform SNMP operations on
   it or on related elements.

   Two mechanisms are provided.

   1. For all OID input parameters to all SNMP Library Functions (but
      not OID utility functions), the token "$n" ('$' followed by an
      integer between 0 and 128) can be used in place of any decimal
      sub-identifier.  This token is expanded by the agent at execution
      time to contain the nth subid of the index for the current
      element.  For example, if the element is interface 7, and the
      objectIdentifier is "1.3.6.1.2.1.2.2.1.3.$0", it will be expanded
      to "1.3.6.1.2.1.2.2.1.3.7".  The special token "$*" is expanded to
      contain all of the subidentifiers of the index of the current
      element, separated by '.' characters.

      It is an RTE if a token is specified that is beyond the length of
      the index for the current element.

      Note that the "$n" convention is only active within strings.

   2. The ec() and ev() functions allow access to the components of the
      index for 'this element'.  ec() takes no argument and returns the
      number of index components that exist.  ev() takes an integer
      argument specifying which component of the index (numbered
      starting at 0) and returns an integer containing the value of the
      n'th subidentifier.  Refer to the Library functions section for
      the complete definition of ec() and ev().

         For example, if 'this element' is frCircuitDLCI.5.57
                                           (ifIndex = 5, DLCI = 57)
               then ec()  returns 2
                    ev(0) returns 5
                    ev(1) returns 57

      This is helpful when one wishes to address a related element.
      Extending the previous example, to find the port speed of the
      port, the circuit (above) runs over:

         portSpeed = getVar("ifSpeed." + ev(0));

      A script may check the type of 'this element' by calling the
      elementName() function.  Although it is possible to write a script
      that will work with different types of elements, many scripts will

Top      Up      ToC       Page 28 
      assume a particular element type and will work incorrectly if used
      on different element types.

7.  Library Functions

   Library functions are built-in functions available primarily to
   provide access to information on the local system or to manipulate
   this information more efficiently.  A group of functions is organized
   into a library, the unit of conformance for function implementation.
   In order to claim conformance to a library, an implementation must
   implement all functions in a library to the specifications of the
   library.

   In order for a management station or a condition or action to
   understand whether a certain library of functions is implemented,
   each library will have a name that it registers in the role table as
   a characteristic of the system element ("0.0") in the default SNMP
   context.  Thus, conformance to a library can be tested with the
   roleMatch library function (in the base library) with the call
   roleMatch ("libraryName", "0.0").

   Note that in the descriptions of these functions below, the function
   prototype describes the type of argument expected.  Even though
   variables are not declared with a particular type, their contents
   must be appropriate for each function argument.  If the type is
   variable, the keyword 'var' will be used.  If only a string is
   appropriate, the keyword 'string' will be used.  If only an integer
   is appropriate, the keyword 'integer' will be used.  If the argument
   is declared as 'string' or 'integer' and a value of a different type
   is passed, the argument will be coerced with ToInteger() or
   ToString().  Any failure of this coercion will cause an RTE (in
   particular for ToInteger(), which will fail if its string-valued
   argument is not a well-formed integer).

   In the function prototype, if the '&' character precedes the
   identifier for an argument, that argument may be modified by the
   function (e.g., "integer &result, ...)").  Arguments without the '&'
   character cannot be modified by the function.  In a script,
   modifiable arguments don't have to be preceded by a '&'.  It is an
   RTE if a constant is passed to a modifiable function argument
   (regardless of whether the function actually writes to the argument).

   In the function prototype, the '[' and ']' characters surround
   arguments that are optional.  In PolicyScript code, the optional
   argument may only be included if all optional arguments to the left
   of it are included.  The function may place restrictions on when an
   optional argument must, or must not, be included.

Top      Up      ToC       Page 29 
   In the function prototype, if a type is listed before the name of the
   function, the function returns a value of that type.  If no type is
   listed, the function returns no value.

8.  Base Function Library

   A standard base library of functions is available to all systems that
   implement this specification.  This library is registered with the
   name "pmBaseFunctionLibrary".  Although the specification of this
   library is modularized into 4 separate sections, conformance to the
   library requires implementation of all functions in all sections.

   The sections are:

      - SNMP library functions
      - Policy library functions
      - Utility functions
      - Library Functions

8.1.  SNMP Library Functions

   Two sets of SNMP Library functions are available with different
   situations in mind:

   - Convenience SNMP Functions

     In an effort to keep simple things simple, these functions are easy
     to use and code that is easy to understand.  These functions will
     suffice for the majority of situations, where a single variable is
     referenced and the desired error recovery is simply (and
     immediately) to give up (and move to the next policy-element
     combination).  In more complex cases, the General SNMP Functions
     can be used at the cost of several times the code complexity.

     The convenience SNMP functions are getVar, exists, setVar,
     setRowStatus, createRow, counterRate, and searchColumn.

   - General SNMP Functions

     The General SNMP functions allow nearly any legal SNMP Message to
     be generated, including those with multiple varbinds, getNext
     operations, notifications, and messages with explicit addressing or
     security specifications.

     The general SNMP functions are writeVar, readVar, snmpSend,
     readError, and writeBulkParameters.

Top      Up      ToC       Page 30 
8.1.1.  SNMP Operations on Non-Local Systems

   From time to time, a script may have to perform an operation on a
   different SNMP system than that on which 'this element' resides.
   Scripts may also have to specify the use of alternate security
   parameters.  In order to do this, the following optional arguments
   are provided for the SNMP library functions:

   snmp-function(...[, integer mPModel,
                       string tDomain, string tAddress,
                       integer secModel, string secName,
                       integer secLevel, string contextEngineID
   ])

   For example:

       getVar("sysDescr.0", "", SNMPv3, "transportDomainUdpIpv4",
              "192.168.1.1:161", USM, "joe", NoAuthNoPriv);

   The use of these arguments is denoted in function definitions by the
   keyword 'NonLocalArgs'.  The definitions of these arguments are as
   follows:

      'mPModel' is the integer value of the SnmpMessageProcessingModel
      to use for this operation.

      'tDomain' is a string containing an ASCII dotted-decimal object
      identifier representing the transport domain to use for this
      operation.

      'tAddress' is a string containing the transport address formatted
      according to the 'tDomain' argument.  The ASCII formats for
      various values of 'tDomain' are defined by the DISPLAY-HINT for a
      TEXTUAL-CONVENTION that represents an address of that type.  The
      DISPLAY-HINTs used are:

         tDomain                    Source of DISPLAY-HINT [5] [11]
         -------                    ----------------------
         transportDomainUdpIpv4     TransportAddressIPv4
         transportDomainUdpIpv6     TransportAddressIPv6
         transportDomainUdpDns      TransportAddressDns
         snmpCLNSDomain             snmpOSIAddress
         snmpCONSDomain             snmpOSIAddress
         snmpDDPDomain              snmpNBPAddress
         snmpIPXDomain              snmpIPXAddress
         rfc1157Domain              snmpUDPAddress
         Other                      Use DISPLAY-HINT "1x:"

Top      Up      ToC       Page 31 
      'secModel' is the integer value of the SnmpSecurityModel to use
      for this operation.

      'secName' is a string value representing the SnmpSecurityName to
      use for this operation.

      'secLevel' is the integer value of the SnmpSecurityLevel to use
      for this operation.

      An SNMP operation will be sent to the target system by using
      security parameters retrieved from a local configuration datastore
      based on 'secModel', 'secName', and 'secLevel'.  It is the
      responsibility of the agent to ensure that sensitive information
      in the local configuration datastore is used on behalf of the
      correct principals, as identified by the security credentials of
      the last entity to modify the pmPolicyAdminStatus for a policy.

      To illustrate how this must be configured, consider an example in
      which 'joe' installs a policy on 'PMAgent' that will periodically
      configure objects on 'TargetAgent' with the credentials of
      'Operator'.  The following conditions must be true for this policy
      to execute with the proper privileges:

      - 'Operator's security credentials for TargetAgent must be
        installed in PMAgent's local configuration datastore (e.g.,
        usmUserTable [6]) indexed by TargetAgent's engineID and
        'Operator'.
      - VACM [9] must be configured on PMAgent so that 'joe' has access
        to the above entry in the appropriate MIB for the local
        configuration datastore (e.g., usmUserTable).
      - 'joe' must be the last user to modify the pmPolicyAdminStatus
        object for the policy.

      See the Security Considerations section for more information.

      For convenience, constants for 'mPModel', 'secModel', and
      'secLevel' are defined in the "Constants" section below.

      'contextEngineID' is a string representing the contextEngineID of
      the SNMP entity targeted by this operation.  It is encoded as a
      pair of hex digits (upper- and lowercase are valid) for each octet
      of the contextEngineID.  If 'tDomain' and 'tAddress' are provided
      but 'contextEngineID' is not, then the operation will be directed
      to the SNMP entity reachable at 'tDomain' and 'tAddress'.

      In order for PolicyScript code to use any of these arguments, all
      optional arguments to the left must be included.  'mPModel',
      'tDomain', 'tAddress', 'secModel', 'secName', and 'secLevel' must

Top      Up      ToC       Page 32 
      be used as a group; if one is specified, they must all be.
      'contextEngineID' may only be specified if all others are
      specified.

      Note that a function that uses NonLocalArgs must provide a
      parameter for the contextName that will be required when the
      NonLocalArgs are present.  Many functions will have the following
      logic:

      ContextName NonLocalArgs
      Supplied    Supplied

      No          No            Addressed to default context on
                                local system.
      Yes         No            Addressed to named context on
                                local system.
      Yes         Yes           Addressed to named context on
                                potentially remote system.
      No          Yes           Not allowed.

8.1.2.  Form of SNMP Values

   Many of the library functions have input or output parameters that
   may be one of the many SMI data types.  The actual type is not
   encoded in the value but is specified elsewhere, possibly by nature
   of the situation in which it is used.  The exact usage for input and
   output is as follows:

   Any Integer value
      (INTEGER, Integer32, Counter32, Counter64, Gauge32, Unsigned32,
      TimeTicks, Counter64):

      On input:
         An Integer or a String that can be successfully coerced to an
         Integer with the ToInteger() operator.  It is an RTE if a
         string is passed that cannot be converted by ToInteger() into
         an integer.

         A string of the form

           enum_decimal: [ letter | digit | '-' ]* '(' decimal_constant
         ')'

         will also be accepted.  In this case the sequence of characters
         before the parentheses and the parentheses themselves are
         completely ignored, and the decimal_constant inside the
         parentheses is converted.  Thus, "frame-relay(32)" translates
         to the integer 32.

Top      Up      ToC       Page 33 
      On output:
         An Integer containing the returned value.

   Octet String
      On input:
         Either a String or an Integer.  If an Integer, it will be
         coerced to a String with the ToString() function.  This string
         will be used as an unencoded representation of the octet string
         value.

      On output:
         A String containing the unencoded value of the octet string.

   Object Identifier
      On input and on output:
         A String containing a decimal ASCII encoded object identifier
         of the following form:

            oid:       subid [ '.' subid ]* [ '.' ]
            subid:     '0' | decimal_constant

      It is an RTE if an Object Identifier argument is not in the form
      above.  Note that a trailing '.' is acceptable and will simply be
      ignored.  (Note, however, that a trailing dot could cause a
      strncmp() comparison of two otherwise-identical OIDs to fail;
      instead, use oidncmp().)

      Note that ASCII descriptors (e.g., "ifIndex") are never used in
      these encodings "over the wire".  They are never returned from
      library functions; nor are they ever accepted by them.  NMS user
      interfaces are encouraged to allow humans to view object
      identifiers with ASCII descriptors, but they must translate those
      descriptors to dotted-decimal format before sending them in MIB
      objects to policy agents.

   Null
      On input:
         The input is ignored.

      On output:
         A zero length string.

Top      Up      ToC       Page 34 
8.1.3.  Convenience SNMP Functions

8.1.3.1.  getVar()

   The getVar() function is used to retrieve the value of an SNMP MIB
   object instance.

      string getVar(string oid [, string contextName, NonLocalArgs])

         'oid' is a string containing an ASCII dotted-decimal
         representation of an object identifier (e.g.,
         "1.3.6.1.2.1.1.1.0").

         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform an SNMP operation on a system different
         from that of 'this element'.

         It is an RTE if the queried object identifier value does not
         exist.

         This function returns a string containing the returned value,
         encoded according to the returned type.  Note that no actual
         SNMP PDU has to be generated and parsed when the policy MIB
         agent resides on the same system as the managed elements.

         It is recommended that NMS user interfaces display and allow
         input of MIB object names by their descriptor values, followed
         by the index in dotted-decimal form (e.g., "ifType.7").

8.1.3.2.  exists()

   The exists() function is used to verify the existence of an SNMP MIB
   object instance.

      integer exists(string oid [, string contextName, NonLocalArgs])

         'oid' is a string containing an ASCII dotted-decimal
         representation of an object identifier (e.g.,
         "1.3.6.1.2.1.1.1.0").

Top      Up      ToC       Page 35 
         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform an SNMP operation on a system different
         from that of 'this element'.

         This function returns the value 1 if the SNMP instance exists
         and 0 if it doesn't exist.  Note that no actual SNMP PDU has to
         be generated and parsed when the policy MIB agent resides on
         the same system as the managed elements.

         It is recommended that NMS user interfaces display and allow
         input of MIB object names by their descriptor values, followed
         by the index in dotted-decimal form (e.g., "ifType.7").

8.1.3.3.  setVar()

   The setVar() function is used to set a MIB object instance to a
   certain value.  The setVar() function is only valid in policyActions.

      setVar(string oid, var value, integer type
             [, string contextName, NonLocalArgs] )

         'oid' is a string containing an ASCII dotted-decimal
         representation of an object identifier (e.g.,
         "1.3.6.1.2.1.1.1.0").

         'value' is a string encoded in the format appropriate to the
         'type' parameter.  The agent will set the variable specified by
         'oid' to the value specified by 'value'.

         'type' will be the type of the 'value' parameter and will be
         set to one of the values for DataType Constants.

         The optional 'contextName' argument contains the SNMP context
         on which to operate.   If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform an SNMP operation on a system different
         from that of 'this element'.  Note that no actual SNMP PDU has
         to be generated and parsed when the policy MIB agent resides on
         the same system as the managed elements.

Top      Up      ToC       Page 36 
         It is an RTE if the set encounters any error.

         It is recommended that NMS user interfaces display and allow
         input of MIB object names by their descriptor values, followed
         by the index in dotted-decimal form (e.g., "ifType.7").

8.1.3.4.  searchColumn()

      integer searchColumn(string columnoid, string &oid,
                           string pattern, integer mode
                           [, string contextName, NonLocalArgs])

         searchColumn performs an SNMP walk on a portion of the MIB
         searching for objects with values equal to the 'pattern'
         parameter.

         'columnoid' constrains the search to those variables that share
         the same OID prefix (i.e., those that are beneath it in the OID
         tree).

         A getnext request will be sent requesting the object identifier
         'oid'.  If 'oid' is an empty string, the value of 'columnoid'
         will be sent.

         The value returned in each response packet will be transformed
         to a string representation of the value of the returned
         variable.  The string representation of the value will be
         formed by putting the value in the form dictated by the "Form
         of SNMP Values" rules, and then by performing the ToString()
         function on this value, forming 'SearchString'.

         The 'mode' value controls what type of match to perform on this
         'SearchString' value.  There are 6 possibilities for mode:

           Mode               Search Action
           ExactMatch         Case sensitive exact match of 'pattern'
                              and 'SearchString'.
           ExactCaseMatch     Case insensitive exact match of 'pattern'
                              and 'SearchString'.
           SubstringMatch     Case sensitive substring match, finding
                              'pattern' in 'SearchString'.
           SubstringCaseMatch Case insensitive substring match, finding
                              'pattern' in 'SearchString'.
           RegexpMatch        Case sensitive regular expression match,
                              searching 'SearchString' for the regular
                              expression given in 'pattern'.

Top      Up      ToC       Page 37 
           RegexpCaseMatch    Case insensitive regular expression match,
                              searching 'SearchString' for the regular
                              expression given in 'pattern'.

         Constants for the values of 'mode' are defined in the
         'Constants' section below.

         searchColumn uses the POSIX extended regular expressions
         defined in POSIX 1003.2.

         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform SNMP operations on a system different
         from that of 'this element'.

         If a match is found, 'oid' is set to the OID of the matched
         value, and 1 is returned.  If the search traverses beyond
         columnoid or returns an error without finding a match, zero is
         returned, and 'oid' isn't modified.

         To find the first match, the caller should set 'oid' to the
         empty string.  To find additional matches, subsequent calls to
         searchColumn should have 'oid' set to the OID of the last
         match, an operation that searchColumn performs automatically.

         For example:
             To find an ethernet interface
             oid = "";
             searchColumn("ifType", oid, "6", 0);

         This sends a getnext request for ifType and continues to walk
         the tree until a value matching 6 is found or a variable
         returns that is not in the 'ifType' subtree.

         To find the next ethernet interface, assuming that interface 3
         was discovered to be the first:

             oid = "ifType.3";
             searchColumn("ifType", oid, "6", 0);

Top      Up      ToC       Page 38 
         In a loop to determine all the ethernet interfaces, this looks
         as follows:

             oid = "";
             while(searchColumn("ifType", oid, "6", 0)){
               /* Do something with oid */
             }

         Note that in the preceding examples, "ifType" is used as a
         notational convenience, and the actual code downloaded to the
         policy MIB agent must use the string "1.3.6.1.2.1.2.2.1.3" as
         there may be no MIB compiler (or MIB file) available on the
         policy MIB agent.

         Note that if the value of 'columnoid' is too short and thus
         references too much of the object identifier tree (e.g.,
         "1.3.6"), 'columnoid' could end up searching a huge number of
         variables (if the value was "1.3.6", it would search ALL
         variables on the agent).  It is the responsibility of the
         caller to make sure that 'columnoid' is set appropriately.

8.1.3.5.  setRowStatus()

      integer setRowStatus(string oid, integer maxTries
                           [, integer freeOnException , integer seed
                            , string contextName, NonLocalArgs])

         setRowStatus is used to automate the process of finding an
         unused row in a read-create table that uses RowStatus whose
         index contains an arbitrary integer component for uniqueness.

         'oid' is a string containing an ASCII dotted-decimal
         representation of an object identifier, with one of the subids
         replaced with a '*' character (e.g.,
         "1.3.6.1.3.1.99.1.2.1.9.*").  'oid' must reference an
         'instance' of the RowStatus object, and the '*' must replace
         any integer index item that may be set to some random value.

         setRowStatus will come up with a number for the selected index
         item and will attempt to create the instance with the
         createAndWait state.  If the attempt fails, it will retry with
         a different random index value.  It will attempt this no more
         than 'maxTries' times.

         If the optional 'freeOnException' argument is present and equal
         to 1, the agent will free this row by setting RowStatus to
         'destroy' if, later in the same script invocation, this script

Top      Up      ToC       Page 39 
         dies with a run-time exception or by a call to fail().  Note
         that this does not apply to exceptions experienced in
         subsequent invocations of the script.

         If the optional 'seed' argument is present, the initial index
         will be set to 'seed'.  Otherwise it will be random.  'seed'
         may not be present if the 'freeOnException' argument is not
         present.

         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform an SNMP operation on a system different
         from that of 'this element'.

         setRowStatus returns the successful integer value for the
         index.  If it is unsuccessful after 'maxTries', or if zero or
         more than one '*' is in OID, -1 will be returned.

         The createRow function (below) can also be used when adding
         rows to tables.  Although createRow has more functionality,
         setRowStatus may be preferable in certain situations (for
         example, to have the opportunity to inspect default values
         created by the agent).

8.1.3.6.  createRow()

      integer createRow(integer reqPDU, integer reqNumVarbinds,
                        integer statusColumn, integer maxTries,
                        integer indexRange,
                        integer &respPDU, integer &respNumVarbinds,
                        integer &index
                        [, integer freeOnException, string contextName,
                        NonLocalArgs])

         createRow is used to automate the process of creating a row in
         a read-create table whose index contains an arbitrary integer
         component for uniqueness.  In particular, it encapsulates the
         algorithm behind either the createAndWait or createAndGo
         mechanism and the algorithm for finding an unused row in the
         table.  createRow is not useful for creating rows in tables
         whose indexes don't contain an arbitrary integer component.

         createRow will perform the operation by sending 'reqPDU' and
         returning the results in 'respPDU'.  Both 'reqPDU' and

Top      Up      ToC       Page 40 
         'respPDU' must previously have been allocated with newPDU.
         'reqPDU' and 'respPDU' may both contain the same PDU handle, in
         which case the 'reqPDU' is sent and then replaced with the
         contents of the received PDU.

         'reqNumVarbinds' is an integer greater than zero that specifies
         which varbinds in the PDU will be used in this operation.  The
         first 'reqNumVarbinds' in the PDU are used.  Each such varbind
         must be of a special form in which the object name must have
         one of its subids replaced with a '*' character (e.g.,
         "1.3.6.1.3.1.99.1.2.1.9.*").  The subid selected to be replaced
         will be an integer index item that may be set to some random
         value.  The same subid should be selected in each varbind in
         the PDU.

         'respNumVarbinds' will be modified to contain the number of
         varbinds received in the last response PDU.

         'statusColumn' identifies which varbind in 'pdu' should be
         treated as the RowStatus column, where 0 identifies the 1st
         varbind.

         createRow will come up with a random integer index value and
         will substitute that value in place of the '*' subid in each
         varbind.  It will then set the value of the RowStatus column to
         select the 'createAndGo' mechanism and execute the set.  If the
         attempt fails due to the unavailability of the 'createAndGo'
         mechanism, it will retry with the 'createAndWait' mechanism
         selected.  If the attempt fails because the chosen index value
         is already in use, the operation will be retried with a
         different random index value.  It will continue to retry
         different index values until it succeeds, until it has made
         'maxTries' attempts, or until it encounters an error.  The
         value of 'maxTries' should be chosen to be high enough to
         minimize the chance that as the table fills up an attempt to
         create a new entry will 'collide' too often and fail.

         All random index values must be between 1 and 'indexRange',
         inclusive.  This is so that values are not attempted for an
         index that fall outside of that index's restricted range (e.g.,
         1..65535).

         If the optional 'freeOnException' argument is present and equal
         to 1, the agent will free this row by setting RowStatus to
         'destroy' if, later in the same script invocation, this script
         dies with a run-time exception or by a call to fail().  Note
         that this does not apply to exceptions experienced in
         subsequent invocations of the script.

Top      Up      ToC       Page 41 
         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         The optional 'NonLocalArgs' provide addressing and security
         information to perform an SNMP operation on a system different
         from that of 'this element'.

         Note that no actual SNMP PDU has to be generated and parsed
         when the policy MIB agent resides on the same system as the
         managed elements.  If no PDU is generated, the agent must
         correctly simulate the behavior of the SNMP Response PDU,
         particularly in case of an error.

         This function returns zero unless an error occurs, in which
         case it returns the proper SNMP Error Constant.  If an error
         occurred, respPDU will contain the last response PDU as
         received from the agent unless no response PDU was received, in
         which case respNumVarbinds will be 0.  In any event, readError
         may be called on the PDU to determine error information for the
         transaction.

         The 'index' parameter returns the chosen index.  If successful,
         'index' will be set to the successful integer index.  If no
         SNMP error occurs but the operation does not succeed due to the
         following reasons, 'index' will be set to -1:

            1) Unsuccessful after 'maxTries'.
            2) An object name had no '*' in it.
            3) An object name had more than one '*' in it.

         For example, createRow() might be used as follows:

         var index, pdu = newPDU(), nVars = 0;

         writeVar(pdu, nVars++, "hlHostControlDataSource.*",
                  "ifIndex." + ev(0), Oid);
         writeVar(pdu, nVars++, "hlHostControlNlMaxDesiredEntries.*",
                  1000, Integer);
         writeVar(pdu, nVars++, "hlHostControlAlMaxDesiredEntries.*",
                  1000, Integer);
         writeVar(pdu, nVars++, "hlHostControlOwner.*", "policy",
                  String);
         writeVar(pdu, nVars++, "hlHostControlStatus.*", "active(1)",
                  Integer);
         if (createRow(pdu, nVars, 4, 20, 65535,
                       pdu, nVars, index) != 0

Top      Up      ToC       Page 42 
             || index == -1)
             return;
         // index now contains index of new row

8.1.3.7.  counterRate()

   When a policy wishes to make a decision based on the rate of a
   counter, it faces a couple of problems:

   1. It may have to run every X minutes but have to make decisions on
      rates calculated over at least Y minutes, where Y > X.  This would
      require the complexity of managing a queue of old counter values.

   2. The policy script has no control over exactly when it will run.

   The counterRate() function is designed to surmount these problems
   easily.

      integer counterRate(string oid, integer minInterval
                          [, integer 64bit,
                          string discOid, integer discMethod,
                          string contextName, NonLocalArgs])

         'counterRate' retrieves the variable specified by oid once per
         invocation.  It keeps track of timestamped values retrieved on
         previous invocations by this execution context so that it can
         calculate a rate over a period longer than that since the last
         invocation.

         'oid' is the object identifier of the counter value that will
         be retrieved.  The most recent previously saved value of the
         same object identifier that is at least 'minInterval' seconds
         old will be subtracted from the newly retrieved value, yielding
         a delta.  If 'minInterval' is zero, this delta will be
         returned.  Otherwise, this delta will be divided by the number
         of seconds elapsed between the two retrievals, and the
         integer-valued result will be returned (rounding down when
         necessary).

         If there was no previously saved retrieval older than
         'minInterval' seconds, then -1 will be returned.  It is an RTE
         if the query returns noSuchName, noSuchInstance, or
         noSuchObject or an object that is not of type Counter32 or
         Counter64.

Top      Up      ToC       Page 43 
         The delta calculation will allow for 32-bit counter semantics
         if it encounters rollover between the two retrievals, unless
         the optional argument '64bit' is present and equal to 1, in
         which case it will allow for 64-bit counter semantics.

         'discOid' and 'discMethod' may only be present together.
         'discOid' contains an object identifier of a discontinuity
         indicator value that will be retrieved simultaneously with each
         counter value:

            1. If 'discMethod' is equal to 1 and the discontinuity
               indicator is less than the last one retrieved, then a
               discontinuity is indicated.
            2. If 'discMethod' is equal to 2 and the discontinuity
               indicated is different from the last one retrieved, then
               a discontinuity is indicated.

         If this value indicates a discontinuity, this counter value
         (and its timestamp) will be stored, but all previously stored
         counter values will be invalidated and -1 will be returned.

         The implementation will have to store a number of timestamped
         counter values.  The implementation must keep all values that
         are newer than minInterval seconds, plus the newest value that
         is older than minInterval seconds.  Other than this one value
         that is older than minInterval seconds, the implementation
         should discard any older values.

         For example:
           Policy that executes every 60 seconds:
               rate = counterRate("ifInOctets.$*", 300);
               if (rate > 1000000)
                   ...

         Another example, with a discontinuity indicator:

           Policy that executes every 60 seconds:
               rate = counterRate("ifInOctets.$*", 300, 0,
                                  "sysUpTime.0", 1);
               if (rate > 1000000)
                   ...

         Another example, with zero minInterval:
           Policy that executes every 60 seconds:
               delta = counterRate("ifInErrors.$*", 0);
               if (delta > 100)
                   ...

Top      Up      ToC       Page 44 
         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

8.1.4.  General SNMP Functions

   It is desirable that a general SNMP interface have the ability to
   perform SNMP operations on multiple variables at once and that it
   allow multiple varbind lists to exist at once.  The newPdu, readVar,
   and writeVar functions exist to provide these facilities in a
   language without pointers, arrays, and memory allocators.

   newPDU is called to allocate a PDU and return an integer handle to
   it.  As PDUs are automatically freed when the script exits and can be
   reused during execution, there is no freePDU().

   readVar and writeVar access a variable length varbind list for a PDU.
   The PDU handle and the index of the variable within that PDU are
   specified in every readVar and writeVar operation.  Once a PDU has
   been fully specified by one or more calls to writeVar, it is passed
   to snmpSend (by referencing the PDU handle) and the number of
   varbinds to be included in the operation.  When a response is
   returned, the contents of the response are returned in another PDU
   and may be read by one or more calls to readVar.  Error information
   may be read from the PDU with the readError function.  Because
   GetBulk PDUs send additional information in the SNMP header, the
   writeBulkParameters function is provided to configure these
   parameters.

   Varbinds in this data store are created automatically whenever they
   are written by any writeVar or snmpSend operation.

   For example:
     var pdu = newPDU();
     var nVars = 0, oid, type, value;

     writeVar(pdu, nVars++, "sysDescr.0", "", Null);
     writeVar(pdu, nVars++, "sysOID.0", "", Null);
     writeVar(pdu, nVars++, "ifNumber.0", "", Null);
     if (snmpSend(pdu, nVars, Get, pdu, nVars))
         return;
     readVar(pdu, 0, oid, value, type);
     readVar(pdu, 1, oid, value, type);
     readVar(pdu, 2, oid, value, type);
     ...

Top      Up      ToC       Page 45 
   or,
     var pdu = newPDU();
     var nVars = 0, oid1, oid2;

     writeVar(pdu, nVars++, "ifIndex", "", Null);
     writeVar(pdu, nVars++, "ifType", "", Null);
     while(!done){
       if (snmpSend(pdu, nVars, Getnext, pdu, nVars))
           continue;
       readVar(pdu, 0, oid1, value, type);
       readVar(pdu, 1, oid2, value, type);
       /* leave OIDs alone, now PDU #0 is set up for next step
          in table walk. */
       if (oidncmp(oid1, "ifIndex", oidlen("ifIndex")))
         done = 0;
       ...
     }

   Note that in the preceding examples, descriptors such as ifType and
   sysDescr are used in object identifiers solely as a notational
   convenience.  The actual code downloaded to the policy MIB agent must
   use a dotted decimal notation only, as there may be no MIB compiler
   (or MIB file) available on the policy MIB agent.

   To conform to this specification, implementations must allow each
   policy script invocation to allocate at least 5 PDUs with at least 64
   varbinds per list.  It is suggested that implementations limit the
   total number of PDUs per invocation to protect other script
   invocations from a malfunctioning script (e.g., a script that calls
   newPDU() in a loop).

8.1.4.1.  newPDU()

      integer newPDU()

         newPDU will allocate a new PDU and return a handle to the PDU.
         If no PDU could be allocated, -1 will be returned.  The PDU's
         initial values of nonRepeaters and maxRepetitions will be zero.

8.1.4.2.  writeVar()

      writeVar(integer pdu, integer varBindIndex,
               string oid, var value, integer type)

         writeVar will store 'oid', 'value', and 'type' in the specified
         varbind.

         'pdu' is the handle to a PDU allocated by newPDU().

Top      Up      ToC       Page 46 
         'varBindIndex' is a non-negative integer that identifies the
         varbind within the specified PDU modified by this call.  The
         first varbind is number 0.

         'oid' is a string containing an ASCII dotted-decimal
         representation of an object identifier (e.g.,
         "1.3.6.1.2.1.1.1.0").

         'value' is the value to be stored, of a type appropriate to the
         'type' parameter.

         'type' will be the type of the value parameter and will be set
         to one of the values for DataType Constants.

         It is an RTE if any of the parameters don't conform to the
         rules above.

8.1.4.3.  readVar()

      readVar(integer pdu, integer varBindIndex, string &oid,
              var &value, integer &type)

         readVar will retrieve the oid, the value, and its type from the
         specified varbind.

         'pdu' is the handle to a PDU allocated by newPDU().

         'varBindIndex' is a non-negative integer that identifies the
         varbind within the specified PDU read by this call.  The first
         varbind is number 0.

         The object identifier value of the referenced varbind will be
         copied into the 'oid' parameter, formatted in an ASCII dotted-
         decimal representation (e.g., "1.3.6.1.2.1.1.1.0").

         'value' is the value retrieved, of a type appropriate to the
         'type' parameter.

         'type' is the type of the value parameter and will be set to
         one of the values for DataType Constants.

         It is an RTE if 'pdu' doesn't reference a valid PDU or
         'varBindIndex' doesn't reference a valid varbind.

Top      Up      ToC       Page 47 
8.1.4.4.  snmpSend()

      integer snmpSend(integer reqPDU, integer reqNumVarbinds,
                       integer opcode,
                       integer &respPDU, integer &respNumVarbinds,
                       [, string contextName , NonLocalArgs] )

         snmpSend will perform an SNMP operation by sending 'reqPDU' and
         returning the results in 'respPDU'.  Both 'reqPDU' and
         'respPDU' must previously have been allocated with newPDU.
         'reqPDU' and 'respPDU' may both contain the same PDU handle, in
         which case the 'reqPDU' is sent and then replaced with the
         contents of the received PDU.  If the opcode specifies a Trap
         or V2trap, 'respPDU' will not be modified.

         'reqNumVarbinds' is an integer greater than zero that specifies
         which varbinds in the PDU will be used in this operation.  The
         first 'reqNumVarbinds' in the PDU are used.  'respNumVarbinds'
         will be modified to contain the number of varbinds received in
         the response PDU, which, in the case of GetBulk or an error,
         may be substantially different from reqNumVarbinds.

         'opcode' is the type of SNMP operation to perform and must be
         one of the values for SNMP Operation Constants listed in the
         'Constants' section below.

         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

         Note that no actual SNMP PDU has to be generated and parsed
         when the policy MIB agent resides on the same system as the
         managed elements.  If no PDU is generated, the agent must
         correctly simulate the behavior of the SNMP Response PDU,
         particularly in case of an error.

         This function returns zero unless an error occurs, in which
         case it returns the proper SNMP Error Constant.  If an error
         occurred, respPDU will contain the response PDU as received
         from the agent, unless no response PDU was received, in which
         case respNumVarbinds will be 0.  In any event, readError may be
         called on the PDU to determine error information for the
         transaction.

         If an SNMP Version 1 trap is requested (the opcode is Trap(4)),
         then SNMP Version 2 trap parameters are supplied and converted
         according to the rules of RFC 3584 [8], section 3.2.  The first

Top      Up      ToC       Page 48 
         variable binding must be sysUpTime.0, and the second must be
         snmpTrapOID.0, as per RFC 3416 [7], section 4.2.6.  Subsequent
         variable bindings are copied to the SNMP Version 1 trap PDU in
         the usual fashion.

8.1.4.5.  readError()

      readError(integer pdu, integer numVarbinds, integer &errorStatus,
                integer &errorIndex, integer &hasException)

         Returns the error information in a PDU.

         'errorStatus' contains the error-status field from the response
         PDU or a local error constant if the error was generated
         locally.  If no error was experienced or no PDU was ever copied
         into this PDU, this value will be 0.

         'errorIndex' contains the error-index field from the response
         PDU.  If no PDU was ever copied into this PDU, this value will
         be 0.

         'hasException' will be 1 if any of the first 'numVarbinds'
         varbinds in the PDU contain an exception (Nosuchobject,
         Nosuchinstance, Endofmibview); otherwise it will be 0.

         It is an RTE if 'pdu' does not reference a valid PDU or if
         'numVarbinds' references varbinds that aren't valid.

8.1.4.6.  writeBulkParameters()

      writeBulkParameters(integer pdu, integer nonRepeaters,
                          integer maxRepetitions)

         Modifies the parameters in a PDU in any subsequent GetBulk
         operation sent by the PDU.  'nonRepeaters' will be copied into
         the PDU's non-repeaters field, and 'maxRepetitions' into the
         max-repetitions field.

         This function may be called before or after writeVar is called
         to add varbinds to the PDU, but it must be called before the
         PDU is sent; otherwise, it will have no effect.  A new PDU is
         initialized with nonRepeaters set to zero and maxRepetitions
         set to zero.  If a Bulk PDU is sent before writeBulkParameters
         is called, these default values will be used.  If
         writeBulkParameters is called to modify a PDU, it is acceptable
         if this PDU is later sent as a type other than bulk.  The
         writeBulkParameters call will only affect subsequent sends of
         Bulk PDUs.  If a PDU is used to receive the contents of a

Top      Up      ToC       Page 49 
         response, the values of nonRepeaters and maxRepetitions are
         never modified.

8.1.5.  Constants for SNMP Library Functions

   The following constants are defined for use with all SNMP Library
   Functions.  Policy code will be executed in an environment where the
   following constants are declared.  (Note that the constant
   declarations below will not be visible in the policyCondition or
   policyAction code.)  These constants are reserved words and cannot be
   used for any variable or function name.

   Although these declarations are expressed here as C 'const's, the
   'const' construct itself is not available to be used in policy code.

   // Datatype Constants

   // From RFC 2578 [2]
   const integer Integer       = 2;
   const integer Integer32     = 2;
   const integer String        = 4;
   const integer Bits          = 4;
   const integer Null          = 5;
   const integer Oid           = 6;
   const integer IpAddress     = 64;
   const integer Counter32     = 65;
   const integer Gauge32       = 66;
   const integer Unsigned32    = 66;
   const integer TimeTicks     = 67;
   const integer Opaque        = 68;
   const integer Counter64     = 70;

   // SNMP Exceptions from RFC 3416 [7]
   const integer NoSuchObject         = 128;
   const integer NoSuchInstance       = 129;
   const integer EndOfMibView         = 130;

   // SNMP Error Constants from RFC 3416 [7]
   const integer NoError              = 0;
   const integer TooBig               = 1;
   const integer NoSuchName           = 2;
   const integer BadValue             = 3;
   const integer ReadOnly             = 4;
   const integer GenErr               = 5;
   const integer NoAccess             = 6;
   const integer WrongType            = 7;
   const integer WrongLength          = 8;
   const integer WrongEncoding        = 9;

Top      Up      ToC       Page 50 
   const integer WrongValue           = 10;
   const integer NoCreation           = 11;
   const integer InconsistentValue    = 12;
   const integer ResourceUnavailable  = 13;
   const integer CommitFailed         = 14;
   const integer UndoFailed           = 15;
   const integer AuthorizationError   = 16;
   const integer NotWritable          = 17;
   const integer InconsistentName     = 18;

   // "Local" Errors
   // These are also possible choices for errorStatus returns
   // For example: unknown PDU, maxVarbinds is bigger than number
   // written with writeVar, unknown opcode, etc.
   const integer BadParameter         = 1000;

   // Request would have created a PDU larger than local limitations
   const integer TooLong              = 1001;

   // A response to the request was received but errors were encountered
   // when parsing it.
   const integer ParseError           = 1002;

   // Local system has complained of an authentication failure
   const integer AuthFailure          = 1003;

   // No valid response was received in a timely fashion
   const integer TimedOut             = 1004;

   // General local failure including lack of resources
   const integer GeneralFailure       = 1005;

   // SNMP Operation Constants from RFC 3416 [7]
   const integer Get                  = 0;
   const integer Getnext              = 1;
   const integer Set                  = 3;
   const integer Trap                 = 4;
   const integer Getbulk              = 5;
   const integer Inform               = 6;
   const integer V2trap               = 7;

   // Constants from RFC 3411 [1] for SnmpMessageProcessingModel
   const integer SNMPv1              = 0;
   const integer SNMPv2c             = 1;
   const integer SNMPv3              = 3;

Top      Up      ToC       Page 51 
   // Constants from RFC 3411 [1] for SnmpSecurityModel
   const integer SNMPv1              = 1;
   const integer SNMPv2c             = 2;
   const integer USM                 = 3;

   // SnmpSecurityLevel Constants from RFC 3411 [1]
   const integer NoAuthNoPriv        = 1;
   const integer AuthNoPriv          = 2;
   const integer AuthPriv            = 3;

   // Constants for use with searchColumn
   const integer ExactMatch          = 0;
   const integer ExactCaseMatch      = 1;
   const integer SubstringMatch      = 2;
   const integer SubstringCaseMatch  = 3;
   const integer RegexpMatch         = 4;
   const integer RegexpCaseMatch     = 5;

8.2.  Policy Library Functions

   Policy Library Functions provide access to information specifically
   related to the execution of policies.

8.2.1.  elementName()

   The elementName() function is used to determine what the current
   element is and can be used to provide information about the type of
   element and how it is indexed.

      string elementName()

         elementName returns a string containing an ASCII dotted-decimal
         representation of an object identifier (e.g.,
         1.3.6.1.2.1.1.1.0).  This object identifier identifies an
         instance of a MIB object that is an attribute of 'this
         element'.

8.2.2.  elementAddress()

      elementAddress(&tDomain, &tAddress)

         elementAddress finds a domain/address pair that can be used to
         access 'this element' and returns the values in 'tDomain' and
         'tAddress'.

Top      Up      ToC       Page 52 
8.2.3.  elementContext()

      string elementContext()

         elementContext() returns a string containing the SNMP
         contextName of 'this element'.

8.2.4.  ec()

   The ec() (element count) and ev() (element value) functions provide
   convenient access to the components of the index for 'this element'.
   Typical uses will be in creating the index to other, related
   elements.

      integer ec()

         ec() returns an integer count of the number of index
         subidentifiers that exist in the index for 'this element'.

8.2.5.  ev()

      integer ev(integer n)

         ev() returns the value of the nth subidentifier in the index
         for 'this element'.  The first subidentifier is indexed at 0.
         It is an RTE if n specifies a subidentifier beyond the last
         subidentifier.

8.2.6.  roleMatch()

   The roleMatch() function is used to check whether an element has been
   assigned a particular role.

      integer roleMatch(string roleString [, string element,
                        string contextName, string contextEngineID])

         'roleString' is a string.  The optional argument 'element'
         contains the OID name of an element, defaulting to the current
         element if 'element' is not supplied.  If roleString exactly
         matches (content and length) any role assigned to the specified
         element, the function returns 1.  If no roles match, the
         function returns 0.

         The optional 'contextName' argument contains the SNMP context
         on which to operate.  If 'contextName' is not present, the
         contextName of 'this element' will be used.  If 'contextName'
         is the zero-length string, the default context is used.

Top      Up      ToC       Page 53 
         'contextEngineID' contains the contextEngineID of the remote
         system on which 'element' resides.  It is encoded as a pair of
         hex digits (upper- and lowercase are valid) for each octet of
         the contextEngineID.  If 'contextEngineID' is not present, the
         contextEngineID of 'this element' will be used.
         'contextEngineID' may only be present if the 'element' and
         'context' arguments are present.

8.2.7.  Scratchpad Functions

   Every maxLatency time period, every policy runs once for each
   element.  When the setScratchpad function executes, it stores a value
   named by a string that can be retrieved with getScratchpad() even
   after this policy execution code exits.  This allows sharing of data
   between a condition and an action, two conditions executing on
   different elements, or even different policies altogether.

   The value of 'scope' controls which policy/element combinations can
   retrieve this 'varName'/'value' pair.  The following are options for
   'scope':

      Global
         The 'varName'/'value' combination will be available in the
         condition or action of any policy while it is executing on any
         element.  Note that any information placed here will be visible
         to all other scripts on this system regardless of their
         authority.  Sensitive information should not be placed in
         global scratchpad variables.

      Policy
         The 'varName'/'value' combination will be available in any
         future execution of the condition or action of the current
         policy (regardless of what element the policy is executing on).
         If a policy is ever deleted, or if its condition or action code
         is modified, all values in its 'Policy' scope will be deleted.

      PolicyElement
         The 'varName'/'value' combination will be available in future
         executions of the condition or action of the current policy,
         but only when the policy is executing on the current element.
         If a policy is ever deleted, or if its condition or action code
         is modified, all values in its 'PolicyElement' scope will be
         deleted.  The agent may also periodically delete values in a
         'PolicyElement' scope if the corresponding element does not
         exist (in other words, if an element disappears for a period
         and reappears, values in its 'PolicyElement' scope may or may
         not be deleted).

Top      Up      ToC       Page 54 
   setScratchpad's 'storageType' argument allows the script to control
   the lifetime of a variable stored in the scratchpad.  If the
   storageType is equal to the constant 'volatile', then this variable
   must be deleted on a reboot.  If it is equal to 'nonVolatile', then
   this variable should be stored in non-volatile storage, where it will
   be available after a reboot.  If the 'storageType' argument is not
   present, the variable will be volatile and will be erased on reboot.

   If the optional 'freeOnException' argument is present and equal to 1,
   the agent will free this variable if, later in the same script
   invocation, this script dies with a run-time exception or by a call
   to fail().  (Note that this does not apply to exceptions experienced
   in subsequent invocations of the script.)

   Note that there may be implementation-specific limits on the number
   of scratchpad variables that can be allocated.  The limit of unique
   scratchpad variables may be different for each scope or storageType.
   It is suggested that implementations limit the total number of
   scratchpad variables per script to protect other scripts from a
   malfunctioning script.  In addition, compliant implementations must
   support at least 50 Global variables, 5 Policy variables per policy,
   and 5 PolicyElement variables per policy-element pair.

   Scratchpad Usage Examples

   Policy  Element    Action
   A       ifIndex.1  setScratchpad(Global, "foo", "55")
   A       ifIndex.1  getScratchpad(Global, "foo", val) --> 55
   A       ifIndex.2  getScratchpad(Global, "foo", val) --> 55
   B       ifIndex.2  getScratchpad(Global, "foo", val) --> 55
   B       ifIndex.2  setScratchpad(Global, "foo", "16")
   A       ifIndex.1  getScratchpad(Global, "foo", val) --> 16

   Policy  Element    Action
   A       ifIndex.1  setScratchpad(Policy, "bar", "75")
   A       ifIndex.1  getScratchpad(Policy, "bar", val) --> 75
   A       ifIndex.2  getScratchpad(Policy, "bar", val) --> 75
   B       ifIndex.1  getScratchpad(Policy, "bar", val) not found
   B       ifIndex.1  setScratchpad(Policy, "bar", "20")
   A       ifIndex.2  getScratchpad(Policy, "bar", val) --> 75
   B       ifIndex.2  getScratchpad(Policy, "bar", val) --> 20

   Policy  Element    Action
   A       ifIndex.1  setScratchpad(PolicyElement, "baz", "43")
   A       ifIndex.1  getScratchpad(PolicyElement, "baz", val) --> 43
   A       ifIndex.2  getScratchpad(PolicyElement, "baz", val) not found
   B       ifIndex.1  getScratchpad(PolicyElement, "baz", val) not found
   A       ifIndex.2  setScratchpad(PolicyElement, "baz", "54")

Top      Up      ToC       Page 55 
   B       ifIndex.1  setScratchpad(PolicyElement, "baz", "65")
   A       ifIndex.1  getScratchpad(PolicyElement, "baz", val) --> 43
   A       ifIndex.2  getScratchpad(PolicyElement, "baz", val) --> 54
   B       ifIndex.1  getScratchpad(PolicyElement, "baz", val) --> 65

   Policy  Element    Action
   A       ifIndex.1  setScratchpad(PolicyElement, "foo", "11")
   A       ifIndex.1  setScratchpad(Global,        "foo", "22")
   A       ifIndex.1  getScratchpad(PolicyElement, "foo", val) --> 11
   A       ifIndex.1  getScratchpad(Global,        "foo", val) --> 22

   Constants

   The following constants are defined for use with the scratchpad
   functions.  Policy code will be executed in an environment where the
   following constants are declared.  (Note that these constant
   declarations will not be visible in the policyCondition or
   policyAction MIB objects.)

   Although these declarations are expressed here as C 'const's, the
   'const' construct itself is not available to be used inside of policy
   code.

   // Scratchpad Constants

   // Values of scope
   const integer Global           = 0;
   const integer Policy           = 1;
   const integer PolicyElement    = 2;

   // Values of storageType
   const integer Volatile         = 0;
   const integer NonVolatile      = 1;

8.2.8.  setScratchpad()

      setScratchpad(integer scope, string varName [, string value,
                    integer storageType, integer freeOnException ])

         The setScratchpad function stores a value that can be retrieved
         even after this policy execution code exits.

         The value of 'scope' controls which policy/element combinations
         can retrieve this 'varName'/'value' pair.  The options for
         'scope' are Global, Policy, and PolicyElement.

Top      Up      ToC       Page 56 
         'varName' is a string used to identify the value.  Subsequent
         retrievals of the same 'varName' in the proper scope will
         return the value stored.  Note that the namespace for 'varName'
         is distinct for each scope.  'varName' is case sensitive.

         'value' is a string containing the value to be stored.
         ToString(value) is called on 'value' to convert it to a string
         before storage.

         If the 'value' argument is missing, the 'varName' in scope
         'scope' will be deleted if it exists.

         If the optional 'storageType' argument is present and is equal
         to the constant 'Volatile', then this variable must be deleted
         on a reboot.  If it is equal to 'NonVolatile', then this
         variable should be stored in non-volatile storage, where it
         will be available after a reboot.  If the 'storageType'
         argument is not present, the variable will be volatile and will
         be erased on reboot.  'storageType' may not be present if the
         'value' argument is not present.  If the variable already
         existed, its previous storageType is updated according to the
         current 'storageType' argument.

         If the optional 'freeOnException' argument is present and equal
         to 1, the agent will free this variable if, later in the same
         script invocation, this script dies with a run-time exception
         or by a call to fail().  (Note that this does not apply to
         exceptions experienced in subsequent invocations of the
         script.)

8.2.9.  getScratchpad()

      integer getScratchpad(integer scope, string varName,
                            string &value)

         The getScratchpad function allows the retrieval of values that
         were stored previously in this execution context or in other
         execution contexts.  The value of 'scope' controls which
         execution contexts can pass a value to this execution context.
         The options for 'scope' are Global, Policy, and PolicyElement.

         'varName' is a string used to identify the value.  Subsequent
         retrievals of the same 'varName' in the proper scope will
         return the value stored.  Note that the namespace for varName
         is distinct for each scope.  As a result, getScratchpad cannot
         force access to a variable in an inaccessible scope; it can
         only retrieve variables by referencing the proper scope in
         which they were set.  'varName' is case sensitive.

Top      Up      ToC       Page 57 
         On successful return, 'value' will be set to the value that was
         previously stored; otherwise, 'value' will not be modified.

         This function returns 1 if a value was previously stored and 0
         otherwise.

8.2.10.  signalError()

   The signalError() function is used by the script to indicate to a
   management station that it is experiencing abnormal behavior.
   signalError() turns on the conditionUserSignal(3) or
   actionUserSignal(5) bit in the associated pmTrackingPEInfo object
   (subsequent calls to signalError() have no additional effect).  This
   bit is initially cleared at the beginning of each execution.  If,
   upon a subsequent execution, the script finishes without calling
   signalError, the bit will be cleared.

      signalError()

         The signalException function takes no arguments and returns no
         value.

8.2.11.  defer()

   Precedence groups enforce the rule that for each element, of the
   ready policies that match the condition, only the one with the
   highest precedence value will be active.  Unfortunately, once the
   winning policy has been selected and the action begins running,
   situations can occur in which the policy script determines that it
   cannot complete its task.  In many such cases, it is desirable that
   the next runner-up ready policy be executed.  In the previous
   example, it would be desirable that at least bronze behavior be
   configured if gold is appropriate but gold isn't possible.

   When a policy defers, it exits, and the ready, condition-matching
   policy with the next-highest precedence is immediately run.  Because
   this might also defer, the execution environment must remember where
   it is in the precedence chain so that it can continue going down the
   chain until an action completes without deferring, or until no
   policies are left in the precedence group.  Once a policy finishes
   successfully, the next iteration will begin at the top of the
   precedence chain.

   There are two ways to defer.  A script can exit by calling fail() and
   specify that it should defer immediately.  Alternately, a script can
   instruct the execution environment to defer automatically in the
   event of a run-time exception.

Top      Up      ToC       Page 58 
      defer(integer deferOnRTE)

         The defer function changes the run-time exception behavior of a
         script.  By default, a script will not defer when it encounters
         an RTE.  If defer(1) is called, the exit behavior is changed so
         that the script will defer when it is terminated due to an RTE.
         If defer(0) is called, the script is reset to its default
         behavior and will not defer.

         Note that calling defer doesn't cause the script to exit.
         Defer only changes the default behavior if an RTE occurs later
         in this invocation.

8.2.12.  fail()

      fail(integer defer, integer free [, string message] )

         The fail function causes the script to optionally perform
         certain functions and then exit.

         If 'defer' is 1, this script will defer to the next lower
         precedence ready policy in the same precedence group whose
         condition matches.  If 'defer' isn't 1, it will not defer.
         Note that if a condition defers, it is functionally equivalent
         to the condition returning false.

         If 'free' is 1, certain registered resources will be freed.
         If, earlier in this script invocation, any rows were created by
         createRow with the 'freeOnException' option, the execution
         environment will set the RowStatus of each row to 'destroy' to
         delete the row.  Further, if earlier in this script invocation
         any scratchpad variables were created or modified with the
         'freeOnException' option, they will be deleted.

         If the optional 'message' argument is present, it will be
         logged to the debugging table if pmPolicyDebugging is turned on
         for this policy.

         This function does not return.  Instead, the script will
         terminate.

8.2.13.  getParameters()

   From time to time, policy scripts may be parameterized so that they
   are supplied with one or more parameters (e.g., site-specific
   constants).  These parameters may be installed in the
   pmPolicyParameters object and are accessible to the script via the
   getParameters() function.  If it is necessary for multiple parameters

Top      Up      ToC       Page 59 
   to be passed to the script, the script can choose whatever
   encoding/delimiting mechanism is most appropriate so that the
   multiple parameters can be stored in the associated instance of
   pmPolicyParameters.

      string getParameters()

         The getParameters function takes no arguments.  It returns a
         string containing the value of the pmPolicyParameters object
         for the running policy.

   For example, if a policy is to apply to "slow speed interfaces" and
   the cutoff point for slow speed should be parameterized, the policy
   filter should be:

      getVar("ifSpeed.$*") == getParameters()

   In this example, one can store the string "128000" in the policy's
   pmPolicyParameters object to cause this policy to act on all 128 Kbps
   interfaces.



(page 59 continued on part 3)

Next RFC Part