はじめに
SNMP の基礎概念について学ぶため、 C で簡単な snmpget リクエスト送信のプログラムを作成します。
環境
- Red Hat Enterprise Linux 7
開発環境のセットアップ
Net-SNMPのインストール
まず、SNMPプログラムを作成するために必要なライブラリであるNet-SNMPをインストールする必要があります。以下のコマンドを実行して、yumを使用してインストールします。
sudo yum install net-snmp net-snmp-devel
SNMPリクエスト送信プログラムの作成
127.0.0.1:161 に v1 の snmpget リクエストを送信するコードを作成します。
コミュニティ名は public, oid は 1.3.6.1.2.1.1.1.0 (sysDescr) です。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
int main(int argc, char **argv) {
// SNMPセッションと変数の初期化
struct snmp_session session, *ss;
struct snmp_pdu *pdu;
struct snmp_pdu *response;
struct variable_list *vars;
oid anOID[MAX_OID_LEN];
size_t anOID_len = MAX_OID_LEN;
int status;
char *ip = "127.0.0.1"; // SNMPエージェントのIPアドレス
char *community = "public"; // コミュニティストリング
char *oid_str = "1.3.6.1.2.1.1.1.0"; // 取得したいOID
// SNMPセッションを初期化
init_snmp("snmpapp");
// SNMPセッションの設定
snmp_sess_init(&session);
session.peername = strdup(ip);
session.version = SNMP_VERSION_1;
session.community = (u_char *) community;
session.community_len = strlen(community);
// セッションを開く
ss = snmp_open(&session);
if (!ss) {
snmp_perror("snmp_open");
exit(1);
}
// OIDを解析
if (!snmp_parse_oid(oid_str, anOID, &anOID_len)) {
snmp_perror("snmp_parse_oid");
exit(1);
}
// GETリクエストPDUを作成
pdu = snmp_pdu_create(SNMP_MSG_GET);
snmp_add_null_var(pdu, anOID, anOID_len);
// リクエストを送信
status = snmp_synch_response(ss, pdu, &response);
// 結果の処理
if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
for (vars = response->variables; vars; vars = vars->next_variable) {
print_value(vars->name, vars->name_length, vars);
}
} else {
if (status == STAT_SUCCESS) {
fprintf(stderr, "Error in packet: %s\n", snmp_errstring(response->errstat));
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No response from %s.\n", session.peername);
} else {
snmp_sess_perror("snmp_synch_response", ss);
}
}
// 応答PDUを解放
if (response) {
snmp_free_pdu(response);
}
// SNMPセッションを閉じる
snmp_close(ss);
return 0;
}
実行すると、 sysDescr の値が得られます。
$ gcc ./snmp_get.c -o snmp_get -lnetsnmp; ./snmp_get
STRING: "Linux <server name> 3.10.0-1160.76.1.el7.x86_64 #1 SMP Tue Jul 26 14:15:37 UTC 2022 x86_64"