idnits 2.17.1 draft-hardaker-eos-oops-01.txt: -(850): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(897): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(1213): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(1214): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(1263): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(1359): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Looks like you're using RFC 2026 boilerplate. This must be updated to follow RFC 3978/3979, as updated by RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document seems to lack a 1id_guidelines paragraph about Internet-Drafts being working documents. == There are 11 instances of lines with non-ascii characters in the document. == No 'Intended status' indicated for this document; assuming Proposed Standard Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Abstract section. ** The document seems to lack a Security Considerations section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The document seems to lack separate sections for Informative/Normative References. All references will be assumed normative when checking for downward references. ** There are 124 instances of too long lines in the document, the longest one being 12 characters in excess of 72. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 137: '...appropriate. It MUST, however, return...' RFC 2119 keyword, line 322: '...mented using the OPTIONAL ASN.1 field ...' RFC 2119 keyword, line 390: '... collecting data. This MUST be a zero...' RFC 2119 keyword, line 392: '... SHOULD contain the va...' RFC 2119 keyword, line 396: '...and responder. The manager MUST treat...' (25 more instances...) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the RFC 3978 Section 5.4 Copyright Line does not match the current year == Line 403 has weird spacing: '... ignore the v...' == The expression 'MAY NOT', while looking like RFC 2119 requirements text, is not defined in RFC 2119, and should not be used. Consider using 'MUST NOT' instead (if that is what you mean). Found 'MAY NOT' in this paragraph: If the dontReturnObjectNumbers is set in the request, the command responder MAY NOT include these fields in the Get-Object-Response-PDU, but the command responder MUST set the bit according to what it actually did. The command responder MUST include these fields if the request did not have the dontReturnObjectNumbers bit set. -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (September 2002) is 7893 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Unused Reference: 'OPREQ' is defined on line 1343, but no explicit reference was found in the text -- Possible downref: Normative reference to a draft: ref. 'OPREQ' Summary: 9 errors (**), 0 flaws (~~), 6 warnings (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 IPSP Working Group W. Hardaker 3 INTERNET-DRAFT Network Associates Laboratories 4 draft-hardaker-eos-oops-01.txt September 2002 6 Object Oriented PDUs for SNMP 7 draft-hardaker-eos-oops-01.txt 9 Status of this Memo 11 This document is an Internet-Draft and is in full conformance with 12 all provisions of Section 10 of RFC2026. Internet-Drafts are working 13 documents of the Internet Engineering Task Force (IETF), its areas, 14 and its working groups. Note that other groups may also distribute 15 working documents as Internet-Drafts. 17 Internet-Drafts are draft documents valid for a maximum of six months 18 and may be updated, replaced, or obsoleted by other documents at any 19 time. It is inappropriate to use Internet-Drafts as reference 20 material or to cite them other than as "work in progress." 22 The list of current Internet-Drafts can be accessed at 23 http://www.ietf.org/ietf/1id-abstracts.txt 25 The list of Internet-Draft Shadow Directories can be accessed at 26 http://www.ietf.org/shadow.html. 28 Copyright Notice 30 Copyright (C) The Internet Society (2002). All Rights Reserved. 32 1. Introduction 34 This draft specifies some new PDU operations intended to optimize 35 SNMP requests for performance. 37 This draft is not a complete specification, but merely is intended 38 to illustrate concepts which can then be discussed within the EoS 39 working group. A complete specification will be completed after the 40 agreed features and packet structure is fairly well solidified so 41 the author doesn't have to rewrite large portions of stuff ;-). 42 There are no error handling codes or elements of procedures defined 43 yet. The concepts, however, have been thought out about a lot. 44 Feedback on what you see within would be greatly appreciated at this 45 point. 47 Terminology in this draft is frequently inconsistent. Forgive the 48 use of the old-school terminology (e.g., "agent") intermixed with 49 new terminology (e.g., "command responder"). The other common error 50 is the usage of the word "column" instead of "sub-identifier" or 51 whatever the next draft for SMIv3 is going to call it (I forget and 52 think it may be changing in the next draft anyway hence I didn't try 53 to get it right in this document). This too will be fixed if a 54 standardized specification on this work goes forward. 56 Some of the stuff in this draft has yet to undergo debate. 57 Particularly the Write operation is not solidified in my mind and 58 will certainly be subject to debate as to whether they go to far 59 into solving the problems that many people have pointed out with 60 existing transactions. Please read the draft all the way through, 61 including the section on "Design Considerations and Questions" 62 before asking questions of the author or the working group. 64 Finally, this is very much a working document. The descriptions 65 described here-in may not even exactly match the author's thoughts, 66 as the document hasn't been extensively proof-read yet. 68 1.1. Related work with the SMIng working group. 70 In revamping this document and the contained PDUs, the direct 71 correlations to the SMIng working group have since been dropped. 72 They'll be reinstated shortly, but for now just know that all the 73 PDUs contained within this document can be used with the new 74 hierarchal structure of a newer SMIv3 MIB structure. 76 To think about it, everywhere you see the word "BER" in a PDU 77 definition, think "BER or recursive". IE, sub-elements within a 78 SMIng working group will be encoded into a BER field in the same way 79 that the containing request needed it. 81 1.2. Table of Contents 83 1. Introduction 1 84 1.1. Related work with the SMIng working group. 2 85 1.2. Table of Contents 2 86 2. Background and Motivations 3 87 2.1. GET-NEXT complexity 3 88 2.2. OID compression 4 89 2.3. Row operations 4 90 2.4. Complex object relationships 4 91 2.5. Retrieving of more data than is desired. 5 92 2.6. Row hole traversal and object grouping 5 93 2.7. Index parsing and OID length restrictions. 6 94 2.8. Transactions 6 95 2.9. Easy conversion to and from popular data formats 6 96 2.10. Human readable error strings 6 97 3. Transport Protocol Considerations 7 98 4. New PDU definitions 7 99 4.1. The Get-Object-PDU 7 100 4.2. The Get-Object-Response PDU 13 101 4.3. The Write-Object-PDU 15 102 4.3.1. Write-Object-PDU transaction semantics 18 103 4.4. The Write-Object-Response-PDU 19 104 5. ASN.1 definitions for the PDUs 21 105 6. Examples 22 106 6.1. Retrieve a specific row from the ifTable 22 107 6.2. A multiple-packet example with a double filter. 23 108 7. Elements of Procedure. 26 109 8. Design Considerations and Questions 26 110 8.1. Return-field ranges 26 111 8.2. Write-Object-PDU complexity 26 112 8.3. Get-Object/Write-Object commonality. 27 113 8.4. Concrete packet formats vs optional field formats. 27 114 8.5. Push Button Functionality. 28 115 9. Author's Addresses: 29 116 10. References 29 117 11. Full Copyright Statement 29 119 2. Background and Motivations 121 Many recognized problems exist within the SNMP protocol [OPREQ,...]. 122 Many of the known problems are addressed by the new protocol 123 operations defined within this draft. The general problems trying 124 to be solved are described in this section. 126 2.1. GET-NEXT complexity 128 A large number of problems result from a devices inability to access 129 it's data in a way that can be efficiently traversed when searching 130 for the next object in a series of GET-NEXT or GET-BULK SNMP 131 requests. Internally, many implementations differ and thus it would 132 be impossible in many cases to define a MIB which would be efficient 133 when implemented on every architecture. 135 The operations defined in this document do not suffer from these 136 problems, as the data can be returned in any order that the agent 137 feels is appropriate. It MUST, however, return data in a consistent 138 manner such that if the same data is requested twice the agent will 139 return the data in the same order. The exact order in which objects 140 are returned is implementation specific. 142 It's the author's belief that every agent will benefit from this, 143 and that most managers don't care in the first place. Manager's are 144 likely to either need the data unsorted in the first place (e.g. may 145 only care about the values each row and not the relationships 146 between the rows) or the data will need to be sorted in a different 147 fashion than the MIB indexing defines in the first place. If the 148 manager does need the data sorted, it's more likely it'll have the 149 power to more easily do sorting via utilization of database 150 technologies that are not realistically available on many agent 151 platforms. 153 2.2. OID compression 155 SNMPv2 PDU consist of a sequence of varbinds and in many cases, when 156 multiple objects are requested from the agent, the OIDs contained 157 within have common prefixes. It is widely recognized as a waste of 158 resources to duplicate this prefix repeatedly. 160 The PDUs defined in this document only rely on a base OID (e.g., an 161 object identifier pointing to a SNMP Table) once, and the sub- 162 objects (e.g., a row in a SNMP Table) underneath it are defined as 163 references from the base OID. Each index set which defines the 164 proper reference for the remainder of the data components in a given 165 "row" or "sub-object" is only included once as well. This allows 166 large groups of data to be transmitted while only requiring a single 167 OID to identify the top most grouping object (e.g., a table). 169 2.3. Row operations 171 The ability to manipulate an entire row within a SNMP Table at once 172 has long been a frustration of programmers implementing the 173 protocol. 175 The PDUs defined in this document are able to operate on entire 176 groups of objects at once, where one of these groupings types is a 177 row within a normal SNMP Table. 179 2.4. Complex object relationships 181 Many people do not properly understand the interrelationships 182 between SNMP Tables and have desired the ability to express their 183 data in a more hierarchal fashion, such that SNMP tables can contain 184 other SNMP tables. Although it is not possible to enable nested 185 datatypes within SMIv2 today, the SMIng working group is trying to 186 solve these problems and create the ability to define more complex 187 relationships in SMIv3. 189 The way object groupings are referenced within the PDUs defined in 190 this document allows hierarchal object data to be transmitted 191 efficiently and as a single group, thus allowing groups defined 192 within SMIv3 to be efficiently transmitted within the PDUs defined 193 in this document, new SMIv3-style objects be deployed. 195 XXX: mention the intention to make the object definitions a bit 196 extensible, so that new types requiring new parameters can be easily 197 handled in the future without replacing the PDUs themselves. 199 2.5. Retrieving of more data than is desired. 201 Extracting only the data needed from a SNMP Table has traditionally 202 required pulling the entire table of data to the management station 203 in many cases, when the indexes and their ordering was not 204 sufficient for requesting subsets of the data desired. 206 The request PDUs defined in this document allow more careful 207 selection of indexing data and allow simple search criteria to be 208 fulfilled. A delicate balance is required to ensure that the 209 devices being polled for data are not taxed with expensive search 210 requests, so the criteria imposed within these documents is limited 211 to a limited set of operators which may or may not be supported by 212 the command responder implementation. The intention is not to shift 213 all the complex decision processing burden from the management 214 station to the command responder, but to increase efficiency on the 215 wire where possible. 217 XXX: the agent will actually have the ability to gain improvements 218 from this optimization since the manager will perform fewer requests 219 as a whole. 221 2.6. Row hole traversal and object grouping 223 When requests to GET, GET-NEXT, and GET-BULK data come back in a 224 SNMP RESPONSE PDU, the data can be hard to organize back into a 225 logical structure again. Holes of data (a row that contains no data 226 for a particular column) within SNMP Tables make processing of the 227 data collected more tedious. Additionally, GET-BULK responses 228 interleave it's data, possibly with END-OF-MIB exceptions, which 229 only adds further complexity to the data processing. 231 Since the PDUs defined in this document deal directly with MIB 232 objects as a whole, the data relationships within an object is 233 preserved. This makes transferring large amounts of data efficient 234 on both the sending and receiving side, as neither side needs to 235 sort VarBinds properly. The data groupings are now appropriately 236 marked within the packet itself. 238 2.7. Index parsing and OID length restrictions. 240 Although the encoding and decoding of Table indexes into and out out 241 OIDs is algorithmic, many SNMP software packages and toolkits make 242 mistakes in implementing the algorithm. Additionally, since the 243 maximum length of an OID is limited to 128 sub-identifiers, it 244 limits the size of the index data that can be contained within an 245 OID. This limitation results in poorly designed and broken MIBs and 246 MIBs with less-than-ideal table indexes. 248 The indexes within the PDUs defined in this document are encoded 249 directly into the packet as opposed to being encoded into the OID 250 first (which is then encoded into the packet). This simplifies both 251 management and agent code and reduces the chances of one side 252 incorrectly encoding or decoding the indexes. Additionally, it 253 provides the ability to use a set of indexes which is larger than 254 the OID-encoded imposed length of 255 sub-identifies. 256 2.8. Transactions 258 The limited set of SNMP transactions have been difficult to cope 259 with when large sets of data must be pushed around, since all the 260 objects within a SNMP SET PDU must be set as if simultaneously. In 261 actuality, configuration data often contains independent segments of 262 data. Typically, independent sets of data must be pushed inside 263 individual PDUS when configuring an agent, which is inefficient. 265 The PDUs defined in this document define a less restrictive and more 266 flexible transaction model that lets large quantities of data be 267 pushed efficiently across the network and will still allow 268 individual groupings to specify whether they are inter-related and 269 must be treated as a single transaction or not and whether or not 270 ordering is important 272 2.9. Easy conversion to and from popular data formats 274 A desire has been shown by network operators for SNMP objects to be 275 easily accessible and convertable to and from more human friendly 276 expression languages and storage systems, like XML or SQL Databases. 277 The objects within the PDUs contained in this document are designed 278 for such a purpose. It should be, for example, trivial to convert 279 them to and from a hierarchial XML schema set describing the objects 280 in question. For the example XML case, the BER hierarchal packet 281 format can be quickly converted to XML by replacing the sequence 282 tags with XML ascii delimiter tags. 284 2.10. Human readable error strings 285 Integer error codes are extremely useful for machine parsibility and 286 interoperability, but it's frequently nice to have an extra error 287 string that may be passed to an operator to assist in extra 288 debugging of problems. The response PDUs defined in this document 289 contain an "error string" for exactly this purpose. 291 3. Transport Protocol Considerations 293 The PDUs defined in this document allow the transmission of large 294 data sets in a more compressed form than previous SNMP PDUs, it is 295 still recommended that large requests and responses be transmitted 296 over a SNMP transmission domain which provides for guaranteed 297 network packet delivery (e.g., TCP). Large responses, containing 298 many objects, carried over transmission domains (e.g., UDP) which 299 can not guarantee delivery are still likely to be problematic. It 300 is well beyond the scope of this document to re-implement reliable 301 transmission mechanisms. 303 4. New PDU definitions 305 This section defines the new PDUs. 307 Right now, these PDUs are not in a ASN.1 standard format simply for 308 clarity to the reader. Proper ASN.1 definitions will be published 309 as the format of the PDUs are more stabilized (probably late 2002) 310 and more widely accepted. ASN.1 is designed for machine 311 readability, and this draft is currently still intended for 312 primarily human consumption. 314 In the mean time, here is a non-ASN.1 PDU breakdown. Any {} pairs 315 below are essentially a BER sequence. At least the larger sequences 316 are expected to be implemented using the non-deterministic sequence 317 type (a beginning and ending sequence tag, rather than a single tag 318 and a length) to ease the burden on encoders. [] means a sequence 319 list (array), ie multiple objects. The author would like to delay 320 the argument over coding semantics until after the PDU structure 321 itself has been defined. Note that some of the fields below might 322 be implemented using the OPTIONAL ASN.1 field tag as well. Again, 323 this will be a discussion for later. 325 4.1. The Get-Object-PDU 327 Here's the breakdown of a Get-Object-PDU (GOP), which can be thought 328 of as a replacement for GET, GETNEXT and GETBULK. 329 Get-Object-PDU ::= { 330 request-id Integer32, 331 option-field {} -- a sequence 332 reserved for future use 334 request-objects[] ::= { 335 { 336 max-return-objects Integer32, 337 skip-objects Integer32, 338 max-depth Integer32, 339 cursor OCTET STRING, 340 flags BITS { restartOnInvalidCursor(0), 341 returnAllDataOnUnsupportedMatch(1), 342 dontReturnObjectNumbers(2), 343 reserved(3) }, 344 option-field {} -- a sequence 345 reserved for future use 346 request-base-OID, -- (eg, OID for a table) 348 index-request-list[] ::= { INDEX1, INDEX2, ... }, 349 column-request-list[] ::= { COLNUM1, COLNUM2, ... }, 351 index-search-objects[] ::= { 352 { index-number Integer32, 353 match-type MATCH-TYPE, 354 index-search-value BER }, 355 ... 356 }, 358 column-search-objects[] ::= { 359 { column-number Integer32, 360 match-type MATCH-TYPE, 361 column-search-value BER }, 362 ... 363 } 364 } 365 ... -- possibly more request-objects 366 } 368 In the above, the following pieces need explaining (and this is not an 369 exact elements of procedure, but should give a feel for how PDU 370 processing will eventually be described): 372 request-id: The standard request-id concept that exists 373 in previous PDUs defined by the previous 374 versions of SNMP 376 max-return-objects: The maximum number of objects to return in one 377 response message. A value of 0 indicates "all". 379 skip-objects: Don't return the first skip-objects objects, 380 but rather return objects numebering from 381 (skip-objects + 1) to (max-return-objects + 382 skip-objects + 1). A value of 0 indicates 383 start returning with the first object. 385 max-depth: The maximum depth of a SMIv3 structure to 386 return. This will be explained in greater 387 detail in a later draft. 389 cursor: An OCTET STRING defining the starting point 390 for collecting data. This MUST be a zero 391 length string for the first request, and 392 SHOULD contain the value in the response 393 for chained requests which are expected to 394 return future data. The value of the 395 cursor is implementation dependent at the 396 command responder. The manager MUST treat 397 it as generic data and should use it when 398 possible to obtain the next set of 399 information in a series of requests. 400 Command responders MUST refer to the value 401 of the skip-objects field if the cursor 402 field is a zero length string. 403 Command responders MUST ignore the value 404 of the skip-objects field if the cursor 405 field is a non-zero length string and is 406 deemed to be a valid cursor. 408 If this object is specified, the skip-objects 409 is ignored by the command responder. 411 Cursors SHOULD be defined by the command 412 responder in such a way as to avoid 413 referencing an existing object in such a 414 way that if the existing object disappears 415 the cursor will become invalid. I.E., 416 where possible, cursors should be data 417 independent where possible and should be a 418 reference into the appropriate place in 419 the storage mechanism and not a reference 420 to a data piece itself within the storage 421 mechanism. 423 If a cursor is deemed invalid by the 424 command responder and it is impossible for 425 it to determine where to start collecting 426 data from, the command responder must do 427 one of two things: 429 a) if the restartOnInvalidCursor flag is 430 set, the search operation should be 431 restarted from the beginning of all 432 possible data. 434 b) if the restartOnInvalidCursor flag is 435 not set, the search operation should 436 start at the point indicated by the 437 skip-objects field. 439 As an example cursor, an agent which was 440 merely performing internal Get-Object-PDU 441 translations to a GETNEXT translations 442 might return a cursor containing the BER 443 encoding of the last OID returned within 444 the response. The next request could 445 merely continue processing using the 446 encoded OID just as if a real GETNEXT had 447 come in. 449 flags: A flag list indicating particular features 450 to be used when processing the PDU. The 451 flag values are described elsewhere in 452 this document. 454 option-field: A sequence reserved for future use. 455 Command responders which encounter unknown 456 option types specified in this sequence 457 MUST ignore the data and proceed as if the 458 field itself didn't exist in the request. 459 Future protocol extensions MUST define 460 extensions to be implemented within this 461 sequence in such a way that the option can 462 be safely ignored by implementations which 463 fail to understand it. 465 This field exists in multiple places in 466 the PDU definitions contained within this 467 document. In all cases, the sequences 468 MUST contain only an OPTION-ized list of 469 parameters to be defined in future 470 documents. The option index numbers for 471 the sequence will be assigned and 472 administered by IANA. 474 Note: all option-field names in this 475 document are identical, which is purely 476 due to laziness. They should be different 477 in each occasion within each new PDU type. 479 request-base-OID: The base OID for a given object ot request 480 information from. For SMIv2 objects, this is 481 either the OID pointing to a table or a 482 particular scalar. 484 index-request-list & These two sequences contain a list of 485 column-request-list: subcomponents to be returned in the 486 response. IE, what particular data 487 elements should be returned. If both 488 elements are empty (2 zero-length 489 sequences) then all data for the given 490 object MUST be returned. Managers SHOULD 491 request accessible indexes elements in the 492 column-request-list if the indexes are 493 accessible and not in the 494 index-request-list. 496 index-search-objects & These two sequences contain a list of 497 column-search-objects: search criteria for the data being 498 requested. If the object data to be 499 returned does not match the criteria 500 imposed by these restrictions in the 501 request, then it shouldn't be returned. 503 index-number: The index number or column-number of a 504 column-number: given index or column object within a 505 table. Indexes should count from 1 in the 506 index list for the given object. The 507 column number should be the assigned 508 number underneath the request-base-OID 509 object. 511 If the dontReturnObjectNumbers is set in 512 the request, the command responder MAY 513 NOT include these fields in the 514 Get-Object-Response-PDU, but the command 515 responder MUST set the bit according to 516 what it actually did. The command 517 responder MUST include these fields if the 518 request did not have the 519 dontReturnObjectNumbers bit set. 521 Implementations SHOULD use column matching 522 in preference to index matching, and thus 523 index matching SHOULD ONLY be used for 524 external index values which don't have a 525 column number assignment within the 526 object. 528 match-type: Specifies the criteria to be imposed for a 529 given search value. The criteria types 530 are listed below: 532 MATCH-TYPE ::= Integer32 { 534 -- any datatypes: 535 equals(0), 536 not-equals(1), 538 -- numerical only: 539 lessThan(10), 540 lessThanOrEqual(11), 541 greaterThan(12), 542 greaterThanOrEqual(13), 544 -- binary comparisons: 545 regexp(20), 546 not-regexp(21), 548 -- ... IANA assigned up to 255 549 -- enterprise specific: 550 -- 256*EnterpriseID to 551 -- 256*EnterpriseID + 255 552 } 554 match-type's are intended for simple 555 expressions to help reduce the data sent 556 over the wire. They are not intended for 557 complex querying which might impose a 558 large burden on the end device who's 559 resources are likely needed for their 560 primary functionality (routing, ...). 561 Multiple match-types within a request are 562 always logically ANDed together. 564 If the returnAllDataOnSearchFailure bit is 565 set, then if a search operation fails due 566 to a condition like an unsupported 567 match-type, all data will be returned as 568 if the search-type operator had always 569 returned "true". If the 570 returnAllDataOnSearchFailure bit is not 571 set, an unSupportedSearchOperation error 572 condition will be returned in the 573 error-status field of the 574 Get-Object-Response-PDU and the error-index 575 field will be set to the N if this is the 576 Nth search criteria contained within the 577 original Get-Object-PDU. 579 4.2. The Get-Object-Response PDU 581 This PDU is sent in response to a Get-Object-PDU. 583 Get-Object-Response-PDU ::= { 584 request-id Integer32, 586 response-objects[] ::= { 587 { 588 error-status Integer32, 589 error-index Integer32, 590 error-string OCTET STRING, 591 cursor OCTET STRING, 592 flags BITS { restartOnInvalidCursor(0), 593 returnAllDataOnSearchFailure(1), 594 dontReturnObjectNumbers(2), 595 containedLastDataObject(3) }, 596 option-field {} -- a sequence 597 reserved for future use 599 request-base-OID, -- (eg, OID for a table) 601 data-list[] ::= { 602 index-data-list[] ::= { 603 { index-number Integer32, -- ** see below 604 index-value BER }, 605 ... 606 }, 608 column-data-list[] ::= { 609 { column-number Integer32, -- ** see below 610 column-value BER }, 611 ... 612 } 613 } 614 } 615 ... -- possibly more response-objects 616 } 617 } 619 In the above, the following pieces need explaining. Items in the 620 above definition not listed here have been previously described. 622 error-status An error status for the entire request 623 operation, if an error occurred which 624 affected the entire operation. Agent's 625 SHOULD strive to put exceptions in the 626 data field where possible instead. 628 error-index An index into "something", where 629 "something" is defined by what the 630 error-status field contains (as an 631 example, the unSupportedSearchRange error 632 indicates it's an index into the search 633 objects in the original request). 635 error-string A string describing the particular error. 636 This SHOULD be set to a human readable 637 string describing the problem in greater 638 detail than the error-status field alone 639 can indicate. 641 flags The flags field MUST be set according to 642 how the response was handled within the 643 responder. Ideally this should be an 644 exact copy of the flags field from the 645 request, assuming the flags were 646 understood. Non-understood flags MUST be 647 set to 0 in the response. 649 If the command responder can determine 650 that the last object to be returned within 651 the requested search range is contained 652 within the Get-Object-Response-PDU, then the 653 containedLastDataObject SHOULD be set. 655 index-number: This will be one of: 656 a) the count of the object into the 657 INDEX clause of the component for 658 which the data is being returned if 659 the dontReturnObjectNumbers flag bit 660 in the response is 0. 661 b) If the dontReturnObjectNumbers flag 662 bit in the request was 1 and the 663 agent response's sets the 664 dontReturnObjectNumbers to 1, then 665 this field is dropped from the 666 response and only the next field (the 667 value) is present. 669 column-number: This will be one of: 670 a) the assigned sub-component number of 671 the object being returned if the 672 dontReturnObjectNumbers flag bit in 673 the response is 0. 674 b) If the dontReturnObjectNumbers flag 675 bit in the request was 1 and the 676 agent response's sets the 677 dontReturnObjectNumbers to 1, then 678 this field is dropped from the 679 response and only the next field (the 680 value) is present. 682 4.3. The Write-Object-PDU 684 This Write-Object-PDU is used to update a remote entity with new 685 data. 687 Write-Object-PDU ::= { 688 request-id Integer32, 689 flags BITS { returnDataOnlyOnError(0) }, 690 option-field {} -- a sequence 691 reserved for future use 693 set-objects[] ::= { 694 { 695 transaction-flags BITS { 696 needSuccess(0), 697 needAll(1), 698 notOrderDependent(2), 699 }, 700 option-field { } -- a sequence 701 reserved for future use 703 transaction-data-list[] ::= { 704 choice { 705 create-transaction, 706 modify-transaction, 707 delete-transaction, 708 set-objects -- sub-transactions 709 -- iana assigned extensions here? 710 }, ... 711 } 712 } 713 ... -- possibly more set-objects 714 } 715 } 717 -- creates new rows. error condition if indexes or required 718 -- columns aren't complete. 719 create-transaction ::= { 720 request-base-OID, -- (eg, OID for a table) 722 index-data-list[] ::= { 723 { index-number Integer32, 724 index-value BER }, 725 ... 726 } 728 column-data-list[] ::= { 729 { column-number Integer32, 730 column-value BER }, 731 ... 732 } 733 } 735 -- modifies existing rows based on search criteria. 736 -- error condition on any modification failure. 737 modify-transaction ::= { 738 request-base-OID, -- (eg, OID for a table) 740 index-search-objects[] ::= { 741 { index-number Integer32, 742 match-type MATCH-TYPE, 743 index-search-value BER }, 744 ... 745 }, 747 column-search-objects[] ::= { 748 { column-number Integer32, 749 match-type MATCH-TYPE, 750 column-search-value BER }, 751 ... 752 } 754 column-data-list[] ::= { 755 { column-number Integer32, -- ** see below 756 column-value BER }, 757 ... 758 } 759 } 760 -- deletes existing rows based on search criteria. 761 -- error condition on any 762 delete-transaction ::= { 763 request-base-OID, -- (eg, OID for a table) 765 index-search-objects[] ::= { 766 { index-number Integer32, 767 match-type MATCH-TYPE, 768 index-search-value BER }, 769 ... 770 }, 772 column-search-objects[] ::= { 773 { column-number Integer32, 774 match-type MATCH-TYPE, 775 column-search-value BER }, 776 ... 777 } 778 } 780 In the above, the following pieces need explaining: 782 flags Global flags to apply to the entire PDU. 783 If the returnDataOnlyOnError bit is set, 784 then the Write-Object-Response-PDU will 785 only contain a duplicate set-objects 786 portion of the message if there was an 787 error somewhere in the processing of the 788 message, otherwise the objects will be 789 truncated. Command Responder 790 implementations SHOULD support this flag, 791 but if for any reason they decide to 792 return the set-objects data portion of the 793 message they MUST NOT set the 794 returnDataOnlyOnError bit. 796 transaction-flags: Flags which apply to each sub-element of 797 the transaction to be performed. 798 Currently there are 3 bits to define 799 transactional processing semantics to be 800 used when processing this message. These 801 values are described in greater detail in 802 the next section. 804 operation: Indicates what type of operation is to be 805 performed by this transaction set. 806 Specifically: 808 create: creates a new row. It is to 809 be considered an error condition if 810 either the row can not be created or 811 if the row already existed. 813 modify: modifies an existing row to 814 replace some or all of the writable 815 parameters within the row. It is an 816 error condition if the row to be 817 modified does not exist. 819 delete: deletes a given row. If the 820 row does not exist or can not be 821 deleted for some reason, it is 822 considered to be an error condition. 823 The column-data-list MUST be empty 824 when transmitting this operation. 826 transaction-data-list: The transaction-data-list contains all of 827 the data to be applied based on the 828 operation choice type. 830 The search criteria imposed by the 831 index-search-objects and 832 column-search-objects are identical in 833 operation to the Get-Object-PDU 834 equivalents, except that instead of 835 requested information back, the 836 column-data field objects should be 837 applied in the case of a create or a 838 modify, or the rows should simply be 839 deleted in the case of a delete. Unlike 840 the Get-Object-PDU match-type handling, an 841 unsupported match-type will always trigger 842 an error condition. 844 4.3.1. Write-Object-PDU transaction semantics 846 In short, the flags defining Write-Object semantics can be 847 summarized as follows: 849 needSuccess 850 If the needSuccess bit is turned on, it means that this trans� 851 action is to be considered a failed transaction if during any 852 time an error condition occurs. If at anytime a failure 853 occurs when processing the transaction-data-list, the entire 854 transaction must be rolled back. 856 needAll 857 If needAll is specified, it means each sub-component in the 858 transaction-data-list must be attempted. 860 notOrderDependent 861 If the notOrderDependent bit is turned on, the transactions 862 contained in the transaction-data-list MAY be executed in an 863 order, or in parallel. Note that they must still revert to 864 their previous values in an error condition requires a state 865 rollback. 867 In short the following bit combinations are described in combination: 869 needSuccess = true, needAll = true: doAll [doUntilFailure] 870 In this case, all contained transactions must succeed. If any 871 failure occurs, the entire set must be rolled back. 873 needSuccess = false, needAll = true: tryAll 874 With this combination set, the command responder must try to 875 achieve all the transactions, however if any fail it is not 876 required to roll back the rest of the transactions. The 877 failed transactions themselves, however, must individually 878 revert to the before-write state. 880 needSuccess = true, needAll = false: doAtLeastOne [doUntilSuc� 881 cess] 882 In this case, at least one must succeed for the transaction as 883 a whole to succeed. More importantly, if any one transaction 884 component does succeed, processing MUST be stopped and the 885 transaction as a whole is considered successful. Another way 886 to put it: at most one successful component is executed never 887 more than one. 889 needSuccess = false, needAll = false: tryAtLeastOne 890 In this case, at least one must succeed for the transaction as 891 a whole to succeed. More importantly, if any one transaction 892 component does succeed, processing MUST be stopped and the 893 transaction as a whole is considered successful. Another way 894 to put it: at most one successful component is executed never 895 more than one. However, in this case even if none of the 896 transaction components succeeds, the transaction as a whole is 897 still considered successful. It is impossible for a transac� 898 tion of this type to be considered a failure in itself. 900 Also, error reporting will always occur on failed objects even if they 901 don't affect the containing transactions and surrounding transactions. 903 4.4. The Write-Object-Response-PDU 904 This Write-Object-Response-PDU returns the results of the Write- 905 Object-PDU operation. Note that more data can be returned in many 906 cases when search operations required operations on multiple rows 907 based on the search criteria. 909 Write-Object-Response-PDU ::= { 910 request-id Integer32, 911 flags BITS { returnDataOnlyOnError(0) }, 912 option-field {} -- a sequence 913 reserved for future use 915 set-objects-response[] ::= { 916 { 917 error-status Integer32, -- will include "tooComplex" 918 error-index Integer32, 919 error-string OCTET STRING, 920 transaction-flags BITS { 921 needSuccess(0), 922 needAll(1), 923 notOrderDependent(2), 924 }, 925 option-field { } -- a sequence 926 reserved for future use 928 transaction-response-list[] ::= { 929 choice { 930 create-transaction-response, 931 modify-transaction-response, 932 delete-transaction-response, 933 set-objects-response -- sub-transactions 934 -- iana assigned extensions here? 935 }, ... 936 } 937 } 938 ... -- possibly more set-objects 939 } 940 } 942 -- duplication of the original requested creation. 943 create-transaction-response ::= { 944 request-base-OID, -- (eg, OID for a table) 946 index-data-list[] ::= { 947 { index-number Integer32, 948 index-value BER }, 949 ... 950 } 951 column-data-list[] ::= { 952 { column-number Integer32, 953 column-value BER }, 954 ... 955 } 956 } 958 -- returns all indexes for all rows affected by the modification request 959 -- note that the return is a array, but the request was not. IE, 960 -- all objects which were operated on are returned. 961 modify-transaction-response[] ::= { { 962 request-base-OID, -- (eg, OID for a table) 964 index-data-list[] ::= { 965 { index-number Integer32, -- ** see below 966 index-value BER }, 967 ... 968 }, 970 column-data-list[] ::= { 971 { column-number Integer32, -- ** see below 972 column-value BER }, 973 ... 974 } 975 } } 977 -- returns all indexes for all rows affected by the deletion request 978 -- note that the return is a array, but the request was not. IE, 979 -- all objects which were operated on are returned. 980 delete-transaction ::= { 981 request-base-OID, -- (eg, OID for a table) 983 index-data-list[] ::= { 984 { index-number Integer32, -- ** see below 985 index-value BER }, 986 ... 987 } 988 } 990 5. ASN.1 definitions for the PDUs 992 To be defined at a later date. 994 6. Examples 996 Here are some example requests and responses of data retrieval (I 997 didn't have time to put in Write examples). In each case, the curly 998 brases indicate a sequence of some kind within BER (in the case of 999 index lists, they'd be a application taged sequence as opposed to 1000 the normal BER sequence). 1002 6.1. Retrieve a specific row from the ifTable 1004 This example retrieves the ifDescr and ifType columns for the 5th 1005 interface from the ifTable 1007 The Request: 1009 Get-Object-PDU { 1010 request-id 1 1011 request-objects ::= { { 1012 max-return-objects 0 -- get all 1013 skip-objects 0 -- starting with the first 1014 cursor "" -- 0 length for first request 1015 flags 0 -- none specified. 1016 option-field {} 1018 request-base-object ::= OID:ifTable 1020 index-request-list ::= {} 1021 column-request-list ::= {2, 3} -- ifDescr, ifType 1023 index-search-objects ::= { 1024 { index-number = 1, -- ifIndex 1025 match-type = 0, -- equals 1026 index-search-value = 5 } -- the fifth 1027 } 1029 column-search-objects ::= { } -- none 1030 } } 1031 } 1033 The Response: 1035 Get-Object-Response-PDU { 1036 request-id 1 1037 response-objects ::= { { 1038 error-status 0 -- noError 1039 error-index 0 -- must be 0 if noError 1040 error-string "" 1041 cursor "interface 5" -- agent implementation cursor. 1043 flags 0 -- none specified. 1044 option-field {} 1046 request-base-object ::= OID:ifTable 1048 data-list ::= { { 1049 index-data-list ::= { } -- none were requested 1051 column-data-list ::= { 1052 { column-number = 2, 1053 column-value = "interface 5" }, 1054 { column-number = 3, 1055 column-value = 6 } -- ethernetCsmacd 1056 } 1057 } } 1058 } } 1059 } 1061 6.2. A multiple-packet example with a double filter. 1063 This example shows the retrieval of the elements of the ifTable 1064 which are of type "ethernetCsmacd" and have a ifSpeed >= 10,000,000 1065 bps. Retrieve only 1 row at a time. Note that the response has the 1066 objects returned in the order the remote agent specified [interface 1067 12, then interface 5], not in something that would map to the older- 1068 style lexographical ordering. The order returned must be consistent 1069 from one request to the next, but the manner in which the ordering 1070 is accomplished is ipmlementation specific. The cursor is used to 1071 indicate to the base agent where the request should restart from. 1072 Also, the dontReturnObjectNumbers bit is specified, which means the 1073 returned response should not include the component numbering fields 1074 and that the manager will remember what the original request was in 1075 order to understand the response. 1076 The first request: 1078 Get-Object-PDU { 1079 request-id 2 1080 request-objects ::= { { 1081 max-return-objects 1 -- only return 1 1082 skip-objects 0 -- starting with the first 1083 cursor "" -- 0 length for first request 1084 flags { dontReturnObjectNumbers } 1085 option-field {} 1087 request-base-object ::= OID:ifTable 1089 index-request-list ::= {} -- none 1090 column-request-list ::= {1, 2, 3} -- ifIndex, ifDescr, ifType 1092 index-search-objects ::= { } -- none 1094 column-search-objects ::= { 1095 { column-number = 3, -- ifType 1096 match-type = 0, -- equals 1097 column-search-value = 6 }, -- ethernetCsmacd 1098 { column-number = 5, -- ifSpeed 1099 match-type = 12, -- greaterThanOrEqual 1100 column-search-value = 10000000 }, -- 10 Mbps 1101 } 1102 } } 1103 } 1105 The first response: 1107 Get-Object-Response-PDU { 1108 request-id 2 1109 response-objects ::= { { 1110 error-status 0 -- noError 1111 error-index 0 -- must be 0 if noError 1112 error-string "" 1113 cursor "interface 12" -- agent implementation cursor. 1114 flags { dontReturnObjectNumbers } 1115 option-field {} 1117 request-base-object ::= OID:ifTable 1119 data-list ::= { { 1120 index-data-list ::= { } -- none requested 1122 column-data-list ::= { 1123 { column-value = 12 } -- ifIndex = 12 1124 { column-value = "interface 12" }, -- idDescr 1125 { column-value = 100000000 } -- ifSpeed = 100Mbs 1126 } 1127 } } 1128 } } 1129 } 1131 The second request to obtain the rest of the data: 1133 Get-Object-PDU { 1134 request-id 2 1135 request-objects ::= { { 1136 max-return-objects 1 -- only return 1 1137 skip-objects 0 -- functionally not used 1138 cursor "interface 12" -- cursor where we left off at 1139 flags { dontReturnObjectNumbers } 1140 option-field {} 1142 request-base-object ::= OID:ifTable 1144 index-request-list ::= {} -- none 1145 column-request-list ::= {1, 2, 5} -- ifIndex, ifDescr, ifSpeed 1147 index-search-objects ::= { } -- none 1149 column-search-objects ::= { 1150 { column-number = 3, -- ifType 1151 match-type = 0, -- equals 1152 column-search-value = 6 }, -- ethernetCsmacd 1153 { column-number = 5, -- ifSpeed 1154 match-type = 12, -- greaterThanOrEqual 1155 column-search-value = 10000000 }, -- 10 Mbps 1156 } 1157 } } 1158 } 1160 The second response: 1162 Get-Object-Response-PDU { 1163 request-id 2 1164 response-objects ::= { { 1165 error-status 0 -- noError 1166 error-index 0 -- must be 0 if noError 1167 error-string "" 1168 cursor "interface 5" -- agent implementation cursor. 1169 flags { dontReturnObjectNumbers } 1170 option-field {} 1172 request-base-object ::= OID:ifTable 1174 data-list ::= { { 1175 index-data-list ::= { } -- none requested 1177 column-data-list ::= { 1178 { column-value = 5 } -- ifIndex = 5 1179 { column-value = "interface 5" }, -- idDescr 1180 { column-value = 100000000 } -- ifSpeed = 100Mbs 1181 } 1182 } } 1183 } } 1184 } 1186 7. Elements of Procedure. 1188 To be done... 1190 8. Design Considerations and Questions 1192 A lot of thought has gone into the PDUs defined in this document. 1193 I've tried to achieve a balance between flexibility and interoper� 1194 ability that will lean toward interoperability most of the time. 1195 Comments welcome. This section describes some of the things that 1196 I'm still thinking about and would like feedback on. 1198 8.1. Return-field ranges 1200 Currently the list of columns/indexes to return contains only a list 1201 of integers, which could be long if you needed every column from 1202 1-25 but not 26-30, for example. Should we support the notion of 1203 "1-25" and if we do, should we only support ranges or should we try 1204 and mix and match. IE, how do you expresss "1-10 and 15 and 20-30": 1205 a) 1,10,15,15,20,30 1206 b) {1,10},15,{20,30} {}s would have to specially tagged sequences 1207 c) 1,2,3,...,10,15,20,21,...,30 1209 8.2. Write-Object-PDU complexity 1211 In the long run, I made the Write-Object-PDU more powerful than I 1212 was originally thinking. It took me a while to decide what to do, 1213 but the more I thought about it the processing of the requests con� 1214 tained within will not be that difficult. Specifically, the opera� 1215 tions are very recursive in nature and the complexity when dealing 1216 with one specific component is isolated. Rollback to some extent is 1217 still going to be necessary, but the PDU likely reduces the amount 1218 of UNDO processing due to the fact that you can encode failure cases 1219 which may be known to be problematic and can be ignored. 1221 I debated for a while whether to put create/delete/modify transac� 1222 tions with the same request, but I've come to believe that it's very 1223 necessary. Specifically, it's likely that you'll only want to 1224 delete a row if and only if the creation of another row succeeds. 1225 If either of these fail, then the entire transaction should fail 1226 else the box may be left in an un-usable state. However, there are 1227 also likely times that they are completely unrelated transactions, 1228 and thus can be flagged as independent using the needSuccess bit. 1230 One possible simplification would be to remove the recursiveness of 1231 the transaction and to leave everything else. If I were to remove 1232 anything, this would likely be it. I don't actually think it'll 1233 remove processing code within the agent, but it may lead to greater 1234 interoperability. I'm not at all convinced that's the case, how� 1235 ever. 1237 8.3. Get-Object/Write-Object commonality. 1239 The more I think about it, the more that I'm beginning to lean 1240 toward the idea that the Get-Object and Write-Object-PDUs should be 1241 similar in design. I debated for a long time whether the search 1242 criteria should go into the Write-Object-PDU or not, and I'm still 1243 not entirely decided (but it's there now). 1245 The danger comes in non-equal sign search criteria where you might 1246 think you know all the data on the far side that you're going to 1247 operate on, but it turns out that new rows have added by another 1248 source and thus you might affect a row you didn't otherwise intend 1249 to. However, I'm currently leaning toward the thought that the 1250 power to affect multiple objects with one transaction would be 1251 greatly beneficial. It will certainly help scaling with respect to 1252 management of extremely large networks containing lots of data which 1253 needs to be modified. 1255 In either case, it would be highly beneficial to retrieve a list of 1256 all the rows which were modified, thus the Write-Object transactions 1257 are designed such that the indexes of all the datasets which have 1258 been affected by the transaction are returned to the caller. This 1259 is one way to check for errors in the case of external modifica� 1260 tions. 1262 So, the real question is: Do we want search criteria in Write-Object 1263 operations? I'm still leaning toward yes (even more so after writ� 1264 ing this section). 1266 8.4. Concrete packet formats vs optional field formats. 1268 Warning: Assumes a lot of knowledge about BER encoding beyond what 1269 SNMP uses today. Some background is given, but not as much as is 1270 probably needed. 1272 The PDUs defined in this document today aren't described in an ASN.1 1273 notation yet. We have a few options when deciding how we want to 1274 encode them. 1276 First, ASN.1/BER has the ability to define "optional" fields. These 1277 fields simply wouldn't exist in the packet unless they are needed. 1278 SNMP has traditionally relied on a fixed packet format without 1279 optional fields. Breaking from this tradition may provide some 1280 packet compression and extensibility benefits. The down side is 1281 that sequences with enumerated data fields have an extra tag/length 1282 wrapper around each component within a sequence. (so data within 1283 becomes: sequence-number-tag length datatype-tag length DATA). Note 1284 that you essentially get a minimum of another 2-byte overhead on 1285 each field within each sequence. 1287 The optional-field structures within the packet, I think, must be 1288 defined using these enumerated sequences and everything within must 1289 be defined as OPTIONAL, or else they may not be expressible in an 1290 extensible way. 1292 However, there are some other cases where we may want to adopt this 1293 style of encoding. In the above PDUs, the following components are 1294 functionally "optional" in nature. Some are sequences, and having a 1295 empty sequence is functionally equivalent to an optional set of 1296 data. However, if truly marked as OPTIONAL then they wouldn't be in 1297 the packet at all (and the two byte "30 00" empty sequence portion 1298 wouldn't be encoded): 1300 Get-Object-PDU: 1301 index-request-list 1302 column-request-list 1303 index-search-objects 1304 column-search-objects 1305 option-field 1306 match-type -- missing is = 1308 Get-Object-Response-PDU: 1309 error-status -- if missing, no error! 1310 error-index 1311 error-string 1312 option-field 1313 index-number 1314 column-number 1316 Write-Object-PDU: 1317 index-search-objects 1318 column-search-objects 1319 option-field 1320 match-type -- missing is = 1322 I don't think we should mix and match encoding styles. IE, we 1323 should probably pick whether we going to do enumerated sequences for 1324 every portion of the packet (suffering the two-byte-minimum overhead 1325 on each portion) or not do it at all. Anyone have preferences? 1327 8.5. Push Button Functionality. 1329 SNMP usage has proven that method invocation is needed within the 1330 protocol. The SET semantics and Write-Object semantics do not make 1331 this easy. Should a "invocation" write method be put in here now, 1332 even though we don't have a SMI that can define it's usage yet? 1334 9. Author's Addresses: 1336 Wes Hardaker 1337 P.O. Box 382 1338 Davis, CA 95617 1339 Email: hardaker@tislabs.com 1341 10. References 1343 [OPREQ] Woodcock, D., "Operator Requirements of Infrastructure Management 1344 Methods", Internet Draft draft-ops-operator-req-mgmt-02.txt, 1345 expired August 2002. 1347 11. Full Copyright Statement 1349 Copyright (C) The Internet Society (2002). All Rights Reserved. 1351 This document and translations of it may be copied and furnished to 1352 others, and derivative works that comment on or otherwise explain it 1353 or assist in its implementation may be prepared, copied, published 1354 and distributed, in whole or in part, without restriction of any 1355 kind, provided that the above copyright notice and this paragraph 1356 are included on all such copies and derivative works. However, this 1357 document itself may not be modified in any way, such as by removing 1358 the copyright notice or references to the Internet Society or other 1359 Internet organizations, except as needed for the purpose of develop� 1360 ing Internet standards in which case the procedures for copyrights 1361 defined in the Internet Standards process must be followed, or as 1362 required to translate it into languages other than English. 1364 The limited permissions granted above are perpetual and will not be 1365 revoked by the Internet Society or its successors or assigns. 1367 This document and the information contained herein is provided on an 1368 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 1369 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 1370 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 1371 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 1372 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1374 12. Humor 1376 GOP GORP? 1377 WOP WORP. 1379 NOP NORP!