TUT:Writing a Dynamically Loadable Object

From Net-SNMP Wiki
Revision as of 20:11, 3 March 2009 by Octo (Talk | contribs) (Added section "Initialization".)

Jump to: navigation, search

This page describes how to build extension for Net-SNMP as shared objects, binary files that can be loaded by the SNMPd daemon directly and are executed as part of the daemon. This differs from the concept of Subagents, see Writing a Subagent: Subagents are separate processes that do not share memory, file descriptors and so on with the daemon and must use interprocess communication (IPC) to communicate with the daemon.

Writing dynamically loadable objects is interesting because you will have the entire API provided by Net-SNMP at your disposal, for example a caching infrastructure. Shared objects loaded this way usually get their configuration from the same configuration file the core daemon uses, which often is a nice thing. Disadvantages are that a programming mistake in your custom extension may crash the entire daemon and that your code is by design always executed as the same user the core daemon is executed as, i. e. potentially with unnecessary privileges ­— or too little, depending on your setup.

Prerequisites

First off, you need to write a MIB module first before you can do this part of the tutorial. We assume you have read and completed the MIB module portion of the toolkit tutorial. This part of the tutorial shows how to install a dynamic module into the agent, assuming you already have written a MIB module which we'll then compile into a dynamic module. For example purposes, we'll refer to some example MIB objects and code: the NET-SNMP-TUTORIAL-MIB MIB, and the example MIB module and it's header file.

Note: For this to work, you must have compiled the net-snmp package with dynamically loadable module support turned on, as well as built it with --enable-shared turned on. (It's on by default, if your system supports it). You can check for support in your agent but looking at the output of the snmpd -H command for the "dlmod" token. If its listed, the compiled agent supports it.

Note: All command line options below assume you have an appropriately setup ~/.snmp/snmp.conf file that allows you to not have to specify a SNMP version number, community name, username, or whatever else in order to talk to your agent. The agent, of course, must have a matching /usr/local/share/snmp/snmpd.conf file (or equivalent).

Here are the files discussed in this example so you can download them:

File Description
Makefile A simple makefile used to build the projects
NET-SNMP-TUTORIAL-MIB.txt The MIB we'll be writing code for in the various pieces of the agent extension tutorial
nstAgentPluginObject.h The MIB module's header file
nstAgentPluginObject.c The MIB module's C source code

Initialization

After loading the shared object to memory, the object loader will look for an initialization function inside the shared object. The name of this function is init_name, where "name" is the name of your extension. The name of the example module is "nstAgentPluginObject", so the loader will look for a function with the following prototype:

void init_nstAgentPluginObject (void);

There's a complementary function, called deinit_name, which is called when the module is unloaded, for example when the daemon is shutting down. Unsurprisingly, the prototype of the example deinit-function is:

void deinit_nstAgentPluginObject (void);

These are the only two functions called by the object loaded. All other functions (and module-global variables) therefore should be declared static.

You can check the names of currently loaded modules using the UCD-DLMOD-MIB::dlmodName OID.

Steps to build the shared object

  1. First off we must get the Makefile file, the nstAgentPluginObject.h file, and the nstAgentPluginObject.c file.
  2. make nstAgentPluginObject.so

Steps to test the shared object via runtime MIB configuration

  1. Start the snmpd and watch the dlmod and nstAgentPluginObject modules interact using the debugging flag (this assumes you already have access control set up properly for your agent):
    % snmpd -f -L -DnstAgentPluginObject,dlmod
  2. In another window, test to make sure that the agent doesn't currently support the nstAgentPluginObject (if you get different results running this command you need to recompile the net-snmp agent without the nstAgentPluginObject mib module compiled in directly):
    % snmpget localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0
    nstAgentPluginObject.0 = No Such Object available on this agent at this OID
  3. Then, run snmpset to create a new row in the dlmod table:
    % snmpset localhost UCD-DLMOD-MIB::dlmodStatus.1 i create
    dlmodStatus.1 = create(6)
  4. See that the row was created:
    % snmptable localhost UCD-DLMOD-MIB::dlmodTable
    SNMP table: dlmodTable
    dlmodName dlmodPath dlmodError dlmodStatus
    unloaded
  5. Then set the properties of the row up to point to our new object and to give it a name:
    % snmpset localhost UCD-DLMOD-MIB::dlmodName.1 s "nstAgentPluginObject" UCD-DLMOD-MIB::dlmodPath.1 s "/path/to/nstAgentPluginObject.so"
    dlmodName.1 = "nstAgentPluginObject"
    dlmodName.1 = "/path/to/nstAgentPluginObject.so"
    % snmptable localhost UCD-DLMOD-MIB::dlmodTable
    SNMP table: dlmodTable
    dlmodName dlmodPath dlmodError dlmodStatus
    nstAgentPluginObject /path/to/nstAgentPluginObject.so unloaded
  6. Finally, load the shared object into the running agent:
    % snmpset localhost UCD-DLMOD-MIB::dlmodStatus.1 i load
    dlmodStatus.1 = loaded(1)
    % snmptable localhost UCD-DLMOD-MIB::dlmodTable
    SNMP table: dlmodTable
    dlmodName dlmodPath dlmodError dlmodStatus
    nstAgentPluginObject /path/to/nstAgentPluginObject.so loaded
  7. If everything above was done correctly, then the following command should work and will access the shared object's data:
    % snmpget localhost NET-SNMP-TUTORIAL-MIB::nstAgentPluginObject.0
    nstAgentPluginObject.0 = INTEGER: 3

Loading via the snmpd.conf file

You can also load shared objects using the "dlmod" token in the snmpd.conf file by putting a line like this in your snmpd.conf file:

     dlmod nstAgentPluginObject /path/to/nstAgentPluginObject.so
   

The first argument specifies the shared object's module name (UCD-DLMOD-MIB::dlmodName) and second argument specifies the full pathname of the shared object file.

Tutorial Sections

About the SNMP Protocol

These tutorial links talk about SNMP generically and how the protocol itself works. They are good introductory reading material and the concepts are important to understand before diving into the later tutorials about Net-SNMP itself.

Net-SNMP Command Line Applications

These tutorial pages discuss the command line tools provided in the Net-SNMP suite of tools. Nearly all the example commands in these tutorials works if you try it yourself, as they're all examples that talk to our online Net-SNMP test agent. Given them a shot!

Application Configuration

All of our applications support configuration to allow you to customize how they behave.

Net-SNMP Daemons

Net-SNMP comes with two long-running daemons: a SNMP agent (snmpd) for responding to management requests and a notification receiver (snmptrapd) for receiving SNMP notifications.

Coding Tutorials

Net-SNMP comes with a highly flexible and extensible API. The API allows you to create your own commands, add extensions to the agent to support your own MIBs and perform specialized processing of notifications.

Debugging SNMP Applications and Agents

All our tools and applications have extensive debugging output. These tutorials talk about how the debugging system works and how you can add your own debugging statements to you code:

Operating System Specific Tutorials