📄 rfc1076.txt
字号:
and will always be written as ID("some arbitrary string") in this RFC. There are situations where it is necessary to specify a type but give no value, such as when referring to the name of the data. In this situation, the same notation is used, but with the value omitted: ID or ID() or ID{} Such objects have zero length and no contents. The latter two forms are used when a distinction is being made between simple and composite data, but the difference is just notation -- the representation is the same. ASN.1 distinguishes between four "classes" of tags: universal, application-specific, context-dependent, and reserved. HEMS and this query language use the first three. Universal tags are assigned in the ASN.1 standard and its addendums for common types, and are understood by any application using ASN.1. Application-specific tags are limited in scope to a particular application. These are used for "well-known" identifiers that must be recognizable in any context, such as derived data types. Finally, context-dependent tags are used for objects whose meaning is dependent upon where they are encountered. Most tags that identify data are context-dependent.5. DATA ORGANIZATION Data in a monitored entity is modeled as a hierarchy. Implementations are not required to organize the data internally as a hierarchy, but they must provide this view of the data through the query language. A hierarchy offers useful structure for the following operations:Trewitt & Partridge [Page 6]RFC 1076 HEMS Monitoring and Control Language November 1988 Organization A hierarchy allows related data to be grouped together in a natural way. Naming The name of a piece of data is just the path from the root to the data of interest. Mapping onto ASN.1 ASN.1 can easily represent a hierarchy by using a "constructor" type as an envelope for an entire subtree. Efficient Representation Hierarchical structures are compact and can be traversed quickly. Safe Locking If it is necessary to lock part of the hierarchy (for example, when doing an update), locking an entire subtree can be done efficiently and safely, with no danger of deadlock. We will use the term "data tree" to refer to this entire structure. Note that this internal model is completely independent of the external ASN.1 representation -- any other suitable representation would do. For the sake of efficiency, we do make a one-to-one mapping between ASN.1 tags and the (internal) names of the nodes. The same could be done for any other external representation. Each node in the hierarchy must have names for its component parts. Although we would normally think of names as being ASCII strings such as "input errors", the actual name is just an ASN.1 tag. Such names are small integers (typically, less than 30) and so can easily be mapped by the monitored entity onto its internal representation. We use the term "dictionary" to mean an internal node in the hierarchy. Leaf nodes contain the actual data. A dictionary may contain both leaf nodes and other dictionaries.5.1 Example Data Tree Here is a possible organization of the hierarchy in an entity that has several network interfaces and does IP routing. The exact organization of data in entities is specified in RFC-1024. This skeletal data tree will be used throughout this RFC in query examples. System { name -- host name clock-msec -- msec since bootTrewitt & Partridge [Page 7]RFC 1076 HEMS Monitoring and Control Language November 1988 interfaces -- # of interfaces memory } Interfaces { -- one per interface InterfaceData{ address, mtu, netMask, ARP{...}, ... } InterfaceData{ address, mtu, netMask, ARP{...}, ... } : } IPRouting { Entry{ ip-addr, interface, cost, ... } Entry{ ip-addr, interface, cost, ... } : } There are three top-level dictionaries in this hierarchy (System, Interfaces, and IPRouting) and three other dictionary types (InterfaceData, Entry, and ARP), each with multiple instances. The "name" of the clock in this entity would be: system{ clock-msec } and the name of a routing table entry's IP address would be: IPRouting{ Entry{ ip-addr } }. More than one piece of data can be named by a single ASN.1 object. The entire collection of system information is named by: system and the name of a routing table's IP address and cost would be: IPRouting{ Entry{ ip-addr, cost } }.5.2 Arrays There is one sub-type of a dictionary that is used as the basis for tables of objects with identical types. We call these dictionaries arrays. In the example above, the dictionaries for interfaces, routing tables, and ARP tables are all arrays. In the examples above, the "ip-addr" and "cost" fields are named. In fact, these names refer to the field values for ALL of the routing table entries -- the name doesn't (and can't) specify which routing table entry is intended. This ambiguity is a problem wherever data is organized in tables. If there was a meaningful index for such tables (e.g., "routing table entry #1"), there would be no problem. Unfortunately, there usually isn't such an index. The solution to this problem requires that the data be accessed on the basis of some of its content. Filters, discussed in section 8.6, provide this mechanism. The primary difference between arrays and plain dictionaries is thatTrewitt & Partridge [Page 8]RFC 1076 HEMS Monitoring and Control Language November 1988 arrays may contain only one type of item, while dictionaries, in general, will contain many different types of items. For example, the dictionary IPRouting (which is an array) will contain only items of type Entry. The fact that these objects are viewed externally as arrays or tables does not mean that they are represented in an implementation as linear lists of objects. Any collection of same-typed objects is viewed as an array, even though it might be stored internally in some other format, for example, as a hash table.6. COMPONENTS OF A QUERY A HEMS query consists of a sequence of ASN.1 objects, interpreted by a simple stack-based interpreter. [Although we define the query language in terms of the operations of a stack machine, the language does not require an implementation to use a stack machine. This is a well-understood model, and is easy to implement.] One ASN.1 tag is reserved for operation codes; all other tags indicate data that will eventually be used by an operation. These objects are pushed onto the stack when received. Opcodes are immediately executed and may remove or add items to the stack. Because ASN.1 itself provides tags, very little needs to be done to the incoming ASN.1 objects to make them suitable for use by the query interpreter. Each ASN.1 object in a query will fit into one of the following categories: Opcode An opcode tells the query interpreter to perform an action. They are described in detail in section 8. Opcodes are represented by an application-specific type whose value determines the operation. Template These are objects that name one or more items in the data tree. Named items may be either simple items (leaf nodes) or entire dictionaries, in which case the entire subtree "underneath" the dictionary is understood. Templates are used to select specific data to be retrieved from the data tree. A template may be either simple or structured, depending upon what it is naming. A template only names the data -- there are no values contained in it. Therefore the leaf objects in a template will all have a length of zero. Examples of very simple templates are: name() or System{} Each of these is just one ASN.1 data object, with zero length. The first names a single data item in the "System"Trewitt & Partridge [Page 9]RFC 1076 HEMS Monitoring and Control Language November 1988 dictionary (and must appear in that context), and the second names the entire "System" dictionary. A more complex template such as: Interfaces{ InterfaceData{ address, netMask, ARP } } names two simple data items and a dictionary, iterated over all occurrences of "InterfaceData" within the Interfaces array. Path A path is a special case of a template that names only a single node in the tree. It specifies a path down into the dictionary tree and names exactly one node in the dictionary tree. Value These are used to give data values when needed in a query, for example, when changing a value in the data tree. A value can be thought of as either a filled-in template or as the ASN.1 representation some part of the data tree. Filter A boolean expression that can be executed in the context of a particular dictionary that is used to select or not select items in the dictionary. The expressions consist of the primitives "equal", "greater-or-equal", "less-or-equal", and "present" possibly joined by "and", "or", and "not". (See section 8.6.) Values, Paths, and Templates usually have names in the context- dependent class, except for a few special cases, which are in the application-specific class.7. REPLY TO A QUERY The data returned to the monitoring entity is a sequence of ASN.1 data items. Conceptually, the reply is a subset of the data tree, where the query selects which portions are to be included. This is exactly true for data retrieval requests, and essentially true for data modification requests -- the reply contains the data after it has been modified. The key point is that the data in a reply represents the state of the data tree immediately after the query was executed. The sequence of the data is determined by the sequence of query language operations and the order of data items within Templates and Values given as input to these operations. If a query requests data from two of the top-level dictionaries in the data tree, by giving two templates such as: System{ name, interfaces } Interfaces{Trewitt & Partridge [Page 10]RFC 1076 HEMS Monitoring and Control Language November 1988 InterfaceData { address, netMask, mtu } } then the response will consist of two ASN.1 data objects, as follows: System { name("system name"), interfaces(2) } Interfaces { InterfaceData { address(36.8.0.1), netMask(FFFF0000), mtu(1500) } InterfaceData { address(10.1.0.1), mtu(1008), netMask(FF000000) } } With few exceptions, each of the data items in the hierarchy is named in the context-specific ASN.1 type space. Because of this, the returned objects must be fully qualified. For example, the name of the entity must always be returned encapsulated inside an ASN.1 object for "System". If it were not, there would be no way to tell if the object that was returned was "name" inside the "System" dictionary or "address" inside the "interfaces" dictionary (assuming in this case that "name" and "address" were assigned the same integer as their ASN.1 tags). Having fully-qualified data simplifies decoding of the data at the receiving end and allows the tags to be locally chosen. Definitions for tags within routing tables won't conflict with definitions for tags within interfaces. Therefore, the people doing the name assignments are less constrained. In addition, most of the identifiers will be fairly small integers, which is an advantage
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -