SNMP(三)使用mib2c.mfd.conf生成的模版

mfd用于生成table的模版,使用此工具链生成将各个功能模块分割开来了。

scalars可以使用mib2c.scalar.conf,trap可以使用mib2c.notify.conf来生成模版。

记录如下,默认使用default即可,其中MyMIB为自行定义的XXX名称:

XXX  DEFINITIONS::=BEGIN
....
....

ExampleTable为自行定义的table:

ExampleTable        OBJECT-TYPE
           SYNTAX SEQUENCE OF ExampleEntry
.....
.....

以下为输出和select信息:

[root@localhost snmp]# mib2c mib2c.mfd.conf MyMIB::ExampleTable
Replacing previous mibNode mib2c.mfd.conf with MyMIB::ExampleTable
writing to -
mib2c has multiple configuration files depending on the type of
code you need to write.  You must pick one depending on your need.

You requested mib2c to be run on the following part of the MIB tree:
  OID:                       	    ExampleTable
  numeric translation:       	    .1.3.6.1.4.1.310.3
  number of scalars within:         0
  number of tables within:          1
  number of notifications within:   0

First, do you want to generate code that is compatible with the
ucd-snmp 4.X line of code, or code for the newer Net-SNMP 5.X code
base (which provides a much greater choice of APIs to pick from):

  1) ucd-snmp style code
  2) Net-SNMP style code

Select your choice : 2

**********************************************************************
		     GENERATING CODE FOR TABLES:
**********************************************************************

  The Net-SNMP agent API is extremely extensive and, in fact, lets
  each programmer write agent code according to the style that works
  best for them based on their experience and their preference.  We're
  going to ask you a serious of questions that will help mib2c
  generate code that best suits *your* needs, as the programmer that
  will be responsible for taking the code and further refining it.  If
  you don't like how the results look, you are always welcome to
  re-run mib2c and select a different set of options.

    There are essentially two tasks involved in processing requests
  for OIDs within a MIB table - firstly identifying the relevant row
  of the table for a given request, and then returning (or updating)
  the appropriate column value within that row.  Many MIB tables model
  the state of some external system (the kernel, a device, processes,
  etc), and the MIB implementation module (the code we're about to
  produce a template for) acts as an interface between this underlying
  system and the SNMP side.  Other tables hold data internally that is
  only available within the agent itself, or at least the master copy
  of the data is held within the agent.

    There are a number of different code templates that can be used to
  implement MIB tables, using various approaches to these two tasks.

  There are three basic approaches to identifying the relevant row:

    1) Pass the request through to the table-specific code, and
       identify the requested row there (for both GET and GETNEXT
       requests).  This is typically the most efficient way to get
       up-to-date information, but relies on suitable
       (programmer-provided) code within the MIB handler.
       Most importantly, you should be an expert to use this choice.

       This will produce code based on the table_dataset handler.

    2) Have table-specific code to provide information about which
       rows exist in the table (by iterating through them in turn),
       but utilise standard helper code to select the appropriate
       row for a given request.  This is particularly suitable for
       tables where the data is naturally stored in a "random" order
       (or differently to the MIB table index), or where rows are
       frequently added to or removed from the table.

         However searching for the requested row is not very efficient,
       and performance can be slow - particularly for large tables with
       many rows.

    3) Hold a locally cached copy of the contents of the table (or at
       least a cache of which rows are valid), and utilise standard
       helper code to select the appropriate row.  This is
       significantly faster than the iterator-based approach, but
       cached data is inevitably slightly "stale" with respect to the
       data from the underlying system being managed.  This approach,
       since it relies on caching of data, is also results in a larger
       memory footprint.  It is less appropriate for tables where rows
       are frequently added or removed externally to the agent (i.e.,
       not via SNMP requests).

       This approach can also be used where _all_ use of the table is
       via SNMP, and there is no external "underlying system".  In
       this case, the local cache is the canonical version of the
       table.

    4) Do not generate code for the tables.

Select the option that best fits your requirements: 3


  Having identified the appropriate row for a given request, there are
  three basic styles of code for returning (or updating) the requested
  column value from within this row:

    1) A single handler routine, which contains all the code needed to
       handle GET and SET requests for each of the column objects.


    2) A set of individual routines, each of which is concerned
       with a particular aspect of processing the request.
       There is one routine for reporting values for GET requests,
       and one routine for each stage of processing a SET request.

    3) A (different) set of individual routines, each of which is
       smaller and more tightly focused than the code generated by
       style 2.  The aim here is to reduce the amount of SNMP specific
       knowledge required to implement a module, and hide much of the
       SNMP terminology and processing within standard generated code
       (which can simply be used sight unseen).

       This will produce code based on the 'mfd' hepler ('MIB for Dummies').

    4) Do not generate code for the tables.

   (In all cases, GETNEXT requests are automatically converted
    into the equivalent GET request, so the MIB specific code
    need only be concerned with GET and SET requests.).
       
Select the code style you wish to use: 3



     The same template code can be generated using
                 mib2c -c mib2c.mfd.conf ExampleTable
Defaults for ExampleTable...
There are no defaults for ExampleTable. Would you like to

  1) Accept hard-coded defaults
  2) Set defaults now [DEFAULT]

Select your choice : 2


This table has writable columns. Do you want to generate
code for writeable columns, or restrict the table to read-only?

  1) generate code with writeable columns [DEFAULT]
  2) generate code with read-only columns

Select your choice : 1


Since your table is writable, do you want to generate code to save and
restore rows in the Net-SNMP persistent store? You should only use this
option if the agent 'owns' the data, and doesn't get the data from an
external source.

  1) do not generate persistent store code [DEFAULT]
  2) generate persistent store code

Select your choice : 1


Writable tables sometimes have dependencies beteen columns
or with other tables. If there are no dependencies in this table, you
probably do not want the extra code.

  1) do not generate dependency code [DEFAULT]
  2) generate dependency code

Select your choice : 1


Do you want to use an existing data structure for the USER context?
This would be a structure used to track data for the entire table,
(similar to a global variable) not individual rows.  (Many
implementations won't need this, in which case the default is fine).


  1) No, use netsnmp_data_list [DEFAULT]
  2) Yes, use my own structure

Select your choice : 1


Do you want to use an existing data structure for the DATA context?
The DATA context holds the data for each MIB column in a given row. By
default, a new data structure will be created with an element for each
column.  If you already have a structure that holds your data, select 2.

  1) No, use generated [DEFAULT]
  2) Yes, use my own structure

Select your choice : 1


Do you need to initialize elements in the 'generated' DATA
context when a new instance is created (eg default values, or other structures
you are going to add that might need initialization to the row request context?
(The most common reasons you might need to do this is are if you want to keep
some non-MIB data for every row, or some columns have default values.)

  1) no, no initialization needed
  2) yes, initilization is needed [DEFAULT]

Select your choice : 2


Do you plan on keeping all data in the format defined by the MIB? If so,
no functions will be generated to map values. If some data will be
stored in a different format, the mapping functions will be generated.
If your MIB has integers with enumerations, mapping functions are more
likely to be needed. (e.g. A TruthValue object will hold the value
1 or 2, but a C boolean would be 1 or 0.)

  1) All values will be stored as defined by the MIB [DEFAULT]
  2) I need to map values to the format defined by the MIB.

Select your choice : 1


Which method would you like to use to gather data about available rows? 

  1) container : [DEFAULT]  This access method uses a netsnmp_container
     to store all row data in memory. This method is best for:
         - Internal data (maintained by the agent)
         - Access speed is important
         - Sufficient memory exists to contain all rows

  2) container-cached : This access method uses a netsnmp_container
     to keep track of the indexes (and data, usually) for each 
     row. This method is best for:
         - External data (maintained by another process/the kernel)
         - Access speed is important
         - Sufficient memory exists to contain all indexes
     
  3) unsorted-external : This access method iterates over all of your data
     to find the row with the appropriate index. This method is good for
         - External data (maintained by another process/the kernel)
         - Using less memory is much more important than access speed
     
Select your choice : 1


When accessing your data, is your data TRANSIENT?

  1) Yes. My data is TRANSIENT (e.g. a pointer to a static buffer that
     my be overwritten during a request) and needs to be copied during
     processing.

  2) Yes. My data is SEMI-TRANSIENT (e.g. an allocated pointer to a
     copy of the data).

  3) No, my data is PERSISTENT (e.g. an allocated pointer to the actual
     data, which is under the agent's control)
  
Select your choice [DEFAULT=1] : 1


Do you want example code to be generated? This will generate example code
for reading data from a text file.

  1) generate example code [DEFAULT]
  2) do not generate example code

Select your choice : 1

Is your table sparse? A sparse table is a table where some
columns might not exist for all rows. Note that if your table
contains a RowStaus column and it supports createAndWait, you
will need sparse table support.

  1) No, all columns always exist for every row [DEFAULT]
  2) Yes, my table is sparse

Select your choice : 1

Do you want a makefile and AgentX subagent source file generated?
This will let you test your table without having to link it into
snmpd. (You can still link it in later.)

  1) do not generate makefile/AgentX code [DEFAULT]
  2) generate makefile/AgentX code

Select your choice : 1

writing to defaults/table-ExampleTable.m2d
Starting MFD code generation...
writing to ExampleTable.h
| +-> Processing table ExampleTable
writing to defaults/node-UserStatus.m2d
writing to defaults/node-CheckTime.m2d
writing to defaults/node-MonSet.m2d
writing to defaults/node-UserIndex.m2d
writing to ExampleTable.c
writing to ExampleTable_data_get.h
writing to ExampleTable_data_get.c
| |   +-> Processing nonindex UserStatus
| |   +-> Processing nonindex CheckTime
| |   +-> Processing nonindex MonSet
writing to ExampleTable_data_set.h
writing to ExampleTable_data_set.c
Use of uninitialized value $key in hash element at /usr/local/lib/perl5/SNMP.pm line 1387, <GEN109> line 408.
Use of uninitialized value $key in hash element at /usr/local/lib/perl5/SNMP.pm line 1388, <GEN109> line 408.
Use of uninitialized value in null operation at /usr/local/lib/perl5/SNMP.pm line 1387, <GEN109> line 408.
| |   +-> Processing nonindex MonSet
writing to ExampleTable_oids.h
writing to ExampleTable_enums.h
writing to ExampleTable_interface.h
writing to ExampleTable_interface.c
writing to ExampleTable_data_access.h
writing to ExampleTable_data_access.c
writing to ExampleTable-README-FIRST.txt
writing to ExampleTable-README-ExampleTable.txt


**********************************************************************
* NOTE WELL: The code generated by mib2c is only a template.  *YOU*  *
* must fill in the code before it'll work most of the time.  In many *
* cases, spots that MUST be edited within the files are marked with  *
* /* XXX */ or /* TODO */ comments.                                  *
**********************************************************************
running indent on ExampleTable.h
running indent on ExampleTable_interface.c
running indent on ExampleTable_data_set.c
running indent on ExampleTable_interface.h
running indent on ExampleTable.c
running indent on ExampleTable_enums.h
running indent on ExampleTable_data_access.c
running indent on ExampleTable_data_get.h
running indent on ExampleTable_data_set.h
running indent on ExampleTable_oids.h
running indent on ExampleTable_data_get.c
running indent on ExampleTable_data_access.h

还有NetSNMP subagent development manual

net-snmp agent开发及mib2c MFD

可以参考参考。

END:记录一下过程,然后根据需求再在这基础上修改添加代码,主要需要修改的是xxxTable_data_access.c 、xxxTable_get.c、xxxTable_set.c,以及对应的.h文件。

Note:这里还需注意的是xxx_CACHE_TIMEOUT 该宏定义,需根据实际需要修改此宏。避免时间过长,或者太短,数据未缓存。另外,关于性能优化,可在Load添加索引即可,把获取数据移到interface.c内,可提升执行性能。

扫描二维码关注公众号,回复: 5082682 查看本文章

猜你喜欢

转载自blog.csdn.net/finderskill/article/details/81005740
今日推荐