您的位置:首页 > 其它

snmpd装载一个动态链接库(so文件),以扩充MIB

2015-06-03 14:43 639 查看
一、概述

一般把提供SNMP服务的一端称之为agent端。相对地,请求的一端称之为管理端。

1、agent端

在161端口侦听,接受来自管理端的SNMP请求包,解析出请求的OID(s),然后取出对应的值,组装成一个SNMP应答包,返回给请求方(即管理端)。

2、管理端

在162端口侦听,接收来自agent端的TRAP(陷阱)包。



n
二、逻辑图




三、扩充MIB流程

通过snmpd装载so, 扩充MIB的时候非常方便。主要流程如下

1、下载最新的net-snmp源码并tar

[root@localhost Desktop]# tar zxvf net-snmp-5.5.tar.gz



2、配置

[root@localhost net-snmp-5.5]# ./configure --with-mib-modules="ucd_snmp $OTHER_MIBS" $OTHER_OPTIONS


这个的作用就是为了让将来编译生成的snmpd具有动态载入SO的能力。



3、编译snmpd及工具

[root@localhost net-snmp-5.5]# make



4、安装snmpd及工具

[root@localhost net-snmp-5.5]# make install

安装snmpd及其他的工具如snmpget,snmpset, snmpwalk, snmptranslate等



5、编译so

[root@localhost net-snmp-5.5]# make -f Makefile_so

三个源文件 Makefile_so, nstAgentPluginObject.h nstAgentPluginObject.c 参见后面

编译生成的so为:nstAgentPluginObject.so



6、在snmpd.conf中最后增加一行 :

dlmod nstAgentPluginObject /root/Desktop/net-snmp-5.5/nstAgentPluginObject.so



7、然后重新启动 snmpd

[root@localhost sbin]# snmpd -c snmpd.conf [ 此处把snmpd.conf文件放在与snmpd相同的目录]



8、测试一下:

[root@localhost net-snmp-5.5]# snmpget -v 1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.3.0

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 3

[root@localhost net-snmp-5.5]# snmpset -v 1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.3.0 i 1900000

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 1900000

[root@localhost net-snmp-5.5]# snmpget -v 1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.3.0

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 1900000
注意,这个OID:1.3.6.1.4.1.8072.2.4.1.1.3.0, 正是我们在 nstAgentPluginObject.c中定义的OID,而且其初始值是3

......

static int nstAgentPluginObject = 3;

static oid nstAgentPluginObject_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 3, 0 };

......

这说明,我们写的so已经成功装载并且生效。

9、支持V3 的测试

snmp的版本有 v1, v2c, v3。其中v3版本对包采取了加密、验证的方式,安全性更高。



在配置文件snmpd.conf中增加以下一段



view demoWrite included .1.3.6.1.4.1.8072.2.4.1.1.3

view demoRead included .1.3.6.1.4.1.8072.2.4.1.1.3

access demogroup "" any auth prefix demoRead demoWrite none

group demogroup usm MD5DESUser

createUser MD5DESUser MD5 "The Net-SNMP Demo password" DES "The Net-SNMP Demo password"



重新启动snmpd, 就可以测试了,以下是测试过程。

[root@localhost sbin]# snmpget -v 3 -n "" -u MD5DESUser -a MD5 -A "The Net-SNMP Demo password" -x DES -X "The Net-SNMP Demo password" -l
authPriv localhost .1.3.6.1.4.1.8072.2.4.1.1.3.0

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 3
[root@localhost sbin]# snmpset -v 3 -n "" -u MD5DESUser -a MD5 -A "The Net-SNMP Demo password" -x DES -X "The Net-SNMP Demo password" -l
authPriv localhost .1.3.6.1.4.1.8072.2.4.1.1.3.0 i 1980000

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 1980000
[root@localhost sbin]# snmpget -v 3 -n "" -u MD5DESUser -a MD5 -A "The Net-SNMP Demo password" -x DES -X "The Net-SNMP Demo password" -l
authPriv localhost .1.3.6.1.4.1.8072.2.4.1.1.3.0

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 1980000

成功!!!!


四、***管理端工具

1、自己写测试工具【代替snmpget等工具】

通过调用 net-snmp提供的api, 按照SNMP包的格式,自行组装一个SNMP包,发给agent, 然后解析agent返回的应答包。将某个OID的值显示出来。

具体步骤如下:



1)、编译程序【生成 snmpdemoapp可执行程序(工具)】

[root@localhost net-snmp-5.5]# make -f Makefile_snmpdemoapp

两个源文件 Makefile_snmpdemoapp 和 snmpdemoapp.c 参见后面



2)、测试

[root@localhost net-snmp-5.5]# snmpget -v 3 -n "" -u MD5DESUser -a MD5 -A "The Net-SNMP Demo password" -x DES -X "The Net-SNMP Demo password" -l authPriv localhost .1.3.6.1.4.1.8072.2.4.1.1.3.0

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 3
[root@localhost net-snmp-5.5]# ./snmpdemoapp .1.3.6.1.4.1.8072.2.4.1.1.3.0

we use V3

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 3

value #1 is NOT a string! Ack!, value is:3
[root@localhost net-snmp-5.5]# snmpset -v 3 -n "" -u MD5DESUser -a MD5 -A "The Net-SNMP Demo password" -x DES -X "The Net-SNMP
Demo password" -l authPriv localhost .1.3.6.1.4.1.8072.2.4.1.1.3.0 i 9870000

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 9870000
[root@localhost net-snmp-5.5]# ./snmpdemoapp .1.3.6.1.4.1.8072.2.4.1.1.3.0

we use V3

NET-SNMP-EXAMPLES-MIB::netSnmpExamples.4.1.1.3.0 = INTEGER: 9870000

value #1 is NOT a string! Ack!, value is:9870000
可见,我们自己写的测试工具已经成功!!!



五、源码

1、nstAgentPluginObject.h


#ifndef NSTAGENTPLUGINOBJECT_H

#define NSTAGENTPLUGINOBJECT_H

void init_nstAgentPluginObject(void);
#endif


2、nstAgentPluginObject.c

#include <net-snmp/net-snmp-config.h>

#include <net-snmp/net-snmp-includes.h>

#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "nstAgentPluginObject.h"
static int nstAgentPluginObject = 3;

static oid nstAgentPluginObject_oid[] =

{ 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 3, 0 };

void

init_nstAgentPluginObject(void)

{


DEBUGMSGTL(("nstAgentPluginObject",

"Initializing the nstAgentPluginObject module\n"));



DEBUGMSGTL(("nstAgentPluginObject",

"Initalizing nstAgentPluginObject scalar integer. Default value = %d\n",

nstAgentPluginObject));
netsnmp_register_int_instance("nstAgentPluginObject",

nstAgentPluginObject_oid,

OID_LENGTH(nstAgentPluginObject_oid),

&nstAgentPluginObject, NULL);
DEBUGMSGTL(("nstAgentPluginObject",

"Done initalizing nstAgentPluginObject module\n"));

}
void

deinit_nstAgentPluginObject(void)

{

unregister_mib(nstAgentPluginObject_oid,OID_LENGTH(nstAgentPluginObject_oid));

}


3、Makefile_so

#

# Warning: you may need more libraries than are included here on the

# build line. The agent frequently needs various libraries in order

# to compile pieces of it, but is OS dependent and we can't list all

# the combinations here. Instead, look at the libraries that were

# used when linking the snmpd master agent and copy those to this

# file.

#
CC=gcc
OBJS1=snmpdemoapp.o

OBJS2=example-demon.o nstAgentSubagentObject.o

OBJS3=asyncapp.o

TARGETS=nstAgentPluginObject.so
CFLAGS=-I. `net-snmp-config --cflags`

BUILDLIBS=`net-snmp-config --libs`

BUILDAGENTLIBS=`net-snmp-config --agent-libs`
# shared library flags (assumes gcc)

DLFLAGS=-fPIC -shared
all: $(TARGETS)

clean:

rm $(OBJS2) $(OBJS2) $(TARGETS)
nstAgentPluginObject.so: nstAgentPluginObject.c Makefile

$(CC) $(CFLAGS) $(DLFLAGS) -c -o nstAgentPluginObject.o nstAgentPluginObject.c

$(CC) $(CFLAGS) $(DLFLAGS) -o nstAgentPluginObject.so nstAgentPluginObject.o


4、snmpdemoapp.c

#include <net-snmp/net-snmp-config.h>

#include <net-snmp/net-snmp-includes.h>

#include <string.h>

#define DEMO_USE_SNMP_VERSION_3
#ifdef DEMO_USE_SNMP_VERSION_3

const char *our_v3_passphrase = "The Net-SNMP Demo Password";

#endif

char local_oid[1000]=".1.3.6.1.2.1.1.1.0";

//const char* local_oid=".1.3.6.1.4.1.8072.2.4.1.1.3.0";
int main(int argc, char ** argv)

{

if(argc==2)

strcpy(local_oid, argv[1]);

//

netsnmp_session session, *ss;

netsnmp_pdu *pdu;

netsnmp_pdu *response;
oid anOID[MAX_OID_LEN];

size_t anOID_len;
netsnmp_variable_list *vars;

int status;

int count=1;


init_snmp("snmpdemoapp");


snmp_sess_init( &session );

session.peername = strdup("localhost");

#ifdef DEMO_USE_SNMP_VERSION_3



session.version=SNMP_VERSION_3;





session.securityName = strdup("MD5User");

session.securityNameLen = strlen(session.securityName);


session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;


session.securityAuthProto = usmHMACMD5AuthProtocol;

session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);

session.securityAuthKeyLen = USM_AUTH_KU_LEN;


if (generate_Ku(session.securityAuthProto,

session.securityAuthProtoLen,

(u_char *) our_v3_passphrase, strlen(our_v3_passphrase),

session.securityAuthKey,

&session.securityAuthKeyLen) != SNMPERR_SUCCESS) {

snmp_perror(argv[0]);

snmp_log(LOG_ERR,

"Error generating Ku from authentication pass phrase. \n");

exit(1);

}

printf(" we use V3\n");



#else


session.version = SNMP_VERSION_1;


session.community = "demopublic";

session.community_len = strlen(session.community);
#endif


SOCK_STARTUP;

ss = snmp_open(&session);
if (!ss) {

snmp_sess_perror("ack", &session);

SOCK_CLEANUP;

exit(1);

}





pdu = snmp_pdu_create(SNMP_MSG_GET);

anOID_len = MAX_OID_LEN;

if (!snmp_parse_oid(local_oid, anOID, &anOID_len)) {

snmp_perror(local_oid);

SOCK_CLEANUP;

exit(1);

}

#if OTHER_METHODS



read_objid(local_oid, anOID, &anOID_len);

get_node("sysDescr.0", anOID, &anOID_len);

read_objid("system.sysDescr.0", anOID, &anOID_len);

printf(" iam herer!!\n");

#endif
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_variable(vars->name, vars->name_length, vars);


for(vars = response->variables; vars; vars = vars->next_variable) {

if (vars->type == ASN_OCTET_STR) {

char *sp = (char *)malloc(1 + vars->val_len);

memcpy(sp, vars->val.string, vars->val_len);

sp[vars->val_len] = '\0';

printf("value #%d is a string: %s\n", count++, sp);

free(sp);

}

else {
printf("value #%d is NOT a string! Ack!\n", count++);

printf("value #%d : %ld\n", count++, *(vars->val.integer) );
}

}

} else {


if (status == STAT_SUCCESS)

fprintf(stderr, "Error in packet\nReason: %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("snmpdemoapp", ss);
}


if (response)

snmp_free_pdu(response);

snmp_close(ss);
SOCK_CLEANUP;

return (0);

}


5、Makefile_snmpdemoapp
#

# Warning: you may need more libraries than are included here on the

# build line. The agent frequently needs various libraries in order

# to compile pieces of it, but is OS dependent and we can't list all

# the combinations here. Instead, look at the libraries that were

# used when linking the snmpd master agent and copy those to this

# file.

#
CC=gcc
OBJS1=snmpdemoapp.o

TARGETS=snmpdemoapp
CFLAGS=-I. `net-snmp-config --cflags`

BUILDLIBS=`net-snmp-config --libs`

BUILDAGENTLIBS=`net-snmp-config --agent-libs`
# shared library flags (assumes gcc)

DLFLAGS=-fPIC -shared
all: $(TARGETS)
snmpdemoapp: $(OBJS1)

$(CC) -o snmpdemoapp $(OBJS1) $(BUILDLIBS)

clean:

rm $(OBJS2) $(OBJS2) $(TARGETS)


6、snmpd.conf

###########################################################################

#

# snmpd.conf

#

# - created by the snmpconf configuration program

#

###########################################################################

# SECTION: Monitor Various Aspects of the Running Host

#

# The following check up on various aspects of a host.
# proc: Check for processes that should be running.

# proc NAME [MAX=0] [MIN=0]

#

# NAME: the name of the process to check for. It must match

# exactly (ie, http will not find httpd processes).

# MAX: the maximum number allowed to be running. Defaults to 0.

# MIN: the minimum number to be running. Defaults to 0.

#

# The results are reported in the prTable section of the UCD-SNMP-MIB tree

# Special Case: When the min and max numbers are both 0, it assumes

# you want a max of infinity and a min of 1.
proc "1 0"

proc aaa_process 2
# disk: Check for disk space usage of a partition.

# The agent can check the amount of available disk space, and make

# sure it is above a set limit.

#

# disk PATH [MIN=100000]

#

# PATH: mount path to the disk in question.

# MIN: Disks with space below this value will have the Mib's errorFlag set.

# Can be a raw integer value (units of kB) or a percentage followed by the %

# symbol. Default value = 100000.

#

# The results are reported in the dskTable section of the UCD-SNMP-MIB tree
disk

disk sda1 10
# load: Check for unreasonable load average values.

# Watch the load average levels on the machine.

#

# load [1MAX=12.0] [5MAX=12.0] [15MAX=12.0]

#

# 1MAX: If the 1 minute load average is above this limit at query

# time, the errorFlag will be set.

# 5MAX: Similar, but for 5 min average.

# 15MAX: Similar, but for 15 min average.

#

# The results are reported in the laTable section of the UCD-SNMP-MIB tree
load 12.0 60 180

load 12 60 180

###########################################################################

# SECTION: System Information Setup

#

# This section defines some of the information reported in

# the "system" mib group in the mibII tree.
# syslocation: The [typically physical] location of the system.

# Note that setting this value here means that when trying to

# perform an snmp SET operation to the sysLocation.0 variable will make

# the agent return the "notWritable" error code. IE, including

# this token in the snmpd.conf file will disable write access to

# the variable.

# arguments: location_string
syslocation aa

syslocation
# syscontact: The contact information for the administrator

# Note that setting this value here means that when trying to

# perform an snmp SET operation to the sysContact.0 variable will make

# the agent return the "notWritable" error code. IE, including

# this token in the snmpd.conf file will disable write access to

# the variable.

# arguments: contact_string
syscontact bb

syscontact
# sysservices: The proper value for the sysServices object.

# arguments: sysservices_number
sysservices 79



###########################################################################

# SECTION: Extending the Agent

#

# You can extend the snmp agent to have it return information

# that you yourself define.
# dlmod: dynamically extend the agent using a shared-object

# arguments: module-name module-path
dlmod nstAgentPluginObject /root/Desktop/net-snmp-5.5/nstAgentPluginObject.so

###########################################################################

# SECTION: Access Control Setup

#

# This section defines who is allowed to talk to your running

# snmp agent.
# rwuser: a SNMPv3 read-write user

# arguments: user [noauth|auth|priv] [restriction_oid]
rwuser root



# rouser: a SNMPv3 read-only user

# arguments: user [noauth|auth|priv] [restriction_oid]
rouser tduan



# rocommunity: a SNMPv1/SNMPv2c read-only access community name

# arguments: community [default|hostname|network/bits] [oid]
rocommunity opublic
# rwcommunity: a SNMPv1/SNMPv2c read-write access community name

# arguments: community [default|hostname|network/bits] [oid]
rwcommunity public

rwcommunity public_semi



###########################################################################

# SECTION: Trap Destinations

#

# Here we define who the agent will send traps to.
# trapsink: A SNMPv1 trap receiver

# arguments: host [community] [portnum]


trapsink 127.0.0.1 public 162
# trap2sink: A SNMPv2c trap receiver

# arguments: host [community] [portnum]


trap2sink 127.0.0.1 public 162
# informsink: A SNMPv2c inform (acknowledged trap) receiver

# arguments: host [community] [portnum]


informsink 127.0.0.1 public 162
# trapcommunity: Default trap sink community to use

# arguments: community-string


trapcommunity public
# authtrapenable: Should we send traps when authentication failures occur

# arguments: 1 | 2 (1 = yes, 2 = no)
authtrapenable 1


view demoWrite included .1.3.6.1.4.1.2021.14.1.1

view demoWrite included .1.3.6.1.4.1.8072.2.4.1.1.3
view demoRead included .1.3.6.1.4.1.2021.14.1.1

view demoRead included .1.3.6.1.2.1.1

view demoRead included .1.3.6.1.4.1.8072
access demogroup "" any auth prefix demoRead demoWrite none

group demogroup usm MD5DESUser

createUser MD5DESUser MD5 "The Net-SNMP Demo password" DES "The Net-SNMP Demo password"
group demogroup usm noAuthUser

group demogroup usm MD5User

group demogroup usm SHAUser

group demogroup usm SHADESUser

createUser noAuthUser

createUser MD5User MD5 "The Net-SNMP Demo Password"

createUser SHAUser SHA "The Net-SNMP Demo Password"

createUser SHADESUser SHA "The Net-SNMP Demo Password" DES "The Net-SNMP Demo Password"

FROM: http://blog.sina.com.cn/s/blog_49f761940100pp30.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: