-
snmp简介
snmp简单网络设备管理协议,用于管理网络IP节点中的各种网络设备如交换机、路由器、防火墙、审计等。
详细介绍可参考百度百科:https://baike.baidu.com/item/%E7%AE%80%E5%8D%95%E7%BD%91%E7%BB%9C%E7%AE%A1%E7%90%86%E5%8D%8F%E8%AE%AE/2986113?fromtitle=SNMP&fromid=133378&fr=aladdin -
snmp获取节点信息
snmp通过oid节点获取到相应设备提供的信息,oid类似地址的概念,是snmp官方定义的一种寻址标准。
详情可参考:https://www.alvestrand.no/objectid/1.3.6.1.html -
MIB
mib库是对snmp网络设备提供服务节点的一个描述,通过mib浏览器加载MIB库就能读取到相应设备的节点信息。MIB可以手动编写,也可以使用snmp开发套件中的mib-builder。
**保存的文件名如图中module-name一致。**新建的mib库需要使用mib compiler编译后供mib browser使用
--
-- VENUS-DAS-MIB.txt
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0 Build 88
-- Tuesday, December 10, 2019 at 20:31:39
--
-- VENUS-DAS-MIB.txt
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0 Build 88
-- Sunday, December 08, 2019 at 20:29:10
--
-- VENUS-DAS-MIB.txt
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0 Build 88
-- Friday, December 06, 2019 at 23:26:35
--
-- TSET-SCALAR-MIB.txt
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0 Build 88
-- Friday, December 06, 2019 at 21:36:16
--
VENUS-DAS-MIB DEFINITIONS ::= BEGIN
IMPORTS
enterprises, Integer32, OBJECT-TYPE
FROM SNMPv2-SMI;
--
-- Node definitions
--
-- Node definitions
--
-- Node definitions
--
-- Node definitions
--
-- 1.3.6.1.4.1.15227
-- 1.3.6.1.4.1.15227
-- 1.3.6.1.4.1.15227
-- 1.3.6.1.4.1.15227
venusDasRoot OBJECT IDENTIFIER ::= { enterprises 15227 }
-- 1.3.6.1.4.1.15227.1
-- 1.3.6.1.4.1.15227.1
-- 1.3.6.1.4.1.15227.1
-- 1.3.6.1.4.1.15227.1
cpuCount OBJECT-TYPE
SYNTAX Integer32 (0..16)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"表示CPU总核心数"
::= { venusDasRoot 1 }
-- 1.3.6.1.4.1.15227.2
-- 1.3.6.1.4.1.15227.2
-- 1.3.6.1.4.1.15227.2
-- 1.3.6.1.4.1.15227.2
cpuUsage OBJECT-TYPE
SYNTAX Integer32 (0..100)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"CPU使用率"
::= { venusDasRoot 2 }
-- 1.3.6.1.4.1.15227.3
-- 1.3.6.1.4.1.15227.3
-- 1.3.6.1.4.1.15227.3
diskTotal OBJECT-TYPE
SYNTAX Integer32 (0..32000000)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"硬盘总容量
单位:M
最大值:32T"
::= { venusDasRoot 3 }
-- 1.3.6.1.4.1.15227.4
-- 1.3.6.1.4.1.15227.4
-- 1.3.6.1.4.1.15227.4
diskUse OBJECT-TYPE
SYNTAX Integer32 (0..32000000)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"硬盘已使用容量
单位:M
最大值:32T"
::= { venusDasRoot 4 }
-- 1.3.6.1.4.1.15227.5
-- 1.3.6.1.4.1.15227.5
-- 1.3.6.1.4.1.15227.5
diskUsage OBJECT-TYPE
SYNTAX Integer32 (0..100)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"硬盘使用率"
::= { venusDasRoot 5 }
-- 1.3.6.1.4.1.15227.6
-- 1.3.6.1.4.1.15227.6
-- 1.3.6.1.4.1.15227.6
memTotal OBJECT-TYPE
SYNTAX Integer32 (0..32000000)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"内存总大小
单位:KB
最大值:32G"
::= { venusDasRoot 6 }
-- 1.3.6.1.4.1.15227.7
-- 1.3.6.1.4.1.15227.7
-- 1.3.6.1.4.1.15227.7
memUse OBJECT-TYPE
SYNTAX Integer32 (0..32000000)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"内存已使用大小
单位:KB
最大值:32G"
::= { venusDasRoot 7 }
-- 1.3.6.1.4.1.15227.8
-- 1.3.6.1.4.1.15227.8
-- 1.3.6.1.4.1.15227.8
memUsage OBJECT-TYPE
SYNTAX Integer32 (0..100)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"内存使用率"
::= { venusDasRoot 8 }
END
--
-- VENUS-DAS-MIB.txt
--
4.安装net-snmp
下载net-snmp源代码,https://github.com/haad/net-snmp
unzip 解压文件
依次执行如下命令执行:
./configure --prefix=/install_path 生成makefile 并且配置安装目录
make 编译
make install 安装到系统,可以在install_path 找到安装的文件。
拷贝当前目录中的EXAMPLE.conf 到/install_path/share/snmp/snmpd.conf
修改:agentAddress udp:127.0.0.1:161
为:agentAddress udp:161 允许所有地址可访问
修改:rocommunity public default -V systemonly
为:rocommunity public default 允许访问所有资源
注释掉:trapsink localhost public
去掉注释:#trap2sink localhost public
添加环境变量后,snmpd 即可启动snmp服务
netstat -anp | grep 161 查看端口监听是否正常
snmpwalk -v 2c -c public localhost 1.3.6.1.4 即可查看snmp服务返回的系统信息
-
扩展mib库
将写好的VENUS-DAS-MIB.txt放在/install_path/share/snmp/mibs
使用snmptranslate -Tp -IR VENUS-DAS-MIB::venusDasRoot 验证是否能获取到节点信息
使用env MIBS="+/install_path/share/snmp/mibs/VENUS-DAS-MIB.txt" mib2c -c mib2c.scalar.conf venusDasRoot 生成需要的c文件和头文件
venusDasRoot.c
/*
* Note: this file originally auto-generated by mib2c
* using mib2c.scalar.conf
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "venusDasRoot.h"
/** Initializes the venusDasRoot module */
void
init_venusDasRoot(void)
{
const oid cpuCount_oid[] = { 1,3,6,1,4,1,15227,1 };
const oid cpuUsage_oid[] = { 1,3,6,1,4,1,15227,2 };
const oid diskTotal_oid[] = { 1,3,6,1,4,1,15227,3 };
const oid diskUse_oid[] = { 1,3,6,1,4,1,15227,4 };
const oid diskUsage_oid[] = { 1,3,6,1,4,1,15227,5 };
const oid memTotal_oid[] = { 1,3,6,1,4,1,15227,6 };
const oid memUse_oid[] = { 1,3,6,1,4,1,15227,7 };
const oid memUsage_oid[] = { 1,3,6,1,4,1,15227,8 };
DEBUGMSGTL(("venusDasRoot", "Initializing\n"));
netsnmp_register_scalar(
netsnmp_create_handler_registration("cpuCount", handle_cpuCount,
cpuCount_oid, OID_LENGTH(cpuCount_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("cpuUsage", handle_cpuUsage,
cpuUsage_oid, OID_LENGTH(cpuUsage_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("diskTotal", handle_diskTotal,
diskTotal_oid, OID_LENGTH(diskTotal_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("diskUse", handle_diskUse,
diskUse_oid, OID_LENGTH(diskUse_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("diskUsage", handle_diskUsage,
diskUsage_oid, OID_LENGTH(diskUsage_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("memTotal", handle_memTotal,
memTotal_oid, OID_LENGTH(memTotal_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("memUse", handle_memUse,
memUse_oid, OID_LENGTH(memUse_oid),
HANDLER_CAN_RONLY
));
netsnmp_register_scalar(
netsnmp_create_handler_registration("memUsage", handle_memUsage,
memUsage_oid, OID_LENGTH(memUsage_oid),
HANDLER_CAN_RONLY
));
}
int
handle_cpuCount(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_cpuCount\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_cpuUsage(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_cpuUsage\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_diskTotal(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_diskTotal\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_diskUse(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_diskUse\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_diskUsage(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_diskUsage\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_memTotal(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_memTotal\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_memUse(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_memUse\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
int
handle_memUsage(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
/* We are never called for a GETNEXT if it's registered as a
"instance", as it's "magically" handled for us. */
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
switch(reqinfo->mode) {
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
/* XXX: a pointer to the scalar's data */,
/* XXX: the length of the data in bytes */);
break;
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_memUsage\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
venusDasRoot.h
/*
* Note: this file originally auto-generated by mib2c
* using mib2c.scalar.conf
*/
#ifndef VENUSDASROOT_H
#define VENUSDASROOT_H
/* function declarations */
void init_venusDasRoot(void);
Netsnmp_Node_Handler handle_cpuCount;
Netsnmp_Node_Handler handle_cpuUsage;
Netsnmp_Node_Handler handle_diskTotal;
Netsnmp_Node_Handler handle_diskUse;
Netsnmp_Node_Handler handle_diskUsage;
Netsnmp_Node_Handler handle_memTotal;
Netsnmp_Node_Handler handle_memUse;
Netsnmp_Node_Handler handle_memUsage;
#endif /* VENUSDASROOT_H */
并且修改代码中类似以下代码的位置,赋值自己想要返回的东西。
/* XXX: a pointer to the scalar’s data /,
/ XXX: the length of the data in bytes */
最后将代码添加到net-snmp源代码的 /agent/mibgroup/路径下
执行 ./configure --perfix=/install_path --with-mib-modules=“venusDasRoot”
添加自定义模块
make && make install
最后启动snmpd
使用snmpwalk -c public -v 2c localhost 1.3.6.1.4.1.15227
即可以获得自定义的处理信息
总结说明:
研究此问题的起因是修改snmp的返回值类型,修改string为integer类型。
通过snmpd.conf extend 脚本的形式返回值永远为string类型,脚本的退出
状态为整形,但是退出值存在0-255的限定范围。
故而采用net-snmp 在snmp中注册回调函数,实现返回值为integer类型。
来源:CSDN
作者:cbk7777777
链接:https://blog.csdn.net/cbk7777777/article/details/103455931