and added files
[bcm963xx.git] / userapps / opensource / net-snmp / AGENT.txt
1 Note, this is based on the text from a web page, which can be found in 
2 the documentation section of the http://www.net-snmp.org web page.
3
4 Extending the UCD-SNMP agent
5 ============================
6
7 This document describes the procedure for writing code to extend
8 the functionality of the UCD-SNMP network management agent.
9 We would be very interested in comment and feedback about how useful
10 useful you find this description, and ways in which it could be improved.
11
12 The information is designed to be read in order - the structure being:
13
14   1. Overview & Introduction
15   2. MIB files, and how they relate to the agent implementation
16   3. Header files
17   4. The basic structure of module implementation code
18   5. The details of non-table based implementations
19   6. The details of simple table based implementations
20   7. The details of more general table based implementations
21   8. How to implement SET-able variables
22
23 While the document is intended to be generally self-contained,
24 it does occasionally refer to code files shipped with the main UCD
25 distribution (in particular the example module), and it may prove
26 useful to have these files available for reference.
27
28 1. How to write a Mib module
29 ============================
30
31 Introduction
32 ------------
33
34 The design of the UCD SNMP agent has always been shaped by the desire to be
35 able to extend its functionality by adding new modules. One of the earliest
36 developments from the underlying CMU code base was the ability to call
37 external scripts, and this is probably the simplest method of extending the
38 agent.
39 However, there are circumstances where such an approach is felt to be
40 inappropriate - perhaps from considerations of speed, access to the
41 necessary data, reliability or elegance. In such cases, the obvious solution
42 is to provide C code that can be compiled into the agent itself to implement
43 the desired module. Many of the more recent developments in the code
44 structure have been intended to ease this process. In particular, one of the
45 more recent additions to the suite is the tool mib2c. This is designed to
46 take a portion of the MIB tree (as defined by a MIB file) and generate the
47 code skeleton necessary to implement this. This document will cover the use
48 mib2c, as well as describing the requirements and functionality of the code
49 in more detail.
50
51 In order to implement a new MIB module, three files are necessary, and these
52 will be considered in turn. Note that, by the very nature of the task, this
53 document cannot cover the details of precisely how to obtain the necessary
54 information from the operating system or application. Instead, it describes
55 the code framework that is needed, freeing the implementer from needing to
56 understand the detailed internals of the agent, and allowing them to
57 concentrate on the particular problem in hand.
58
59 It may prove useful to examine some of the existing module implementations
60 and examples in the light of this description, and suitable examples will be
61 referred to at the appropriate points. However, it should be remembered that
62 the UCD agent seeks to support a wide variety of systems, often with
63 dramatically differing implementations and interfaces, and this is reflected
64 in the complexity of the code. Also, the agent has developed gradually over
65 the years, and there is often some measure of duplication or redundancy as a
66 result.
67 As the FAQ states, the official slogan of the UCD-SNMP developers is
68
69      The current implementation is non-obvious and may need to be
70      improved.
71
72 This document describes the ideal, straightforward cases - real life is
73 rarely so simple, and the example modules may prove easier to follow at a
74 first reading.
75 It is also advisable to have a compiled and installed implementation
76 available before starting to extend the agent. This will make debugging and
77 testing the agent much easier.
78
79 A note regarding terminology - the word "module" is widely used throughout
80 this document, with a number of different meanings.
81
82    * support for a new MIB,
83      i.e. the whole of the functionality that is required. This is usually
84      termed a MIB module;
85    * a self-contained subset of this, implemented as a single unit.
86      This is usually termed an implementation module (or simply "a module");
87    * the combination of such subsets, usually termed a module group.
88
89 Note that the first and third of these are often synonymous - the
90 difference being that a MIB module refers to the view from outside the
91 agent, regarding this as a seamless whole and hiding the internal
92 implementation. A "module group" is used where the internal structure is of
93 more relevance, and recognises the fact that the functionality may be
94 provided by a number of co-operating implementation modules.
95
96 Anyway, enough waffle - on with the details: The three files needed are
97
98    * a MIB definition file;
99    * a C header file;
100    * a C implementation file.
101
102 The next part looks at the MIB definition file, and how this impacts on the
103 agent implementation.
104
105 2. The MIB File
106 ===============
107
108 The first file needed is the MIB file that defines the MIB module to be
109 implemented.
110 Strictly speaking, this is not absolutely necessary, as the agent itself
111 does not make any direct use of the MIB definitions. However, it is
112 advisable to start with this for three reasons:
113
114    * It provides an initial specification for what is to be implemented.
115      Code development is always easier if you know what you are meant to be
116      writing!
117    * If the new MIB file is read in with the other MIB files,
118      this lets the applications provided with the suite be used to test the
119      new agent, and report (hopefully meaningful) symbolic OIDs and values,
120      rather than the bare numeric forms.
121      (N.B: Remember to tell the application to load the new MIB. See the
122      relevant question in the FAQ)
123    * The tool mib2c uses this description to produce the two code files.
124      This is by far the easiest way to develop a new module.
125
126 If the intention is to implement a 'standard' MIB module, or a
127 vendor-specific one, then the construction of this file will have already
128 been done for you. If the intention is to provide a totally new, private
129 module, then you will need to write this yourself, in addition to the agent
130 code files.
131 A description of MIB file format and syntax is beyond the scope of this
132 document, and most books on SNMP management should provide some information
133 on this subject. One book which concentrates on this is
134
135      Understanding SNMP MIBS
136      (Perkins & McGinnis, Prentice Hall, ISBN 0-13-437708-7).
137
138 This blatant plug is wholly unrelated to the fact that David Perkins is an
139 active member of the development group, and is regarded as our resident
140 "protocol guru and policeman". (In fact, this book concentrates on MIB
141 files in rather more detail than is appropriate in more general SNMP works).
142 Information on other books covering SNMP and Network Management more generally
143 is available on the SimpleWeb site (among other places).
144 See the FAQ for more details.
145
146 Assigned OID numbers
147 --------------------
148
149 One word of advice - even if you are developing a totally private MIB
150 module, you will still need to position this somewhere within the overall
151 MIB tree. Please do NOT simply choose a location "at random". Any such is
152 likely to have either been assigned to some other organisation, or may be so
153 assigned some time in the future. However much you may regard your project
154 as a totally internal affair, such projects have a tendency to exceed their
155 expected scope, both in terms of lifetime and distribution (not to mention
156 the potential OID clash if you subsequently need to use elements from the
157 legitimate owner's tree).
158 It is simple and cheap (i.e. free!) to obtain your own official segment of
159 the MIB tree (see http://www.iana.org for an application form), and having
160 done so, you then have complete global authority over it. If you have
161 problems with this, it's worth contacting the development team (email:
162 net-snmp-coders@lists.sourceforge.net) for advice. Please do think to the
163 future, and be a good Net citizen by using a legitimately assigned OID as
164 the root of your new MIB.
165
166 MIB division
167 ------------
168
169 The next point to consider, whether writing by hand or using mib2c,
170 implementing an existing MIB, or writing a new one, is whether and how to
171 divide up the MIB tree. This is a purely internal implementation decision,
172 and will not be visible to management applications querying the agent. A
173 sensible choice of partitioning will result in a simpler, clearer
174 implementation, which should ease both the initial development and
175 subsequent maintenance of the module.
176 Unfortunately, this choice is one of the module-specific decisions, so must
177 be made on a case-by-case basis. For a simple, self-contained module, it may
178 well be reasonable to implement the module as a single block (examples
179 include the SNMP statistics subtree RFC 1907 or the TCP subtree RFC 2011).
180 More complex and diverse modules (such as the Host Resources MIB - RFC 1514)
181 are more naturally considered as a number of individual sub-modules.
182 Some guidelines to bear in mind when deciding on this division:
183
184    * A MIB sub-tree consisting purely of scalar objects with a common
185      OID prefix would normally be handled in a single implementation module;
186    * Separate scalar subtrees would normally be in different implementation
187      modules;
188    * A table can either be handled within the same implementation module
189      as related scalar objects in the same subtree, or in a separate
190      implementation module;
191    * Variables that rely on the same underlying data structure to retrieve
192      their values, should probably be in the same implementation module (and
193      conversely, (though less so) those that don't, shouldn't).
194
195 As an initial rule of thumb, a good initial division is likely to be
196 obtained by treating each table and each scalar sub-tree separately. This
197 can be seen in the current agent, where most of the MIB-II modules (RFC
198 1213) are implemented in separate files (see the files under mibgroup/mibII).
199 Note that many of these combine scalar and table handling in the same file,
200 though they are implemented using separate routines.
201   This is also the approach used by mib2c, which constructs a single pair of
202 code files, but uses a separate routine for each table (and another for all
203 the scalar variables).
204   Ultimately, the final consideration (concerning the underlying data) is
205 the most important, and should guide the basic division. For example, the
206 Host Resources Running Software and Running Software Performance modules,
207 while separate in the MIB tree, use the same underlying kernel data and so
208 are implemented together.
209
210 MIB name
211 --------
212
213 The final requirement at this stage is to choose a name for each
214 implementation module. This should be reasonably short, meaningful, unique
215 and unlikely to clash with other (existing or future) modules. Mib2c uses
216 the label of the root node of the MIB sub-tree as this name, and this is a
217 reasonable choice in most cases.
218 Recent changes to the agent code organisation have introduced the idea of
219 module groups of related implementation modules. This is used, for example,
220 to identify the constituent modules of a 'split' MIB (such as the Host
221 Resources MIB), or those relating to a particular organisation (such as
222 UCD).
223 As with the division, this naming and grouping is a purely internal matter,
224 and is really only visible when configuring and compiling the agent.
225
226 So much for the MIB file. The next part considers the C header file.
227
228 3. The C code header file
229 =========================
230
231 If the MIB file is the definition of the module for external network
232 management applications (where applications includes network management
233 personnel!), then the header file has traditionally served effectively the
234 same purpose for the agent itself.
235 Recent changes to the recommended code structure has resulted in the header
236 file becoming increasingly simpler. It now simply contains definitions of the
237 publically visible routines, and can be generated completely by mib2c.
238
239 Function prototypes
240 -------------------
241
242 For those interested in the details of this file (for example, if coding a
243 module by hand), then the details of these definitions are as follows. Every
244 header file will have the following two function prototype definitions
245
246         extern void          init_example (void);
247         extern FindVarMethod var_example;
248
249 If the module includes any tables, or other collections of variables that
250 are implemented in separate routines, then this second definition will be
251 repeated for each of these.
252 In addition, if any of the variables can be SET (and it is intended to
253 implement them as such), there will be a function prototype definitions for
254 each of these, of the form:
255
256         extern WriteMethod write_varName;
257
258 These prototypes are in fact typedef'ed in <agent/snmp_vars.h>.
259
260 Module dependancies
261 -------------------
262
263 This header file is also used to inform the compilation system of any
264 dependancies between this module and any others. There is one utility module
265 which is required by almost every module, and this is included using the
266 directive
267
268
269 (which is produced automatically by mib2c). This same syntax can be used to
270 trigger the inclusion of other related modules. An example of this can be
271 seen in mibII/route_write.h which relies on the mibII/ip module, thus:
272
273         config_require( mibII/ip )
274
275 One use of this directive is to define a module group, by supplying a header
276 file consisting exclusively of such config_require directives.  It can then
277 be included or excluded from the agent very simply. Examples of this can be
278 seen in mibgroup/mibII.h or mibgroup/host.h, which list the consituent
279 sub-modules of the MIB-II and Host Resources MIBs respectively.
280
281 MIB file information
282 --------------------
283
284 Most of the information in this file is (understandably) aimed at the network
285 management agent itself.  However, there is one common header file directive
286 that is actually intended to affect the utility commands that are included
287 within the full distribution:
288
289         config_add_mib( HOST-RESOURCES-MIB )
290
291   This is used to add the MIB file being implemented to the default list of
292 MIBs loaded by such commands.  This means that querying the agent will return
293 informative names and values, rather than the raw numeric forms that SNMP
294 actually works with.  Of course, it is always possible for the utilities
295 to specify that this MIB should be loaded anyway.  But specifying this file
296 within the module header file is a useful hint that a particular MIB should
297 be loaded, without needing to ask for it explicitly.
298   Note that this will only affect the binaries compiled as part of the same
299 configuration run.  It will have no effect on pre-installed binaries, or
300 those compiled following a different configuration specification.
301
302 Magic Numbers
303 -------------
304
305 The other common element within the header file defines a set of "magic
306 numbers" - one for each object within the implementation module. In fact,
307 this can equally well appear within the main code file, as part of the
308 variable structure (which will be described in the next part).
309   This is the technique used by mib2c, but most handcrafted modules have
310 tended to define these as part of the header file, probably for clarity.
311
312   The only necessity is that the names and values are distinct (or more
313 precisely, the values are distinct within a single variable handling routine).
314 In practise, they tend to be defined using integers incrementing from 1,
315 or as the same as the final sub-identifier of the corresponding MIB object
316 (or indeed both, as these are frequently themselves successive integers).
317   This is not mandatory, and a counter-example can be seen in the
318 example module, where two of the object form a sub-tree, and the corresponding
319 magic numbers are based on the final *two* sub-identifiers (to ensure that
320 the values are unique).  But this construction is definitely unusual, and
321 the majority of modules simply use successive integers.
322
323 Header file protection
324 ----------------------
325
326 Normally, the only other contents of the header file will be the
327 #ifndef/#define/#endif statements surrounding the whole file. This is used
328 to ensure that the header file is only included once by any source code file
329 (or more accurately, that there is no effect if it is inadvertantly included
330 a second time).
331 Again, as with the rest of the header file, this is generated automatically
332 by mib2c.
333
334 Having finished all the preparatory work (or let mib2c deal with it), the
335 next part starts to look at the code file that actually implements the
336 module.
337
338 4. Core structure of the implementation code
339 ============================================
340
341 The core work of implementing the module is done in the C code file. As
342 indicated earlier, much of the detail of this will be dependent on the
343 particular module being implemented, and this can only be described by the
344 individual programmer concerned.
345 However, there is a fairly clearly defined framework that the implementation
346 will need to follow, though this varies slightly depending on the style of
347 the module being implemented (in particular whether it forms a table or a
348 series of individual values). The differences will be covered in the
349 following pages, but we first need to consider the overall shape of the
350 framework, and the elements that are common to all styles. These are
351 essentially the compulsory routines, the common header definitions, and
352 assorted initialisation code.
353 As with the header file, most of this will be generated automatically by
354 mib2c.
355
356 Standard includes
357 -----------------
358
359 Certain header files are either compulsory, or required so frequently that
360 they should be included as a matter of course. These are as follows:
361
362   #include <config.h>                   // local SNMP configuration details
363   #include "mib_module_config.h"        // list of which modules are supported
364   #if HAVE_STDLIB_H
365   #include <stdlib.h>
366   #endif
367   #if HAVE_STRING_H
368   #include <string.h>
369   #else
370   #include <strings.h>
371   #endif
372
373   #include <sys/types.h>
374
375 All of these will usually be the first files to be included.
376
377   #include "mibincl.h"                  // Standard set of SNMP includes
378   #include "util_funcs.h"               // utility function declarations
379   #include "read_config.h"              // if the module uses run-time
380                                         //      configuration controls
381   #include "auto_nlist.h"               // structures for a BSD-based
382                                         //      kernel using nlist
383   #include "system.h"
384
385   #include "name.h"                     // the module-specific header
386
387 These conventionally come at the end of the list of includes. In between
388 will come all the standard system-provided header files required for the
389 library functions used in the file.
390
391 Module definition
392 -----------------
393
394 Much of the code defining the contents of the MIB has traditionally been
395 held in the header file. However, much of this has slowly migrated to the
396 code file, and this is now the recommended location for it (as typified by
397 the output of mib2c).
398   The main element of this is a variable structure specifying the details of 
399 the objects implemented.  This takes the form of an unconstrained array of
400 type struct variableN (where N is the length of the longest suffix in the
401 table). Thus
402
403                 struct variable2 example_variables[] = {
404                         <individual entries go here>
405                 };
406
407 Each entry corresponds to one object in the MIB tree (or one column in the
408 case of table entries), and these should be listed in increasing OID order.
409 A single entry consists of six fields:
410
411    * a magic number (the #defined integer constant described above)
412    * a type indicator (from the values listed in <snmplib/snmp_impl.h>)
413    * an access indicator (essentially RWRITE or RONLY)
414    * the name of the routine used to handle this entry
415    * the length of the OID suffix used, and
416    * an array of integers specifying this suffix (more on this in a moment)
417
418 Thus a typical variable entry would look like:
419
420         { EXAMPLESTRING, ASN_OCTET_STR, RONLY, var_example, 1, {1}}
421
422 If the magic numbers have not been defined in the header file, then they
423 should be defined here, usually comming immediately before the corresponding
424 variable entry.  This is the technique used by mib2c.
425
426 Note that in practise, only certain sizes of the structure variableN
427 are defined (listed in <agent/var_struct.h>), being sufficient to meet the
428 common requirements. If your particular module needs a non-supported value,
429 the easiest thing is simply to use the next largest value that is supported.
430
431 The module also needs to declare the location within the MIB tree where
432 it should be registered. This is done using a declaration of the form
433
434         oid example_variables_oid[] = { 1,3,6,1,4,1,2021,254 }
435
436 where the contents of the array give the object identifier of the root of
437 the module.
438
439 Module initialisation
440 ---------------------
441
442 Many modules require some form of initialisation before they can start
443 providing the necessary information. This is done by providing a routine
444 called init_{name} (where {name} is the name of the module).
445 This routine is theoretically optional, but in practise is required to
446 register this module with the main agent at the very least. This specifies
447 the list of variables being implemented (from the variableN structure)
448 and declare where these fit into the overall MIB tree.
449
450 This is done by using the REGISTER_MIB macro, as follows:
451
452         REGISTER_MIB( "example",  example_variables, variable2,
453                         example_variables_oid );
454
455 where "example" is used for identification purposed (and is usually the name
456 being used for the module), example_variables is the structure defining the
457 variables being implemented, variable2 is the type used for this structure,
458 and example_variables_oid is the location of the root.
459
460 In fact, this macro is simply a wrapper round the routine register_mib(),
461 but the details of this can safely be ignored, unless more control over the
462 registration is required.
463
464 One common requirement, particularly on older operating systems or for the
465 more obscure areas of the system, is to be able to read data directly from
466 kernel memory. The preparation for this is typically done here by one or
467 more statements of the form
468
469         #ifdef {NAME}_SYMBOL
470         auto_nlist( {NAME}_SYMBOL, 0, 0);
471         #endif
472
473 where {NAME}_SYMBOL is defined as part of the system-specific configuration,
474 to be the name of the appropriate kernel variable or data structure. (The
475 two 0 values are because the kernel information is simply being primed at
476 this point - this call will be reused later when the actual values are
477 required). Note that this is probably the first thing described so far which
478 isn't provided by mib2c!
479
480 Other possibilities for initialisation may include registering config file
481 directive handlers (which are documented in the read_config(5) man page), and
482 registering the MIB module (either in whole or in part) in the sysOR table.
483 The first of these is covered in the example module, and the second in many
484 of the other modules within the main UCD distribution.
485
486 Variable handling
487 -----------------
488
489 The other obligatory routine is that which actually handles a request for a
490 particular variable instance. This is the routine that appeared in the
491 variableN structure, so while the name is not fixed, it should be the same
492 as was used there.
493 This routine has six parameters, which will be described in turn.
494
495 Four of these parameters are used for passing in information about the
496 request, these being:
497
498         struct variable *vp;
499                 // The entry in the variableN array from the
500                 //   header file, for the object under consideration.
501                 // Note that the name field of this structure has been
502                 //   completed into a fully qualified OID, by prepending
503                 //   the prefix common to the whole array.
504         oid *name;      // The OID from the request
505         int *length;    // The length of this OID
506         int exact;      // A flag to indicate whether this is an exact
507                         // request (GET/SET) or an 'inexact' one (GETNEXT)
508
509 Four of the parameters are used to return information about the answer.
510 The function also returns a pointer to the actual data for the variable
511 requested (or NULL if this data is not available for any reason).
512 The other result parameters are:
513
514         oid *name;      // The OID being returned
515         int *length;    // The length of this OID
516         int *var_len;   // The length of the answer being returned
517         WriteMethod **write_method;
518                         // A pointer to the SET function for this variable
519
520 Note that two of the parameters (name and length) serve a dual purpose,
521 being used for both input and output.
522
523 The first thing that this routine needs to do is to validate the request, to
524 ensure that it does indeed lie in the range implemented by this particular
525 module. This is done in slightly different ways, depending on the style of
526 the module, so this will be discussed in more detail later.
527   At the same time, it is common to retrieve some of the information needed
528 for answering the query.
529
530 Then the routine uses the Magic Number field from the vp parameter to determine
531 which of the possible variables being implemented is being requested. This is
532 done using a switch statement, which should have as many cases as there are
533 entries in the variableN array (or more precisely, as many as specify this
534 routine as their handler), plus an additional default case to handle an
535 erroneous call.
536 Each branch of the switch statement needs to ensure that the return
537 parameters are filled in correctly, set up a (static) return variable with
538 the correct data, and then return a pointer to this value. These can be done
539 separately for each branch, or once at the start, being overridden in
540 particular branches if necessary.
541
542 In fact, the default validation routines make the assumption that the
543 variable is both read-only, and of integer type (which includes the COUNTER
544 and GAUGE types among others), and set the return paramaters write_method and
545 var_len appropriately. These settings can then be corrected for those cases
546 when either or both of these assumptions are wrong. Examples of this can be
547 seen in the example module.
548 EXAMPLEINTEGER is writeable, so this branch sets the write_method parameter,
549 and EXAMPLEOBJECTID is not an integer, so this branch sets the var_len
550 parameter.  In the case of EXAMPLESTRING, both assumptions are wrong, so this
551 branch needs to set both these parameters explicitly.
552
553 Note that because the routine returns a pointer to a static result, a
554 suitable variable must be declared somewhere for this. Two global variables
555 are provided for this purpose - long_return (for integer results) and
556 return_buf (for other types). This latter is a generic array (of type
557 u_char) that can contain up to 256 bytes of data. Alternatively, static
558 variables can be declared, either within the code file, or local to this
559 particular variable routine. This last is the approach adopted by mib2c,
560 which defines four such local variables, (long_ret, string, objid and c64).
561
562 Mib2c requirements
563 ------------------
564
565 Most of the code described here is generated by mib2c. The main exceptions
566 (which therefore need to be provided by the programmer) are
567
568    * Any initialisation, other than the basic registration
569      (including kernel data initialisation, config file handling, or sysOR
570      registration).
571    * Retrieving the necessary data, and setting the appropriate return
572      value correctly.
573    * The var_len (and possibly write_method) return parameters for variable
574      types that are not recognised by mib2c
575    * The contents of any write routines (see later).
576
577 Everything else should be useable as generated.
578
579 This concludes the preliminary walk-through of the general structure of the
580 C implementation. To fill in the details, we will need to consider the
581 various styles of module separately. The next part will look at scalar (i.e.
582 non-table based) modules.
583
584 5. Non-table-based modules
585 ==========================
586
587 Having looked at the general structure of a module implementation, it's now
588 time to look at this in more detail. We'll start with the simplest style of
589 module - a collection of independent variables. This could easily be
590 implemented as a series of completely separate modules - the main reason for
591 combining them is to avoid the proliferation of multiple versions of very
592 similar code.
593
594 Recall that the variable handling routine needs to cover two distinct
595 purposes - validation of the request, and provision of the answer. In this
596 style of module, these are handled separately. Once again, mib2c does much
597 of the donkey work, generating the whole of the request validation code (so
598 the description of this section can be skipped if desired), and even
599 providing a skeleton for returning the data. This latter still requires some
600 input from the programmer, to actually return the correct results (rather
601 than dummy values).
602
603 Request Validation
604 ------------------
605
606 This is done using a standard utility function header_generic. The
607 parameters for this are exactly the same as for the main routine, and are
608 simply passed through directly. It returns an integer result, as a flag to
609 indicate whether the validation succeeded or not.
610 If the validation fails, then the main routine should return immediately,
611 leaving the parameters untouched, and indicate the failure by returning a
612 NULL value. Thus the initial code fragment of a scalar-variable style
613 implementation will typically look like:
614
615     u_char  *
616     var_system(vp, name, length, exact, var_len, write_method)
617     {
618         if (header_generic(vp, name, length, exact, var_len, write_method)
619                                                 == MATCH_FAILED )
620             return NULL;
621
622         [ etc, etc, etc ]
623     }
624
625 Although the utility function can be used as a "black box", it's worth
626 looking more closely at exactly what it does (since the table-handling
627 modules will need to do something fairly similar). It has two (or possibly
628 three) separate functions:
629
630    * checking that the request is valid,
631    * setting up the OID for the result,
632    * and (optionally) setting up default values for the other return
633      parameters.
634
635 In order to actually validate the request, the header routine first needs to
636 construct the OID under consideration, in order to compare it with that
637 originally asked for. The driving code has already combined the OID prefix
638 (constant throughout the module) with the entry-specific suffix, before
639 calling the main variable handler. This is available via the name field of
640 the parameter vp. For a scalar variable, completing the OID is therefore
641 simply a matter of appending the instance identifier 0 to this. The full OID
642 is built up in a local oid array newname defined for this purpose.
643 This gives the following code fragment:
644
645     int
646     header_generic(vp, name, length, exact, var_len, write_method)
647     {
648         oid newname[MAX_OID_LEN];
649
650         memcpy((char *)newname, (char *)vp->name,
651                         (int)vp->namelen * sizeof(oid));
652         newname[ vp->namelen ] = 0;
653
654                 :
655     }
656
657 Having formed the OID, this can then be compared against the variable
658 specified in the original request, which is available as the name parameter.
659 This comparison is done using the snmp_oid_compare function, which takes the
660 two OIDs (together with their respective lengths), and returns -1, 0 or 1
661 depending on whether the first OID precedes, matches or follows the second.
662
663 In the case of an 'exact' match (i.e. a GET/SET/etc), then the request is
664 only valid if the two OIDs are identical (snmp_oid_compare returns 0). In
665 the case of a GETNEXT (or GETBULK) request, it's valid if the OID being
666 considered comes after that of the original request (snmp_oid_compare
667 returns -1).
668
669 This gives the code fragment
670
671         result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1);
672                         // +1 because of the extra instance sub-identifier
673         if ((exact && (result != 0))            // GET match fails
674                 || (!exact && (result >= 0)))   // GETNEXT match fails
675             return(MATCH_FAILED);
676
677 Note that in this case, we're only interested in the single variable
678 indicated by the vp parameter. The fact that this module may well implement
679 other variables as well is ignored. The 'lexically next' requirement of the
680 GETNEXT request is handled by working through the variable entries in order
681 until one matches. And yes, this is not the most efficient implementation
682 possible!
683 Note that in releases prior to 3.6, the snmp_oid_compare function was called
684 simply compare.
685
686 Finally, having determined that the request is valid, this routine must
687 update the name and length parameters to return the OID being processed. It
688 also sets default values for the other two return parameters.
689
690         memcpy( (char *)name,(char *)newname,
691                 ((int)vp->namelen + 1) * sizeof(oid));
692         *length = vp->namelen + 1;
693         *write_method = 0;              // Non-writeable
694         *var_len = sizeof(long);        // default to integer results
695         return(MATCH_SUCCEEDED);
696
697 These three code fragments combine to form the full header_generic code
698 which can be seen in the file util_funcs.c
699
700 Note: This validation used to be done using a separate function for each
701 module (conventionally called header_{name}), and many modules may still be
702 coded in this style. The code for these are to all intents and purposes
703 identical to the header_generic routine described above.
704
705 Data Retrieval
706 --------------
707
708 The other main job of the request handling routine is to retrieve any
709 necessary data, and return the appropriate answer to the original request.
710 This must be done even if mib2c is being used to generate the framework of
711 the implementation. As has been indicated earlier, the different cases are
712 handled using a switch statement, with the Magic Number field of the vp
713 parameter being used to distinguish between them.
714 The data necessary for answering the request can be retrieved for each
715 variable individually in the relevant case statement (as is the case with
716 the system group), or using a common block of data before processing the
717 switch (as is done for the ICMP group, among others).
718
719 With many of the modules implemented so far, this data is read from a kernel
720 structure. This can be done using the auto_nlist routine already mentioned,
721 providing a variable in which to store the results and an indication of its
722 size (see the !HAVE_SYS_TCPIPSTATS_H case of the ICMP group for an example).
723 Alternatively, there may be ioctl calls on suitable devices, specific system
724 calls, or special files that can be read to provide the necessary
725 information.
726
727 If the available data provides the requested value immediately, then the
728 individual branch becomes a simple assignment to the appropriate static
729 return variable - either one of the global static variables (e.g. long_return)
730 or the local equivalents (such as generated by mib2c).
731 Otherwise, the requested value may need to be calculated by combining two or
732 more items of data (e.g. IPINHDRERRORS in mibII/ip.c) or by applying a
733 mapping or other calculation involving available information (e.g.
734 IPFORWARDING from the same group).
735
736 In each of these cases, the routine should return a pointer to the result
737 value, casting this to the pseudo-generic (u_char *)
738
739 So much for the scalar case. The next part looks at how to handle simple
740 tables.
741
742 6. Simple tables
743 ================
744
745 Having considered the simplest style of module implementation, we now turn
746 our attention to the next style - a simple table. The tabular nature of
747 these is immediately apparent from the MIB definition file, but the
748 qualifier "simple" deserves a word of explanation.
749 A simple table, in this context, has four characteristics:
750
751   1. It is indexed by a single integer value;
752   2. Such indices run from 1 to a determinable maximum;
753   3. All indices within this range are valid;
754   4. The data for a particular index can be retrieved directly
755      (e.g. by indexing into an underlying data structure).
756
757 If any of the conditions are not met, then the table is not a pure simple
758 one, and the techniques described here are not applicable. The next section
759 of this guide will cover the more general case. (In fact, it may be possible
760 to use the bulk of the techniques covered here, though special handling will
761 be needed to cope with the invalid assumption or assumptions). Note that
762 mib2c assumes that all tables are simple.
763
764 As with the scalar case, the variable routine needs to provide two basic
765 functions - request validation and data retrieval.
766
767 Validation
768 ----------
769
770 This is provided by the shared utility routine header_simple_table. As with
771 the scalar header routine, this takes the same parameters as the main
772 variable routine, with one addition - the maximum valid index. Mib2c
773 generates a dummy token for this, which must be replaced by the appropriate
774 value.
775 As with the header routine, it also returns an indication of whether the
776 request was valid, as well as setting up the return parameters with the
777 matching OID information, and defaults for var_len and write_method.
778 Note that in releases prior to 3.6, this job was performed by the routine
779 checkmib. However, the return values of this were the reverse of those for
780 generic_header and header_simple_table. A version of checkmib is still
781 available for compatability purposes, but you are encouraged to use
782 header_simple_table instead.
783
784 The basic code fragment (see ucd-snmp/disk.c) is therefore of the form:
785
786         unsigned char *
787         var_extensible_disk(vp, name, length, exact, var_len, write_method)
788         {
789             if (header_simple_table(vp,name,length,exact,var_len,write_method,numdisks)
790                                         == MATCH_FAILED)
791                 return(NULL);
792
793             [ etc, etc, etc ]
794
795         }
796
797 Note that the maximum index value parameter does not have to be a
798 permanently fixed constant. It specifies the maximum valid index at the time
799 the request is processed, and a subsequent request may have a different
800 maximum.
801 An example of this can be seen in mibII/sysORTable.c where the table is held
802 purely internally to the agent code, including its size (and hence the
803 maximum valid index). This maximum could also be retrieved via a system
804 call, or via a kernel data variable.
805
806 Data Retrieval
807 --------------
808
809 As with the scalar case, the other required function is to retrieve the data
810 requested. However, given the definition of a simple table this is simply a
811 matter of using the single, integer index sub-identifier to index into an
812 existing data structure. This index will always be the last index of the OID
813 returned by header_simple_table, so can be obtained as name[*length-1].
814 A good example of this type of table can be seen in ucd-snmp/disk.c
815
816 With some modules, this underlying table may be relatively large, or only
817 accessible via a slow or cumbersome interface. The implementation described
818 so far may prove unacceptably slow, particularly when walking a MIB tree
819 requires the table to be loaded afresh for each variable requested.
820
821 In these circumstances, a useful technique is to cache the table when it is
822 first read in, and use that cache for subsequent requests. This can be done
823 by having a separate routine to read in the table. This uses two static
824 variables, one a structure or array for the data itself, and the other an
825 additional timestamp to indicate when the table was last loaded. When a call
826 is made to this routine to "read" the table, it can first check whether the
827 cached table is "new enough". If so, it can return immediately, and the
828 system will use the cached data.
829 Only if the cached version is sufficiently old that it's probably out of
830 date, is it necessary to retrieve the current data, updating the cached
831 version and the timestamp value.
832 This is particularly useful if the data itself is relatively static, such as
833 a list of mounted filesystems. There is an example of this technique in the
834 Host Resources implementation.
835
836 As with the scalar case, mib2c simply provides placeholder dummy return
837 values. It's up to the programmer to fill in the details.
838
839 The next part concludes the examination of the detailed implementation by
840 looking at more general tables.
841
842 7. General Tables
843 =================
844
845 Some table structures are not suitable for the simple table approach, due to
846 the failure of one or more of the assumptions listed earlier. Perhaps they
847 are indexed by something other than a single integer (such as a 4-octet IP
848 address), or the maximum index is not easily determinable (such as the
849 interfaces table), or not all indices are valid (running software), or the
850 necessary data is not directly accessible (interfaces again).
851 In such circumstances, a more general approach is needed. In contrast with
852 the two styles already covered, this style of module will commonly combine
853 the two functions of request validation and data retrieval. Note that mib2c
854 will assume the simple table case, and this will need to be corrected.
855
856 General table algorithm
857 -----------------------
858
859 The basic algorithm is as follows:
860
861      Perform any necessary initialization, then walk through the
862      underlying instances, retrieving the data for each one, until the
863      desired instance is found. If no valid entry is found, return
864      failure.
865
866 For an exact match (GET and similar), identifying the desired instance is
867 trivial - construct the OID (from the 'vp' variable parameter and the index
868 value or values), and see whether it matches the requested OID.
869 For GETNEXT, the situation is not quite so simple. Depending on the
870 underlying representation of the data, the entries may be returned in the
871 same order as they should appear in the table (i.e. lexically increasing by
872 index). However, this is not guaranteed, and the natural way of retrieving
873 the data may be in some "random" order. In this case, then the whole table
874 needs to be traversed for each request. in order to determine the
875 appropriate successor.
876 This random order is the worst case, and dictates the structure of the code
877 used in most currently implemented tables. The ordered case can be regarded
878 as a simplification of this more general one.
879
880 The algorithm outlined above can now be expanded into the following
881 pseudo-code:
882
883         Init_{Name}_Entry();    // Perform any necessary initialisation
884
885         while (( index = Get_Next_{Name}_Entry() ) != EndMarker ) {
886                         // This steps through the underlying table,
887                         //   returning the current index,
888                         //   or some suitable end-marker when all
889                         //   the entries have been examined.
890                         // Note that this routine should also return the
891                         //   data for this entry, either via a parameter
892                         //   or using some external location.
893
894             construct OID from vp->name and index
895             compare new OID and request
896             if valid {
897                 save current data
898                 if finished     // exact match, or ordered table
899                     break;      //  so don't look at any more entries
900
901             }
902
903                 //  Otherwise, we need to loop round, and examine
904                 //    the next entry in the table.  Either because
905                 //    the entry wasn't valid for this request,
906                 //    or the entry was a possible "next" candidate,
907                 //    but we don't know that there isn't there's a
908                 //    better one later in the table.
909         }
910
911         if no saved data        // Nothing matched
912            return failure
913
914                 // Otherwise, go on to the switch handling
915                 //  we've already covered in the earlier styles.
916
917 This is now very close to the actual code used in many current
918 implementations (such as the the routine header_ifEntry in
919 mibII/interfaces.c). Notice that the pseudo-code fragment if valid expands
920 in practise to
921
922         if ((exact && (result == 0))  ||
923                         // GET request, and identical OIDs
924             (!exact && (result < 0)) )
925                         // GETNEXT, and candidate OID is later
926                         //  than requested OID.
927
928 This is a very common expression, that can be seen in most of the table
929 implementations.
930
931 Notice also that the interfaces table returns immediately the first valid
932 entry is found, even for GETNEXT requests. This is because entries are
933 returned in lexical order, so the first succeeding entry will be the one
934 that's required.
935 (As an aside, this also means that the underlying data can be saved
936 implicitly within the 'next entry' routine - not very clean, but it saves
937 some unnecessary copying).
938
939 The more general case can be seen in the TCP and UDP tables (see mibII/tcp.c
940 and mibII/udp.c). Here, the if valid fragment expands to:
941
942         if ( exact && (result == 0)) {
943                 // save results
944                 break;
945         }
946         else if (!exact && (result < 0)) {
947             if ( .... ) {       // no saved OID, or this OID
948                                 //  precedes the saved OID
949                 // save this OID into 'lowest'
950                 // save the results into Lowinpcb
951                 // don't break, since we still need to look
952                 //      at the rest of the table
953             }
954         }
955
956 The GET match handling is just as we've already seen - is this the requested
957 OID or not. If so, save the results and move on to the switch statement.
958   The GETNEXT case is more complicated. As well as considering whether this
959 is a possible match (using the same test we've already seen), we also have to
960 check whether this is a better match than anything we've already seen. This
961 is done by comparing the current candidate (newname) with the best match found
962 so far (lowest).
963   Only if this extra comparison shows that the new OID is earlier than the
964 saved one, do we need to save both the new OID, and any associated data
965 (such as the inpcb block, and state flag). But having found one better
966 match, we don't know that there isn't an even better one later on. So we
967 can't break out of the enclosing loop - we need to keep going and examine
968 all the remaining entries of the table.
969
970 These two cases (the TCP and UDP tables) also show a more general style of
971 indexing. Rather than simply appending a single index value to the OID
972 prefix, these routines have to add the local four-octet IP address plus port
973 (and the same for the remote end in the case of the TCP table). This is the
974 purpose of the op and cp section of code that precedes the comparison.
975
976 These two are probably among the most complex cases you are likely to
977 encounter. If you can follow the code here, then you've probably cracked the
978 problem of understanding how the agent works.
979
980 Finally, the next part discusses how to implement a writable (or SETable)
981 object in a MIB module.
982
983 8. How to implement a SETable object
984 ====================================
985
986 Finally, the only remaining area to cover is that of setting data - the
987 handling of SNMPSET. Particular care should be taken here for two reasons.
988
989 Firstly, any errors in the earlier sections can have limited effect. The
990 worst that is likely to happen is that the agent will either return invalid
991 information, or possibly crash. Either way, this is unlikely to affect the
992 operation of the workstation as a whole. If there are problems in the
993 writing routine, the results could be catastrophic (particularly if writing
994 data directly into kernel memory).
995
996 Secondly, this is the least well understood area of the agent, at least by
997 the author. There are relatively few variables that are defined as READ-WRITE
998 in the relevant MIBs, and even fewer that have actually been implemented as
999 such. I'm therefore describing this from a combination of my understanding
1000 of how SETs ought to work, personal experience of very simple SET handling
1001 and what's actually been done by others (which do not necessarily coincide).
1002
1003 There are also subtle differences between the setting of simple scalar
1004 variables (or individual entries within a table), and the creation of a new
1005 row within a table. This will therefore be considered separately.
1006
1007 With these caveats, and a healthy dose of caution, let us proceed. Note that
1008 the UCD-SNMP development team can accept no responsibility for any damage or
1009 loss resulting from either following or ignoring the information presented
1010 here. You coded it - you fix it!
1011
1012 Write routine
1013 -------------
1014
1015 The heart of SET handling is the write_method parameter from the variable
1016 handling routine. This is a pointer to the relevant routine for setting the
1017 variable in question. Mib2c will generate one such routine for each setable
1018 variable. This routine should be declared using the template
1019
1020         int
1021         write_variable(
1022            int      action,
1023            u_char   *var_val,
1024            u_char   var_val_type,
1025            int      var_val_len,
1026            u_char   *statP,
1027            oid      *name,
1028            int      name_len );
1029
1030 Most of these parameters are fairly self explanatory:
1031 The last two hold the OID to be set, just as was passed to the main variable
1032 routine.
1033
1034 The second, third and fourth parameters provide information about the new
1035 desired value, both the type, value and length. This is very similar to the
1036 way that results are returned from the main variable routine.
1037
1038 The return value of the routine is simply an indication of whether the
1039 current stage of the SET was successful or not. We'll come back to this in a
1040 minute. Note that it is the responsibility of this routine to check that the
1041 OID and value provided are appropriate for the variable being implemented.
1042 This includes (but is not limited to) checking:
1043
1044    * the OID is recognised as one this routine can handle
1045      (this should be true if the routine only handles the one variable, and
1046      there are no errors in the main variable routine or driving code, but
1047      it does no harm to check).
1048    * the value requested is the correct type expected for this OID
1049    * the value requested is appropriate for this OID
1050      (within particular ranges, suitable length, etc, etc)
1051
1052 There are two parameters remaining to be considered.
1053
1054 The fifth parameter, statP, is the value that would be returned from a GET
1055 request on this particular variable. It could be used to check that the
1056 requested new value is consistent with the current state, but its main use
1057 is to denote that a new table row is being created.
1058 In most cases (particularly when dealing with scalar values or single elements
1059 of tables), you can normally simply ignore this parameter.
1060
1061 Actions
1062 -------
1063
1064 The final parameter to consider is the first one - action. To understand
1065 this, it's necessary to know a bit about how SETs are implemented.
1066 The design of SNMP calls for all variables in a SET request to be done "as
1067 if simultaneously" - i.e. they should all succeed or all fail. However, in
1068 practise, the variables are handled in succession. Thus, if one fails, it
1069 must be possible to "undo" any changes made to the other variables in the
1070 request.
1071 This is a well understood requirement in the database world, and is usually
1072 implemented using a "multi-stage commit". This is certainly the mechanism
1073 expected within the SNMP community (and has been made explicit in the work
1074 of the AgentX extensibility group). In other words, the routine to handle
1075 setting a variable will be called more than once, and the routine must be
1076 able to perform the appropriate actions depending on how far through the
1077 process we currently are. This is determined by the value of the action
1078 parameter.
1079
1080 This is implemented using three basic phases:
1081
1082 RESERVE is used to check the syntax of all the variables provided, that the
1083 values being set are sensible and consistent, and to allocate any resources
1084 required for performing the SET. After this stage, the expectation is that
1085 the set ought to succeed, though this is not guaranteed.
1086 (In fact, with the UCD agent, this is done in two passes - RESERVE1, and
1087 RESERVE2, to allow for dependancies between variables).
1088
1089 If any of these calls fail (in either pass) the write routines are called
1090 again with the FREE action, to release any resources that have been
1091 allocated. The agent will then return a failure response to the requesting
1092 application.
1093
1094 Assuming that the RESERVE phase was successful, the next stage is indicated
1095 by the action value ACTION. This is used to actually implement the set
1096 operation. However, this must either be done into temporary (persistent)
1097 storage, or the previous value stored similarly, in case any of the
1098 subsequent ACTION calls fail.
1099  This can be seen in the example module, where both write routines have
1100 static 'old' variables, to hold the previous value of the relevant object.
1101
1102 If the ACTION phase does fail (for example due to an apparently valid, but
1103 unacceptable value, or an unforeseen problem), then the list of write
1104 routines are called again, with the UNDO action. This requires the routine
1105 to reset the value that was changed to its previous value (assuming it was
1106 actually changed), and then to release any resources that had been
1107 allocated. As with the FREE phase, the agent will then return an indication
1108 of the error to the requesting application.
1109
1110 Only once the ACTION phase has completed successfully, can the final COMMIT
1111 phase be run. This is used to complete any writes that were done into
1112 temporary storage, and then release any allocated resources. Note that all
1113 the code in this phase should be "safe" code that cannot possibly fail (cue
1114 hysterical laughter). The whole intent of the ACTION/COMMIT division is that
1115 all of the fallible code should be done in the ACTION phase, so that it can
1116 be backed out if necessary.
1117
1118 Table row creation
1119 ------------------
1120
1121 What about creating new rows in a table, I hear you ask. Good Question.
1122 This case can often be detected by the fact that a GET request would have
1123 failed, and hence the fifth parameter, statP, will be null.  This contrasts
1124 with changing the values of an element of an existing row, when the statP
1125 parameter would hold the previous value.
1126
1127 The details of precisely how to create a new row will clearly depend on the
1128 underlying format of the table.  However, one implementation strategy would
1129 be as follows:
1130
1131   *  The first column object to be SET would return a null value from the
1132         var_name routine.  This null statP parameter would be the signal
1133         to create a new temporary instance of the underlying data structure,
1134         filled with dummy values.
1135   *  Subsequent column objects would return pointers to the appropriate
1136         field of this new data structure from the var_name routine,
1137         which would then be filled in by the write routine.
1138   *  Once all the necessary fields had been SET, the completed temporary
1139         instance could be moved into the "standard" structure (or copied,
1140         or otherwise used to set things up appropriately).
1141
1142 However, this is purely a theoretical strategy, and has not been tried
1143 by the author.  No guarantees are given as to whether this would actually
1144 work.  There are also questions regarding how to handle incomplete
1145 or overlapping SET requests.
1146 Anyone who has experience of doing this, please get in touch!
1147
1148   ------------------------------------------------------------------------
1149 And that's it. Congratulations for getting this far. If you understand
1150 everything that's been said, then you now know as much as the rest of us
1151 about the inner workings of the UCD-SNMP agent. (Well, very nearly).
1152 All that remains is to try putting this into practise. Good luck!
1153
1154 And if you've found this helpful, gifts of money, chocolate, alcohol, and
1155 above all feedback, would be most appreciated :-)
1156
1157   ------------------------------------------------------------------------
1158 Copyright 1999, 2000 - D.T.Shield.
1159 Not to be distributed without the explicit permission of the author.