Ciscoルータのポート一覧をRubyとSNMPで取得する

[前回](http://qiita.com/kooshin/items/1853e245d7162498cea9)は``snmpwalk``コマンドでCiscoルータのポート一覧を表示しました。
今回は``Ruby``を用いて、ポート一覧を見やすく表示します。
合わせてトラフィック量も表示します。

## SNMP OID
今回利用するOIDは下記のとおりです。

* ifDescr（1.3.6.1.2.1.2.2.1.2）：インタフェース名（FastEthernet0）
* ifName（1.3.6.1.2.1.31.1.1.1.1：インタフェース名（上記の省略形、Fa0）
* ifAlias(1.3.6.1.2.1.31.1.1.1.18)：description
* ifAdminStatus（1.3.6.1.2.1.2.2.1.7）：設定の状態（shutdown / no shutdown）
* ifOperStatus（1.3.6.1.2.1.2.2.1.8）：現在の状態（LinkDown / LinkUp）
* ifHCInOctets（1.3.6.1.2.1.31.1.1.1.6）：入力カウンタ（64bit版）
* ifHCOutOctets（1.3.6.1.2.1.31.1.1.1.10）：出力カウンタ（64bit版）

## 実装
``Ruby2.2.1``と[Ruby SNMP](http://snmplib.rubyforge.org/)の``snmp 1.2.0``を利用しました。
SNMPを取得する部分はサンプルをそのまま流用して、表示書式を揃えて出力するようにしています。

```ruby:snmpwalk1.rb
#!/usr/bin/env ruby
require 'snmp'

ifAdminStatus_values = Hash[*%w(1 up 2 down 3 testing)]
ifOperStatus_values = Hash[*%w(1 up 2 down 3 testing 4 unknown 5 dormant 6 notPresent 7 lowerLayerDown)]

ifTable_columns = ['ifDescr', 'ifName', 'ifAlias', 'ifAdminStatus', 'ifOperStatus', 'ifHCInOctets', 'ifHCOutOctets']

puts "%-23s,%-10s,%-15s,%-6s,%-6s,%10s,%10s" % ['Interface', 'I/F', 'description', 'Admin', 'Oper', 'In', 'Out']

SNMP::Manager.open(host: '192.168.88.101', community: 'public') do |manager|
  manager.walk(ifTable_columns) do |row|
    values = row.map{|vb| vb.value.to_s }
    values[3] = ifAdminStatus_values[values[3]]
    values[4] = ifOperStatus_values[values[4]]
    values[5] = '-1' if values[5] == 'noSuchInstance'
    values[6] = '-1' if values[6] == 'noSuchInstance'
    puts "%-23s,%-10s,%-15s,%-6s,%-6s,%10s,%10s" % values
  end 
end
```

ifAdminStatusとifOperStatusは、SNMPで取得できる状態が数値のため、見やすくするために
文字列に変換しています。数値と文字列の対応付けは[Cisco SNMPオブジェクトナビゲータ](http://tools.cisco.com/Support/SNMP/do/BrowseOID.do?local=ja)を見て実装しています。

ifHCInOctetsとifHCOutOctetsは、インタフェースのトラフィックカウンタを参照できます。
カウンタに対応していないインタフェースの場合、``noSuchInstance``となるため、``-1``に変換しています。

## 実行結果
``Ubuntu15.04``の``Ruby2.2.1``で実行した結果です。
SNMPを取得しているCiscoルータはCisco1812Jを利用しています。

```zsh:実行結果
% ruby snmpwalk1.rb
Interface              ,I/F       ,description    ,Admin ,Oper  ,        In,       Out
FastEthernet0          ,Fa0       ,WAN            ,up    ,up    ,    932750,   1076990
FastEthernet1          ,Fa1       ,LAN            ,down  ,down  ,         0,         0
BRI0                   ,BR0       ,               ,down  ,down  ,        -1,        -1
BRI0:1                 ,BR0:1     ,               ,down  ,down  ,        -1,        -1
BRI0:2                 ,BR0:2     ,               ,down  ,down  ,        -1,        -1
FastEthernet2          ,Fa2       ,SW1            ,up    ,down  ,         0,         0
FastEthernet3          ,Fa3       ,SW2            ,up    ,down  ,         0,         0
FastEthernet4          ,Fa4       ,               ,up    ,down  ,         0,         0
FastEthernet5          ,Fa5       ,               ,up    ,down  ,         0,         0
FastEthernet6          ,Fa6       ,               ,up    ,down  ,         0,         0
FastEthernet7          ,Fa7       ,               ,up    ,down  ,         0,         0
FastEthernet8          ,Fa8       ,               ,up    ,down  ,         0,         0
FastEthernet9          ,Fa9       ,               ,up    ,down  ,         0,         0
Null0                  ,Nu0       ,               ,up    ,up    ,        -1,        -1
Vlan1                  ,Vl1       ,               ,up    ,down  ,         0,         0
BRI0-Physical          ,BR0       ,               ,down  ,down  ,        -1,        -1
BRI0-Signaling         ,BR0       ,               ,down  ,down  ,        -1,        -1
BRI0:1-Bearer Channel  ,BR0:1     ,               ,down  ,down  ,        -1,        -1
BRI0:2-Bearer Channel  ,BR0:2     ,               ,down  ,down  ,        -1,        -1
```

## パケットキャプチャ
Wiresharkでパケットキャプチャした結果です。

ポート数と同じ合計19リクエスト。1リクエストあたり7OIDを取得。
リクエストは180-190バイト。レスポンスは200-222バイト。

* 192.168.88.3 : パソコン
* 192.168.88.101 : ルータ

```csv:パケットキャプチャ結果
No.,Time,Source,Destination,Protocol,Length,Info
 1,0.000000000,192.168.88.3  ,192.168.88.101,SNMP,181,get-next-request
 2,0.001878000,192.168.88.101,192.168.88.3  ,SNMP,217,get-response
 3,0.002674000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
 4,0.004467000,192.168.88.101,192.168.88.3  ,SNMP,213,get-response
 5,0.005270000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
 6,0.007091000,192.168.88.101,192.168.88.3  ,SNMP,200,get-response
 7,0.007707000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
 8,0.009523000,192.168.88.101,192.168.88.3  ,SNMP,205,get-response
 9,0.010239000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
10,0.012034000,192.168.88.101,192.168.88.3  ,SNMP,205,get-response
11,0.012762000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
12,0.014483000,192.168.88.101,192.168.88.3  ,SNMP,213,get-response
13,0.015170000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
14,0.016899000,192.168.88.101,192.168.88.3  ,SNMP,213,get-response
15,0.017453000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
16,0.019139000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
17,0.020399000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
18,0.022145000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
19,0.022930000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
20,0.024662000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
21,0.025358000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
22,0.027057000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
23,0.027867000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
24,0.029552000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
25,0.030146000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
26,0.031834000,192.168.88.101,192.168.88.3  ,SNMP,210,get-response
27,0.032426000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
28,0.034193000,192.168.88.101,192.168.88.3  ,SNMP,202,get-response
29,0.034838000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
30,0.036636000,192.168.88.101,192.168.88.3  ,SNMP,202,get-response
31,0.037548000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
32,0.039377000,192.168.88.101,192.168.88.3  ,SNMP,212,get-response
33,0.040038000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
34,0.041888000,192.168.88.101,192.168.88.3  ,SNMP,213,get-response
35,0.042588000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
36,0.044430000,192.168.88.101,192.168.88.3  ,SNMP,222,get-response
37,0.045298000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
38,0.047068000,192.168.88.101,192.168.88.3  ,SNMP,222,get-response
39,0.048408000,192.168.88.3  ,192.168.88.101,SNMP,189,get-next-request
40,0.050199000,192.168.88.101,192.168.88.3  ,SNMP,200,get-response
``