首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows 下 Net-SNMP Agent 擴展實戰 (四):Trap 主動上報實現

     編輯:關於C語言

承接前三篇 (Get/Set 處理),本文聚焦 Net-SNMP Agent 擴展的最後一塊拼圖——主動發送 Trap/Inform 通知。示例代碼展示如何註冊週期性告警回調、構建 SNMPv1/v2c Trap PDU、動態綁定變量綁定、會話管理與資源釋放。

核心流程圖解

  1. snmp_alarm_register() 註冊週期性定時器 (預設 5 秒/30 秒)。
  2. 回調 send_trap2() 中創建 SNMP_MSG_TRAP2 (v2c) 或 SNMP_MSG_TRAP (v1) PDU。
  3. create_trap_session() 建立目標管理站會話 (IP、Community、版本)。
  4. 業務邏輯判斷 (CPU/記憶體/磁盤閾值) → snmp_add_var() 動態加入 VarBind。
  5. send_trap_vars() 發送 → snmp_free_pdu()/snmpd_free_trapsinks() 清理。

關鍵代碼逐段解析

1. 告警定時器註冊

void init_alarm_info(void) {
    DEBUGMSGTL(("dcsserver", "initializing (setting callback alarm)\n"));
    snmp_alarm_register(
        5,                    // 間隔秒數 (示例 5s,生產建議 30s+)
        SA_REPEAT,            // 週期性觸發
        send_trap2,           // 回調函數
        NULL                  // 回調參數
    );
}

SA_REPEAT 確保回調週期性執行;若需一次性告警可用 0 旗標。

2. Trap PDU 構建與會話建立

void send_trap2(unsigned int clientreg, void *clientarg) {
    // 企業私有 OID 基礎: 1.3.6.1.4.1.9000.2
    static oid oid_cpu_Alarm[]    = {1,3,6,1,4,1,9000,2,1};
    static oid oid_memory_Alarm[] = {1,3,6,1,4,1,9000,2,2};
    static oid oid_disk_Alarm[]   = {1,3,6,1,4,1,9000,2,3};

    netsnmp_pdu *pdu = snmp_pdu_create(SNMP_MSG_TRAP2); // v2c Trap
    if (!pdu) { log_error("create trap PDU failed"); return; }

    // 建立 Trap 發送會話
    // SNMPv1: port=0 (內部自動用 162), community="public"
    int status = create_trap_session(DEFAULT_ADDR, 0, "public", SNMP_VERSION_1, SNMP_MSG_TRAP);
    if (status == 0) { log_error("create_trap_session failed"); snmp_free_pdu(pdu); return; }
    // ...
}

關鍵點:

  • DEFAULT_ADDR 通常為 127.0.0.1 或配置文件讀取的 NMS IP。
  • v1 Trap 時 create_trap_session 第 2 參數必須為 0,否則會警告 (內部會強制用 162)。
  • 企業 OID 1.3.6.1.4.1.9000 需向 IANA 申請或使用實驗段 .1.3.6.1.4.1.99999。

3. 動態 VarBind 綁定業務告警


bool flag = false;
// CPU > 85%
if (GetUsedCPU() > 85) {
    flag = true;
    snmp_add_var(pdu, oid_cpu_Alarm, OID_LENGTH(oid_cpu_Alarm), 's', "cpu Alarming");
}
// Memory > 85%
if (GetUsedMemory() > 85) {
    flag = true;
    snmp_add_var(pdu, oid_memory_Alarm, OID_LENGTH(oid_memory_Alarm), 's', "memory Alarming");
}
// Disk C: > 85%
if (GetUsedDisk() > 85) {
    flag = true;
    snmp_add_var(pdu, oid_disk_Alarm, OID_LENGTH(oid_disk_Alarm), 's', "disk Alarming");
}

// 有告警才發送
if (flag) {
    send_trap_vars(1, 0, pdu->variables); // 發送 VarBind 鏈表
}

's' 表示 OCTET STRING 類型;實際部署建議用 'i' (INTEGER) 傳遞具體百分比,便於 NMS 做閾值圖表。

4. 資源釋放


snmpd_free_trapsinks(); // 釋放會話緩存的 trap sinks
snmp_free_pdu(pdu);     // 釋放 PDU 結構

補充:Net-SNMP 內部 notification.c 機制

源碼 agent/notification.c 提供 send_v2trap() 高層封裝,但要求 snmpd 啟用 trapsink/trap2sink 配置並運行主 Agent 進程。本文示例採用獨立 create_trap_session 方式,適合 Subagent (AgentX) 或獨立可執行檔主動上報場景,不依賴主 Agent 狀態。

版本選擇建議

場景推薦版本Port 參數PDU 類型
傳統網管設備相容SNMPv10SNMP_MSG_TRAP
現代 NMS (Zabbix/PRRG/NetBrain)SNMPv2c162SNMP_MSG_TRAP2
需確認送達 (ACK/重傳)SNMPv2c Inform162SNMP_MSG_INFORM

完整系列回顧

  1. 環境搭建與 MIB 註冊
  2. Get/GetNext 處理
  3. Set 指令處理
  4. Trap 主動上報 (本文)

至此,Windows 下 Net-SNMP Agent 擴展核心技術棧已完整覆蓋。實際部署時請注意:

  • Community 字串務必通過配置文件注入,避免硬編碼 public。
  • 告警頻率建議 ≥ 30 秒,防止 NMS 風暴。
  • 關鍵路徑加入 DEBUGMSGTL 方便現場排查。

來源:vcsky.net havenzhao

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved