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

来源:互联网 发布:java行业薪资 编辑:程序博客网 时间:2024/05/23 01:24

一、概述

 

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

 

1、agent端

 

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

 

2、管理端

 

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


 

n
二、逻辑图
snmpd装载一个动态链接库(so文件),以扩充MIB
三、扩充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
0 0
原创粉丝点击