

<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.net-snmp.org/wiki/index.php?action=history&amp;feed=atom&amp;title=TUT%3AWriting_a_MIB_Module</id>
		<title>TUT:Writing a MIB Module - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.net-snmp.org/wiki/index.php?action=history&amp;feed=atom&amp;title=TUT%3AWriting_a_MIB_Module"/>
		<link rel="alternate" type="text/html" href="http://www.net-snmp.org/wiki/index.php?title=TUT:Writing_a_MIB_Module&amp;action=history"/>
		<updated>2026-05-05T00:36:10Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.26.3</generator>

	<entry>
		<id>http://www.net-snmp.org/wiki/index.php?title=TUT:Writing_a_MIB_Module&amp;diff=26036&amp;oldid=prev</id>
		<title>Magfr: Created page with &quot;This page is the first in a series to guide you through the creation of custom extensions to the core Net-SNMP daemon, usually called an SNMP &quot;agent&quot;. In this article we will...&quot;</title>
		<link rel="alternate" type="text/html" href="http://www.net-snmp.org/wiki/index.php?title=TUT:Writing_a_MIB_Module&amp;diff=26036&amp;oldid=prev"/>
				<updated>2023-09-12T05:36:23Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;This page is the first in a series to guide you through the creation of custom extensions to the core Net-SNMP daemon, usually called an SNMP &amp;quot;agent&amp;quot;. In this article we will...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This page is the first in a series to guide you through the creation of custom extensions to the core Net-SNMP daemon, usually called an SNMP &amp;quot;agent&amp;quot;. In this article we will describe how to build your extension &amp;lt;em&amp;gt;into&amp;lt;/em&amp;gt; the daemon. The two following articles will describe how to put your changes into a shared object (see [[TUT:Writing a Dynamically Loadable Object|Writing a Dynamically Loadable Object]]) and a separate daemon (see [[TUT:Writing a Subagent|Writing a Subagent]]).&lt;br /&gt;
&lt;br /&gt;
Extensions (or &amp;lt;em&amp;gt;&amp;quot;MIB modules&amp;quot;&amp;lt;/em&amp;gt;) usually make use of the API provided by Net-SNMP and are therefore written in C. For instructions on writing extensions in Perl, please read [[Tut:Extending snmpd using perl|Extending SNMPd using Perl]].&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;Big Picture&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The main task of custom extensions is to register a callback function which handles requests for a specific [[OID]]. Version 5.0 of the Net-SNMP agent tries to make this task as easy as possible by providing so called &amp;lt;em&amp;gt;[[Agent Helpers|helper modules]]&amp;lt;/em&amp;gt;. Each request is handled in a &amp;lt;em&amp;gt;chain&amp;lt;/em&amp;gt; in Net-SNMP, as described in the [[Agent Architecture]]. You can &amp;lt;em&amp;gt;inject&amp;lt;/em&amp;gt; helper modules into this chain, so that helper modules are called before control reaches the actual callback function. This can, for example, be used to install a &amp;lt;em&amp;gt;cache&amp;lt;/em&amp;gt; in front of the actual data acquisition, which may be costly.&lt;br /&gt;
&lt;br /&gt;
== Recommended Reading List ==&lt;br /&gt;
&lt;br /&gt;
It is most helpful if you have the time to read through some documentation that describes how the Net-SNMP agent architecture works.  Thus, if you&amp;#039;re starting from scratch, the suggested reading order for information about the agent is:&lt;br /&gt;
&lt;br /&gt;
* The [[Agent Architecture]] describes the internals of the agent, and how the &amp;#039;&amp;#039;handler&amp;#039;&amp;#039; system works.&lt;br /&gt;
* The [[Agent Helpers]] list describes the available MIB helpers available, which will be used in detail below.&lt;br /&gt;
* The rest of the tutorial below where you actually get to play with some code.&lt;br /&gt;
&lt;br /&gt;
Can you skip some things on this list and jump straight to the real-code below?  Absolutely!  But you&amp;#039;ll probably regret it later.&lt;br /&gt;
&lt;br /&gt;
== Writing Your First Module ==&lt;br /&gt;
&lt;br /&gt;
We will now walk you through the process of developing increasingly more complex &amp;lt;em&amp;gt;MIB objects&amp;lt;/em&amp;gt;, beginning with a scalar, then a table, persistent data, notifications, and so on.&lt;br /&gt;
&lt;br /&gt;
=== MIBs For Dummies and mib2c  ===&lt;br /&gt;
&lt;br /&gt;
Writing modules for MIBs is a long and sometimes troublesome process, much like writing a parser. And just like writing a parser, you don&amp;#039;t have to do everything by hand: MIBs can already be processed by computers pretty well, so there is no need to start from square one every time. The tool to convert an existing MIB to some C code is called &amp;lt;strong&amp;gt;mib2c&amp;lt;/strong&amp;gt; and is part of the Net-SNMP distribution. There is a [[MIB for Dummies]] tutorial on using [[mib2c]] and &amp;#039;&amp;#039;{{code|local/mib2c.mfd.conf}}&amp;#039;&amp;#039; to generate a code template for a table.&lt;br /&gt;
&lt;br /&gt;
=== A simple scalar attached to a variable  ===&lt;br /&gt;
&lt;br /&gt;
The first example, [http://www.net-snmp.org/dev/agent/scalar__int_8c-example.html scalar_int.c], only consists of an initialization function, &amp;lt;code&amp;gt;init_scalar_int&amp;lt;/code&amp;gt;, which registers the module-global integer &amp;lt;code&amp;gt;example1&amp;lt;/code&amp;gt; with the SNMP agent (aka. &amp;quot;daemon&amp;quot;). The prototype and name of the initialization function must follow this schema:&lt;br /&gt;
&lt;br /&gt;
 void init_&amp;lt;em&amp;gt;module_name&amp;lt;/em&amp;gt; (void);&lt;br /&gt;
&lt;br /&gt;
In the example code, the &amp;lt;em&amp;gt;module&amp;#039;s&amp;lt;/em&amp;gt; name is &amp;quot;scalar_int&amp;quot;, hence the name of the initialization function.&lt;br /&gt;
&lt;br /&gt;
Within the initialization function, the API function [http://www.net-snmp.org/dev/agent/group__instance.html#ga20 netsnmp_register_int_instance] is called to actually register the integer at a specified OID. The prototype of that API function is:&lt;br /&gt;
&lt;br /&gt;
 int netsnmp_register_int_instance (const char *name,&lt;br /&gt;
                                    oid        *reg_oid,&lt;br /&gt;
                                    size_t      reg_oid_len,&lt;br /&gt;
                                    int        *it,&lt;br /&gt;
                                    Netsnmp_Node_Handler *subhandler);&lt;br /&gt;
&lt;br /&gt;
The first argument, &amp;lt;em&amp;gt;name&amp;lt;/em&amp;gt;, is a the short description of the object being registered. The second argument is the OID to assign to this object — the length of the OID is stored in the third argument. It is recommended to use the &amp;lt;code&amp;gt;OID_LENGTH&amp;lt;/code&amp;gt; macro which will only work with statically allocated OIDs (arrays work, pointers don&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
For the sake of simplicity the default &amp;lt;em&amp;gt;subhandler&amp;lt;/em&amp;gt; is used in the example code, therefore &amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; is passed as fifth argument. The default handler allows the integer to be read with a &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; request as well as set with a &amp;lt;code&amp;gt;SET&amp;lt;/code&amp;gt; request.&lt;br /&gt;
&lt;br /&gt;
Simple integer registration functions, including read-only registration and the default handlers, are declared in &amp;lt;code&amp;gt;agent/instance.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== A simple scalar with the value returned from code ===&lt;br /&gt;
&lt;br /&gt;
Here is [http://www.net-snmp.org/dev/agent/delayed__instance_8c-example.html some example code about writing a MIB Module] that describes how to implement a generic instance (not tied to a variable, like the above example) as well as how to delay answering queries for a bit (in the example, an alarm is set to add a delay to the answer).&lt;br /&gt;
&lt;br /&gt;
=== A table of data, stored within the agent ===&lt;br /&gt;
&lt;br /&gt;
Here is [http://www.net-snmp.org/dev/agent/data__set_8c-example.html a more complex  example] that implements a table, where the table data is completely contained within the agent. &lt;br /&gt;
&lt;br /&gt;
=== Sending SNMP notifications (traps and informs) from inside the agent. ===&lt;br /&gt;
&lt;br /&gt;
Here is [http://www.net-snmp.org/dev/agent/notification_8c-example.html an example of how to use the agent&amp;#039;s internal notification sending API] to send a notification to all of the agent&amp;#039;s trap receivers. &lt;br /&gt;
&lt;br /&gt;
=== The older (and thus most backward compatible) ucd-snmp 4.X API ===&lt;br /&gt;
&lt;br /&gt;
Of course, you can continue to write code using the older API set. A tutorial on it can be found [http://www.net-snmp.org/tutorial/tutorial-4/toolkit/mib_module/ here].&lt;br /&gt;
&lt;br /&gt;
== The MIB Module API ==&lt;br /&gt;
&lt;br /&gt;
The new API is documented more completely [http://www.net-snmp.org/dev/agent/group__handler.html here]. Additionally, see the complete list of (mostly) documented available helpers and other information [http://www.net-snmp.org/tutorial/tutorial-4/toolkit/mib_module/ here].&lt;br /&gt;
&lt;br /&gt;
== Compiling in your new MIB module ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: you will need to have previously installed the Net-SNMP Source Package on your system before proceeding.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
There are a few ways to get your new MIB module loaded and accessible via SNMP requests. We&amp;#039;ll discuss all three ways separately. To make this easy to test the procedures outlined below, we&amp;#039;ve provided three simple mib modules which implement the three simple scalars in the [http://www.net-snmp.org/tutorial/tutorial-5/toolkit/mib_module/NET-SNMP-TUTORIAL-MIB.txt NET-SNMP-TUTORIAL-MIB] MIB. To see how MIBs can be properly used by the tools, please see the [[TUT:Using_and_loading_mibs | mib-options tutorial]]. &lt;br /&gt;
&lt;br /&gt;
#; Compile it into the master agent. &lt;br /&gt;
&lt;br /&gt;
Lets assume you&amp;#039;re going to compile in a new mib module. For our example, lets use the [http://www.net-snmp.org/tutorial/tutorial-5/toolkit/mib_module/nstAgentModuleObject.c example mib module] and it&amp;#039;s [http://www.net-snmp.org/tutorial/tutorial-5/toolkit/mib_module/nstAgentModuleObject.h header file]. To do this, you would put the nstAgentModuleObject.h and nstAgentModuleObject.c files into the net-snmp source code directory. You do this by copying them into a agent/mibgroup/nstAgentModuleObject.h and agent/mibgroup/nstAgentModuleObject.c file. &lt;br /&gt;
&lt;br /&gt;
Next, you have to configure the package to find them and compile them into the agent. To do this, you run the configure script giving it the extra module names you want it to load: &lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;./configure --with-mib-modules=&amp;quot;nstAgentModuleObject&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
If you had multiple modules to include (like a second &amp;quot;XXX&amp;quot; module, for example), you can separate them with spaces inside the quotes (e.g., --with-mib-modules=&amp;quot;nstAgentModuleObject XXX&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
Note that nstAgentModuleObject is the prefix and the configure script will actually look for a nstAgentModuleObject.h and a nstAgentModuleObject.c file. You must have a .h file and you can not get it to work with just a .c file. &lt;br /&gt;
&lt;br /&gt;
Build your new agent with your new code in it by running make: &lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
Finally, install the whole lot by running make install: &lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;make install&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    &lt;br /&gt;
Now that the agent is installed, you need to add some basic configuration (see other tutorials for&lt;br /&gt;
more configuration options). Here we just add a simple read-only and read-write community strings&lt;br /&gt;
(&amp;#039;&amp;#039;tutget&amp;#039;&amp;#039; and &amp;#039;&amp;#039;tutset&amp;#039;&amp;#039;, respectively) for the tutorial MIB branch:&lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;echo &amp;quot;rocommunity tutget 127.0.0.1 .1.3.6.1.4.1.8072.2.4&amp;quot; &amp;gt;&amp;gt; /usr/local/etc/snmp/snmpd.conf&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;echo &amp;quot;rwcommunity tutset 127.0.0.1 .1.3.6.1.4.1.8072.2.4&amp;quot; &amp;gt;&amp;gt; /usr/local/etc/snmp/snmpd.conf&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can test out the functionality by starting the snmpd agent: &lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;/usr/local/sbin/snmpd -f -L -d&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Incoming and outgoing packets are printed (-d), to show what&amp;#039;s happening, and the agent is run as a &amp;#039;non-daemon&amp;#039; command (-f -L) so that you can see these messages. Note that this ties up the current shell, so you&amp;#039;ll need to run the following checks in a different terminal window.    &lt;br /&gt;
&lt;br /&gt;
And then running snmpget and snmpset on the scalar object: &lt;br /&gt;
&lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;snmpget -v2c -c tutget localhost NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0 = INTEGER: 1&lt;br /&gt;
  &lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;snmpset -v2c -c tutset localhost NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0 = 5&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0 = INTEGER: 5&lt;br /&gt;
  &lt;br /&gt;
  % &amp;#039;&amp;#039;&amp;#039;snmpget -v2c -c tutget localhost NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  NET-SNMP-TUTORIAL-MIB::nstAgentModuleObject.0 = INTEGER: 5&lt;br /&gt;
    &lt;br /&gt;
You can also compile your code into a &amp;quot;subagent&amp;quot; which then attaches itself to the master agent using [http://www.scguild.com/agentx/ the AgentX subagent protocol]. Our libraries provide support to make this easy to do and this is discussed in greater detail in [[TUT:Writing_a_Subagent | a later section]]. &lt;br /&gt;
 &lt;br /&gt;
Finally, you can also compile your code into pluggable shared object and tell the snmpd agent to load it. This is also discussed in greater detail in [[TUT:Writing_a_Dynamically_Loadable_Object | a later section ]].&lt;br /&gt;
&lt;br /&gt;
== Set Processing ==&lt;br /&gt;
&lt;br /&gt;
To process an SNMP-SET, the agent must use a series of calls to the mib module code to ensure that processing of all sets in the incoming packet can be successful. This gives you or other mib modules the chance to bail out early on in the transaction sequence and thus stop all of the transactions in the set from happening. This is important for continuity. However, it makes set code processing a bit more complex. Let&amp;#039;s examine a simple state diagram that the master agent uses at each step of the way: &lt;br /&gt;
&lt;br /&gt;
[[Image:set-actions.jpg]]&lt;br /&gt;
&lt;br /&gt;
In a perfect operation with no failures, we take the vertical path on the left. If any of the mib modules being acted upon returns an error of any kind, we will branch to the right to one of the failure states where you must clean up and possibly undo what you did in previous steps.&lt;br /&gt;
&lt;br /&gt;
If you need even finer-grained SET processing with even more states, check out the [[baby_steps]] [[Agent Helpers|helper]] module.&lt;br /&gt;
&lt;br /&gt;
{{TUT:LIST}}&lt;/div&gt;</summary>
		<author><name>Magfr</name></author>	</entry>

	</feed>