📄 rfc1076.txt
字号:
Trewitt & Partridge [Page 21]
RFC 1076 HEMS Monitoring and Control Language November 1988
there is an enormous amount of data about each), then you have to
have some way to name it. One possibility would be to just number
the interfaces and refer to the desired interface as
InterfaceData(3)
for the third one.
But this is not sufficient, because interface numbers may change over
time, perhaps from one reboot to the next. It is even worse when
dealing with arrays with many elements, such as routing tables, TCP
connections, etc. Large, changing arrays are probably the more
common case, in fact. Because of the lack of utility of indexing in
this context, there is no general mechanism provided in the language
for indexing.
A better scheme is to select objects based upon some value contained
in them, such as the IP address. The query language uses filters to
select specific table entries that an operator will operate on. The
operators BEGIN, GET, GET-ATTRIBUTES, SET, and DELETE can take a
filter argument that restricts their operation to entries that match
the filter.
A filter is a boolean expression that is executed for each element in
an array. If an array entry "matches" the filter (i.e., if the filter
produces a "true" result), then it is used by the operation. A
filter expression is very restricted: it can only compare data
contained in the array element and the comparisons are only against
constants. Comparisons may be connected by AND, OR and NOT
operators.
The ASN.1 definition of a filter is:
Filter ::= [APPLICATION 2] CHOICE {
present [0] DataPath,
equal [1] DataValue,
greaterOrEqual [2] DataValue,
lessOrEqual [3] DataValue,
and [4] SEQUENCE OF Filter,
or [5] SEQUENCE OF Filter,
not [6] Filter
}
DataPath ::= ANY -- Path with no value
DataValue ::= ANY -- Single data value
This definition is similar to the filters used in the ISO monitoring
protocol (CMIP) and was derived from that specification.
Trewitt & Partridge [Page 22]
RFC 1076 HEMS Monitoring and Control Language November 1988
"DataPath" is the name of a single data item; "DataValue" is the
value of a single data item. The three comparisons are all of the
form "data OP constant", where "data" is the value from the tree,
"constant" is the value from the filter expression, and "OP" is one
of equal, greater-than-or-equal, or less-than-or-equal. The last
operation, "present", tests to see if the named item exists in the
data tree. By its nature, it requires no value, so only a path needs
to be given.
Here is an example of a filter that matches an Interface whose IP
address is 10.1.0.1:
Filter{ equal{ address(10.0.0.51) } }
Note that the name of the data to be compared is relative to the
"InterfaceData" dictionary.
Each operator, when given a filter argument, takes an array
(dictionary containing only one type of item) as its first argument.
In the current example, this would be "Interfaces". The items in it
are all of type "InterfaceData". This tag is referred to as the
"iteration tag".
Before a filtered operation is used, BEGIN must be used to put the
array (dictionary) on top of the stack, to establish it as the
context that the filter iterates over. The general operation of a
filtered operation is then:
1. Iterate over the items in the array.
2. For each element in the array, execute the filter.
3. If the filter succeeds, do the requested operation
(GET/SET/etc.) on the matched element, using the
template/value/path as input to the operation. At this
point, the execution of the operation is the same as in
the non-filtered case.
This is a model of operation; actual implementations may take
advantage of whatever lookup techniques are available for the
particular table (array) involved.
Therefore, there are three inputs to a filtered operation:
1. The "current dictionary" on the stack. This is the
array-type dictionary to be searched, set by an earlier
BEGIN.
2. A filter, to test each item in the array. Each path or
value mentioned in the filter must be named in the context
Trewitt & Partridge [Page 23]
RFC 1076 HEMS Monitoring and Control Language November 1988
of an item in the array, as if it was the current
dictionary. For example, in the case where a filtered
operation iterates over the set of "InterfaceData" items
in the "Interfaces" array, each value or path in the
filter should name an item in the "InterfaceData"
dictionary, such as "address".
3. A template, path, or value associated with the operation
to be performed. The leading ASN.1 tag in this must match
the iteration tag. In the current example where the
filter is searching the "Interfaces" dictionary, the first
tag in the template/tag/value must be "InterfaceData".
The operators which take filters as arguments are:
BEGIN array path filter BEGIN array dict
Find a dictionary in <array> that matches <filter>. Use
that as the starting point for <path> and push the
dictionary corresponding to <path> onto the stack. If more
than one dictionary matches <filter>, then any of the
matches may be used. This specification does not state how
the choice is made. At least one dictionary must match; it
is an error if there are no matches. (Perhaps it should be
an error for there to be multiple matches; actual
experience is needed to decide.)
GET array template filter GET array
For each item in <array> that matches <filter>, fill in the
template with values from the data tree and emit the
result. The first tag of <template> must be equal to the
iteration tag. Selected parts of matched items are emitted
based upon <template>, just as in a non-filtered GET
operation.
GET-ATTRIBUTES
array template filter GET-ATTRIBUTES array
Same as GET, except emit attributes rather than data
values.
SET array value filter SET array
Same as GET, except set the values in <value> rather than
retrieving values. Several values in the data tree will be
changed if the filter matches more than one item in the
array.
DELETE array filter DELETE array
Delete the entry(s) in <array> that match <filter>.
Trewitt & Partridge [Page 24]
RFC 1076 HEMS Monitoring and Control Language November 1988
Notes about filter execution:
- Expressions are executed by inorder tree traversal.
- Since the filter operations are all GETs and comparisons,
there are no side-effects to filter execution, so an
implementation is free to execute only as much of the
filter as required to produce a result (e.g., don't execute
the rest of an AND if the first comparison turns out to be
false).
- It is not an error for a filter to test a data item that
isn't in the data tree. In this situation, the comparison
just fails (is false). This means that filters don't need
to test for the existence of optional data before
attempting to compare it.
Here is an example of how filtering would be used to obtain the input
and output packet counts for the interface with IP address 10.0.0.51.
Interfaces BEGIN -- dictionary
InterfaceData{ pktsIn, pktsOut } -- template
Filter{ equal{ address(10.0.0.51) } }
GET
END -- finished with dict
The returned value would be something like:
Interfaces{ -- BEGIN
InterfaceData{ pktsIn(1345134), pktsOut(1023729) }
-- GET
} -- END
The annotations indicate which part of the response is generated by
the different operators in the query.
Here is an example of accessing a table contained within some other
table. Suppose we want to get at the ARP table for the interface
with IP address 36.8.0.1 and retrieve the entire ARP entry for the
host with IP address 36.8.0.23. In order to retrieve a single entry
in the ARP table (using a filtered GET), a BEGIN must be used to get
down to the ARP table. Since the ARP table is contained within the
Interfaces dictionary (an array), a filtered BEGIN must be used.
Interfaces BEGIN -- dictionary
InterfaceData{ ARP } -- path
Filter{ equal{ address(36.8.0.1) } } -- filter
BEGIN -- filtered BEGIN
Trewitt & Partridge [Page 25]
RFC 1076 HEMS Monitoring and Control Language November 1988
-- Now in ARP table for 38.0.0.1; get entry for 38.8.0.23.
addrMap -- whole entry
Filter{ equal{ ipAddr(36.8.0.23) } } -- filter
GET -- filtered GET
END
END
The result would be:
Interfaces{ -- first BEGIN
InterfaceData{ ARP{ -- second BEGIN
addrMap{ ipAddr(36.8.0.23), physAddr(..) } -- from GET
} } -- first END
} -- second END
Note which parts of the output are generated by different parts of
the query.
Here is an example of how the SET operator would be used to shut down
the interface with ip-address 10.0.0.51 by changing its status to
"down".
Interfaces BEGIN -- get dictionary
Interface{ Status(down) } -- value to set
Filter{ equal{ IP-addr(10.0.0.51) } }
SET
END
If the SET is successful, the result would be:
Interfaces{ -- BEGIN
Interface{ Status(down) } -- from SET
} -- END
8.7 Terminating a Query
A query is implicitly terminated when there are no more ASN.1 objects
to be processed by the interpreter. For a perfectly-formed query,
the interpreter would be back in the state it was when it started:
the stack would have only the root dictionary on it, and all of the
ASN.1 objects in the result would be terminated.
If there are still "open" ASN.1 objects in the result (caused by
leaving ENDs off of the query), then these are closed, as if a
sufficient number of ENDs were provided. This condition would be
indicated by the existence of dictionaries other than the root
dictionary on the stack.
Trewitt & Partridge [Page 26]
RFC 1076 HEMS Monitoring and Control Language November 1988
If an extra END is received that would pop the root dictionary off of
the stack, the query is terminated immediately. No error is
generated.
9. EXTENDING THE SET OF VALUES
There are two ways to extend the set of values understood by the
query language. The first is to register the data and its meaning
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -