# SNMP

> SNMP v1、v2c、v3 に応答するネットワーク機器（UPS、PDU、スイッチ、ルーター、精密空調、環境センサー）を、各タグの読み出し周期ごとにエージェントを通して読みます。「SNMP エージェント」のカード、数字または標準名で書くタグの OID、各オブジェクトを読むデータ型、読み取りと書き込み、エージェントのオブジェクトを見つけるたどり、そして 2 つの完全な例です。

**SNMP** ドライバーは、機械室の機器をその SNMP エージェントを通して読み書きします。UPS、PDU、スイッチ、ルーター、精密空調、温度や湿度のセンサーです。サーバーの管理コントローラーを読む [Redfish](driver-redfish) ドライバーを補うもので、両方で機械室全体をカバーします。各タグはエージェントのオブジェクトを 1 つ、`upsBatteryStatus.0` や `ifHCInOctets.2` のような OID で読み、値はほかのどのタグの値とも同じところに届きます。Logic、ダッシュボード、そして [Process](process) の試験台の実行記録です。

問い合わせるのはステーションです。各タグは読み出し周期ごとに SNMPv1、SNMPv2c、SNMPv3 のいずれかで読まれ、「機器」のカードの**読み出し周期（ms）**はどのドライバーとも同じように働き、各タグで上書きできます。機器が自分から送るもの、つまりトラップは受け取りません。[知っておきたい制限](#limits-worth-knowing)を参照してください。

このドライバーの機器はエージェント 1 つで、そのホストの UDP ポート 161 で到達します。機器はドライバーの下に置かれ、フォルダーに整理でき、シリアル回線もブローカーも持たないどのドライバーとも同じく **ドライバー → フォルダー → 機器 → タグ** となります。

## ドライバーのページ {#the-drivers-page}

Connector の構成の権限があるとき、ページにはこのドライバー独自のスキャンの範囲のカードがあり、機器検出がたどるエージェントとサブツリーを持ちます（[機器検出](#discovery)を参照）。その下には、どのドライバーとも同じ**機器**の表（[機器の表](connector-drivers#the-device-table)を参照）があり、タイトルの右にある**機器を追加**で増やします。空のときは「機器はまだありません。」と表示します。ドライバーのバーには**機器検出**があり、スキャンの範囲のカードがそろうまで灰色です。

## 機器 {#device}

### 接続 {#connection}

| 項目 | 意味 | 既定値 |
| --- | --- | --- |
| **ホスト** | エージェントのホスト名か IP アドレス。 | 空 |
| **ポート** | エージェントが応答する UDP ポートで、1 から 65535。欄が空のときは 161 が灰色で表示され、エージェントにはそのポートで問い合わせます。 | 161 |

新しい機器にはホストがありません。「ホストがまだ入力されていません」と表示し、ホストが入るまで何も送りません。見出しに出る Base URI は実行時のアドレスで、バージョン、有効な SNMPv3 のセキュリティ、応答のタイムアウト、再試行回数を含みます。`snmp://192.168.10.40:161?version=2c&timeoutMs=2000&retries=1`、または `snmp://192.168.10.2:161?version=3&security=authPriv&auth=sha256&priv=aes128&timeoutMs=2000&retries=1` です。community、ユーザー、パスワードは決して含みません。

### 「SNMP エージェント」のカード {#the-snmp-agent-card}

「接続」のカードの下にある **SNMP エージェント**のカードは、エージェントへの問い合わせ方を示します。描かれる欄はバージョンと、SNMPv3 ではセキュリティレベルに従います。

| 項目 | 表示 | 意味 | 既定値 |
| --- | --- | --- | --- |
| **SNMP バージョン** | 常時 | SNMPv1、SNMPv2c、SNMPv3 のいずれかで、それぞれの下に 1 行出ます。SNMPv1：「SNMPv1 には 64 ビットのカウンターがありません。エージェントにないオブジェクトがあるとリクエスト全体が拒否され、ドライバーはそれを除いて問い合わせ直します。」SNMPv2c：「SNMPv2c は 64 ビットのカウンターを読みます。エージェントにないオブジェクトは、そのタグだけが失敗します。ほとんどの機器が応答します。」SNMPv3：「SNMPv3 はユーザーで認証し、セキュリティレベルに従ってメッセージに署名し、暗号化します。」 | SNMPv2c |
| **Community** | SNMPv1、SNMPv2c | エージェントが応答する community で、255 バイトまで。入力を隠す欄で、空のときは `public` をヒントとして表示しますが、値にはしません。下には「エージェントは受け付けない community のリクエストを無視するため、community の誤りは応答しないエージェントのように見えます。」 | 空 |
| **SNMPv3 ユーザー** | SNMPv3 | エージェントが持つユーザーで、32 文字まで。 | 空 |
| **セキュリティレベル** | SNMPv3 | **署名と暗号化（authPriv）**：「すべてのメッセージを認証パスワードで署名し、暗号化パスワードで暗号化します。」**署名のみ（authNoPriv）**：「すべてのメッセージを認証パスワードで署名し、暗号化せずに送ります。」**署名も暗号化もなし（noAuthNoPriv）**：「ユーザー名だけを送ります。署名も暗号化もしません。」 | **署名と暗号化（authPriv）** |
| **認証プロトコル** | SNMPv3、署名あり | MD5、SHA-1、SHA-256、SHA-384、SHA-512。 | SHA-1 |
| **認証パスワード** | SNMPv3、署名あり | メッセージに署名するパスワード。 | 空 |
| **暗号化プロトコル** | SNMPv3、authPriv | DES、AES-128、AES-192、AES-256。 | AES-128 |
| **暗号化パスワード** | SNMPv3、authPriv | メッセージを暗号化するパスワード。 | 空 |
| **応答のタイムアウト（ms）** | 常時 | 100 から 60000：「リクエストを再送するまでに、エージェントの応答を待つ時間です。」 | 2000 |
| **再試行回数** | 常時 | 0 から 5：「応答のないリクエストを再送する回数です。超えると機器はオフラインとみなされます。」 | 1 |

2 つのパスワードの下には「各パスワードは、エージェントがこのユーザーに設定しているもので、8 文字以上です。」と出ます。ユーザー、セキュリティレベル、2 つのプロトコルは、機器自身の設定ページでエージェントがそのユーザーに設定しているものです。ステーションはそれをエージェントに問い合わせることができません。MD5、SHA-1、DES を選べるのは、設置済みの多くの機器がそれより新しいものを受け付けないからです。

まだ入力されていない資格情報は誤りではありません。機器は保存され、それが入るまでドライバーはエージェントに何も送らず、カードの下の落ち着いた 1 行が足りないものを示します。次のうち最初のものです。

| 足りないもの | カードの表示 |
| --- | --- |
| community（SNMPv1、SNMPv2c） | 「エージェントが応答する community を入力してください。それまで機器は何も送りません。」 |
| ユーザー（SNMPv3） | 「SNMPv3 のユーザーを入力してください。それまで機器は何も送りません。」 |
| 認証パスワード（authNoPriv、authPriv） | 「認証パスワードを入力してください。それまで機器は何も送りません。」 |
| 暗号化パスワード（authPriv） | 「暗号化パスワードを入力してください。それまで機器は何も送りません。」 |

ホストがあって資格情報がまだ足りない機器は接続せず、その最後のエラーがエージェントの待っている資格情報を示します。カードが受け付けられない値は保存されず、カードがその理由を赤で示します。

| 入力したもの | カードの表示 |
| --- | --- |
| 8 文字未満の認証パスワード | 「認証パスワードは 8 文字以上にしてください。」 |
| 8 文字未満の暗号化パスワード | 「暗号化パスワードは 8 文字以上にしてください。」 |
| 32 文字を超えるユーザー、または 255 バイトを超える community | 「ユーザーは 32 文字まで、community は 255 バイトまでです。」 |
| 100 から 60000 の範囲外の応答のタイムアウト、または 0 から 5 の範囲外の再試行回数 | 欄は有効な値に戻り、「100 から 60000 までの数値を入力してください。」または「0 から 5 までの数値を入力してください。」と表示します。 |

保存もカードと同じ規則を守り、拒否したときは操作ログ帯がそう伝えます：「機器 'UPS room 1' に、ドライバーが使えない SNMP の設定があります。開いて、パネルが示す欄を直してください。」community と 2 つのパスワードは、どの機器の資格情報とも同じように保管されます（[資格情報と証明書](connector-devices#credentials-and-certificates)を参照）。入力した Windows アカウントのために保存時に保護され、構成のエクスポートでは封印され、Base URI、診断ログ、エージェントの応答には決して出ません。別の Windows アカウントで入力されたものは空で戻り、機器は一度も入力されていないときと同じようにそれを待ちます。

## タグのアドレス {#tag-addressing}

### OID {#the-oid}

このドライバーのタグは、エージェントのオブジェクトを 1 つ読みます。タグの「信号源」のカードには **OID** の欄があり、その下に「数字で書いた OID（例: 1.3.6.1.2.1.1.3.0）か、インスタンス付きの標準名（例: sysUpTime.0、ifInOctets.2、upsBatteryStatus.0）」という助言が出ます。タグをどの形で書いても、リクエストが運ぶのは数字です。

| 書き方 | 読み方 |
| --- | --- |
| `1.3.6.1.2.1.1.3.0`、`.1.3.6.1.2.1.1.3.0`、`iso.3.6.1.2.1.1.3.0` | その数字で、パネルは `sysUpTime.0` と呼びます。 |
| `sysUpTime.0`、`sysUpTime`、`SNMPv2-MIB::sysUpTime.0`（大文字と小文字は区別しません） | 単一の値で、唯一のインスタンス `.0` は省略できます。 |
| `ifInOctets.2` | テーブルの列と、その行のインデックス（ここではインターフェース 2）で、インデックスは常に書きます。 |
| `enterprises.318.1.1.1.2.2.1.0` | 枝とその下の数字です。機器独自の MIB のオブジェクトで、数字で表示します。 |

欄の下には、読み取り専用で、OID が 2 つの形で出ます。

| 表示 | 示すもの |
| --- | --- |
| **MIB の名前** | オブジェクトの標準名とインスタンス（`ifInOctets.2`）。その下に、MIB がそのオブジェクトについて言うこと、つまり MIB、持つ値の種類、書き込みを受け付けるかを、`IF-MIB · Counter32 · 読み取り専用` や `UPS-MIB · Integer32 · 書き込み可` のように示します。ドライバーが名前を知らないオブジェクトでは「標準名なし」です。 |
| **数字の OID** | 数字で書いた OID で、すべてのリクエストが運ぶものです。 |

標準名のないオブジェクトでは「機器独自の MIB のオブジェクトです。MIB ファイルは読まないため、数字で表示します。」という行が加わります。ドライバーが読めない OID のタグは保存されず、タグのページがその理由を示します。

| 入力したもの | タグのページの表示 |
| --- | --- |
| OID なし | 「このドライバーでは OID が必須です。」 |
| ドライバーが知らない名前 | 「この名前は、ドライバーが知っている標準 MIB オブジェクトではありません。OID を数字で書いてください。」 |
| 行のない列（`ifInOctets` など） | 「テーブルの列には行のインデックスが必要です（例: ifInOctets.1）。」 |
| 0 以外のインスタンスを持つ単一の値（`sysUpTime.1` など） | 「単一の値のインスタンスは .0 だけで、省略できます。」 |
| 枝だけ（`enterprises` や `ifTable` など） | 「ツリーの枝は値を指しません。その下にあるオブジェクトの数字を書いてください。」 |
| 2 を超える最初の数、40 以上の 2 番目の数、128 個を超える数、4294967295 を超える数 | 「OID は 0、1、2 のいずれかと 40 未満の数で始まり、4294967295 以下の数を最大 128 個持ちます。」 |
| OID ではないそのほかのもの | 「OID を数字（例: 1.3.6.1.2.1.1.3.0）か、インスタンス付きの標準名（例: sysUpTime.0）で書いてください。」 |

保存も同じ規則を守ります：「タグ 'Battery status' は、SNMP ドライバーが読める OID を指していません。開いて、タグのパネルが示すアドレスを直してください。」読み取り専用の行**取得元のアドレス（バス上）**は、ドライバーが受け取る数字を示します。`upsBatteryStatus.0` と書いたタグなら `1.3.6.1.2.1.33.1.2.1.0` です。

### ドライバーが知っている名前 {#the-names-the-driver-knows}

ドライバーは、名前を付ける価値のある標準 MIB のオブジェクトの表を 1 つ持っています。RFC から書き起こしたもので、どのステーションでも名前は同じ意味です。MIB ファイルは読みません。

| MIB | 名前を付けるもの |
| --- | --- |
| SNMPv2-MIB（RFC 3418） | system グループ：`sysDescr`、`sysObjectID`、`sysUpTime`、`sysContact`、`sysName`、`sysLocation`、`sysServices`。 |
| IF-MIB（RFC 2863） | `ifNumber`、インターフェースの表（`ifDescr`、`ifOperStatus`、`ifInOctets`、`ifOutErrors` など）と、64 ビットのカウンターを持つその拡張（`ifName`、`ifHCInOctets`、`ifHCOutOctets`、`ifHighSpeed`、`ifAlias`）。 |
| UPS-MIB（RFC 1628） | UPS の識別、バッテリー、入力、出力、バイパス、アラーム、テスト、制御、設定：`upsBatteryStatus`、`upsEstimatedChargeRemaining`、`upsOutputSource`、`upsOutputPercentLoad` など。 |
| ENTITY-SENSOR-MIB（RFC 3433） | センサーの表：`entPhySensorType`、`entPhySensorScale`、`entPhySensorValue`、`entPhySensorOperStatus` など。 |
| ENTITY-MIB（RFC 6933） | センサーのラベルとなる物理エンティティの名前、説明、クラス：`entPhysicalName`、`entPhysicalDescr`、`entPhysicalClass`。 |
| HOST-RESOURCES-MIB（RFC 2790） | システム（`hrSystemUptime`、`hrSystemProcesses`）、ストレージの表（`hrStorageUsed`）、プロセッサーの表（`hrProcessorLoad`）。 |

`driver_capabilities` はすべての名前を OID とともに一覧にします。[エージェントのツール](#agent-tools)を参照してください。

### データ型とアクセス {#data-types-and-access}

**データ型**の一覧には、オブジェクトを損失なく読める型だけが出ます。

| オブジェクトが持つもの | いちばん自然に読む型 | ほかに選べる型 |
| --- | --- | --- |
| Integer32（列挙型と TruthValue を含む） | Int32 | Int64、Float、Double、String |
| Counter32、Gauge32、TimeTicks（100 分の 1 秒単位） | UInt32 | Int64、Double、String |
| Counter64 | UInt64 | Double、String |
| DisplayString | String | |
| バイト列、IP アドレス、OID | String：バイト列は 16 進数（`00:1A:2B`）、アドレスはドット区切り、OID はドット区切り | |
| 標準名のないオブジェクト | Float | Int32、UInt32、Int64、UInt64、Double、String：読み取り時のエージェントの応答で決まります |

カウンターは 16,777,216 を超えると丸めてしまう Float では選べず、Counter64 は半分を超えるカウントを拒否してしまう Int64 では選べません。Boolean は決して選べません。SNMP には真偽値がなく、その TruthValue（1 が真、2 が偽）と機器独自の 0 と 1 では、同じ型を正反対の 2 通りに読んでしまうため、状態は Int32 で読みます。OID が変わると、新しいオブジェクトが読めない型は、いちばん自然に読める型に変わります。読めない型は拒否され、読める型が示されます：「ifHCOutOctets.2 は次のいずれかとして読みます: UInt64, Double, String。」

MIB が読み取り専用と宣言している標準オブジェクト（カウンター、`sysUpTime`、状態）では**読み取りのみ**だけが選べ、「アクセス」の欄には「読み取り専用：この値は機器が報告するもので、外から設定するものではありません。」と出ます。MIB が書き込み可能と宣言している標準オブジェクト（`sysContact`、`sysName`、`sysLocation`、`ifAdminStatus`、`ifAlias`、UPS-MIB のテスト、制御、設定のオブジェクト）と機器独自の MIB のオブジェクトでは、すべてのアクセスが選べます。書き込みを受け付けるかどうかはエージェント自身の答えです。

## 読み取り {#reading}

各タグの読み出し周期ごとに、ステーションは GET を送ります。エージェントの応答が、タグに何を表示するかを決めます（[値の変換経路](connector-value-pipeline)を参照）。

| エージェントの応答 | 読み取りの結果 |
| --- | --- |
| 値 | タグ自身の段階が変換する前の、タグの型の値。数を含むテキスト（一部の機器が書く `23.5`）は数値のタグで読めます。 |
| タグの型に収まらない値（UInt32 に負の数など） | そのタグの読み取り失敗で、理由が付きます。機器はほかのタグを読み続けます。 |
| noSuchObject、noSuchInstance、またはそのオブジェクトだけのエラー | そのタグの読み取り失敗で、エージェントの応答の名前が付きます。機器はほかのタグを読み続けます。オブジェクトが 1 つないとリクエスト全体が拒否される SNMPv1 では、ドライバーはそれを除いて問い合わせ直します。 |
| すべての再試行のあとも、応答のタイムアウト内に何もない | 無応答です。機器はオフラインになって再接続し、[応答しなかった機器](connector-value-pipeline#the-device-did-not-answer)についてのタグの方針が表示を決めます。原因にはエージェント、待ち時間、試行回数が示され、受け付けない community や SNMPv3 ユーザーに対してもエージェントは黙ることが添えられます。 |
| SNMPv3 の報告（知らないユーザー、誤ったパスワードやプロトコル、エージェントが受け付けないセキュリティレベル）、またはそのポートで待ち受けるエージェントがいないというホストの応答 | その原因による接続の失敗で、診断ログと機器の最後のエラーに出ます。機器は再接続します。 |

機器は一度に 1 つのリクエストを送ります。読み取りはタグのオブジェクトを問い合わせ、同じリクエストで、新しい応答を持たない機器のほかのタグも、32 個の OID まで問い合わせます。リクエストが大きすぎる（tooBig）と答えるエージェントには、それ以降その半分を送ります。こうして持ち帰った応答は、別のタグの読み出し周期の半分より新しいあいだ、そのタグ自身の読み取りに使われるので、40 個のタグでも 1 巡あたり 1 つか 2 つのリクエストで済みます。SNMPv3 エージェントのエンジンは接続ごとに 1 回学習し、エージェントが時間の窓の外だと報告したリクエストは、エージェント自身の値でもう一度送ります。

## 書き込み {#writing}

書き込むアクセスのタグは、機器のキューを通して SET を送ります。書き込みはほかのどのドライバーとも同じ経路を通ります。書き込み欄は工学値を受け取り、生の値を送る前に変換段階を逆にたどります（[Connector](connector)を参照）。SET が運ぶ値の種類は、エージェントがそのオブジェクトに最後に答えた種類、それがなければ MIB が宣言する種類、それもなければいま GET が答える種類、最後にタグ自身の型です（Int32 は Integer32、UInt32 は Gauge32、String は OCTET STRING）。その種類に収まらない値は、何も送る前に拒否されます。

| エージェントの応答 | 書き込みの報告 |
| --- | --- |
| エラーなし | 完了です。機器が保持していた応答はすべて捨てられ、次の読み取りはもう一度問い合わせます。 |
| エラーステータス | 「現場設備が書き込みを拒否しました：`<reason>`。」理由は RFC 3416 の書き方でステータスを示します。`notWritable (17)`、`wrongType (7)`、`wrongValue (10)`、SNMPv1 では `readOnly (4)` などです。 |
| すべての再試行のあとも、応答のタイムアウト内に何もない | 「書き込みを確認できませんでした：現場設備が時間内に応答しませんでした。」 |

## 機器検出 {#discovery}

### 「スキャンの範囲」のカード {#the-scan-scope-card}

Connector の構成の権限があるとき、ドライバーのページには**スキャンの範囲**のカードがあり、その下に「1 つのエージェントの標準サブツリーをたどり、見つかったものを一覧にします。SNMPv3 エージェントは機器を通してスキャンするので、その機器をエージェントとして選んでください。」という行があります。

| 項目 | 意味 | 既定値 |
| --- | --- | --- |
| **スキャンするエージェント** | **ここに入力したアドレス**、またはこのドライバーの機器を名前で。機器のエージェントは、保存されているとおりのホスト、ポート、バージョン、設定、資格情報で読み、まだ保存を待っている機器の編集は先に保存します。SNMPv3 エージェントをスキャンする唯一の方法です。 | **ここに入力したアドレス** |
| **エージェントのアドレス** | 入力したエージェント：ホスト名か IP アドレスで、下のポートと違うときはコロンのあとにポートを書きます。 | 空 |
| **ポート** | 入力したエージェント：1 から 65535。 | 161 |
| **SNMP バージョン** | 入力したエージェント：SNMPv1 か SNMPv2c。 | SNMPv2c |
| **Community** | 入力したエージェント：エージェントが応答する community で、入力を隠す欄に `public` がヒントとして出ます。下には「このスキャンだけで使います。結果から追加した機器は、これを自分の community として保持します。」 | 空 |
| **サブツリー** | それぞれのチェック：**システム（SNMPv2-MIB）**、**インターフェース（IF-MIB）**、**無停電電源装置（UPS-MIB）**、**センサー（ENTITY-SENSOR-MIB）**、**ホストのリソース（HOST-RESOURCES-MIB）**。 | ホストのリソース以外のすべて |
| **追加でたどる** | 「もう 1 つのサブツリーを、数字か標準名の下で指定します（例: enterprises.318）。機器独自のオブジェクトは数字で返ります。」 | 空 |

範囲にまだ足りないものはカードの下に赤で示され、そろうまで機器検出は灰色のままです。

| 範囲 | カードの表示 |
| --- | --- |
| アドレスのない入力したエージェント | 「スキャンする SNMP エージェントのアドレスを入力してください。」 |
| ホストではないアドレスの入力したエージェント | 「「http://192.168.0.30」は SNMP エージェントのアドレスではありません。ホスト名か IP アドレスを、必要ならポートを付けて書いてください（例：192.168.0.30 や 192.168.0.30:161）。」 |
| community のない、または 255 バイトを超える community の入力したエージェント | 「エージェントが応答する community を入力してください（255 バイトまで）。」 |
| もうない機器 | 「スキャン対象に選んだ SNMP 機器はもうありません。スキャンする別のエージェントを選んでください。」 |
| ホストか、エージェントに必要な資格情報のない機器 | 「機器 'UPS room 1' には、ホストか、エージェントに必要な資格情報がまだありません。先に SNMP カードを完成させてください。」 |
| OID ではない、たどるサブツリー | 「'vendor' はたどれる OID ではありません。数字か、標準名の下に書いてください（例: enterprises.318）。」 |
| 何もチェックせず、何も指定しない | 「サブツリーを 1 つ以上選ぶか、たどるサブツリーを指定してください。」 |

スキャンする機器に保存できない編集があるときは、スキャンは始まりません：「スキャンする機器の編集を保存できなかったため、機器検出は始まりませんでした。」

### スキャンが提示するもの {#what-the-scan-offers}

機器検出はまずエージェントに名前（`sysName.0`）を尋ね、これでエージェントがその資格情報に応答することも確かめます。そのあと、チェックした各サブツリーと指定したサブツリーを、SNMPv2c と SNMPv3 では GETBULK、SNMPv1 では GETNEXT で、エージェントがその外を答えるまでたどります。進行の行は読んだ数を数えます：「192.168.10.40:161 の SNMP エージェントをたどっています: 120 個のオブジェクトを検出。」スキャンは最大 2000 個のオブジェクトを最長 60 秒たどります。そこで打ち切られたとき、または途中でエージェントが黙ったときは、見つけたものを残し、そう伝えます：「192.168.10.40:161 のたどりは途中で止まりました（2000 個のオブジェクトを検出）。スキャンは最大 2000 個のオブジェクトを最長 60 秒たどり、エージェントが応答しなくなった時点で止まります。」

スキャンはエージェントごとに候補を 1 つ提示します。名前は sysName（エージェントが名前を返さないときは機器の名前かホスト）で、読んだときのバージョン、タイムアウト、再試行回数を持ち、見つけたオブジェクトを候補のタグとして持ちます。

| 見つかったオブジェクト | タグの名前 | データ型 | アクセス |
| --- | --- | --- | --- |
| ドライバーが名前を知っている単一の値 | `.0` を除いた名前：`sysUpTime` | 応答した値をいちばん自然に読む型 | MIB が書き込み可能と宣言していれば読み書き、それ以外は読み取りのみ |
| ドライバーが名前を知っている表の列 | 名前と行：`ifInOctets.2` | 同じ | 同じ |
| 機器独自の MIB のオブジェクト | 数字：`1.3.6.1.4.1.318.1.1.1.2.2.1.0` | 同じ | 読み取りのみ |

どのタグの型にも収まらない値は除かれます。入力したアドレスのスキャンから追加した機器は、スキャンが使った community を保持し、どの機器の資格情報とも同じように保護します。機器のスキャンから追加した機器は、その機器の資格情報を持ちます。このドライバーの機器がすでにエージェントを読んでいる候補（スキャンした機器、または同じホストとポートの別の機器）は**設定済み**と示されます。そのカードには、その機器のどのタグもまだ読んでいないオブジェクトだけが並び（名前で書いた OID と数字で書いた OID は同じものと数えます）、**開く**の前にある**タグにして追加**が、チェックしたものをその機器に追加します。スキャンのそのほかの動きは[機器検出](connector-discovery)にあります。

機器自身のページでも、ドライバーのページを使わずに同じことができます。「タグ」のカードの見出しにある**タグ検出**は、その機器の設定と資格情報でエージェントを巡回し、標準のサブツリーと、タグがすでに読んでいるメーカーの枝（その下のタグがあれば `enterprises.318`）をたどって、まだタグがないオブジェクトだけを出します（[機器のタグを検出する](connector-discovery#discovering-a-devices-tags)を参照）。

## 例：SNMPv2c の UPS {#example-a-ups-over-snmpv2c}

ネットワークカード付きの UPS が 192.168.10.40 で SNMPv2c に応答し、そのカードに読み取り用の community が設定されています。バッテリーを読みます。

1. ドライバーのページで**機器を追加**し、名前を `UPS room 1` にして、**ホスト**に 192.168.10.40 を入力し、**ポート**は 161 のままにします。
2. **SNMP エージェント**のカードで SNMPv2c のままにし、**Community** にカードの読み取り用 community を入力し、**応答のタイムアウト（ms）**は 2000、**再試行回数**は 1 のままにします。community を求めていた行が消えます。
3. **タグを追加**で `Battery status`、**OID** `upsBatteryStatus.0`、**データ型** Int32 にします。欄の下では MIB の名前が upsBatteryStatus.0 で `UPS-MIB · Integer32 · 読み取り専用` と出て、数字の OID は 1.3.6.1.2.1.33.1.2.1.0、アクセスは読み取りのみのままです。値は 1 unknown、2 batteryNormal、3 batteryLow、4 batteryDepleted のいずれかです。
4. **タグを追加**で `Battery charge`、**OID** `upsEstimatedChargeRemaining.0`、**データ型** Int32、**単位** % にします。
5. UPS が報告するなら、**タグを追加**で `Minutes remaining`、**OID** `upsEstimatedMinutesRemaining.0`、**データ型** Int32、**単位** min にします。

Base URI は `snmp://192.168.10.40:161?version=2c&timeoutMs=2000&retries=1` です。エージェントはツールで同じことをします。

```
device_upsert name="UPS room 1" driver=Snmp host=192.168.10.40 snmpVersion=V2c snmpCommunity="<the UPS card's read community>"
tag_upsert device="UPS room 1" name="Battery status" address=upsBatteryStatus.0 opcUaType=Int32
tag_upsert device="UPS room 1" name="Battery charge" address=upsEstimatedChargeRemaining.0 opcUaType=Int32 unit=%
tag_upsert device="UPS room 1" name="Minutes remaining" address=upsEstimatedMinutesRemaining.0 opcUaType=Int32 unit=min
```

## 例：SNMPv3 でのスイッチのインターフェースカウンター {#example-a-switchs-interface-counters-over-snmpv3}

192.168.10.2 のマネージドスイッチが、ユーザー `scada` に対して SNMPv3 で応答し、スイッチ側では SHA-256 の認証と AES-128 の暗号化が設定されています。ポート 2 のトラフィックと状態を読みます。

1. **機器を追加**し、名前を `Core switch`、**ホスト**を 192.168.10.2、**ポート**を 161 にします。
2. **SNMP エージェント**のカードで SNMPv3 を選び、**SNMPv3 ユーザー**に `scada` と入力し、**署名と暗号化（authPriv）**のままにし、**認証プロトコル**で SHA-256 を選んでそのパスワードを入力し、**暗号化プロトコル**は AES-128 のままにしてそのパスワードを入力します。どちらもスイッチが `scada` に設定しているもので、8 文字以上です。
3. **タグを追加**で `Port 2 in`、**OID** `ifHCInOctets.2` にします。データ型は 64 ビットのカウンターを読む型である UInt64 になり、一覧には UInt64、Double、String だけが出ます。**単位**は B です。
4. **タグを追加**で `Port 2 out`、**OID** `ifHCOutOctets.2`、UInt64、**単位** B にします。
5. **タグを追加**で `Port 2 state`、**OID** `ifOperStatus.2`、**データ型** Int32 にします。1 up、2 down、3 testing、7 lowerLayerDown です。

`.2` はスイッチのインターフェースのインデックスで、`ifName.2` が名前を示すものです。インターフェースのサブツリーをスキャンすると、すべてのインターフェースがインデックスとともに一覧になります。Base URI は `snmp://192.168.10.2:161?version=3&security=authPriv&auth=sha256&priv=aes128&timeoutMs=2000&retries=1` です。ツールでは、オブジェクトが読めない `opcUaType`（`ifHCOutOctets.2` に Int32 など）は、読める型を示して拒否されます。

```
device_upsert name="Core switch" driver=Snmp host=192.168.10.2 snmpVersion=V3 username=scada password="<authentication password>" snmpSecurityLevel=AuthPriv snmpAuthProtocol=Sha256 snmpPrivacyProtocol=Aes128 snmpPrivacyPassword="<privacy password>"
tag_upsert device="Core switch" name="Port 2 in" address=ifHCInOctets.2 opcUaType=UInt64 unit=B
tag_upsert device="Core switch" name="Port 2 out" address=ifHCOutOctets.2 opcUaType=UInt64 unit=B
tag_upsert device="Core switch" name="Port 2 state" address=ifOperStatus.2 opcUaType=Int32
```

## エージェントのツール {#agent-tools}

`driver_capabilities` はこのドライバーを `snmp` の下で説明します。バージョンとそれぞれが受け取る資格情報、セキュリティレベルとプロトコル、応答のタイムアウトと再試行回数、OID の書き方、値の種類ごとの型、ドライバーが知っているすべての名前（MIB、OID、書き込みを受け付けるか）、読み取りと書き込みの動き、機器検出、上の 2 つの例です。`device_upsert driver=Snmp` は `host`、`port`（既定は 161）、`snmpVersion`（`V1`、既定の `V2c`、`V3`）、SNMPv1 と SNMPv2c では `snmpCommunity`（`''` で消去）、SNMPv3 では `username`（ユーザー）、`password`（その認証パスワードで 8 文字以上）、`snmpSecurityLevel`（既定の `AuthPriv`、`AuthNoPriv`、`NoAuthNoPriv`）、`snmpAuthProtocol`（`Md5`、既定の `Sha1`、`Sha256`、`Sha384`、`Sha512`）、`snmpPrivacyProtocol`（`Des`、既定の `Aes128`、`Aes192`、`Aes256`）、`snmpPrivacyPassword` を受け取り、さらに `responseTimeoutMs`（100 から 60000、既定は 2000）と `snmpRetries`（0 から 5、既定は 1）を受け取ります。SNMPv3 の機器への community や、community の機器への SNMPv3 の項目は拒否されます。ツールが返す機器は `snmp` を持ちます。バージョン、`hasCommunity`、有効なセキュリティレベルとプロトコル、`hasPrivacyPassword`、タイムアウト、再試行回数、そしてまだ待っている資格情報を示す `missingCredential` です。秘密は決して返しません。`tag_upsert` は OID を `address` として受け取り、`opcUaType` の既定はオブジェクトをいちばん自然に読む型です。`wireQuantity` と `eipPath` は拒否されます。`device_discover driver=Snmp` は、`target`（ホストで、161 でなければ `port` も）を `snmpVersion`（`V1` か `V2c`）と `snmpCommunity` とともにたどるか、このドライバーの機器の名前である `snmpDevice` をたどります。SNMPv3 エージェントをスキャンする唯一の方法は後者です。`snmpSubtrees` は標準サブツリー（`System`、`Interfaces`、`Ups`、`Sensors`、`HostResources` をコンマ区切り）を選び、`snmpSubtree` はもう 1 つ加えます。ツールはスキャンの community を保持しません。スキャンが見つけたものから作る機器は `device_upsert` でもう一度それを受け取り、設定済みの機器に足りないタグは `tag_upsert` で追加します。そのほかのツールは[エージェントのツール](agent-tools)にあります。

## 知っておきたい制限 {#limits-worth-knowing}

- 何かが起きたときに機器が自分から送るトラップとインフォームは受け取りません。どの値も読み出し周期ごとに読むので、残量の減ったバッテリーは、その状態を次に読んだときにわかります。
- MIB ファイルは取り込みません。ドライバーが知っている名前は、内蔵する標準 MIB のものです。`enterprises` の下にある機器独自の MIB のオブジェクトは数字で書き、数字で表示し、その意味はメーカーの資料で確かめます。
- ステーションは SNMP エージェントではありません。ステーション自身を SNMP で読むことはできません。
- スキャンが SNMPv3 エージェントに届くのは、そのユーザーとパスワードを持つ機器を通したときだけで、community やユーザーを自分から試すことはありません。
- スキャンは最大 2000 個のオブジェクトを最長 60 秒たどります。大きなスイッチでは、要らないサブツリーのチェックを外すか、要るサブツリーを指定してください。
- Boolean のタグはありません。TruthValue や機器独自のオンとオフは Int32 で読みます。
