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
可以参考参考。
END:记录一下过程,然后根据需求再在这基础上修改添加代码,主要需要修改的是xxxTable_data_access.c 、xxxTable_get.c、xxxTable_set.c,以及对应的.h文件。
Note:这里还需注意的是xxx_CACHE_TIMEOUT 该宏定义,需根据实际需要修改此宏。避免时间过长,或者太短,数据未缓存。另外,关于性能优化,可在Load添加索引即可,把获取数据移到interface.c内,可提升执行性能。
扫描二维码关注公众号,回复:
5082682 查看本文章