netsnmp 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +26 -4
- data/lib/netsnmp.rb +12 -0
- data/lib/netsnmp/client.rb +1 -1
- data/lib/netsnmp/mib.rb +151 -0
- data/lib/netsnmp/mib/parser.rb +750 -0
- data/lib/netsnmp/oid.rb +4 -10
- data/lib/netsnmp/version.rb +1 -1
- data/sig/mib.rbs +18 -0
- data/sig/mib/parser.rbs +7 -0
- data/sig/oid.rbs +1 -1
- data/spec/client_spec.rb +6 -6
- data/spec/handlers/celluloid_spec.rb +1 -1
- data/spec/mib_spec.rb +13 -0
- data/spec/spec_helper.rb +2 -0
- metadata +23 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b080e928ed8014ae935e3bafd2356c21304b60f1c29c2c5327f7694e2825567a
         | 
| 4 | 
            +
              data.tar.gz: de052efcd0958285cf8ae5609fadca6519d94e48af2076f74d1a76886e6f5309
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9ead6354c915b389219ef88a0227fe509347897b4980278cd4daf08d410014effeb1863c2d4aa36ddcc019c9dd018f9ec383771812e50de75ed3f6d29d35fd38
         | 
| 7 | 
            +
              data.tar.gz: 323eb76b9ed6538704897d000b03d100c04b3443dd2b7c6b2313da67db065a0adca5f31431eef0b571eb9a29a4d9762fd6151fc90840c149cdf023634ab802d3
         | 
    
        data/README.md
    CHANGED
    
    | @@ -55,6 +55,7 @@ All of these issues are resolved here. | |
| 55 55 |  | 
| 56 56 | 
             
            * Client Interface, which supports SNMP v3, v2c, and v1
         | 
| 57 57 | 
             
            * Supports get, getnext, set and walk calls.
         | 
| 58 | 
            +
            * MIB support.
         | 
| 58 59 | 
             
            * Proxy IO object support (for eventmachine/celluloid-io)
         | 
| 59 60 | 
             
            * Ruby >= 2.1 support (modern)
         | 
| 60 61 | 
             
            * Pure Ruby (no FFI)
         | 
| @@ -73,12 +74,11 @@ manager = NETSNMP::Client.new(host: "localhost", port: 33445, username: "simulat | |
| 73 74 | 
             
                                          context: "a172334d7d97871b72241397f713fa12")
         | 
| 74 75 |  | 
| 75 76 | 
             
            # SNMP get
         | 
| 76 | 
            -
             | 
| 77 | 
            -
            manager.get(oid: "1.3.6.1.2.1.1.0") #=> 'tt'
         | 
| 77 | 
            +
            manager.get(oid: "sysName.0") #=> 'tt'
         | 
| 78 78 |  | 
| 79 79 | 
             
            # SNMP walk
         | 
| 80 80 | 
             
            # sysORDescr
         | 
| 81 | 
            -
            manager.walk(oid: " | 
| 81 | 
            +
            manager.walk(oid: "sysORDescr").each do |oid_code, value|
         | 
| 82 82 | 
             
              # do something with them  
         | 
| 83 83 | 
             
              puts "for #{oid_code}: #{value}"
         | 
| 84 84 | 
             
            end
         | 
| @@ -135,6 +135,29 @@ manager.set("somecounteroid", value: 999999, type: 6) | |
| 135 135 | 
             
            ```
         | 
| 136 136 | 
             
            * Fork this library, extend support, write a test and submit a PR (the desired solution ;) )
         | 
| 137 137 |  | 
| 138 | 
            +
            ## MIB
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            `netsnmp` will load the default MIBs from known or advertised (via `MIBDIRS`) directories (provided that they're installed in the system). These will be used for the OID conversion.
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            Sometimes you'll need to load more, your own MIBs, in which case, you can use the following API:
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            ```ruby
         | 
| 145 | 
            +
            require "netsnmp"
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            NETSNMP::MIB.load("MY-MIB")
         | 
| 148 | 
            +
            # or, if it's not in any of the known locations
         | 
| 149 | 
            +
            NETSNMP::MIB.load("/path/to/MY-MIB.txt")
         | 
| 150 | 
            +
            ```
         | 
| 151 | 
            +
             | 
| 152 | 
            +
            You can install common SNMP mibs by using your package manager:
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            ```
         | 
| 155 | 
            +
            # using apt-get
         | 
| 156 | 
            +
            > apt-get install snmp-mibs-downloader
         | 
| 157 | 
            +
            # using apk
         | 
| 158 | 
            +
            > apk --update add net-snmp-libs
         | 
| 159 | 
            +
            ```
         | 
| 160 | 
            +
             | 
| 138 161 | 
             
            ## Concurrency
         | 
| 139 162 |  | 
| 140 163 | 
             
            In ruby, you are usually adviced not to share IO objects across threads. The same principle applies here to `NETSNMP::Client`: provided you use it within a thread of execution, it should behave safely. So, something like this would be possible:
         | 
| @@ -272,7 +295,6 @@ The job of the CI is: | |
| 272 295 |  | 
| 273 296 | 
             
            There are some features which this gem doesn't support. It was built to provide a client (or manager, in SNMP language) implementation only, and the requirements were fulfilled. However, these notable misses will stand-out:
         | 
| 274 297 |  | 
| 275 | 
            -
            * No MIB support (you can only work with OIDs)
         | 
| 276 298 | 
             
            * No server (Agent, in SNMP-ish) implementation.
         | 
| 277 299 | 
             
            * No getbulk support.
         | 
| 278 300 |  | 
    
        data/lib/netsnmp.rb
    CHANGED
    
    | @@ -34,6 +34,17 @@ rescue LoadError | |
| 34 34 | 
             
            end
         | 
| 35 35 |  | 
| 36 36 | 
             
            module NETSNMP
         | 
| 37 | 
            +
              module IsNumericExtensions
         | 
| 38 | 
            +
                refine String do
         | 
| 39 | 
            +
                  def integer?
         | 
| 40 | 
            +
                    each_byte do |byte|
         | 
| 41 | 
            +
                      return false unless byte >= 48 && byte <= 57
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    true
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 37 48 | 
             
              module StringExtensions
         | 
| 38 49 | 
             
                # If you wonder why this is there: the oauth feature uses a refinement to enhance the
         | 
| 39 50 | 
             
                # Regexp class locally with #match? , but this is never tested, because ActiveSupport
         | 
| @@ -73,6 +84,7 @@ require "netsnmp/timeticks" | |
| 73 84 | 
             
            require "netsnmp/oid"
         | 
| 74 85 | 
             
            require "netsnmp/varbind"
         | 
| 75 86 | 
             
            require "netsnmp/pdu"
         | 
| 87 | 
            +
            require "netsnmp/mib"
         | 
| 76 88 | 
             
            require "netsnmp/session"
         | 
| 77 89 |  | 
| 78 90 | 
             
            require "netsnmp/scoped_pdu"
         | 
    
        data/lib/netsnmp/client.rb
    CHANGED
    
    
    
        data/lib/netsnmp/mib.rb
    ADDED
    
    | @@ -0,0 +1,151 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "mib/parser"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module NETSNMP
         | 
| 6 | 
            +
              module MIB
         | 
| 7 | 
            +
                using IsNumericExtensions
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                OIDREGEX = /^[\d\.]*$/
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                module_function
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                MIBDIRS = ENV.fetch("MIBDIRS", File.join("/usr", "share", "snmp", "mibs")).split(":")
         | 
| 14 | 
            +
                PARSER = Parser.new
         | 
| 15 | 
            +
                @parser_mutex = Mutex.new
         | 
| 16 | 
            +
                @modules_loaded = []
         | 
| 17 | 
            +
                @object_identifiers = {}
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # Translates na identifier, such as "sysDescr", into an OID
         | 
| 20 | 
            +
                def oid(identifier)
         | 
| 21 | 
            +
                  prefix, *suffix = case identifier
         | 
| 22 | 
            +
                                    when Array
         | 
| 23 | 
            +
                                      identifier
         | 
| 24 | 
            +
                                    else
         | 
| 25 | 
            +
                                      identifier.split(".", 2)
         | 
| 26 | 
            +
                                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # early exit if it's an OID already
         | 
| 29 | 
            +
                  unless prefix.integer?
         | 
| 30 | 
            +
                    load_defaults
         | 
| 31 | 
            +
                    # load module if need be
         | 
| 32 | 
            +
                    idx = prefix.index("::")
         | 
| 33 | 
            +
                    if idx
         | 
| 34 | 
            +
                      mod = prefix[0..(idx - 1)]
         | 
| 35 | 
            +
                      type = prefix[(idx + 2)..-1]
         | 
| 36 | 
            +
                      return unless load(mod)
         | 
| 37 | 
            +
                    else
         | 
| 38 | 
            +
                      type = prefix
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    return if type.nil? || type.empty?
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    prefix = @object_identifiers[type] ||
         | 
| 44 | 
            +
                             raise(Error, "can't convert #{type} to OID")
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  [prefix, *suffix].join(".")
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                # This is a helper function, do not rely on this functionality in future
         | 
| 52 | 
            +
                # versions
         | 
| 53 | 
            +
                def identifier(oid)
         | 
| 54 | 
            +
                  @object_identifiers.select do |_, full_oid|
         | 
| 55 | 
            +
                    full_oid.start_with?(oid)
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                # Loads a MIB. Can be called multiple times, as it'll load it once.
         | 
| 61 | 
            +
                #
         | 
| 62 | 
            +
                # Accepts the MIB name in several ways:
         | 
| 63 | 
            +
                #
         | 
| 64 | 
            +
                #     MIB.load("SNMPv2-MIB")
         | 
| 65 | 
            +
                #     MIB.load("SNMPv2-MIB.txt")
         | 
| 66 | 
            +
                #     MIB.load("/path/to/SNMPv2-MIB.txt")
         | 
| 67 | 
            +
                #
         | 
| 68 | 
            +
                def load(mod)
         | 
| 69 | 
            +
                  unless File.file?(mod)
         | 
| 70 | 
            +
                    moddir = nil
         | 
| 71 | 
            +
                    MIBDIRS.each do |mibdir|
         | 
| 72 | 
            +
                      if File.exist?(File.join(mibdir, mod))
         | 
| 73 | 
            +
                        moddir = File.join(mibdir, mod)
         | 
| 74 | 
            +
                        break
         | 
| 75 | 
            +
                      elsif File.extname(mod).empty? && File.exist?(File.join(mibdir, "#{mod}.txt"))
         | 
| 76 | 
            +
                        moddir = File.join(mibdir, "#{mod}.txt")
         | 
| 77 | 
            +
                        break
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                    return false unless moddir
         | 
| 81 | 
            +
                    mod = moddir
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                  return true if @modules_loaded.include?(mod)
         | 
| 84 | 
            +
                  do_load(mod)
         | 
| 85 | 
            +
                  @modules_loaded << mod
         | 
| 86 | 
            +
                  true
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                TYPES = ["OBJECT-TYPE", "OBJECT IDENTIFIER", "MODULE-IDENTITY"].freeze
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                STATIC_MIB_TO_OID = {
         | 
| 92 | 
            +
                  "iso" => "1"
         | 
| 93 | 
            +
                }.freeze
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                #
         | 
| 96 | 
            +
                # Loads the MIB all the time, where +mod+ is the absolute path to the MIB.
         | 
| 97 | 
            +
                #
         | 
| 98 | 
            +
                def do_load(mod)
         | 
| 99 | 
            +
                  data = @parser_mutex.synchronize { PARSER.parse(File.read(mod)) }
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  imports = load_imports(data)
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  data[:declarations].each_with_object(@object_identifiers) do |dec, types|
         | 
| 104 | 
            +
                    next unless TYPES.include?(dec[:type])
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    oid = String(dec[:value]).split(/ +/).flat_map do |cp|
         | 
| 107 | 
            +
                      if cp.integer?
         | 
| 108 | 
            +
                        cp
         | 
| 109 | 
            +
                      else
         | 
| 110 | 
            +
                        STATIC_MIB_TO_OID[cp] || @object_identifiers[cp] || begin
         | 
| 111 | 
            +
                          imported_mod, = imports.find do |_, identifiers|
         | 
| 112 | 
            +
                            identifiers.include?(cp)
         | 
| 113 | 
            +
                          end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                          raise Error, "didn't find a module to import \"#{cp}\" from" unless imported_mod
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                          load(imported_mod)
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                          @object_identifiers[cp]
         | 
| 120 | 
            +
                        end
         | 
| 121 | 
            +
                      end
         | 
| 122 | 
            +
                    end.join(".")
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                    types[String(dec[:name])] = oid
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                #
         | 
| 129 | 
            +
                # Reformats the import lists into an hash indexed by module name, to a list of
         | 
| 130 | 
            +
                # imported names
         | 
| 131 | 
            +
                #
         | 
| 132 | 
            +
                def load_imports(data)
         | 
| 133 | 
            +
                  return unless data[:imports]
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  data[:imports].each_with_object({}) do |import, imp|
         | 
| 136 | 
            +
                    imp[String(import[:name])] = case import[:ids]
         | 
| 137 | 
            +
                                                 when Hash
         | 
| 138 | 
            +
                                                   [String(import[:ids][:name])]
         | 
| 139 | 
            +
                                                 else
         | 
| 140 | 
            +
                                                   import[:ids].map { |id| String(id[:name]) }
         | 
| 141 | 
            +
                                                 end
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                def load_defaults
         | 
| 146 | 
            +
                  # loading the defaults MIBS
         | 
| 147 | 
            +
                  load("SNMPv2-MIB")
         | 
| 148 | 
            +
                  load("IF-MIB")
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
            end
         | 
| @@ -0,0 +1,750 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "parslet"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module NETSNMP::MIB
         | 
| 6 | 
            +
              class Parser < Parslet::Parser
         | 
| 7 | 
            +
                root :mibfile
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def spaced(character = nil)
         | 
| 10 | 
            +
                  if character.nil? && block_given?
         | 
| 11 | 
            +
                    yield >> space.repeat
         | 
| 12 | 
            +
                  else
         | 
| 13 | 
            +
                    str(character) >> space.repeat
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def curly(atom)
         | 
| 18 | 
            +
                  str("{") >> space.repeat >> atom >> space.repeat >> str("}")
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def bracketed(atom)
         | 
| 22 | 
            +
                  str("(") >> space.repeat >> atom >> space.repeat >> str(")")
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def square_bracketed(atom)
         | 
| 26 | 
            +
                  str("[") >> space.repeat >> atom >> space.repeat >> str("]")
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def with_separator(atom, separator = nil)
         | 
| 30 | 
            +
                  if separator
         | 
| 31 | 
            +
                    sep = if separator.is_a?(String)
         | 
| 32 | 
            +
                            space.repeat >> str(separator) >> space.repeat
         | 
| 33 | 
            +
                          else
         | 
| 34 | 
            +
                            separator
         | 
| 35 | 
            +
                          end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    atom >> (sep >> atom).repeat
         | 
| 38 | 
            +
                  else
         | 
| 39 | 
            +
                    atom >> (space.repeat >> atom).repeat
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                rule(:mibfile) do
         | 
| 44 | 
            +
                  space.repeat >> modules.maybe
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                rule(:modules) do
         | 
| 48 | 
            +
                  with_separator(mod)
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                rule(:mod) do
         | 
| 52 | 
            +
                  spaced { module_name.as(:name) } >> module_oid >>
         | 
| 53 | 
            +
                    spaced("DEFINITIONS") >> colon_colon_part >>
         | 
| 54 | 
            +
                    spaced("BEGIN") >>
         | 
| 55 | 
            +
                    exports_part.as(:exports) >>
         | 
| 56 | 
            +
                    linkage_part.as(:imports) >>
         | 
| 57 | 
            +
                    declaration_part.as(:declarations) >>
         | 
| 58 | 
            +
                    spaced("END")
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                rule(:module_name) { uppercase_identifier }
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                rule(:module_oid) do
         | 
| 64 | 
            +
                  spaced { curly(object_identifier) }.maybe
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                rule(:declaration_part) do
         | 
| 68 | 
            +
                  spaced { declarations }.maybe
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                rule(:exports_part) do
         | 
| 72 | 
            +
                  spaced { exports_clause }.maybe
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                rule(:exports_clause) do
         | 
| 76 | 
            +
                  spaced("EXPORTS") >> spaced { import_identifiers } >> str(";")
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                rule(:linkage_part) do
         | 
| 80 | 
            +
                  spaced { linkage_clause }.maybe
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                rule(:linkage_clause) do
         | 
| 84 | 
            +
                  spaced("IMPORTS") >> spaced { import_part } >> str(";")
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                rule(:import_part) do
         | 
| 88 | 
            +
                  imports.maybe
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                rule(:imports) { with_separator(import) }
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                rule(:import) do
         | 
| 94 | 
            +
                  spaced { import_identifiers.as(:ids) } >> spaced("FROM") >> module_name.as(:name)
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                rule(:import_identifiers) { with_separator(import_identifier.as(:name), ",") }
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                rule(:import_identifier) do
         | 
| 100 | 
            +
                  lowercase_identifier | uppercase_identifier | imported_keyword
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                rule(:imported_keyword) do
         | 
| 104 | 
            +
                  imported_smi_keyword |
         | 
| 105 | 
            +
                    str("BITS") |
         | 
| 106 | 
            +
                    str("Integer32")  |
         | 
| 107 | 
            +
                    str("IpAddress")  |
         | 
| 108 | 
            +
                    str("MANDATORY-GROUPS") |
         | 
| 109 | 
            +
                    str("MODULE-COMPLIANCE") |
         | 
| 110 | 
            +
                    str("MODULE-IDENTITY") |
         | 
| 111 | 
            +
                    str("OBJECT-GROUP") |
         | 
| 112 | 
            +
                    str("OBJECT-IDENTITY") |
         | 
| 113 | 
            +
                    str("OBJECT-TYPE") |
         | 
| 114 | 
            +
                    str("Opaque") |
         | 
| 115 | 
            +
                    str("TEXTUAL-CONVENTION") |
         | 
| 116 | 
            +
                    str("TimeTicks") |
         | 
| 117 | 
            +
                    str("Unsigned32")
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                rule(:imported_smi_keyword) do
         | 
| 121 | 
            +
                  str("AGENT-CAPABILITIES") |
         | 
| 122 | 
            +
                    str("Counter32") |
         | 
| 123 | 
            +
                    str("Counter64") |
         | 
| 124 | 
            +
                    str("Gauge32") |
         | 
| 125 | 
            +
                    str("NOTIFICATION-GROUP") |
         | 
| 126 | 
            +
                    str("NOTIFICATION-TYPE") |
         | 
| 127 | 
            +
                    str("TRAP-TYPE")
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                rule(:declarations) do
         | 
| 131 | 
            +
                  with_separator(declaration)
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                rule(:declaration) do
         | 
| 135 | 
            +
                  type_declaration |
         | 
| 136 | 
            +
                    value_declaration |
         | 
| 137 | 
            +
                    object_identity_clause |
         | 
| 138 | 
            +
                    object_type_clause |
         | 
| 139 | 
            +
                    traptype_clause |
         | 
| 140 | 
            +
                    notification_type_clause |
         | 
| 141 | 
            +
                    module_identity_clause |
         | 
| 142 | 
            +
                    module_compliance_clause |
         | 
| 143 | 
            +
                    object_group_clause |
         | 
| 144 | 
            +
                    notification_group_clause |
         | 
| 145 | 
            +
                    agent_capabilities_clause |
         | 
| 146 | 
            +
                    macro_clause
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                rule(:macro_clause) do
         | 
| 150 | 
            +
                  spaced { macro_name.as(:name) } >> spaced { str("MACRO").as(:type) } >> colon_colon_part >>
         | 
| 151 | 
            +
                    spaced("BEGIN") >>
         | 
| 152 | 
            +
                    # ignoring macro clauses
         | 
| 153 | 
            +
                    match("^(?!END)").repeat >>
         | 
| 154 | 
            +
                    spaced("END")
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                rule(:macro_name) do
         | 
| 158 | 
            +
                  str("MODULE-IDENTITY") |
         | 
| 159 | 
            +
                    str("OBJECT-TYPE") |
         | 
| 160 | 
            +
                    str("TRAP-TYPE") |
         | 
| 161 | 
            +
                    str("NOTIFICATION-TYPE") |
         | 
| 162 | 
            +
                    str("OBJECT-IDENTITY") |
         | 
| 163 | 
            +
                    str("TEXTUAL-CONVENTION") |
         | 
| 164 | 
            +
                    str("OBJECT-GROUP") |
         | 
| 165 | 
            +
                    str("NOTIFICATION-GROUP") |
         | 
| 166 | 
            +
                    str("MODULE-COMPLIANCE") |
         | 
| 167 | 
            +
                    str("AGENT-CAPABILITIES")
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                rule(:agent_capabilities_clause) do
         | 
| 171 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 172 | 
            +
                    spaced { str("AGENT-CAPABILITIES").as(:type) } >>
         | 
| 173 | 
            +
                    spaced("PRODUCT-RELEASE") >> spaced { text } >>
         | 
| 174 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 175 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 176 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 177 | 
            +
                    spaced { module_part_capabilities }.maybe >>
         | 
| 178 | 
            +
                    colon_colon_part >> curly(object_identifier)
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                rule(:module_part_capabilities) do
         | 
| 182 | 
            +
                  modules_capabilities
         | 
| 183 | 
            +
                end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                rule(:modules_capabilities) do
         | 
| 186 | 
            +
                  with_separator(module_capabilities)
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                rule(:module_capabilities) do
         | 
| 190 | 
            +
                  spaced("SUPPORTS") >>
         | 
| 191 | 
            +
                    module_name_capabilities >>
         | 
| 192 | 
            +
                    spaced("INCLUDES") >> curly(capabilities_groups) >>
         | 
| 193 | 
            +
                    spaced { variation_part }.maybe
         | 
| 194 | 
            +
                end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                rule(:module_name_capabilities) do
         | 
| 197 | 
            +
                  spaced { uppercase_identifier } >> object_identifier | uppercase_identifier
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                rule(:capabilities_groups) do
         | 
| 201 | 
            +
                  with_separator(capabilities_group)
         | 
| 202 | 
            +
                end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                rule(:capabilities_group) { objectIdentifier }
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                rule(:variation_part) do
         | 
| 207 | 
            +
                  variations
         | 
| 208 | 
            +
                end
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                rule(:variations) do
         | 
| 211 | 
            +
                  with_separator(variation)
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                rule(:variation) do
         | 
| 215 | 
            +
                  spaced("VARIATION") >> object_identifier >>
         | 
| 216 | 
            +
                    spaced { syntax_part }.maybe >>
         | 
| 217 | 
            +
                    spaced { write_syntax_part } >>
         | 
| 218 | 
            +
                    spaced { variation_access_part }.maybe >>
         | 
| 219 | 
            +
                    spaced { creation_part }.maybe >>
         | 
| 220 | 
            +
                    spaced { def_val_part }.maybe >>
         | 
| 221 | 
            +
                    spaced("DESCRIPTION") >> text
         | 
| 222 | 
            +
                end
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                rule(:variation_access_part) do
         | 
| 225 | 
            +
                  spaced("ACCESS") >> variation_access
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                rule(:variation_access) { lowercase_identifier }
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                rule(:creation_part) do
         | 
| 231 | 
            +
                  spaced("CREATION-REQUIRES") >> curly(cells)
         | 
| 232 | 
            +
                end
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                rule(:cells) { with_separator(cell, ",") }
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                rule(:cell) { object_identifier }
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                rule(:notification_group_clause) do
         | 
| 239 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 240 | 
            +
                    spaced { str("NOTIFICATION-GROUP").as(:type) } >>
         | 
| 241 | 
            +
                    spaced { notifications_part } >>
         | 
| 242 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 243 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 244 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 245 | 
            +
                    colon_colon_part >> curly(object_identifier)
         | 
| 246 | 
            +
                end
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                rule(:notifications_part) do
         | 
| 249 | 
            +
                  spaced("NOTIFICATIONS") >> curly(notifications)
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                rule(:notifications) do
         | 
| 253 | 
            +
                  with_separator(notification, ",")
         | 
| 254 | 
            +
                end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                rule(:notification) do
         | 
| 257 | 
            +
                  notification_name
         | 
| 258 | 
            +
                end
         | 
| 259 | 
            +
             | 
| 260 | 
            +
                rule(:object_group_clause) do
         | 
| 261 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 262 | 
            +
                    spaced { str("OBJECT-GROUP").as(:type) } >>
         | 
| 263 | 
            +
                    spaced { object_group_objects_part } >>
         | 
| 264 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 265 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 266 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 267 | 
            +
                    colon_colon_part >> curly(object_identifier)
         | 
| 268 | 
            +
                end
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                rule(:object_group_objects_part) do
         | 
| 271 | 
            +
                  spaced("OBJECTS") >> curly(objects)
         | 
| 272 | 
            +
                end
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                rule(:module_compliance_clause) do
         | 
| 275 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 276 | 
            +
                    spaced { str("MODULE-COMPLIANCE").as(:type) } >>
         | 
| 277 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 278 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 279 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 280 | 
            +
                    spaced { compliance_modules } >>
         | 
| 281 | 
            +
                    colon_colon_part >> curly(object_identifier)
         | 
| 282 | 
            +
                end
         | 
| 283 | 
            +
             | 
| 284 | 
            +
                rule(:compliance_modules) do
         | 
| 285 | 
            +
                  with_separator(compliance_module)
         | 
| 286 | 
            +
                end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
                rule(:compliance_module) do
         | 
| 289 | 
            +
                  spaced { str("MODULE") >> (space_in_line.repeat(1) >> compliance_module_name).maybe } >>
         | 
| 290 | 
            +
                    spaced { mandatory_part }.maybe >>
         | 
| 291 | 
            +
                    compliances.maybe
         | 
| 292 | 
            +
                end
         | 
| 293 | 
            +
             | 
| 294 | 
            +
                rule(:compliance_module_name) do
         | 
| 295 | 
            +
                  uppercase_identifier
         | 
| 296 | 
            +
                end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                rule(:mandatory_part) do
         | 
| 299 | 
            +
                  spaced("MANDATORY-GROUPS") >> curly(mandatory_groups)
         | 
| 300 | 
            +
                end
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                rule(:compliances) do
         | 
| 303 | 
            +
                  with_separator(compliance).as(:compliances)
         | 
| 304 | 
            +
                end
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                rule(:compliance) do
         | 
| 307 | 
            +
                  compliance_group | compliance_object
         | 
| 308 | 
            +
                end
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                rule(:compliance_group) do
         | 
| 311 | 
            +
                  spaced { str("GROUP").as(:type) } >> spaced { object_identifier.as(:name) } >>
         | 
| 312 | 
            +
                    spaced("DESCRIPTION") >> text
         | 
| 313 | 
            +
                end
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                rule(:compliance_object) do
         | 
| 316 | 
            +
                  spaced { str("OBJECT").as(:type) } >>
         | 
| 317 | 
            +
                    spaced { object_identifier.as(:name) } >>
         | 
| 318 | 
            +
                    spaced { syntax_part }.maybe >>
         | 
| 319 | 
            +
                    spaced { write_syntax_part }.maybe >>
         | 
| 320 | 
            +
                    spaced { access_part }.maybe >>
         | 
| 321 | 
            +
                    spaced("DESCRIPTION") >> text
         | 
| 322 | 
            +
                end
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                rule(:syntax_part) do
         | 
| 325 | 
            +
                  spaced("SYNTAX") >> syntax.as(:syntax)
         | 
| 326 | 
            +
                end
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                rule(:write_syntax_part) do
         | 
| 329 | 
            +
                  (spaced("WRITE-SYNTAX") >> spaced { syntax }).maybe
         | 
| 330 | 
            +
                end
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                rule(:access_part) do
         | 
| 333 | 
            +
                  (spaced("MIN-ACCESS") >> spaced { access }).maybe
         | 
| 334 | 
            +
                end
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                rule(:mandatory_groups) do
         | 
| 337 | 
            +
                  with_separator(mandatory_group, ",").as(:groups)
         | 
| 338 | 
            +
                end
         | 
| 339 | 
            +
             | 
| 340 | 
            +
                rule(:mandatory_group) { object_identifier.as(:name) }
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                rule(:module_identity_clause) do
         | 
| 343 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 344 | 
            +
                    spaced { str("MODULE-IDENTITY").as(:type) } >>
         | 
| 345 | 
            +
                    (spaced("SUBJECT-CATEGORIES") >> curly(category_ids)).maybe >>
         | 
| 346 | 
            +
                    spaced("LAST-UPDATED") >> spaced { ext_utc_time } >>
         | 
| 347 | 
            +
                    spaced("ORGANIZATION") >> spaced { text.as(:organization) } >>
         | 
| 348 | 
            +
                    spaced("CONTACT-INFO") >> spaced { text.as(:contact_info) } >>
         | 
| 349 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 350 | 
            +
                    spaced { revisions }.maybe >>
         | 
| 351 | 
            +
                    colon_colon_part >> curly(object_identifier.as(:value))
         | 
| 352 | 
            +
                end
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                rule(:ext_utc_time) { text }
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                rule(:revisions) do
         | 
| 357 | 
            +
                  with_separator(revision)
         | 
| 358 | 
            +
                end
         | 
| 359 | 
            +
             | 
| 360 | 
            +
                rule(:revision) do
         | 
| 361 | 
            +
                  spaced("REVISION") >> spaced { ext_utc_time } >>
         | 
| 362 | 
            +
                    spaced("DESCRIPTION") >>
         | 
| 363 | 
            +
                    text
         | 
| 364 | 
            +
                end
         | 
| 365 | 
            +
             | 
| 366 | 
            +
                rule(:category_ids) do
         | 
| 367 | 
            +
                  with_separator(category_id, ",")
         | 
| 368 | 
            +
                end
         | 
| 369 | 
            +
             | 
| 370 | 
            +
                rule(:category_id) do
         | 
| 371 | 
            +
                  spaced { lowercase_identifier } >> bracketed(number) | lowercase_identifier
         | 
| 372 | 
            +
                end
         | 
| 373 | 
            +
             | 
| 374 | 
            +
                rule(:notification_type_clause) do
         | 
| 375 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 376 | 
            +
                    spaced { str("NOTIFICATION-TYPE").as(:type) } >>
         | 
| 377 | 
            +
                    spaced { notification_objects_part }.maybe >>
         | 
| 378 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 379 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 380 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 381 | 
            +
                    colon_colon_part >> curly(notification_name)
         | 
| 382 | 
            +
                end
         | 
| 383 | 
            +
             | 
| 384 | 
            +
                rule(:notification_objects_part) do
         | 
| 385 | 
            +
                  spaced("OBJECTS") >> curly(objects)
         | 
| 386 | 
            +
                end
         | 
| 387 | 
            +
             | 
| 388 | 
            +
                rule(:objects) do
         | 
| 389 | 
            +
                  with_separator(object, ",")
         | 
| 390 | 
            +
                end
         | 
| 391 | 
            +
             | 
| 392 | 
            +
                rule(:object) do
         | 
| 393 | 
            +
                  object_identifier
         | 
| 394 | 
            +
                end
         | 
| 395 | 
            +
             | 
| 396 | 
            +
                rule(:notification_name) do
         | 
| 397 | 
            +
                  object_identifier
         | 
| 398 | 
            +
                end
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                rule(:traptype_clause) do
         | 
| 401 | 
            +
                  spaced { fuzzy_lowercase_identifier.as(:name) } >>
         | 
| 402 | 
            +
                    spaced { str("TRAP-TYPE").as(:type) } >> spaced { enterprise_part } >>
         | 
| 403 | 
            +
                    spaced { var_part }.maybe >>
         | 
| 404 | 
            +
                    spaced { descr_part }.maybe >>
         | 
| 405 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 406 | 
            +
                    colon_colon_part >> number
         | 
| 407 | 
            +
                end
         | 
| 408 | 
            +
             | 
| 409 | 
            +
                rule(:enterprise_part) do
         | 
| 410 | 
            +
                  spaced("ENTERPRISE") >> object_identifier |
         | 
| 411 | 
            +
                    spaced("ENTERPRISE") >> curly(object_identifier)
         | 
| 412 | 
            +
                end
         | 
| 413 | 
            +
             | 
| 414 | 
            +
                rule(:var_part) do
         | 
| 415 | 
            +
                  spaced("VARIABLES") >> curly(var_types)
         | 
| 416 | 
            +
                end
         | 
| 417 | 
            +
             | 
| 418 | 
            +
                rule(:var_types) do
         | 
| 419 | 
            +
                  with_separator(var_type, ",")
         | 
| 420 | 
            +
                end
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                rule(:var_type) { object_identifier }
         | 
| 423 | 
            +
             | 
| 424 | 
            +
                rule(:descr_part) do
         | 
| 425 | 
            +
                  spaced("DESCRIPTION") >> text
         | 
| 426 | 
            +
                end
         | 
| 427 | 
            +
             | 
| 428 | 
            +
                rule(:object_type_clause) do
         | 
| 429 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 430 | 
            +
                    spaced { str("OBJECT-TYPE").as(:type) } >>
         | 
| 431 | 
            +
                    spaced { syntax_part }.maybe >>
         | 
| 432 | 
            +
                    spaced { units_part }.maybe >>
         | 
| 433 | 
            +
                    spaced { max_access_part }.maybe >>
         | 
| 434 | 
            +
                    (spaced("STATUS") >> spaced { status }).maybe >>
         | 
| 435 | 
            +
                    spaced { description_clause }.maybe >>
         | 
| 436 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 437 | 
            +
                    spaced { index_part }.maybe >>
         | 
| 438 | 
            +
                    spaced { mib_index }.maybe >>
         | 
| 439 | 
            +
                    spaced { def_val_part }.maybe >>
         | 
| 440 | 
            +
                    colon_colon_part >> curly(object_identifier.as(:value))
         | 
| 441 | 
            +
                end
         | 
| 442 | 
            +
             | 
| 443 | 
            +
                rule(:object_identity_clause) do
         | 
| 444 | 
            +
                  spaced { lowercase_identifier.as(:name) } >>
         | 
| 445 | 
            +
                    spaced { str("OBJECT-IDENTITY").as(:type) } >>
         | 
| 446 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 447 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 448 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 449 | 
            +
                    colon_colon_part >> curly(object_identifier)
         | 
| 450 | 
            +
                end
         | 
| 451 | 
            +
             | 
| 452 | 
            +
                rule(:units_part) do
         | 
| 453 | 
            +
                  spaced("UNITS") >> text.as(:units)
         | 
| 454 | 
            +
                end
         | 
| 455 | 
            +
             | 
| 456 | 
            +
                rule(:max_access_part) do
         | 
| 457 | 
            +
                  spaced("MAX-ACCESS") >> access | spaced("ACCESS") >> access
         | 
| 458 | 
            +
                end
         | 
| 459 | 
            +
             | 
| 460 | 
            +
                rule(:access) { lowercase_identifier }
         | 
| 461 | 
            +
             | 
| 462 | 
            +
                rule(:description_clause) do
         | 
| 463 | 
            +
                  spaced("DESCRIPTION") >> text
         | 
| 464 | 
            +
                end
         | 
| 465 | 
            +
             | 
| 466 | 
            +
                rule(:index_part) do
         | 
| 467 | 
            +
                  spaced("AUGMENTS") >> curly(entry)
         | 
| 468 | 
            +
                end
         | 
| 469 | 
            +
             | 
| 470 | 
            +
                rule(:mib_index) do
         | 
| 471 | 
            +
                  spaced("INDEX") >> curly(index_types)
         | 
| 472 | 
            +
                end
         | 
| 473 | 
            +
             | 
| 474 | 
            +
                rule(:def_val_part) do
         | 
| 475 | 
            +
                  spaced("DEFVAL") >> curly(valueof_simple_syntax)
         | 
| 476 | 
            +
                end
         | 
| 477 | 
            +
             | 
| 478 | 
            +
                rule(:valueof_simple_syntax) do
         | 
| 479 | 
            +
                  value | lowercase_identifier | text | curly(object_identifiers_defval)
         | 
| 480 | 
            +
                end
         | 
| 481 | 
            +
             | 
| 482 | 
            +
                rule(:object_identifiers_defval) do
         | 
| 483 | 
            +
                  with_separator(object_identifier_defval)
         | 
| 484 | 
            +
                end
         | 
| 485 | 
            +
             | 
| 486 | 
            +
                rule(:object_identifier_defval) do
         | 
| 487 | 
            +
                  spaced { lowercase_identifier } >> bracketed(number) |
         | 
| 488 | 
            +
                    number
         | 
| 489 | 
            +
                end
         | 
| 490 | 
            +
             | 
| 491 | 
            +
                rule(:index_types) do
         | 
| 492 | 
            +
                  with_separator(index_type, ",")
         | 
| 493 | 
            +
                end
         | 
| 494 | 
            +
             | 
| 495 | 
            +
                rule(:index_type) do
         | 
| 496 | 
            +
                  spaced("IMPLIED") >> idx | idx
         | 
| 497 | 
            +
                end
         | 
| 498 | 
            +
             | 
| 499 | 
            +
                rule(:idx) do
         | 
| 500 | 
            +
                  object_identifier
         | 
| 501 | 
            +
                end
         | 
| 502 | 
            +
             | 
| 503 | 
            +
                rule(:entry) do
         | 
| 504 | 
            +
                  object_identifier
         | 
| 505 | 
            +
                end
         | 
| 506 | 
            +
             | 
| 507 | 
            +
                rule(:value_declaration) do
         | 
| 508 | 
            +
                  spaced { fuzzy_lowercase_identifier.as(:name) } >>
         | 
| 509 | 
            +
                    spaced { str("OBJECT IDENTIFIER").as(:type) } >>
         | 
| 510 | 
            +
                    colon_colon_part >> curly(object_identifier.as(:value))
         | 
| 511 | 
            +
                end
         | 
| 512 | 
            +
             | 
| 513 | 
            +
                rule(:fuzzy_lowercase_identifier) do
         | 
| 514 | 
            +
                  lowercase_identifier | uppercase_identifier
         | 
| 515 | 
            +
                end
         | 
| 516 | 
            +
             | 
| 517 | 
            +
                rule(:object_identifier) do
         | 
| 518 | 
            +
                  sub_identifiers
         | 
| 519 | 
            +
                end
         | 
| 520 | 
            +
             | 
| 521 | 
            +
                rule(:sub_identifiers) do
         | 
| 522 | 
            +
                  with_separator(sub_identifier, space_in_line.repeat)
         | 
| 523 | 
            +
                end
         | 
| 524 | 
            +
             | 
| 525 | 
            +
                rule(:sub_identifier) do
         | 
| 526 | 
            +
                  fuzzy_lowercase_identifier |
         | 
| 527 | 
            +
                    number |
         | 
| 528 | 
            +
                    spaced { lowercase_identifier } >> bracketed(number)
         | 
| 529 | 
            +
                end
         | 
| 530 | 
            +
             | 
| 531 | 
            +
                rule(:type_declaration) do
         | 
| 532 | 
            +
                  spaced { type_name.as(:vartype) } >> colon_colon_part >> type_declaration_rhs
         | 
| 533 | 
            +
                end
         | 
| 534 | 
            +
             | 
| 535 | 
            +
                rule(:type_name) do
         | 
| 536 | 
            +
                  uppercase_identifier | type_smi
         | 
| 537 | 
            +
                end
         | 
| 538 | 
            +
             | 
| 539 | 
            +
                rule(:type_smi) do
         | 
| 540 | 
            +
                  type_smi_and_sppi | type_smi_only
         | 
| 541 | 
            +
                end
         | 
| 542 | 
            +
             | 
| 543 | 
            +
                rule(:type_declaration_rhs) do
         | 
| 544 | 
            +
                  spaced { choice_clause } |
         | 
| 545 | 
            +
                    spaced { str("TEXTUAL-CONVENTION") } >>
         | 
| 546 | 
            +
                    spaced { display_part }.maybe >>
         | 
| 547 | 
            +
                    spaced("STATUS") >> spaced { status } >>
         | 
| 548 | 
            +
                    spaced("DESCRIPTION") >> spaced { text } >>
         | 
| 549 | 
            +
                    spaced { refer_part }.maybe >>
         | 
| 550 | 
            +
                    spaced("SYNTAX") >> syntax |
         | 
| 551 | 
            +
                    syntax
         | 
| 552 | 
            +
                end
         | 
| 553 | 
            +
             | 
| 554 | 
            +
                rule(:refer_part) do
         | 
| 555 | 
            +
                  spaced("REFERENCE") >> text
         | 
| 556 | 
            +
                end
         | 
| 557 | 
            +
             | 
| 558 | 
            +
                rule(:choice_clause) do
         | 
| 559 | 
            +
                  # Ignoring choice syntax
         | 
| 560 | 
            +
                  spaced { str("CHOICE").as(:type) } >> curly(match("[^\}]").repeat)
         | 
| 561 | 
            +
                end
         | 
| 562 | 
            +
             | 
| 563 | 
            +
                rule(:syntax) do
         | 
| 564 | 
            +
                  object_syntax | spaced("BITS").as(:type) >> curly(named_bits)
         | 
| 565 | 
            +
                end
         | 
| 566 | 
            +
             | 
| 567 | 
            +
                rule(:display_part) do
         | 
| 568 | 
            +
                  spaced("DISPLAY-HINT") >> text
         | 
| 569 | 
            +
                end
         | 
| 570 | 
            +
             | 
| 571 | 
            +
                rule(:named_bits) do
         | 
| 572 | 
            +
                  with_separator(named_bit, ",")
         | 
| 573 | 
            +
                end
         | 
| 574 | 
            +
             | 
| 575 | 
            +
                rule(:named_bit) do
         | 
| 576 | 
            +
                  spaced { lowercase_identifier } >> bracketed(number)
         | 
| 577 | 
            +
                end
         | 
| 578 | 
            +
             | 
| 579 | 
            +
                rule(:object_syntax) do
         | 
| 580 | 
            +
                  conceptual_table |
         | 
| 581 | 
            +
                    entry_type |
         | 
| 582 | 
            +
                    simple_syntax |
         | 
| 583 | 
            +
                    application_syntax |
         | 
| 584 | 
            +
                    type_tag >> simple_syntax |
         | 
| 585 | 
            +
                    row.as(:value)
         | 
| 586 | 
            +
                end
         | 
| 587 | 
            +
             | 
| 588 | 
            +
                rule(:simple_syntax) do
         | 
| 589 | 
            +
                  spaced { str("INTEGER").as(:type) } >> (integer_subtype | enum_spec).maybe |
         | 
| 590 | 
            +
                    spaced { str("Integer32").as(:type) >> space } >> integer_subtype.maybe |
         | 
| 591 | 
            +
                    spaced { str("OCTET STRING").as(:type) } >> octetstring_subtype.maybe |
         | 
| 592 | 
            +
                    spaced { str("OBJECT IDENTIFIER").as(:type) } >> any_subtype |
         | 
| 593 | 
            +
                    spaced { uppercase_identifier.as(:type) } >> (integer_subtype | enum_spec | octetstring_subtype)
         | 
| 594 | 
            +
                end
         | 
| 595 | 
            +
             | 
| 596 | 
            +
                rule(:application_syntax) do
         | 
| 597 | 
            +
                  spaced { str("IpAddress").as(:type) >> space } >> any_subtype |
         | 
| 598 | 
            +
                    spaced { str("NetworkAddress").as(:type) >> space } >> any_subtype |
         | 
| 599 | 
            +
                    spaced { str("Counter32").as(:type) >> space } >> integer_subtype.maybe |
         | 
| 600 | 
            +
                    spaced { str("Gauge32").as(:type) >> space } >> integer_subtype.maybe |
         | 
| 601 | 
            +
                    spaced { str("Unsigned32").as(:type) >> space } >> integer_subtype.maybe |
         | 
| 602 | 
            +
                    spaced { str("TimeTicks").as(:type) >> space } >> any_subtype |
         | 
| 603 | 
            +
                    spaced { str("Opaque").as(:type) >> space } >> octetstring_subtype.maybe |
         | 
| 604 | 
            +
                    spaced { str("Counter64").as(:type) >> space } >> integer_subtype.maybe
         | 
| 605 | 
            +
                end
         | 
| 606 | 
            +
             | 
| 607 | 
            +
                rule(:conceptual_table) do
         | 
| 608 | 
            +
                  spaced { str("SEQUENCE OF").as(:type) } >> row.as(:value)
         | 
| 609 | 
            +
                end
         | 
| 610 | 
            +
             | 
| 611 | 
            +
                rule(:entry_type) do
         | 
| 612 | 
            +
                  spaced { str("SEQUENCE").as(:type) } >> curly(sequence_items)
         | 
| 613 | 
            +
                end
         | 
| 614 | 
            +
             | 
| 615 | 
            +
                rule(:type_tag) do
         | 
| 616 | 
            +
                  spaced { square_bracketed(spaced("APPLICATION") >> number.as(:application_type)) } >> spaced("IMPLICIT") |
         | 
| 617 | 
            +
                    spaced { square_bracketed(spaced("UNIVERSAL") >> number.as(:universal_type)) } >> spaced("IMPLICIT")
         | 
| 618 | 
            +
                end
         | 
| 619 | 
            +
             | 
| 620 | 
            +
                rule(:sequence_items) do
         | 
| 621 | 
            +
                  with_separator(sequence_item, ",")
         | 
| 622 | 
            +
                end
         | 
| 623 | 
            +
             | 
| 624 | 
            +
                rule(:sequence_item) do
         | 
| 625 | 
            +
                  spaced { lowercase_identifier } >> spaced { sequence_syntax }
         | 
| 626 | 
            +
                end
         | 
| 627 | 
            +
             | 
| 628 | 
            +
                rule(:sequence_syntax) do
         | 
| 629 | 
            +
                  str("BITS") |
         | 
| 630 | 
            +
                    sequence_object_syntax |
         | 
| 631 | 
            +
                    spaced { uppercase_identifier } >> any_subtype
         | 
| 632 | 
            +
                end
         | 
| 633 | 
            +
             | 
| 634 | 
            +
                rule(:sequence_object_syntax) do
         | 
| 635 | 
            +
                  sequence_simple_syntax | sequence_application_syntax
         | 
| 636 | 
            +
                end
         | 
| 637 | 
            +
             | 
| 638 | 
            +
                rule(:sequence_simple_syntax) do
         | 
| 639 | 
            +
                  spaced("INTEGER") >> any_subtype |
         | 
| 640 | 
            +
                    spaced("Integer32") >> any_subtype |
         | 
| 641 | 
            +
                    spaced("OCTET STRING") >> any_subtype |
         | 
| 642 | 
            +
                    spaced("OBJECT IDENTIFIER") >> any_subtype
         | 
| 643 | 
            +
                end
         | 
| 644 | 
            +
             | 
| 645 | 
            +
                rule(:sequence_application_syntax) do
         | 
| 646 | 
            +
                  spaced { str("IpAddress") >> space } >> any_subtype |
         | 
| 647 | 
            +
                    spaced { str("COUNTER32") } >> any_subtype |
         | 
| 648 | 
            +
                    spaced { str("Gauge32") >> space } >> any_subtype |
         | 
| 649 | 
            +
                    spaced { str("Unsigned32") >> space } >> any_subtype |
         | 
| 650 | 
            +
                    spaced { str("TimeTicks") >> space } >> any_subtype |
         | 
| 651 | 
            +
                    str("Opaque") |
         | 
| 652 | 
            +
                    spaced { str("Counter64") >> space } >> any_subtype
         | 
| 653 | 
            +
                end
         | 
| 654 | 
            +
             | 
| 655 | 
            +
                rule(:row) { uppercase_identifier }
         | 
| 656 | 
            +
             | 
| 657 | 
            +
                rule(:integer_subtype) { bracketed(ranges) }
         | 
| 658 | 
            +
             | 
| 659 | 
            +
                rule(:octetstring_subtype) do
         | 
| 660 | 
            +
                  bracketed(spaced("SIZE") >> bracketed(ranges))
         | 
| 661 | 
            +
                end
         | 
| 662 | 
            +
             | 
| 663 | 
            +
                rule(:any_subtype) do
         | 
| 664 | 
            +
                  (integer_subtype | octetstring_subtype | enum_spec).maybe
         | 
| 665 | 
            +
                end
         | 
| 666 | 
            +
             | 
| 667 | 
            +
                rule(:enum_spec) { curly(enum_items) }
         | 
| 668 | 
            +
             | 
| 669 | 
            +
                rule(:enum_items) do
         | 
| 670 | 
            +
                  with_separator(enum_item.as(:enum), ",")
         | 
| 671 | 
            +
                end
         | 
| 672 | 
            +
             | 
| 673 | 
            +
                rule(:enum_item) do
         | 
| 674 | 
            +
                  fuzzy_lowercase_identifier.as(:name) >> space.repeat >> bracketed(number.as(:value))
         | 
| 675 | 
            +
                end
         | 
| 676 | 
            +
             | 
| 677 | 
            +
                rule(:ranges) do
         | 
| 678 | 
            +
                  with_separator(range.as(:range), "|")
         | 
| 679 | 
            +
                end
         | 
| 680 | 
            +
             | 
| 681 | 
            +
                rule(:range) do
         | 
| 682 | 
            +
                  value.as(:min) >> space.repeat >> (str("..") >> space.repeat >> value.as(:max)).maybe
         | 
| 683 | 
            +
                end
         | 
| 684 | 
            +
             | 
| 685 | 
            +
                rule(:value) do
         | 
| 686 | 
            +
                  number | hexstring | binstring
         | 
| 687 | 
            +
                end
         | 
| 688 | 
            +
             | 
| 689 | 
            +
                rule(:status) { lowercase_identifier }
         | 
| 690 | 
            +
             | 
| 691 | 
            +
                rule(:uppercase_identifier) do
         | 
| 692 | 
            +
                  match("[A-Z]") >> match("[A-Za-z0-9\-]").repeat
         | 
| 693 | 
            +
                end
         | 
| 694 | 
            +
             | 
| 695 | 
            +
                rule(:lowercase_identifier) do
         | 
| 696 | 
            +
                  match("[a-z]") >> match("[A-Za-z0-9\-]").repeat
         | 
| 697 | 
            +
                end
         | 
| 698 | 
            +
             | 
| 699 | 
            +
                rule(:type_smi_and_sppi) do
         | 
| 700 | 
            +
                  str("IpAddress") | str("TimeTicks") | str("Opaque") | str("Integer32") | str("Unsigned32")
         | 
| 701 | 
            +
                end
         | 
| 702 | 
            +
             | 
| 703 | 
            +
                rule(:type_smi_only) do
         | 
| 704 | 
            +
                  str("Counter") | str("Gauge32") | str("Counter64")
         | 
| 705 | 
            +
                end
         | 
| 706 | 
            +
             | 
| 707 | 
            +
                rule(:colon_colon_part) { spaced("::=") }
         | 
| 708 | 
            +
             | 
| 709 | 
            +
                rule(:space_in_line) { match('[ \t]').repeat(1) }
         | 
| 710 | 
            +
                rule(:cr) { match("\n") }
         | 
| 711 | 
            +
                rule(:space) do
         | 
| 712 | 
            +
                  # this rule match all not important text
         | 
| 713 | 
            +
                  (match('[ \t\r\n]') | comment_line).repeat(1)
         | 
| 714 | 
            +
                end
         | 
| 715 | 
            +
             | 
| 716 | 
            +
                rule(:comment_line) do
         | 
| 717 | 
            +
                  (match('\-\-') >> match('[^\n]').repeat >> match('\n'))
         | 
| 718 | 
            +
                end
         | 
| 719 | 
            +
             | 
| 720 | 
            +
                rule(:space?) { space.maybe }
         | 
| 721 | 
            +
                rule(:digit) { match["0-9"] }
         | 
| 722 | 
            +
                rule(:hexchar) { match("[0-9a-fA-F]") }
         | 
| 723 | 
            +
                rule(:empty) { str("") }
         | 
| 724 | 
            +
                rule(:number) do
         | 
| 725 | 
            +
                  (
         | 
| 726 | 
            +
                    str("-").maybe >> (
         | 
| 727 | 
            +
                      str("0") | (match("[1-9]") >> digit.repeat)
         | 
| 728 | 
            +
                    ) >> (
         | 
| 729 | 
            +
                      str(".") >> digit.repeat(1)
         | 
| 730 | 
            +
                    ).maybe >> (
         | 
| 731 | 
            +
                      match("[eE]") >> (str("+") | str("-")).maybe >> digit.repeat(1)
         | 
| 732 | 
            +
                    ).maybe
         | 
| 733 | 
            +
                  ).repeat(1)
         | 
| 734 | 
            +
                end
         | 
| 735 | 
            +
             | 
| 736 | 
            +
                rule(:hexstring) do
         | 
| 737 | 
            +
                  str("'") >> hexchar.repeat >> str("'") >> match("[hH]")
         | 
| 738 | 
            +
                end
         | 
| 739 | 
            +
             | 
| 740 | 
            +
                rule(:binstring) do
         | 
| 741 | 
            +
                  str("'") >> match["0-1"].repeat >> str("'")
         | 
| 742 | 
            +
                end
         | 
| 743 | 
            +
             | 
| 744 | 
            +
                rule(:text) do
         | 
| 745 | 
            +
                  str('"') >> (
         | 
| 746 | 
            +
                    str('\\') >> any | str('"').absent? >> any
         | 
| 747 | 
            +
                  ).repeat >> str('"')
         | 
| 748 | 
            +
                end
         | 
| 749 | 
            +
              end
         | 
| 750 | 
            +
            end
         | 
    
        data/lib/netsnmp/oid.rb
    CHANGED
    
    | @@ -10,16 +10,10 @@ module NETSNMP | |
| 10 10 |  | 
| 11 11 | 
             
                module_function
         | 
| 12 12 |  | 
| 13 | 
            -
                def build( | 
| 14 | 
            -
                   | 
| 15 | 
            -
                   | 
| 16 | 
            -
             | 
| 17 | 
            -
                  when OIDREGEX
         | 
| 18 | 
            -
                    o = o[1..-1] if o.start_with?(".")
         | 
| 19 | 
            -
                    o
         | 
| 20 | 
            -
                  # TODO: MIB to OID
         | 
| 21 | 
            -
                  else raise Error, "can't convert #{o} to OID"
         | 
| 22 | 
            -
                  end
         | 
| 13 | 
            +
                def build(id)
         | 
| 14 | 
            +
                  oid = MIB.oid(id)
         | 
| 15 | 
            +
                  oid = oid[1..-1] if oid.start_with?(".")
         | 
| 16 | 
            +
                  oid
         | 
| 23 17 | 
             
                end
         | 
| 24 18 |  | 
| 25 19 | 
             
                def to_asn(oid)
         | 
    
        data/lib/netsnmp/version.rb
    CHANGED
    
    
    
        data/sig/mib.rbs
    ADDED
    
    | @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module NETSNMP
         | 
| 2 | 
            +
              module MIB
         | 
| 3 | 
            +
                MIBDIRS: Array[String]
         | 
| 4 | 
            +
                PARSER: Parser
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                @parser_mutex: Mutex
         | 
| 7 | 
            +
                @modules_loaded: Array[String]
         | 
| 8 | 
            +
                @object_identifiers: Hash[String, String]
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def self?.oid: (String identifier) -> String?
         | 
| 11 | 
            +
                             | (Array[_ToS] identifier) -> String?
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self?.load: (String mod) -> void
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self?.load_imports: (?Hash[Symbol, untyped] data) -> Hash[String, Array[String]]?
         | 
| 16 | 
            +
                def self?.load_defaults: () -> void
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
    
        data/sig/mib/parser.rbs
    ADDED
    
    
    
        data/sig/oid.rbs
    CHANGED
    
    
    
        data/spec/client_spec.rb
    CHANGED
    
    | @@ -22,7 +22,7 @@ RSpec.describe NETSNMP::Client do | |
| 22 22 | 
             
                  let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
         | 
| 23 23 | 
             
                  let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
         | 
| 24 24 | 
             
                  let(:walk_oid) { "1.3.6.1.2.1.1" }
         | 
| 25 | 
            -
                  let(:set_oid) { " | 
| 25 | 
            +
                  let(:set_oid) { "sysUpTime.0" } # sysUpTimeInstance
         | 
| 26 26 | 
             
                  let(:get_result) { "DEVICE-192.168.1.1" }
         | 
| 27 27 | 
             
                  let(:next_result) { "The Cloud" }
         | 
| 28 28 | 
             
                  let(:walk_result) do
         | 
| @@ -48,10 +48,10 @@ RSpec.describe NETSNMP::Client do | |
| 48 48 | 
             
                      community: "public"
         | 
| 49 49 | 
             
                    }
         | 
| 50 50 | 
             
                  end
         | 
| 51 | 
            -
                  let(:get_oid) { " | 
| 51 | 
            +
                  let(:get_oid) { "sysName.0" }
         | 
| 52 52 | 
             
                  let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
         | 
| 53 | 
            -
                  let(:walk_oid) { " | 
| 54 | 
            -
                  let(:set_oid) { " | 
| 53 | 
            +
                  let(:walk_oid) { "system" }
         | 
| 54 | 
            +
                  let(:set_oid) { "sysUpTime.0" }
         | 
| 55 55 | 
             
                  let(:get_result) { "DEVICE-192.168.1.1" }
         | 
| 56 56 | 
             
                  let(:next_result) { "The Cloud" }
         | 
| 57 57 | 
             
                  let(:walk_result) do
         | 
| @@ -78,9 +78,9 @@ RSpec.describe NETSNMP::Client do | |
| 78 78 | 
             
                    context: "a172334d7d97871b72241397f713fa12"
         | 
| 79 79 | 
             
                  }
         | 
| 80 80 | 
             
                end
         | 
| 81 | 
            -
                let(:get_oid) { " | 
| 81 | 
            +
                let(:get_oid) { "sysName.0" }
         | 
| 82 82 | 
             
                let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
         | 
| 83 | 
            -
                let(:set_oid) { " | 
| 83 | 
            +
                let(:set_oid) { "sysUpTime.0" } # sysUpTimeInstance
         | 
| 84 84 | 
             
                let(:walk_oid) { "1.3.6.1.2.1.1.9.1.3" }
         | 
| 85 85 | 
             
                let(:get_result) { "tt" }
         | 
| 86 86 | 
             
                let(:next_result) { "KK12" }
         | 
| @@ -4,7 +4,7 @@ require "celluloid/io" | |
| 4 4 | 
             
            require_relative "../support/request_examples"
         | 
| 5 5 | 
             
            require_relative "../support/celluloid"
         | 
| 6 6 |  | 
| 7 | 
            -
            RSpec.describe "with cellulloid", type: :celluloid do
         | 
| 7 | 
            +
            RSpec.describe "with cellulloid", type: :celluloid, if: RUBY_ENGINE == "truffleruby" do
         | 
| 8 8 | 
             
              include CelluloidHelpers
         | 
| 9 9 | 
             
              let(:user_options) do
         | 
| 10 10 | 
             
                { username: "authprivmd5des", auth_password: "maplesyrup",
         | 
    
        data/spec/mib_spec.rb
    ADDED
    
    | @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe NETSNMP::MIB do
         | 
| 4 | 
            +
              describe ".oid" do
         | 
| 5 | 
            +
                it { expect(described_class.oid("1.2.3.4")).to eq("1.2.3.4") }
         | 
| 6 | 
            +
                it { expect(described_class.oid("ifTable")).to eq("1.3.6.1.2.1.2.2") }
         | 
| 7 | 
            +
                it { expect(described_class.oid("sysDescr.0")).to eq("1.3.6.1.2.1.1.1.0") }
         | 
| 8 | 
            +
                it { expect(described_class.oid("ifTable.1.23")).to eq("1.3.6.1.2.1.2.2.1.23") }
         | 
| 9 | 
            +
                it { expect(described_class.oid("IF-MIB::ifTable.1.23")).to eq("1.3.6.1.2.1.2.2.1.23") }
         | 
| 10 | 
            +
                it { expect(described_class.oid("IFMIB::ifTable.1.23")).to be_nil }
         | 
| 11 | 
            +
                it { expect(described_class.oid("IF-MIB::")).to be_nil }
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,15 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: netsnmp
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Tiago Cardoso
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 12 | 
            -
            dependencies: | 
| 11 | 
            +
            date: 2021-01-16 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: parslet
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 13 27 | 
             
            description: |2
         | 
| 14 28 | 
             
                  Wraps the net-snmp core usage into idiomatic ruby.
         | 
| 15 29 | 
             
                  It is designed to support as many environments and concurrency frameworks as possible.
         | 
| @@ -28,6 +42,8 @@ files: | |
| 28 42 | 
             
            - lib/netsnmp/encryption/none.rb
         | 
| 29 43 | 
             
            - lib/netsnmp/errors.rb
         | 
| 30 44 | 
             
            - lib/netsnmp/message.rb
         | 
| 45 | 
            +
            - lib/netsnmp/mib.rb
         | 
| 46 | 
            +
            - lib/netsnmp/mib/parser.rb
         | 
| 31 47 | 
             
            - lib/netsnmp/oid.rb
         | 
| 32 48 | 
             
            - lib/netsnmp/pdu.rb
         | 
| 33 49 | 
             
            - lib/netsnmp/scoped_pdu.rb
         | 
| @@ -39,6 +55,8 @@ files: | |
| 39 55 | 
             
            - lib/netsnmp/version.rb
         | 
| 40 56 | 
             
            - sig/client.rbs
         | 
| 41 57 | 
             
            - sig/message.rbs
         | 
| 58 | 
            +
            - sig/mib.rbs
         | 
| 59 | 
            +
            - sig/mib/parser.rbs
         | 
| 42 60 | 
             
            - sig/netsnmp.rbs
         | 
| 43 61 | 
             
            - sig/oid.rbs
         | 
| 44 62 | 
             
            - sig/openssl.rbs
         | 
| @@ -51,6 +69,7 @@ files: | |
| 51 69 | 
             
            - sig/varbind.rbs
         | 
| 52 70 | 
             
            - spec/client_spec.rb
         | 
| 53 71 | 
             
            - spec/handlers/celluloid_spec.rb
         | 
| 72 | 
            +
            - spec/mib_spec.rb
         | 
| 54 73 | 
             
            - spec/oid_spec.rb
         | 
| 55 74 | 
             
            - spec/pdu_spec.rb
         | 
| 56 75 | 
             
            - spec/security_parameters_spec.rb
         | 
| @@ -91,6 +110,7 @@ test_files: | |
| 91 110 | 
             
            - spec/spec_helper.rb
         | 
| 92 111 | 
             
            - spec/session_spec.rb
         | 
| 93 112 | 
             
            - spec/client_spec.rb
         | 
| 113 | 
            +
            - spec/mib_spec.rb
         | 
| 94 114 | 
             
            - spec/oid_spec.rb
         | 
| 95 115 | 
             
            - spec/varbind_spec.rb
         | 
| 96 116 | 
             
            - spec/support/request_examples.rb
         |