This article describes how to extend Net-SNMP agent toolkit to instrument the EtherLike-MIB (RFC 3635) with hardcoded defaults. This article will describe the setup on windows (I used XP SP3) and Linux (I used openSUSE 11.0) required to develop this agent.
The following instructions were carried out for net-snmp source version 5.4.2.1. This article assumes the following default paths:
- Net-SNMP un-archived on windows in C:\net-snmp and ~/net-snmp on Linux.
- Net-SNMP installed in C:\usr on Windows and /usr/local on Linux.
1.1. Setup the development environment
- Download and install MSVC++ Express 2005 from http://www.microsoft.com/express/2005/download/default.aspx. There is some compilation issue of the net-snmp code with MSVC++ 2008 (Orcas) and i did not bother to fix it but used the 2005 instead.
- Download and setup platform sdk as described in http://www.microsoft.com/express/2005/platformsdk/default.aspx. Be sure to setup the development environment using the PSDK as described in the link step-wise.
- Download net-snmp source from http://www.net-snmp.org/download.html. The net-snmp version 5.4.2.1 can be downloaded from there.
1.2. Build and install net-snmp from source on windows
- Un-archive the net-snmp source to say c:\net-snmp.
- Follow the README.win32 to build the net-snmp code (Read the section Microsoft Visual C++ - Workspace – Building).
-
- We need to first load the winsdk.dsw in the MSVC++ 2005 express. Below is the screenshot of all projects that make up the win32sdk workspace in MSVC++.
-
Figure 1 - Projects in win32sdk.dsw
- Modify the win32\netsnmp\netsnmpconfig.h file to add:
#define HAVE_WIN32_PLATFORM_SDK 1
Build in order, the following project for (Release | Debug) configuration.
i. libagent
ii. libhelpers
iii. libnetsnmptrapd
iv. libsnmp
v. netsnmpmibsdk
Go to Build > Batch Build… and select the (Debug | Release) configuration of all projects except for the ones you built in step c above.
If everything is okay with setup, then build should go fine too.
Using cmd line on windows, go to c:\net-snmp and run the command: win32\install_netsnmp.bat to install net-snmp you built above to location c:\usr.
Set the c:\usr\bin to PATH environment variable for easy access to the command line snmp client and agent executables.
1.3. Build and install net-snmp from source on Linux
Un-archive the net-snmp source to say ~/net-snmp.
Follow the INSTALL to build the net-snmp code. Run the following commands on shell prompt:
cd ~/net-snmp
./configure
make
make install (run as root)
The make install step will install the net-snmp binaries by default in /usr/local path.
1.4. Configuring the snmpd agent (snmpd.conf)
Configure snmp agent by running snmpconf command (see man page) or copy the C:/net-snmp/Example.conf and modify.
snmpconf –g basic_setup
I used the following configuration. Copy-paste the text below into a file named snmpd.conf. The agent is configured for snmp v2c and with rwcommunity string of public.
com2sec local localhost public
group MyRWGroup v1 local
group MyRWGroup v2c local
group MyRWGroup usm local
view all included .1 80
# context sec.model sec.level match read write notif
access MyROGroup "" any noauth exact all none none
access MyRWGroup "" any noauth exact all all none
syslocation Right here, right now.
syscontact Me <me@somewhere.org>
Save the file in path :
C:\usr\etc\snmp\snmpd.conf (on Windows)
/etc/snmp/snmpd.conf (on Linux)
1.5. Load the MIB module and generate the C code
The EtherLike-MIB has 5 tables (columnar variables).
For mib2c code generation I used linux host. Run the following commands on shell prompt:
mkdir ethmib_src
cd ethmib_src
export MIBS=ALL
EtherLike-MIB was part of the net-snmp distribution so all we need is to tell mib2c to use it by setting the environment variable MIBS.
mib2c –c mib2c.create-dataset.conf dot3StatsTable
This will generate dot3StatsTable.c and dot3StatsTable.h files.
Similarly run the similar command for the other tables in the mib.
mib2c –c mib2c.create-dataset.conf dot3PauseTable
mib2c –c mib2c.create-dataset.conf dot3HCStatsTable
mib2c –c mib2c.create-dataset.conf dot3CollTable
mib2c –c mib2c.create-dataset.conf dot3ControlTable
Use the ethmib_src and use it for windows agent extension too.
1.6. Use the generated source files to instrument the mib on Windows
On Windows, the above generated source files can be copied to c:\net-snmp\agent\mibgroups. You may also create a folder names EtherLike-MIB and sub-folders for each table like dot3StatsTable etc, and keep the respective table *.c and *.h files in the folder with the table name.
Add the generated sources in the MSVC++ netsnmpmibssdk project as shown below:
Figure 2 - EtherLike-MIB files added to the netsnmpmibssdk project.
Add the dot3StatsTable.h and dot3StatsTable.c files to your 'netsnmpmibssdk' project in VC++.
Next edit the '<sourcedir>\win32\mib_module_includes.h' file to add an include to your .h file.
#include "mibgroup/EtherLike-MIB/dot3StatsTable/dot3StatsTable.h"
#include "mibgroup/EtherLike-MIB/dot3HCStatsTable/dot3HCStatsTable.h"
#include "mibgroup/EtherLike-MIB/dot3CollTable/dot3CollTable.h"
#include "mibgroup/EtherLike-MIB/dot3ControlTable/dot3ControlTable.h"
#include "mibgroup/EtherLike-MIB/dot3PauseTable/dot3PauseTable.h"
Next edit the '<sourcedir>\win32\mib_module_inits.h' file to add code to call your initialize function.
if (should_init("dot3StatsTable")) init_dot3StatsTable();
if (should_init("dot3HCStatsTable")) init_dot3HCStatsTable();
if (should_init("dot3CollTable")) init_dot3CollTable();
if (should_init("dot3ControlTable")) init_dot3ControlTable();
if (should_init("dot3PauseTable")) init_dot3PauseTable();
1.7. Instrument the EtherLike-MIB
This section only instruments the dot3StatsTable generated source to return some default data. Other table instrumentation can be done in the similar manner.
Edit the dot3StatsTable.c file as shown below to return some hardcoded data. The changes to the generated code have been highlighted.
/*
* Note: this file originally auto-generated by mib2c using
* : mib2c.create-dataset.conf 9375 2004-02-02 19:06:54Z rstory $
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "dot3StatsTable.h"
/** Initialize the dot3StatsTable table by defining its contents and how it's structured */
void
initialize_table_dot3StatsTable(void)
{
static oid dot3StatsTable_oid[] = {1,3,6,1,2,1,10,7,2};
size_t dot3StatsTable_oid_len = OID_LENGTH(dot3StatsTable_oid);
netsnmp_table_data_set *table_set;
// variables declared – wrajnees
netsnmp_table_row *row;
static int _max_cols = 21; // there are 18 columns in this table.
int column = 0;
int index = 1;
int val = 20;
static oid objid_etherchipset[] = { 0 }; /* ethernetChipset vendor oid */
// end variables declared.
/* create the table structure itself */
table_set = netsnmp_create_table_data_set("dot3StatsTable");
/* comment this out or delete if you don't support creation of new rows */
table_set->allow_creation = 1;
/***************************************************
* Adding indexes
*/
DEBUGMSGTL(("initialize_table_dot3StatsTable",
"adding indexes to table dot3StatsTable\n"));
netsnmp_table_set_add_indexes(table_set,
ASN_INTEGER, /* index: dot3StatsIndex */
0);
DEBUGMSGTL(("initialize_table_dot3StatsTable",
"adding column types to table dot3StatsTable\n"));
netsnmp_table_set_multi_add_default_row(table_set,
/*COLUMN_DOT3STATSINDEX, ASN_INTEGER, 0,
NULL, 0,*/
COLUMN_DOT3STATSALIGNMENTERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSFCSERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSSINGLECOLLISIONFRAMES, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSMULTIPLECOLLISIONFRAMES, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSSQETESTERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSDEFERREDTRANSMISSIONS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSLATECOLLISIONS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSEXCESSIVECOLLISIONS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSCARRIERSENSEERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSFRAMETOOLONGS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSETHERCHIPSET, ASN_OBJECT_ID, 0,
NULL, 0,
COLUMN_DOT3STATSSYMBOLERRORS, ASN_COUNTER, 0,
NULL, 0,
COLUMN_DOT3STATSDUPLEXSTATUS, ASN_INTEGER, 0,
NULL, 0,
COLUMN_DOT3STATSRATECONTROLABILITY, ASN_INTEGER, 0,
NULL, 0,
COLUMN_DOT3STATSRATECONTROLSTATUS, ASN_INTEGER, 0,
NULL, 0,
0);
/* registering the table with the master agent */
/* note: if you don't need a subhandler to deal with any aspects
of the request, change dot3StatsTable_handler to "NULL" */
netsnmp_register_table_data_set(netsnmp_create_handler_registration("dot3StatsTable", NULL,
dot3StatsTable_oid,
dot3StatsTable_oid_len,
HANDLER_CAN_RONLY),
table_set, NULL);
// Add code - wrajnees
/*
* create the a row for the table, and add the data
*/
row = netsnmp_create_table_data_row();
/*
* set the index to the IETF WG name "snmpv3"
*/
netsnmp_table_row_add_index(row, ASN_INTEGER, (u_char*)&index, sizeof(index));
/*
* set the column 2 and above
*/
for (column = 2; column <= _max_cols; column++) {
// Following columns are not valid.
switch(column) {
case 12: // INVALIDs
case 14:
case 15:
break;
case 17: // OID
netsnmp_set_row_column(row, column, ASN_OBJECT_ID,
(u_char*)objid_etherchipset, 1*sizeof(oid));
break;
case 19: // INTEGER
case 21:
netsnmp_set_row_column(row, column, ASN_INTEGER,
(u_char*)&val, sizeof(val));
break;
case 20: // TRUTH_VALUE
netsnmp_set_row_column(row, column, ASN_INTEGER,
(u_char*)&val, sizeof(val));
break;
default: // COUNTER
netsnmp_set_row_column(row, column, ASN_COUNTER,
(u_char*)&val, sizeof(val));
break;
}
}
/*
* add the row to the table
*/
netsnmp_table_dataset_add_row(table_set, row);
/*
* Finally, this actually allows the "add_row" token it the
* * snmpd.conf file to add rows to this table.
* * Example snmpd.conf line:
* * add_row netSnmpIETFWGTable eos "Glenn Waters" "Dale Francisco"
*/
netsnmp_register_auto_data_table(table_set, NULL);
// End add code - wrajnees
}
/** Initializes the dot3StatsTable module */
void
init_dot3StatsTable(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_dot3StatsTable();
}
Now rebuild the netsnmpmibssdk project and then snmpdsdk project, in order.
Run the following command to re-install the modified agent with the dot3StatsTable changes.
cd c:\net-snmp
win32\install_netsnmp.bat
Start the new agent as follows:
cd c:\usr\bin
snmpd.exe –f –Lo –V
Open a MIB Browser to walk the dot3StatsTable instrumentation:
1.8. Instrumentation on Linux
Copy the generated source to the path ~/net-snmp/agent/mibgroups and run the following commands:
./configure –with-mib-modules=”dot3StatsTable dot3PauseTable dot3HCStatsTable dot3CollTable dot3ControlTable”
make
make install (run as root)
Start the snmpd as:
/usr/local/sbin/snmpd –f –Lo –V
Run a command line snmpwalk to test it.
$ snmpwalk -v 2c -mAll -c public localhost dot3StatsTable
EtherLike-MIB::dot3StatsAlignmentErrors.1 = Counter32: 20
EtherLike-MIB::dot3StatsFCSErrors.1 = Counter32: 20
EtherLike-MIB::dot3StatsSingleCollisionFrames.1 = Counter32: 20
EtherLike-MIB::dot3StatsMultipleCollisionFrames.1 = Counter32: 20
EtherLike-MIB::dot3StatsSQETestErrors.1 = Counter32: 20
EtherLike-MIB::dot3StatsDeferredTransmissions.1 = Counter32: 20
EtherLike-MIB::dot3StatsLateCollisions.1 = Counter32: 20
EtherLike-MIB::dot3StatsExcessiveCollisions.1 = Counter32: 20
EtherLike-MIB::dot3StatsInternalMacTransmitErrors.1 = Counter32: 20
EtherLike-MIB::dot3StatsCarrierSenseErrors.1 = Counter32: 20
2. Co-existance with MS Windows SNMP Agent
We have 2 approaches to getting the net-snmp agent to co-exist with the Microsoft provided SNMP agent:
As of Net-SNMP 5.4, the Net-SNMP agent is able to load the Windows SNMP service extension DLLs by using the Net-SNMP winExtDLL extension. In this scenario, MS SNMP agent is installed but disabled. This is required because winExtDLL extension and existing windows extensions use Windows SNMP API from snmpapi.dll. The limitations of this approach are:
linkUp/Down generic traps are not received for some unknown reason.
sysUpTime.0 does not report the correct uptime for the agent. This is because the Windows extension checks for the uptime of the SNMP service, which is not running when Net-SNMP is running.
Alternatively, Net-SNMP agent can run as a proxy SNMP agent and will proxy for the MS SNMP agent (running at a non-default port) for those MIBs that MS SNMP agent instruments. For all other MIBs, Net-SNMP agent can service the SNMP requests. This approach does not suffer from the winExtDLL approach’s limitation, but then we need to run two snmp agents (net-snmp and MS snmp agents).
This sums up in short, the development setup required to get started with extending the net-snmp agent.