Class: SNMP

Inherits:
Object show all
Defined in:
lib/gri/msnmp.rb

Constant Summary collapse

OIDS =
{
  'iso'=>'1',
  'org'=>'1.3',
  'dod'=>'1.3.6',
  'internet'=>'1.3.6.1',
  'directory'=>'1.3.6.1.1',
  'mgmt'=>'1.3.6.1.2',
  'mib-2'=>'1.3.6.1.2.1',
  'system'=>'1.3.6.1.2.1.1',
  'sysDescr'=>'1.3.6.1.2.1.1.1',
  'sysObjectID'=>'1.3.6.1.2.1.1.2',
  'sysUpTime'=>'1.3.6.1.2.1.1.3',
  'sysContact'=>'1.3.6.1.2.1.1.4',
  'sysName'=>'1.3.6.1.2.1.1.5',
  'sysLocation'=>'1.3.6.1.2.1.1.6',
  'sysServices'=>'1.3.6.1.2.1.1.7',

  'interfaces'=>'1.3.6.1.2.1.2',
  'ifNumber'=>'1.3.6.1.2.1.2.1',
  'ifTable'=>'1.3.6.1.2.1.2.2',
  'ifEntry'=>'1.3.6.1.2.1.2.2.1',
  'ifIndex'=>'1.3.6.1.2.1.2.2.1.1',
  'ifInOctets'=>'1.3.6.1.2.1.2.2.1.10',
  'ifInUcastPkts'=>'1.3.6.1.2.1.2.2.1.11',
  'ifInNUcastPkts'=>'1.3.6.1.2.1.2.2.1.12',
  'ifInDiscards'=>'1.3.6.1.2.1.2.2.1.13',
  'ifInErrors'=>'1.3.6.1.2.1.2.2.1.14',
  'ifInUnknownProtos'=>'1.3.6.1.2.1.2.2.1.15',
  'ifOutOctets'=>'1.3.6.1.2.1.2.2.1.16',
  'ifOutUcastPkts'=>'1.3.6.1.2.1.2.2.1.17',
  'ifOutNUcastPkts'=>'1.3.6.1.2.1.2.2.1.18',
  'ifOutDiscards'=>'1.3.6.1.2.1.2.2.1.19',
  'ifDescr'=>'1.3.6.1.2.1.2.2.1.2',
  'ifOutErrors'=>'1.3.6.1.2.1.2.2.1.20',
  'ifOutQLen'=>'1.3.6.1.2.1.2.2.1.21',
  'ifSpecific'=>'1.3.6.1.2.1.2.2.1.22',
  'ifType'=>'1.3.6.1.2.1.2.2.1.3',
  'ifMtu'=>'1.3.6.1.2.1.2.2.1.4',
  'ifSpeed'=>'1.3.6.1.2.1.2.2.1.5',
  'ifPhysAddress'=>'1.3.6.1.2.1.2.2.1.6',
  'ifAdminStatus'=>'1.3.6.1.2.1.2.2.1.7',
  'ifOperStatus'=>'1.3.6.1.2.1.2.2.1.8',
  'ifLastChange'=>'1.3.6.1.2.1.2.2.1.9',

  'ipAddrTable'=>'1.3.6.1.2.1.4.20',
  'ipAddrEntry'=>'1.3.6.1.2.1.4.20.1',
  'ipAdEntIfIndex'=>'1.3.6.1.2.1.4.20.1.2',
  'ipAdEntNetMask'=>'1.3.6.1.2.1.4.20.1.3',
  'ipNetToMediaIfIndex'=>'1.3.6.1.2.1.4.22.1.1',
  'ipNetToMediaPhysAddress'=>'1.3.6.1.2.1.4.22.1.2',
  'ipNetToMediaNetAddress'=>'1.3.6.1.2.1.4.22.1.3',
  'ipNetToMediaType'=>'1.3.6.1.2.1.4.22.1.4',

  'tcp'=>'1.3.6.1.2.1.6',
  'tcpCurrEstab'=>'1.3.6.1.2.1.6.9.0',
  'tcpActiveOpens'=>'1.3.6.1.2.1.6.5.0',
  'tcpPassiveOpens'=>'1.3.6.1.2.1.6.6.0',
  'tcpAttemptFails'=>'1.3.6.1.2.1.6.7.0',
  'tcpEstabResets'=>'1.3.6.1.2.1.6.8.0',
  'tcpInSegs'=>'1.3.6.1.2.1.6.10.0',
  'tcpOutSegs'=>'1.3.6.1.2.1.6.11.0',
  'tcpRetransSegs'=>'1.3.6.1.2.1.6.12.0',
  'tcpInErrs'=>'1.3.6.1.2.1.6.14.0',
  'tcpOutRsts'=>'1.3.6.1.2.1.6.15.0',

  'udp'=>'1.3.6.1.2.1.7',
  'udpInDatagrams' => '1.3.6.1.2.1.7.1.0',
  'udpNoPorts' => '1.3.6.1.2.1.7.2.0',
  'udpInErrors' => '1.3.6.1.2.1.7.3.0',
  'udpOutDatagrams' => '1.3.6.1.2.1.7.4.0',

  'host'=>'1.3.6.1.2.1.25',
  'hrSystem'=>'1.3.6.1.2.1.25.1',
  'hrSystemNumUsers'=>'1.3.6.1.2.1.25.1.5.0',
  'hrSystemProcesses'=>'1.3.6.1.2.1.25.1.6.0',
  'hrSystemMaxProcesses'=>'1.3.6.1.2.1.25.1.7.0',
  'hrStorage'=>'1.3.6.1.2.1.25.2',
  'hrStorageTypes'=>'1.3.6.1.2.1.25.2.1',
  'hrStorageFixedDisk'=>'1.3.6.1.2.1.25.2.1.4',
  'hrMemorySize'=>'1.3.6.1.2.1.25.2.2.0',
  'hrStorageTable'=>'1.3.6.1.2.1.25.2.3',
  'hrStorageEntry'=>'1.3.6.1.2.1.25.2.3.1',
  'hrStorageIndex'=>'1.3.6.1.2.1.25.2.3.1.1',
  'hrStorageType'=>'1.3.6.1.2.1.25.2.3.1.2',
  'hrStorageDescr'=>'1.3.6.1.2.1.25.2.3.1.3',
  'hrStorageAllocationUnits'=>'1.3.6.1.2.1.25.2.3.1.4',
  'hrStorageSize'=>'1.3.6.1.2.1.25.2.3.1.5',
  'hrStorageUsed'=>'1.3.6.1.2.1.25.2.3.1.6',

  'hrSWRunName'=>'1.3.6.1.2.1.25.4.2.1.2',
  'hrSWRunPath'=>'1.3.6.1.2.1.25.4.2.1.4',
  'hrSWRunParameters'=>'1.3.6.1.2.1.25.4.2.1.5',
  'hrSWRunPerfCPU'=>'1.3.6.1.2.1.25.5.1.1.1',
  'hrSWRunPerfMem'=>'1.3.6.1.2.1.25.5.1.1.2',

  'ifMIB'=>'1.3.6.1.2.1.31',
  'ifXEntry'=>'1.3.6.1.2.1.31.1.1.1',
  'ifName'=>'1.3.6.1.2.1.31.1.1.1.1',
  'ifInMulticastPkts'=>'1.3.6.1.2.1.31.1.1.1.2',
  'ifInBroadcastPkts'=>'1.3.6.1.2.1.31.1.1.1.3',
  'ifOutMulticastPkts'=>'1.3.6.1.2.1.31.1.1.1.4',
  'ifOutBroadcastPkts'=>'1.3.6.1.2.1.31.1.1.1.5',
  'ifHCInOctets'=>'1.3.6.1.2.1.31.1.1.1.6',
  'ifHCInUcastPkts'=>'1.3.6.1.2.1.31.1.1.1.7',
  'ifHCInMulticastPkts'=>'1.3.6.1.2.1.31.1.1.1.8',
  'ifHCInBroadcastPkts'=>'1.3.6.1.2.1.31.1.1.1.9',
  'ifHCOutOctets'=>'1.3.6.1.2.1.31.1.1.1.10',
  'ifHCOutUcastPkts'=>'1.3.6.1.2.1.31.1.1.1.11',
  'ifHCOutMulticastPkts'=>'1.3.6.1.2.1.31.1.1.1.12',
  'ifHCOutBroadcastPkts'=>'1.3.6.1.2.1.31.1.1.1.13',
  'ifLinkUpDownTrapEnable'=>'1.3.6.1.2.1.31.1.1.1.14',
  'ifHighSpeed'=>'1.3.6.1.2.1.31.1.1.1.15',
  'ifPromiscuousMode'=>'1.3.6.1.2.1.31.1.1.1.16',
  'ifConnectorPresent'=>'1.3.6.1.2.1.31.1.1.1.17',
  'ifAlias'=>'1.3.6.1.2.1.31.1.1.1.18',

  'entityMIB'=>'1.3.6.1.2.1.47',
  'entPhysicalEntry'=>'1.3.6.1.2.1.47.1.1.1.1',
  'entPhysicalDescr'=>'1.3.6.1.2.1.47.1.1.1.1.2',
  'entPhysicalName'=>'1.3.6.1.2.1.47.1.1.1.1.7',

  'experimental'=>'1.3.6.1.3',
  'private'=>'1.3.6.1.4',
  'enterprises'=>'1.3.6.1.4.1',
}
ROIDS =
{}
RECV_SIZE =
2000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port = nil) ⇒ SNMP

Returns a new instance of SNMP.



435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/gri/msnmp.rb', line 435

def initialize host, port=nil
  port ||= 161
  if ROIDS.empty?
    for sym, oid in OIDS
      ROIDS[BER.enc_v_oid(oid)] = sym
    end
  end
  @host = host
  @port = port
  @request_id = 1000
  @retries = 3
  @timeout = 4
  @ver = "\x02\x01\x00" # INT: 0 (ver 1)
  @community = "\x04\x06public"
  @numeric = false
  @state = :IDLE
  @sock = nil
end

Instance Attribute Details

#numericObject

Returns the value of attribute numeric.



425
426
427
# File 'lib/gri/msnmp.rb', line 425

def numeric
  @numeric
end

#sockObject (readonly)

Returns the value of attribute sock.



424
425
426
# File 'lib/gri/msnmp.rb', line 424

def sock
  @sock
end

#stateObject

Returns the value of attribute state.



425
426
427
# File 'lib/gri/msnmp.rb', line 425

def state
  @state
end

Class Method Details

.add_oid(sym, oid) ⇒ Object



427
428
429
# File 'lib/gri/msnmp.rb', line 427

def self.add_oid sym, oid
  OIDS[sym] = oid
end

.enoid2name(enoid) ⇒ Object



475
476
477
478
479
480
481
482
483
484
485
486
487
# File 'lib/gri/msnmp.rb', line 475

def self.enoid2name enoid
  a = BER.dec_oid enoid
  n = a.size
  n0 = n

  while n > 1
    if (s = ROIDS[BER.enc_a_oid(a[0, n])])
      return ([s] + a[n, n0-n]).join('.')
    end
    n -= 1
  end
  s || a.join('.')
end

.update(h) ⇒ Object



431
432
433
# File 'lib/gri/msnmp.rb', line 431

def self.update h
  OIDS.merge! h
end

Instance Method Details

#_walk(enoid, &cb) ⇒ Object



521
522
523
524
# File 'lib/gri/msnmp.rb', line 521

def _walk enoid, &cb
  walk_start enoid, &cb
  req_loop enoid
end

#closeObject



459
460
461
# File 'lib/gri/msnmp.rb', line 459

def close
  @sock.close
end

#community=(community) ⇒ Object



468
469
470
# File 'lib/gri/msnmp.rb', line 468

def community=(community)
  @community = BER.enc_str community
end

#connectObject



454
455
456
457
# File 'lib/gri/msnmp.rb', line 454

def connect
  @sock = UDPSocket.new
  @sock.connect @host, @port
end

#enoid2name(enoid) ⇒ Object



472
473
474
# File 'lib/gri/msnmp.rb', line 472

def enoid2name enoid
  SNMP.enoid2name enoid
end

#get(oid_list, &cb) ⇒ Object



546
547
548
549
550
551
552
553
# File 'lib/gri/msnmp.rb', line 546

def get oid_list, &cb
  oids = oid_list.map {|s| BER.enc_v_oid(OIDS[s]||s)}
  varbind = BER.cat_enoid oids
  get_varbind(varbind) {|enoid, tag, val|
    oid = @numeric ? (BER.dec_oid(enoid).join('.')) : (enoid2name enoid)
    cb.call oid, tag, val
  }
end

#get_start(varbind, &cb) ⇒ Object



535
536
537
538
539
# File 'lib/gri/msnmp.rb', line 535

def get_start varbind, &cb
  @req_enoid = ''
  @cb = cb
  @state = :GET_REQ
end

#get_varbind(varbind, &cb) ⇒ Object



541
542
543
544
# File 'lib/gri/msnmp.rb', line 541

def get_varbind varbind, &cb
  get_start varbind, &cb
  req_loop varbind
end

#make_msg(cmd, err_index, varbind) ⇒ Object



489
490
491
492
493
494
495
# File 'lib/gri/msnmp.rb', line 489

def make_msg cmd, err_index, varbind
  @request_id += 1
  @enc_request_id = BER.enc_int @request_id
  s = @enc_request_id + "\x02\x01\x00" + err_index + varbind
  s = @ver + @community + cmd + BER.enc_len(s.size) + s
  s = "\x30" + BER.enc_len(s.size) + s
end

#make_req(st, arg) ⇒ Object



497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/gri/msnmp.rb', line 497

def make_req st, arg
  case st
  when :GETBULK_REQ
    vb = "\x06" + BER.enc_len(arg.size) + arg + "\x05\x00"
    vb = "\x30" + BER.enc_len(vb.size) + vb
    varbind = "\x30" + BER.enc_len(vb.size) + vb
    s = make_msg "\xa5", "\x02\x01\x0c", varbind
  when :GETNEXT_REQ
    vb = "\x06" + BER.enc_len(arg.size) + arg + "\x05\x00"
    vb = "\x30" + BER.enc_len(vb.size) + vb
    varbind = "\x30" + BER.enc_len(vb.size) + vb
    s = make_msg "\xa1", "\x02\x01\x00", varbind
  when :GET_REQ
    s = make_msg "\xa0", "\x02\x01\x00", arg
  end
  s
end

#recv_msg(msg) ⇒ Object



579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
# File 'lib/gri/msnmp.rb', line 579

def recv_msg msg
  enc_request_id, @error_status, @error_index, varbind = BER.dec_msg msg
  return unless enc_request_id == @enc_request_id
  unless @error_status == 0
    @state = :IDLE
    return
  end

  vars = BER.dec_varbind varbind
  if vars.empty?
    @state = :SUCCESS
    return
  end
  for var in vars
    if (var[1] != 130) and var[0].index(@req_enoid) #130=endOfMibView
      @cb.call(*var)
    else
      @state = :SUCCESS
    end
  end
  enoid = vars[-1][0]
rescue StandardError
  raise SystemCallError, 'broken packet'
end

#req_loop(arg) ⇒ Object



555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/gri/msnmp.rb', line 555

def req_loop arg
  connect unless @sock
  until @state == :SUCCESS or @state == :IDLE
    s = make_req @state, arg
    @retry_count = 0
    while true
      @sock.send s, 0
      if (a = IO.select([@sock], nil, nil, @timeout))
        msg = @sock.recv RECV_SIZE, 0
        arg = recv_msg msg
        if arg
          @state = :SUCCESS if @state == :GET_REQ
          break
        end
      else
        if (@retry_count += 1) >= @retries
          @state = :IDLE
          return
        end
      end
    end
  end
end

#version=(ver) ⇒ Object



463
464
465
466
# File 'lib/gri/msnmp.rb', line 463

def version=(ver)
  ver = {'1'=>0, '2c'=>1}[ver] || 0
  @ver = BER.enc_int ver
end

#walk(oid, &cb) ⇒ Object



526
527
528
529
530
531
532
533
# File 'lib/gri/msnmp.rb', line 526

def walk oid, &cb
  noid = OIDS[oid] || oid
  enoid = BER.enc_v_oid noid
  _walk(enoid) {|enoid, tag, val|
    oid = @numeric ? (BER.dec_oid(enoid).join('.')) : (enoid2name enoid)
    cb.call oid, tag, val
  }
end

#walk_start(enoid, &cb) ⇒ Object



515
516
517
518
519
# File 'lib/gri/msnmp.rb', line 515

def walk_start enoid, &cb
  @req_enoid = enoid
  @cb = cb
  @state = (@ver == "\002\001\001") ? :GETBULK_REQ : :GETNEXT_REQ
end