1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1996-2017. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%%---------------------------------------------------------------------- 22%% Number of expected shift/reduce warnings 23%% This is ugly but... 24%%---------------------------------------------------------------------- 25 26Expect 2. 27 28 29%% ---------------------------------------------------------------------- 30Nonterminals 31%% ---------------------------------------------------------------------- 32accessv1 33definition 34defvalpart 35description 36descriptionfield 37displaypart 38entry 39namedbits 40fatherobjectname 41fieldname 42fields 43implies 44import 45import_stuff 46imports 47imports_from_one_mib 48index 49indexpartv1 50indextypev1 51indextypesv1 52parentintegers 53listofdefinitions 54listofimports 55mib 56mibname 57nameassign 58newtype 59newtypename 60objectidentifier 61objectname 62objecttypev1 63prodrel 64range_num 65referpart 66size 67sizedescr 68statusv1 69syntax 70tableentrydefinition 71traptype 72type 73usertype 74variables 75varpart 76 77%v2 78moduleidentity 79revisionpart 80revisions 81listofdefinitionsv2 82mibid 83last_updated 84organization 85contact_info 86revision 87revision_string 88revision_desc 89v1orv2 90objectidentity 91objecttypev2 92unitspart 93indexpartv2 94indextypesv2 95indextypev2 96statusv2 97accessv2 98notification 99objectspart 100objects 101definitionv2 102textualconvention 103objectgroup 104notificationgroup 105modulecompliance 106mc_modulepart 107mc_modules 108mc_module 109mc_modulenamepart 110mc_mandatorypart 111mc_compliancepart 112mc_compliances 113mc_compliance 114mc_compliancegroup 115mc_object 116mc_accesspart 117agentcapabilities 118ac_status 119ac_modulepart 120ac_modules 121ac_module 122ac_modulenamepart 123ac_variationpart 124ac_variations 125ac_variation 126ac_accesspart 127ac_access 128ac_creationpart 129syntaxpart 130writesyntaxpart 131fsyntax 132defbitsvalue 133defbitsnames 134. 135%% ---------------------------------------------------------------------- 136Terminals 137%% ---------------------------------------------------------------------- 138integer variable atom string quote '{' '}' '::=' ':' '=' ',' '.' '(' ')' ';' '|' 139'ACCESS' 140'BEGIN' 141'BIT' 142'Counter' 143'DEFINITIONS' 144'DEFVAL' 145'DESCRIPTION' 146'DISPLAY-HINT' 147'END' 148'ENTERPRISE' 149'FROM' 150'Gauge' 151'IDENTIFIER' 152'IMPORTS' 153'INDEX' 154'INTEGER' 155'IpAddress' 156'NetworkAddress' 157'OBJECT' 158'OBJECT-TYPE' 159'OCTET' 160'OF' 161'Opaque' 162'REFERENCE' 163'SEQUENCE' 164'SIZE' 165'STATUS' 166'STRING' 167'SYNTAX' 168'TRAP-TYPE' 169'TimeTicks' 170'VARIABLES' 171 172%v2 173'LAST-UPDATED' 174'ORGANIZATION' 175'CONTACT-INFO' 176'MODULE-IDENTITY' 177'NOTIFICATION-TYPE' 178'PRODUCT-RELEASE' 179'AGENT-CAPABILITIES' 180'INCLUDES' 181'SUPPORTS' 182'VARIATION' 183'CREATION-REQUIRES' 184'MODULE-COMPLIANCE' 185'OBJECT-GROUP' 186'NOTIFICATION-GROUP' 187'REVISION' 188'OBJECT-IDENTITY' 189'MAX-ACCESS' 190'UNITS' 191'AUGMENTS' 192'IMPLIED' 193'OBJECTS' 194'TEXTUAL-CONVENTION' 195'NOTIFICATIONS' 196'MODULE' 197'MANDATORY-GROUPS' 198'GROUP' 199'WRITE-SYNTAX' 200'MIN-ACCESS' 201'BITS' 202'DisplayString' 203'PhysAddress' 204'MacAddress' 205'TruthValue' 206'TestAndIncr' 207'AutonomousType' 208'InstancePointer' 209'VariablePointer' 210'RowPointer' 211'RowStatus' 212'TimeStamp' 213'TimeInterval' 214'DateAndTime' 215'StorageType' 216'TDomain' 217'TAddress' 218. 219 220 221Rootsymbol mib. 222Endsymbol '$end'. 223 224% ********************************************************************** 225 226mib -> mibname 'DEFINITIONS' implies 'BEGIN' 227 import v1orv2 'END' 228 : {Version, Defs} = '$6', 229 #pdata{mib_version = Version, 230 mib_name = '$1', 231 imports = '$5', 232 defs = Defs}. 233 234v1orv2 -> moduleidentity listofdefinitionsv2 : 235 {v2_mib, ['$1'|lreverse(v1orv2_mod, '$2')]}. 236v1orv2 -> listofdefinitions : {v1_mib, lreverse(v1orv2_list, '$1')}. 237 238definition -> objectidentifier : '$1'. 239definition -> objecttypev1 : '$1'. 240definition -> newtype : '$1'. 241definition -> tableentrydefinition : '$1'. 242definition -> traptype : '$1'. 243 244listofdefinitions -> definition : ['$1'] . 245listofdefinitions -> listofdefinitions definition : ['$2' | '$1']. 246 247import -> '$empty' : []. 248import -> 'IMPORTS' imports ';' : 249%% i("import ->" 250%% "~n imports: ~p", ['$2']), 251 '$2'. 252 253imports -> imports_from_one_mib : 254%% i("imports ->" 255%% "~n imports_from_one_mib: ~p", ['$1']), 256 ['$1']. 257imports -> imports_from_one_mib imports : 258%% i("imports ->" 259%% "~n imports_from_one_mib: ~p" 260%% "~n imports: ~p", ['$1', '$2']), 261 ['$1' | '$2']. 262 263imports_from_one_mib -> listofimports 'FROM' variable : 264%% i("imports_from_one_mib ->" 265%% "~n listofimports: ~p" 266%% "~n variable: ~p", ['$1', '$3']), 267 {{val('$3'), lreverse(imports_from_one_mib, '$1')}, line_of('$2')}. 268 269listofimports -> import_stuff : 270%% i("listofimports ->" 271%% "~n import_stuff: ~p", ['$1']), 272 ['$1']. 273listofimports -> listofimports ',' import_stuff : 274%% i("listofimports ->" 275%% "~n listofimports: ~p" 276%% "~n import_stuff: ~p", ['$1', '$3']), 277 ['$3' | '$1']. 278 279import_stuff -> 'OBJECT-TYPE' : {builtin, 'OBJECT-TYPE'}. 280import_stuff -> 'TRAP-TYPE' : {builtin, 'TRAP-TYPE'}. 281import_stuff -> 'NetworkAddress' : {builtin, 'NetworkAddress'}. 282import_stuff -> 'TimeTicks' : {builtin, 'TimeTicks'}. 283import_stuff -> 'IpAddress' : {builtin, 'IpAddress'}. 284import_stuff -> 'Counter' : {builtin, 'Counter'}. 285import_stuff -> 'Gauge' : {builtin, 'Gauge'}. 286import_stuff -> 'Opaque' : {builtin, 'Opaque'}. 287import_stuff -> variable : filter_v2imports(get(snmp_version), val('$1')). 288import_stuff -> atom : {node, val('$1')}. 289%%v2 290import_stuff -> 'MODULE-IDENTITY' 291 : ensure_ver(2,'$1'), {builtin, 'MODULE-IDENTITY'}. 292import_stuff -> 'NOTIFICATION-TYPE' 293 : ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-TYPE'}. 294import_stuff -> 'AGENT-CAPABILITIES' 295 : ensure_ver(2,'$1'), {builtin, 'AGENT-CAPABILITIES'}. 296import_stuff -> 'MODULE-COMPLIANCE' 297 : ensure_ver(2,'$1'), {builtin, 'MODULE-COMPLIANCE'}. 298import_stuff -> 'NOTIFICATION-GROUP' 299 : ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-GROUP'}. 300import_stuff -> 'OBJECT-GROUP' 301 : ensure_ver(2,'$1'), {builtin, 'OBJECT-GROUP'}. 302import_stuff -> 'OBJECT-IDENTITY' 303 : ensure_ver(2,'$1'), {builtin, 'OBJECT-IDENTITY'}. 304import_stuff -> 'TEXTUAL-CONVENTION' 305 : ensure_ver(2,'$1'), {builtin, 'TEXTUAL-CONVENTION'}. 306import_stuff -> 'DisplayString' 307 : ensure_ver(2,'$1'), {builtin, 'DisplayString'}. 308import_stuff -> 'PhysAddress' 309 : ensure_ver(2,'$1'), {builtin, 'PhysAddress'}. 310import_stuff -> 'MacAddress' 311 : ensure_ver(2,'$1'), {builtin, 'MacAddress'}. 312import_stuff -> 'TruthValue' 313 : ensure_ver(2,'$1'), {builtin, 'TruthValue'}. 314import_stuff -> 'TestAndIncr' 315 : ensure_ver(2,'$1'), {builtin, 'TestAndIncr'}. 316import_stuff -> 'AutonomousType' 317 : ensure_ver(2,'$1'), {builtin, 'AutonomousType'}. 318import_stuff -> 'InstancePointer' 319 : ensure_ver(2,'$1'), {builtin, 'InstancePointer'}. 320import_stuff -> 'VariablePointer' 321 : ensure_ver(2,'$1'), {builtin, 'VariablePointer'}. 322import_stuff -> 'RowPointer' 323 : ensure_ver(2,'$1'), {builtin, 'RowPointer'}. 324import_stuff -> 'RowStatus' 325 : ensure_ver(2,'$1'), {builtin, 'RowStatus'}. 326import_stuff -> 'TimeStamp' 327 : ensure_ver(2,'$1'), {builtin, 'TimeStamp'}. 328import_stuff -> 'TimeInterval' 329 : ensure_ver(2,'$1'), {builtin, 'TimeInterval'}. 330import_stuff -> 'DateAndTime' 331 : ensure_ver(2,'$1'), {builtin, 'DateAndTime'}. 332import_stuff -> 'StorageType' 333 : ensure_ver(2,'$1'), {builtin, 'StorageType'}. 334import_stuff -> 'TDomain' 335 : ensure_ver(2,'$1'), {builtin, 'TDomain'}. 336import_stuff -> 'TAddress' 337 : ensure_ver(2,'$1'), {builtin, 'TAddress'}. 338import_stuff -> 'BITS' 339 : ensure_ver(2,'$1'), {builtin, 'BITS'}. 340 341traptype -> objectname 'TRAP-TYPE' 'ENTERPRISE' objectname varpart 342 description referpart implies integer : 343 Trap = make_trap('$1', '$4', lreverse(traptype, '$5'), 344 '$6', '$7', val('$9')), 345 {Trap, line_of('$2')}. 346 347% defines a name to an internal node. 348objectidentifier -> objectname 'OBJECT' 'IDENTIFIER' nameassign : 349 {Parent, SubIndex} = '$4', 350 Int = make_internal('$1', dummy, Parent, SubIndex), 351 {Int, line_of('$2')}. 352 353% defines name, access and type for a variable. 354objecttypev1 -> objectname 'OBJECT-TYPE' 355 'SYNTAX' syntax 356 'ACCESS' accessv1 357 'STATUS' statusv1 358 'DESCRIPTION' descriptionfield 359 referpart indexpartv1 defvalpart 360 nameassign : 361 Kind = kind('$13', '$12'), 362 OT = make_object_type('$1', '$4', '$6', '$8', '$10', 363 '$11', Kind, '$14'), 364 {OT, line_of('$2')}. 365 366newtype -> newtypename implies syntax : 367 NT = make_new_type('$1', dummy, '$3'), 368 {NT, line_of('$2')}. 369 370tableentrydefinition -> newtypename implies 'SEQUENCE' '{' fields '}' : 371 Seq = make_sequence('$1', lreverse(tableentrydefinition, '$5')), 372 {Seq, line_of('$3')}. 373 374% returns: list of {<fieldname>, <asn1_type>} 375fields -> fieldname fsyntax : 376 [{val('$1'), '$2'}]. 377 378fields -> fields ',' fieldname fsyntax : [{val('$3'), '$4'} | '$1']. 379 380fsyntax -> 'BITS' : {{bits,[{dummy,0}]},line_of('$1')}. 381fsyntax -> syntax : '$1'. 382 383fieldname -> atom : '$1'. 384 385syntax -> usertype : {{type, val('$1')}, line_of('$1')}. 386syntax -> type : {{type, cat('$1')},line_of('$1')}. 387syntax -> type size : {{type_with_size, cat('$1'), '$2'},line_of('$1')}. 388syntax -> usertype size : {{type_with_size,val('$1'), '$2'},line_of('$1')}. 389syntax -> 'INTEGER' '{' namedbits '}' : 390 {{type_with_enum, 'INTEGER', '$3'}, line_of('$1')}. 391syntax -> 'BITS' '{' namedbits '}' : 392 ensure_ver(2,'$1'), 393 {{bits, '$3'}, line_of('$1')}. 394syntax -> usertype '{' namedbits '}' : 395 {{type_with_enum, 'INTEGER', '$3'}, line_of('$1')}. 396syntax -> 'SEQUENCE' 'OF' usertype : 397 {{sequence_of,val('$3')},line_of('$1')}. 398 399size -> '(' sizedescr ')' : make_range('$2'). 400size -> '(' 'SIZE' '(' sizedescr ')' ')' : make_range('$4'). 401 402%% Returns a list of integers describing a range. 403sizedescr -> range_num '.' '.' range_num : ['$1', '$4']. 404sizedescr -> range_num '.' '.' range_num sizedescr :['$1', '$4' |'$5']. 405sizedescr -> range_num : ['$1']. 406sizedescr -> sizedescr '|' sizedescr : ['$1', '$3']. 407 408range_num -> integer : val('$1') . 409range_num -> quote atom : make_range_integer(val('$1'), val('$2')) . 410range_num -> quote variable : make_range_integer(val('$1'), val('$2')) . 411 412namedbits -> atom '(' integer ')' : [{val('$1'), val('$3')}]. 413namedbits -> namedbits ',' atom '(' integer ')' : 414 [{val('$3'), val('$5')} | '$1']. 415 416usertype -> variable : '$1'. 417 418type -> 'OCTET' 'STRING' : {'OCTET STRING', line_of('$1')}. 419type -> 'BIT' 'STRING' : {'BIT STRING', line_of('$1')}. 420type -> 'OBJECT' 'IDENTIFIER' : {'OBJECT IDENTIFIER', line_of('$1')}. 421type -> 'INTEGER' : '$1'. 422type -> 'NetworkAddress' : '$1'. 423type -> 'IpAddress' : '$1'. 424type -> 'Counter' : ensure_ver(1,'$1'),'$1'. 425type -> 'Gauge' : ensure_ver(1,'$1'),'$1'. 426type -> 'TimeTicks' : '$1'. 427type -> 'Opaque' : '$1'. 428type -> 'DisplayString' : ensure_ver(2,'$1'), '$1'. 429type -> 'PhysAddress' : ensure_ver(2,'$1'), '$1'. 430type -> 'MacAddress' : ensure_ver(2,'$1'), '$1'. 431type -> 'TruthValue' : ensure_ver(2,'$1'), '$1'. 432type -> 'TestAndIncr' : ensure_ver(2,'$1'), '$1'. 433type -> 'AutonomousType' : ensure_ver(2,'$1'), '$1'. 434type -> 'InstancePointer' : ensure_ver(2,'$1'), '$1'. 435type -> 'VariablePointer' : ensure_ver(2,'$1'), '$1'. 436type -> 'RowPointer' : ensure_ver(2,'$1'), '$1'. 437type -> 'RowStatus' : ensure_ver(2,'$1'), '$1'. 438type -> 'TimeStamp' : ensure_ver(2,'$1'), '$1'. 439type -> 'TimeInterval' : ensure_ver(2,'$1'), '$1'. 440type -> 'DateAndTime' : ensure_ver(2,'$1'), '$1'. 441type -> 'StorageType' : ensure_ver(2,'$1'), '$1'. 442type -> 'TDomain' : ensure_ver(2,'$1'), '$1'. 443type -> 'TAddress' : ensure_ver(2,'$1'), '$1'. 444 445% Returns: {FatherName, SubIndex} (the parent) 446nameassign -> implies '{' fatherobjectname parentintegers '}' : {'$3', '$4' }. 447nameassign -> implies '{' parentintegers '}' : { root, '$3'}. 448 449 450varpart -> '$empty' : []. 451varpart -> 'VARIABLES' '{' variables '}' : '$3'. 452variables -> objectname : ['$1']. 453variables -> variables ',' objectname : ['$3' | '$1']. 454 455implies -> '::=' : '$1'. 456implies -> ':' ':' '=' : w("Sloppy asignment on line ~p", [line_of('$1')]), '$1'. 457descriptionfield -> string : lreverse(descriptionfield, val('$1')). 458descriptionfield -> '$empty' : undefined. 459description -> 'DESCRIPTION' string : lreverse(description, val('$2')). 460description -> '$empty' : undefined. 461 462displaypart -> 'DISPLAY-HINT' string : display_hint('$2') . 463displaypart -> '$empty' : undefined . 464 465% returns: {indexes, undefined} 466% | {indexes, IndexList} where IndexList is a list of aliasnames. 467indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lreverse(indexpartv1, '$3')}. 468indexpartv1 -> '$empty' : {indexes, undefined}. 469 470indextypesv1 -> indextypev1 : ['$1']. 471indextypesv1 -> indextypesv1 ',' indextypev1 : ['$3' | '$1']. 472 473indextypev1 -> index : '$1'. 474 475index -> objectname : '$1'. 476 477parentintegers -> integer : [val('$1')]. 478parentintegers -> atom '(' integer ')' : [val('$3')]. 479parentintegers -> integer parentintegers : [val('$1') | '$2']. 480parentintegers -> atom '(' integer ')' parentintegers : [val('$3') | '$5']. 481 482defvalpart -> 'DEFVAL' '{' integer '}' : {defval, val('$3')}. 483defvalpart -> 'DEFVAL' '{' atom '}' : {defval, val('$3')}. 484defvalpart -> 'DEFVAL' '{' '{' defbitsvalue '}' '}' : {defval, '$4'}. 485defvalpart -> 'DEFVAL' '{' quote atom '}' : 486 {defval, make_defval_for_string(line_of('$1'), 487 lreverse(defvalpart_quote_atom, val('$3')), 488 val('$4'))}. 489defvalpart -> 'DEFVAL' '{' quote variable '}' : 490 {defval, make_defval_for_string(line_of('$1'), 491 lreverse(defvalpart_quote_variable, val('$3')), 492 val('$4'))}. 493defvalpart -> 'DEFVAL' '{' string '}' : 494 {defval, lreverse(defvalpart_string, val('$3'))}. 495defvalpart -> '$empty' : undefined. 496 497defbitsvalue -> defbitsnames : '$1'. 498defbitsvalue -> '$empty' : []. 499 500defbitsnames -> atom : [val('$1')]. 501defbitsnames -> defbitsnames ',' atom : [val('$3') | '$1']. 502 503objectname -> atom : val('$1'). 504mibname -> variable : val('$1'). 505fatherobjectname -> objectname : '$1'. 506newtypename -> variable : val('$1'). 507 508accessv1 -> atom: accessv1('$1'). 509 510statusv1 -> atom : statusv1('$1'). 511 512referpart -> 'REFERENCE' string : lreverse(referpart, val('$2')). 513referpart -> '$empty' : undefined. 514 515 516%%---------------------------------------------------------------------- 517%% SNMPv2 grammatics 518%%v2 519%%---------------------------------------------------------------------- 520moduleidentity -> mibid 'MODULE-IDENTITY' 521 'LAST-UPDATED' last_updated 522 'ORGANIZATION' organization 523 'CONTACT-INFO' contact_info 524 'DESCRIPTION' descriptionfield 525 revisionpart nameassign : 526 MI = make_module_identity('$1', '$4', '$6', '$8', 527 '$10', '$11', '$12'), 528 {MI, line_of('$2')}. 529 530mibid -> atom : val('$1'). 531last_updated -> string : lreverse(last_updated, val('$1')) . 532organization -> string : lreverse(organization, val('$1')) . 533contact_info -> string : lreverse(contact_info, val('$1')) . 534 535revisionpart -> '$empty' : [] . 536revisionpart -> revisions : lreverse(revisionpart, '$1') . 537 538revisions -> revision : ['$1'] . 539revisions -> revisions revision : ['$2' | '$1'] . 540revision -> 'REVISION' revision_string 'DESCRIPTION' revision_desc : 541 make_revision('$2', '$4') . 542 543revision_string -> string : lreverse(revision_string, val('$1')) . 544revision_desc -> string : lreverse(revision_desc, val('$1')) . 545 546definitionv2 -> objectidentifier : '$1'. 547definitionv2 -> objecttypev2 : '$1'. 548definitionv2 -> textualconvention : '$1'. 549definitionv2 -> objectidentity : '$1'. 550definitionv2 -> newtype : '$1'. 551definitionv2 -> tableentrydefinition : '$1'. 552definitionv2 -> notification : '$1'. 553definitionv2 -> objectgroup : '$1'. 554definitionv2 -> notificationgroup : '$1'. 555definitionv2 -> modulecompliance : '$1'. 556definitionv2 -> agentcapabilities : '$1'. 557 558listofdefinitionsv2 -> '$empty' : [] . 559listofdefinitionsv2 -> listofdefinitionsv2 definitionv2 : ['$2' | '$1']. 560 561textualconvention -> newtypename implies 'TEXTUAL-CONVENTION' displaypart 562 'STATUS' statusv2 description referpart 'SYNTAX' syntax : 563 NT = make_new_type('$1', 'TEXTUAL-CONVENTION', '$4', 564 '$6', '$7', '$8', '$10'), 565 {NT, line_of('$3')}. 566 567objectidentity -> objectname 'OBJECT-IDENTITY' 'STATUS' statusv2 568 'DESCRIPTION' string referpart nameassign : 569 {Parent, SubIndex} = '$8', 570 Int = make_internal('$1', 'OBJECT-IDENTITY', 571 Parent, SubIndex), 572 {Int, line_of('$2')}. 573 574objectgroup -> objectname 'OBJECT-GROUP' objectspart 575 'STATUS' statusv2 description referpart nameassign : 576 OG = make_object_group('$1', '$3', '$5', '$6', '$7', '$8'), 577 {OG, line_of('$2')}. 578 579notificationgroup -> objectname 'NOTIFICATION-GROUP' 'NOTIFICATIONS' '{' 580 objects '}' 'STATUS' statusv2 description referpart 581 nameassign : 582 NG = make_notification_group('$1', '$5', '$8', '$9', 583 '$10', '$11'), 584 {NG, line_of('$2')}. 585 586modulecompliance -> objectname 'MODULE-COMPLIANCE' 'STATUS' statusv2 587 description referpart mc_modulepart nameassign : 588%% io:format("modulecompliance -> " 589%% "~n '$1': ~p" 590%% "~n '$4': ~p" 591%% "~n '$5': ~p" 592%% "~n '$6': ~p" 593%% "~n '$7': ~p" 594%% "~n '$8': ~p" 595%% "~n", ['$1', '$4', '$5', '$6', '$7', '$8']), 596 MC = make_module_compliance('$1', '$4', '$5', '$6', 597 '$7', '$8'), 598%% io:format("modulecompliance -> " 599%% "~n MC: ~p" 600%% "~n", [MC]), 601 {MC, line_of('$2')}. 602 603 604agentcapabilities -> objectname 'AGENT-CAPABILITIES' 605 'PRODUCT-RELEASE' prodrel 606 'STATUS' ac_status 607 description referpart ac_modulepart nameassign : 608 AC = make_agent_capabilities('$1', '$4', '$6', '$7', 609 '$8', '$9', '$10'), 610 {AC, line_of('$2')}. 611 612prodrel -> string : lreverse(prodrel, val('$1')). 613 614ac_status -> atom : ac_status('$1'). 615 616ac_modulepart -> ac_modules : 617 lreverse(ac_modulepart, '$1'). 618ac_modulepart -> '$empty' : 619 []. 620 621ac_modules -> ac_module : 622 ['$1']. 623ac_modules -> ac_module ac_modules : 624 ['$1' | '$2']. 625 626ac_module -> 'SUPPORTS' ac_modulenamepart 'INCLUDES' '{' objects '}' ac_variationpart : 627 make_ac_module('$2', '$5', '$7'). 628 629ac_modulenamepart -> mibname : '$1'. 630ac_modulenamepart -> '$empty' : undefined. 631 632ac_variationpart -> '$empty' : 633 []. 634ac_variationpart -> ac_variations : 635 lreverse(ac_variationpart, '$1'). 636 637ac_variations -> ac_variation : 638 ['$1']. 639ac_variations -> ac_variation ac_variations : 640 ['$1' | '$2']. 641 642%% ac_variation -> ac_objectvariation. 643%% ac_variation -> ac_notificationvariation. 644 645ac_variation -> 'VARIATION' objectname syntaxpart writesyntaxpart ac_accesspart ac_creationpart defvalpart description : 646 make_ac_variation('$2', '$3', '$4', '$5', '$6', '$7', '$8'). 647 648ac_accesspart -> 'ACCESS' ac_access : '$2'. 649ac_accesspart -> '$empty' : undefined. 650 651ac_access -> atom: ac_access('$1'). 652 653ac_creationpart -> 'CREATION-REQUIRES' '{' objects '}' : 654 lreverse(ac_creationpart, '$3'). 655ac_creationpart -> '$empty' : 656 []. 657 658mc_modulepart -> '$empty' : 659 []. 660mc_modulepart -> mc_modules : 661 lreverse(mc_modulepart, '$1'). 662 663mc_modules -> mc_module : 664 ['$1']. 665mc_modules -> mc_module mc_modules : 666 ['$1' | '$2']. 667 668mc_module -> 'MODULE' mc_modulenamepart mc_mandatorypart mc_compliancepart : 669 make_mc_module('$2', '$3', '$4'). 670 671mc_modulenamepart -> mibname : '$1'. 672mc_modulenamepart -> '$empty' : undefined. 673 674mc_mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}' : 675 lreverse(mc_mandatorypart, '$3'). 676mc_mandatorypart -> '$empty' : 677 []. 678 679mc_compliancepart -> mc_compliances : 680 lreverse(mc_compliancepart, '$1'). 681mc_compliancepart -> '$empty' : 682 []. 683 684mc_compliances -> mc_compliance : 685 ['$1']. 686mc_compliances -> mc_compliance mc_compliances : 687 ['$1' | '$2']. 688 689mc_compliance -> mc_compliancegroup : 690 '$1'. 691mc_compliance -> mc_object : 692 '$1'. 693 694mc_compliancegroup -> 'GROUP' objectname description : 695 make_mc_compliance_group('$2', '$3'). 696 697mc_object -> 'OBJECT' objectname syntaxpart writesyntaxpart mc_accesspart description : 698 make_mc_object('$2', '$3', '$4', '$5', '$6'). 699 700syntaxpart -> 'SYNTAX' syntax : '$2'. 701syntaxpart -> '$empty' : undefined. 702 703writesyntaxpart -> 'WRITE-SYNTAX' syntax : '$2'. 704writesyntaxpart -> '$empty' : undefined. 705 706mc_accesspart -> 'MIN-ACCESS' accessv2 : '$2'. 707mc_accesspart -> '$empty' : undefined. 708 709objecttypev2 -> objectname 'OBJECT-TYPE' 710 'SYNTAX' syntax 711 unitspart 712 'MAX-ACCESS' accessv2 713 'STATUS' statusv2 714 'DESCRIPTION' descriptionfield 715 referpart indexpartv2 defvalpart 716 nameassign : 717 Kind = kind('$14', '$13'), 718 OT = make_object_type('$1', '$4', '$5', '$7', '$9', 719 '$11', '$12', Kind, '$15'), 720 {OT, line_of('$2')}. 721 722indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lreverse(indexpartv2, '$3')}. 723indexpartv2 -> 'AUGMENTS' '{' entry '}' : {augments, '$3'}. 724indexpartv2 -> '$empty' : {indexes, undefined}. 725 726indextypesv2 -> indextypev2 : ['$1']. 727indextypesv2 -> indextypesv2 ',' indextypev2 : ['$3' | '$1']. 728 729indextypev2 -> 'IMPLIED' index : {implied,'$2'}. 730indextypev2 -> index : '$1'. 731 732entry -> objectname : '$1'. 733 734unitspart -> '$empty' : undefined. 735unitspart -> 'UNITS' string : units('$2') . 736 737statusv2 -> atom : statusv2('$1'). 738 739accessv2 -> atom: accessv2('$1'). 740 741notification -> objectname 'NOTIFICATION-TYPE' objectspart 742 'STATUS' statusv2 'DESCRIPTION' descriptionfield referpart 743 nameassign : 744 Not = make_notification('$1','$3','$5', '$7', '$8', '$9'), 745 {Not, line_of('$2')}. 746 747objectspart -> 'OBJECTS' '{' objects '}' : lreverse(objectspart, '$3'). 748objectspart -> '$empty' : []. 749 750objects -> objectname : ['$1']. 751objects -> objects ',' objectname : ['$3'|'$1']. 752 753%%---------------------------------------------------------------------- 754Erlang code. 755%%---------------------------------------------------------------------- 756 757-include("snmp_types.hrl"). 758-include("snmpc_lib.hrl"). 759-include("snmpc.hrl"). 760 761% value 762val(Token) -> element(3, Token). 763 764line_of(Token) -> element(2, Token). 765 766%% category 767cat(Token) -> element(1, Token). 768 769statusv1(Tok) -> 770 case val(Tok) of 771 mandatory -> mandatory; 772 optional -> optional; 773 obsolete -> obsolete; 774 deprecated -> deprecated; 775 Else -> return_error(line_of(Tok), 776 "(statusv1) syntax error before: " ++ atom_to_list(Else)) 777 end. 778 779statusv2(Tok) -> 780 case val(Tok) of 781 current -> current; 782 deprecated -> deprecated; 783 obsolete -> obsolete; 784 Else -> return_error(line_of(Tok), 785 "(statusv2) syntax error before: " ++ atom_to_list(Else)) 786 end. 787 788ac_status(Tok) -> 789 case val(Tok) of 790 current -> current; 791 obsolete -> obsolete; 792 Else -> return_error(line_of(Tok), 793 "(ac_status) syntax error before: " ++ atom_to_list(Else)) 794 end. 795 796accessv1(Tok) -> 797 case val(Tok) of 798 'read-only' -> 'read-only'; 799 'read-write' -> 'read-write'; 800 'write-only' -> 'write-only'; 801 'not-accessible' -> 'not-accessible'; 802 Else -> return_error(line_of(Tok), 803 "(accessv1) syntax error before: " ++ atom_to_list(Else)) 804 end. 805 806accessv2(Tok) -> 807 case val(Tok) of 808 'not-accessible' -> 'not-accessible'; 809 'accessible-for-notify' -> 'accessible-for-notify'; 810 'read-only' -> 'read-only'; 811 'read-write' -> 'read-write'; 812 'read-create' -> 'read-create'; 813 Else -> return_error(line_of(Tok), 814 "(accessv2) syntax error before: " ++ atom_to_list(Else)) 815 end. 816 817ac_access(Tok) -> 818 case val(Tok) of 819 'not-implemented' -> 'not-implemented'; % only for notifications 820 'accessible-for-notify' -> 'accessible-for-notify'; 821 'read-only' -> 'read-only'; 822 'read-write' -> 'read-write'; 823 'read-create' -> 'read-create'; 824 'write-only' -> 'write-only'; % for backward-compatibility only 825 Else -> return_error(line_of(Tok), 826 "(ac_access) syntax error before: " ++ atom_to_list(Else)) 827 end. 828 829%% --------------------------------------------------------------------- 830%% Various basic record build functions 831%% --------------------------------------------------------------------- 832 833make_module_identity(Name, LU, Org, CI, Desc, Revs, NA) -> 834 #mc_module_identity{name = Name, 835 last_updated = LU, 836 organization = Org, 837 contact_info = CI, 838 description = Desc, 839 revisions = Revs, 840 name_assign = NA}. 841 842make_revision(Rev, Desc) -> 843 #mc_revision{revision = Rev, 844 description = Desc}. 845 846make_object_type(Name, Syntax, MaxAcc, Status, Desc, Ref, Kind, NA) -> 847 #mc_object_type{name = Name, 848 syntax = Syntax, 849 max_access = MaxAcc, 850 status = Status, 851 description = Desc, 852 reference = Ref, 853 kind = Kind, 854 name_assign = NA}. 855 856make_object_type(Name, Syntax, Units, MaxAcc, Status, Desc, Ref, Kind, NA) -> 857 #mc_object_type{name = Name, 858 syntax = Syntax, 859 units = Units, 860 max_access = MaxAcc, 861 status = Status, 862 description = Desc, 863 reference = Ref, 864 kind = Kind, 865 name_assign = NA}. 866 867make_new_type(Name, Macro, Syntax) -> 868 #mc_new_type{name = Name, 869 macro = Macro, 870 syntax = Syntax}. 871 872make_new_type(Name, Macro, DisplayHint, Status, Desc, Ref, Syntax) -> 873 #mc_new_type{name = Name, 874 macro = Macro, 875 status = Status, 876 description = Desc, 877 reference = Ref, 878 display_hint = DisplayHint, 879 syntax = Syntax}. 880 881make_trap(Name, Ent, Vars, Desc, Ref, Num) -> 882 #mc_trap{name = Name, 883 enterprise = Ent, 884 vars = Vars, 885 description = Desc, 886 reference = Ref, 887 num = Num}. 888 889make_notification(Name, Vars, Status, Desc, Ref, NA) -> 890 #mc_notification{name = Name, 891 vars = Vars, 892 status = Status, 893 description = Desc, 894 reference = Ref, 895 name_assign = NA}. 896 897make_agent_capabilities(Name, ProdRel, Status, Desc, Ref, Mods, NA) -> 898 #mc_agent_capabilities{name = Name, 899 product_release = ProdRel, 900 status = Status, 901 description = Desc, 902 reference = Ref, 903 modules = Mods, 904 name_assign = NA}. 905 906make_ac_variation(Name, 907 undefined = _Syntax, 908 undefined = _WriteSyntax, 909 Access, 910 undefined = _Creation, 911 undefined = _DefVal, 912 Desc) -> 913%% io:format("make_ac_variation -> entry with" 914%% "~n Name: ~p" 915%% "~n Access: ~p" 916%% "~n Desc: ~p" 917%% "~n", [Name, Access, Desc]), 918 #mc_ac_notification_variation{name = Name, 919 access = Access, 920 description = Desc}; 921 922make_ac_variation(Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc) -> 923%% io:format("make_ac_variation -> entry with" 924%% "~n Name: ~p" 925%% "~n Syntax: ~p" 926%% "~n WriteSyntax: ~p" 927%% "~n Access: ~p" 928%% "~n Creation: ~p" 929%% "~n DefVal: ~p" 930%% "~n Desc: ~p" 931%% "~n", [Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc]), 932 #mc_ac_object_variation{name = Name, 933 syntax = Syntax, 934 write_syntax = WriteSyntax, 935 access = Access, 936 creation = Creation, 937 default_value = DefVal, 938 description = Desc}. 939 940make_ac_module(Name, Grps, Var) -> 941 #mc_ac_module{name = Name, 942 groups = Grps, 943 variation = Var}. 944 945 946make_module_compliance(Name, Status, Desc, Ref, Mods, NA) -> 947 #mc_module_compliance{name = Name, 948 status = Status, 949 description = Desc, 950 reference = Ref, 951 modules = Mods, 952 name_assign = NA}. 953 954make_mc_module(Name, Mand, Compl) -> 955 #mc_mc_module{name = Name, 956 mandatory = Mand, 957 compliance = Compl}. 958 959make_mc_compliance_group(Name, Desc) -> 960 #mc_mc_compliance_group{name = Name, 961 description = Desc}. 962 963make_mc_object(Name, Syntax, WriteSyntax, Access, Desc) -> 964 #mc_mc_object{name = Name, 965 syntax = Syntax, 966 write_syntax = WriteSyntax, 967 access = Access, 968 description = Desc}. 969 970make_object_group(Name, Objs, Status, Desc, Ref, NA) -> 971 #mc_object_group{name = Name, 972 objects = Objs, 973 status = Status, 974 description = Desc, 975 reference = Ref, 976 name_assign = NA}. 977 978make_notification_group(Name, Objs, Status, Desc, Ref, NA) -> 979 #mc_notification_group{name = Name, 980 objects = Objs, 981 status = Status, 982 description = Desc, 983 reference = Ref, 984 name_assign = NA}. 985 986make_sequence(Name, Fields) -> 987 #mc_sequence{name = Name, 988 fields = Fields}. 989 990make_internal(Name, Macro, Parent, SubIdx) -> 991 #mc_internal{name = Name, 992 macro = Macro, 993 parent = Parent, 994 sub_index = SubIdx}. 995 996 997 998%% --------------------------------------------------------------------- 999 1000 1001%%---------------------------------------------------------------------- 1002%% Purpose: Find how much room needs to be allocated for the data type 1003%% (when sending it in a PDU (the maximum difference will be 1004%% the size allocated)). 1005%% This is applicable for OCTET STRINGs and OBJECT IDENTIFIERs. 1006%% 1007%% Or : Find the range of integers in the integer list. 1008%% This is applicable for INTEGERs 1009%% 1010%% Arg: A list of integers. 1011%%---------------------------------------------------------------------- 1012 1013make_range_integer(RevHexStr, h) -> 1014 erlang:list_to_integer(lists:reverse(RevHexStr), 16); 1015make_range_integer(RevHexStr, 'H') -> 1016 erlang:list_to_integer(lists:reverse(RevHexStr), 16); 1017make_range_integer(RevBitStr, b) -> 1018 erlang:list_to_integer(lists:reverse(RevBitStr), 2); 1019make_range_integer(RevBitStr, 'B') -> 1020 erlang:list_to_integer(lists:reverse(RevBitStr), 2); 1021make_range_integer(RevStr, Base) -> 1022 throw({error, {invalid_base, Base, lists:reverse(RevStr)}}). 1023 1024make_range(XIntList) -> 1025 IntList = lists:flatten(XIntList), 1026 {range, lists:min(IntList), lists:max(IntList)}. 1027 1028make_defval_for_string(Line, Str, Atom) -> 1029 case lists:member(Atom, [h, 'H', b, 'B']) of 1030 true -> 1031 case catch make_defval_for_string2(Str, Atom) of 1032 Defval when is_list(Defval) -> 1033 Defval; 1034 {error, ErrStr} -> 1035 snmpc_lib:print_error("Bad DEFVAL ~w string ~p - ~s", 1036 [Atom, Str, ErrStr], 1037 Line), 1038 ""; 1039 _Else -> 1040 snmpc_lib:print_error("Bad DEFVAL ~w string ~p", 1041 [Atom, Str], 1042 Line), 1043 "" 1044 end; 1045 false -> 1046 snmpc_lib:print_error("Bad DEFVAL string type ~w for ~p", 1047 [Atom, Str], 1048 Line), 1049 "" 1050 end. 1051 1052 1053make_defval_for_string2([], h) -> []; 1054make_defval_for_string2([X16,X|HexString], h) -> 1055 lists:append(hex_to_bytes(snmpc_misc:to_upper([X16,X])), 1056 make_defval_for_string2(HexString, h)); 1057make_defval_for_string2([_Odd], h) -> 1058 throw({error, "odd number of bytes in hex string"}); 1059make_defval_for_string2(HexString, 'H') -> 1060 make_defval_for_string2(HexString,h); 1061 1062make_defval_for_string2(BitString, 'B') -> 1063 bits_to_bytes(BitString); 1064make_defval_for_string2(BitString, b) -> 1065 make_defval_for_string2(BitString, 'B'). 1066 1067bits_to_bytes(BitStr) -> 1068 lists:reverse(bits_to_bytes(lists:reverse(BitStr), 1, 0)). 1069 1070bits_to_bytes([], 1, _Byte) -> % empty bitstring 1071 []; 1072bits_to_bytes([], 256, _Byte) -> % correct; multiple of 8 1073 []; 1074% If we are to support arbitrary length of bitstrings. This migth 1075% be needed in the new SMI. 1076%bits_to_bytes([], N, Byte) -> 1077% [Byte]; 1078bits_to_bytes([], _N, _Byte) -> 1079 throw({error, "not a multiple of eight bits in bitstring"}); 1080bits_to_bytes(Rest, 256, Byte) -> 1081 [Byte | bits_to_bytes(Rest, 1, 0)]; 1082bits_to_bytes([$1 | T], N, Byte) -> 1083 bits_to_bytes(T, N*2, N + Byte); 1084bits_to_bytes([$0 | T], N, Byte) -> 1085 bits_to_bytes(T, N*2, Byte); 1086bits_to_bytes([_BadChar | _T], _N, _Byte) -> 1087 throw({error, "bad character in bit string"}). 1088 1089%%---------------------------------------------------------------------- 1090%% These HEX conversion routines are stolen from module asn1_bits by 1091%% klacke@erix.ericsson.se 1092%% I didn't want to ship the entire asn1-compiler so I used cut-and-paste. 1093%%---------------------------------------------------------------------- 1094 1095%% hex_to_bytes(HexNumber) when is_atom(HexNumber) -> 1096%% hex_to_bytes(atom_to_list(HexNumber)); 1097 1098hex_to_bytes(HexNumber) -> 1099 case length(HexNumber) rem 2 of 1100 1 -> %% Odd 1101 hex_to_bytes(lists:append(HexNumber,[$0]),[]); 1102 0 -> %% even 1103 hex_to_bytes(HexNumber,[]) 1104 end. 1105 1106hex_to_bytes([],R) -> 1107 lists:reverse(R); 1108hex_to_bytes([Hi,Lo|Rest],Res) -> 1109 hex_to_bytes(Rest,[hex_to_byte(Hi,Lo)|Res]). 1110 1111hex_to_four_bits(Hex) -> 1112 if 1113 Hex == $0 -> 0; 1114 Hex == $1 -> 1; 1115 Hex == $2 -> 2; 1116 Hex == $3 -> 3; 1117 Hex == $4 -> 4; 1118 Hex == $5 -> 5; 1119 Hex == $6 -> 6; 1120 Hex == $7 -> 7; 1121 Hex == $8 -> 8; 1122 Hex == $9 -> 9; 1123 Hex == $A -> 10; 1124 Hex == $B -> 11; 1125 Hex == $C -> 12; 1126 Hex == $D -> 13; 1127 Hex == $E -> 14; 1128 Hex == $F -> 15; 1129 true -> throw({error, "bad hex character"}) 1130 end. 1131 1132hex_to_byte(Hi,Lo) -> 1133 (hex_to_four_bits(Hi) bsl 4) bor hex_to_four_bits(Lo). 1134 1135kind(DefValPart,IndexPart) -> 1136 case DefValPart of 1137 undefined -> 1138 case IndexPart of 1139 {indexes, undefined} -> {variable, []}; 1140 {indexes, Indexes} -> 1141 {table_entry, {indexes, Indexes}}; 1142 {augments,Table} -> 1143 {table_entry,{augments,Table}} 1144 end; 1145 {defval, DefVal} -> {variable, [{defval, DefVal}]} 1146 end. 1147 1148display_hint(Val) -> 1149 case val(Val) of 1150 Str when is_list(Str) -> 1151 lists:reverse(Str); 1152 _ -> 1153 throw({error, {invalid_display_hint, Val}}) 1154 end. 1155 1156units(Val) -> 1157 case val(Val) of 1158 Str when is_list(Str) -> 1159 lists:reverse(Str); 1160 _ -> 1161 throw({error, {invalid_units, Val}}) 1162 end. 1163 1164ensure_ver(Ver, Line, What) -> 1165 case get(snmp_version) of 1166 Ver -> ok; 1167 _Other -> 1168 snmpc_lib:print_error( 1169 "~s is only allowed in SNMPv~p.",[What,Ver],Line) 1170 end. 1171 1172 1173ensure_ver(Ver,Token) -> 1174 ensure_ver(Ver,line_of(Token), atom_to_list(cat(Token))). 1175 1176filter_v2imports(2,'Integer32') -> {builtin, 'Integer32'}; 1177filter_v2imports(2,'Counter32') -> {builtin, 'Counter32'}; 1178filter_v2imports(2,'Gauge32') -> {builtin, 'Gauge32'}; 1179filter_v2imports(2,'Unsigned32') -> {builtin, 'Unsigned32'}; 1180filter_v2imports(2,'Counter64') -> {builtin, 'Counter64'}; 1181filter_v2imports(_,Type) -> {type, Type}. 1182 1183w(F, A) -> 1184 ?vwarning(F, A). 1185 1186lreverse(_Tag, L) when is_list(L) -> 1187 lists:reverse(L); 1188lreverse(Tag, X) -> 1189 exit({bad_list, Tag, X}). 1190 1191 1192%% i(F, A) -> 1193%% io:format("~w:" ++ F ++ "~n", [?MODULE|A]). 1194 1195