| @open -@ |
| mib2c has multiple configuration files depending on the type of |
| code you need to write. You must pick one depending on your need. |
| |
| You requested mib2c to be run on the following part of the MIB tree: |
| OID: $name |
| numeric translation: $name.objectID |
| @eval $numS = count_scalars@ |
| number of scalars within: $numS |
| @eval $numT = count_tables@ |
| number of tables within: $numT |
| @eval $numN = count_notifications@ |
| number of notifications within: $numN |
| |
| First, do you want to generate code that is compatible with the |
| ucd-snmp 4.X line of code, or code for the newer Net-SNMP 5.X code |
| base (which provides a much greater choice of APIs to pick from): |
| |
| 1) ucd-snmp style code |
| 2) Net-SNMP style code |
| |
| @prompt $ans Select your choice : @ |
| @if $ans == 1@ |
| ********************************************************************** |
| GENERATING CODE FOR THE 4.X LINE OF CODE (THE OLDER API) |
| ********************************************************************** |
| |
| using the mib2c.old-api.conf configuration file to generate your code. |
| @run mib2c.old-api.conf@ |
| |
| @elsif $ans != 2@ |
| Invalid answer. |
| @else@ |
| @if $numS > 0 && $numT > 0@ |
| ********************************************************************** |
| MIXED MIB TEMPLATE |
| ********************************************************************** |
| The portion of the MIB tree that you have selected contains both |
| scalar objects and MIB tables. The automatically generated Net-SNMP |
| style code cannot handle both of these simultaneously (though you |
| could generate the two files separately, and then merge the two). |
| |
| Which code do you want to generate: |
| |
| 1) Scalar objects |
| 2) MIB tables |
| |
| @prompt $ans Select your choice : @ |
| @if $ans == 1 @ |
| @eval $numT = 0@ |
| @elsif $ans == 2@ |
| @eval $numS = 0@ |
| @else@ |
| Invalid answer |
| @eval $numS = 0@ |
| @eval $numT = 0@ |
| @end@ |
| @end@ |
| @if $numS > 0@ |
| |
| ********************************************************************** |
| GENERATING CODE FOR SCALAR OBJECTS: |
| ********************************************************************** |
| |
| It looks like you have some scalars in the mib you requested, so I |
| will now generate code for them if you wish. You have two choices |
| for scalar API styles currently. Pick between them, or choose not |
| to generate any code for the scalars: |
| |
| 1) If you're writing code for some generic scalars |
| (by hand use: "mib2c -c mib2c.scalar.conf $name") |
| |
| 2) If you want to magically "tie" integer variables to integer |
| scalars |
| (by hand use: "mib2c -c mib2c.int_watch.conf $name") |
| |
| 3) Don't generate any code for the scalars |
| |
| @prompt $ans Select your choice: @ |
| @if $ans == 1@ |
| using the mib2c.scalar.conf configuration file to generate your code. |
| @run mib2c.scalar.conf@ |
| @elsif $ans == 2@ |
| using the mib2c.int_watch.conf configuration file to generate your code. |
| @run mib2c.int_watch.conf@ |
| @elsif $ans != 3@ |
| WARNING: Unknown response. Skipping code generation for scalars. |
| @end@ |
| @end@ # scalars |
| |
| @if $numT > 0@ |
| ********************************************************************** |
| GENERATING CODE FOR TABLES: |
| ********************************************************************** |
| |
| The Net-SNMP agent API is extremely extensive and, in fact, lets |
| each programmer write agent code according to the style that works |
| best for them based on their experience and their preference. We're |
| going to ask you a serious of questions that will help mib2c |
| generate code that best suits *your* needs, as the programmer that |
| will be responsible for taking the code and further refining it. If |
| you don't like how the results look, you are always welcome to |
| re-run mib2c and select a different set of options. |
| |
| There are essentially two tasks involved in processing requests |
| for OIDs within a MIB table - firstly identifying the relevant row |
| of the table for a given request, and then returning (or updating) |
| the appropriate column value within that row. Many MIB tables model |
| the state of some external system (the kernel, a device, processes, |
| etc), and the MIB implementation module (the code we're about to |
| produce a template for) acts as an interface between this underlying |
| system and the SNMP side. Other tables hold data internally that is |
| only available within the agent itself, or at least the master copy |
| of the data is held within the agent. |
| |
| There are a number of different code templates that can be used to |
| implement MIB tables, using various approaches to these two tasks. |
| |
| There are three basic approaches to identifying the relevant row: |
| |
| 1) Pass the request through to the table-specific code, and |
| identify the requested row there (for both GET and GETNEXT |
| requests). This is typically the most efficient way to get |
| up-to-date information, but relies on suitable |
| (programmer-provided) code within the MIB handler. |
| Most importantly, you should be an expert to use this choice. |
| |
| This will produce code based on the table_dataset handler. |
| |
| 2) Have table-specific code to provide information about which |
| rows exist in the table (by iterating through them in turn), |
| but utilise standard helper code to select the appropriate |
| row for a given request. This is particularly suitable for |
| tables where the data is naturally stored in a "random" order |
| (or differently to the MIB table index), or where rows are |
| frequently added to or removed from the table. |
| |
| However searching for the requested row is not very efficient, |
| and performance can be slow - particularly for large tables with |
| many rows. |
| |
| 3) Hold a locally cached copy of the contents of the table (or at |
| least a cache of which rows are valid), and utilise standard |
| helper code to select the appropriate row. This is |
| significantly faster than the iterator-based approach, but |
| cached data is inevitably slightly "stale" with respect to the |
| data from the underlying system being managed. This approach, |
| since it relies on caching of data, is also results in a larger |
| memory footprint. It is less appropriate for tables where rows |
| are frequently added or removed externally to the agent (i.e., |
| not via SNMP requests). |
| |
| This approach can also be used where _all_ use of the table is |
| via SNMP, and there is no external "underlying system". In |
| this case, the local cache is the canonical version of the |
| table. |
| |
| 4) Do not generate code for the tables. |
| |
| @prompt $ans1 Select the option that best fits your requirements: @ |
| |
| @if ($ans1 == 2) || ($ans1 == 3)@ |
| |
| Having identified the appropriate row for a given request, there are |
| three basic styles of code for returning (or updating) the requested |
| column value from within this row: |
| |
| 1) A single handler routine, which contains all the code needed to |
| handle GET and SET requests for each of the column objects. |
| |
| @if $ans1 == 2@ |
| The code typically looks like a single function with a large 'case' |
| statement covering each of the columns. |
| |
| This will produce code based on the 'iterator' hepler. |
| @end@ |
| |
| 2) A set of individual routines, each of which is concerned |
| with a particular aspect of processing the request. |
| @if $ans1 == 2 @ |
| Each column object within the table has one routine for |
| retrieving the current value, and another for setting a new one. |
| |
| This will produce code based on the 'iterate_access' hepler. |
| @else@ |
| There is one routine for reporting values for GET requests, |
| and one routine for each stage of processing a SET request. |
| @end@ |
| |
| 3) A (different) set of individual routines, each of which is |
| smaller and more tightly focused than the code generated by |
| style 2. The aim here is to reduce the amount of SNMP specific |
| knowledge required to implement a module, and hide much of the |
| SNMP terminology and processing within standard generated code |
| (which can simply be used sight unseen). |
| @if $name !~ /Table$/i@ |
| However this style of code can only be generated when mib2c |
| is run on an individual MIB table. To use this approach, you |
| will need to re-invoke mib2c with the name of a single MIB table. |
| @end@ |
| |
| This will produce code based on the 'mfd' hepler ('MIB for Dummies'). |
| |
| 4) Do not generate code for the tables. |
| |
| (In all cases, GETNEXT requests are automatically converted |
| into the equivalent GET request, so the MIB specific code |
| need only be concerned with GET and SET requests.). |
| |
| @prompt $ans2 Select the code style you wish to use: @ |
| @end@ |
| |
| @eval $template = NONE@ |
| @if $ans1 == 1@ |
| @eval $template = "create-dataset"@ |
| |
| @elsif $ans1 == 2@ |
| @if $ans2 == 1@ |
| @eval $template = iterate@ |
| @elsif $ans2 == 2@ |
| @eval $template = iterate_access@ |
| @elsif $ans2 == 3@ |
| @eval $template = mfd@ |
| @elsif $ans2 != 4@ |
| WARNING: Unknown response. Skipping code generation for tables. |
| @end@ |
| |
| @elsif $ans1 == 3@ |
| @if $ans2 == 1@ |
| There are actually two alternative templates that use this |
| style of code - differing primarily in the data structure |
| used for representing a row of the table |
| |
| 1) The first is well suited for situations where there is a |
| natural existing data structure, or where the contents of |
| the table may need to be interpreted for some additional |
| purpose, other than simply implementing the table in SNMP. |
| |
| This will produce code based on the 'table_data' hepler. |
| |
| 2) The second is slightly more efficient, but introduces some |
| minor constraints on the form of the per-row data structure. |
| |
| This will produce code based on the 'container' hepler. |
| |
| @prompt $ans3 Select the row representation you wish to use: @ |
| |
| @if $ans3 == 1@ |
| @eval $template = table_data@ |
| @elsif $ans3 == 2@ |
| @eval $template = container@ |
| @else@ |
| WARNING: Unknown response. Skipping code generation for tables. |
| @end@ |
| @elsif $ans2 == 2@ |
| @eval $template = "array-user"@ |
| @elsif $ans2 == 3@ |
| @eval $template = mfd@ |
| @else@ |
| WARNING: Unknown response. Skipping code generation for tables. |
| @end@ |
| |
| @elsif $ans1 != 4@ |
| WARNING: Unknown response. Skipping code generation for tables. |
| @end@ |
| |
| @if $template ne NONE@ |
| The same template code can be generated using |
| mib2c -c mib2c.${template}.conf $name |
| @run mib2c.${template}.conf@ |
| @end@ |
| @end@ # tables |
| |
| @if $numN > 0@ |
| ********************************************************************** |
| GENERATING CODE FOR NOTIFICATIONS: |
| ********************************************************************** |
| |
| Would you like to generate code for sending notifications from within |
| the agent? |
| |
| @prompt $ans "y" or "n": @ |
| @if ("$ans" eq "y") or ("$ans" eq "yes")@ |
| using mib2c.notify.conf to generate code for sending notifications |
| @run mib2c.notify.conf@ |
| @end@ |
| |
| # GENERATING HEADER FILE DEFINITIONS |
| # |
| # To generate just a header with a define for each column number in |
| # your table: |
| # |
| # mib2c -c mib2c.column_defines.conf ${name} |
| # |
| # To generate just a header with a define for each enum for any |
| # column containing enums: |
| # |
| # mib2c -c mib2c.column_enums.conf ${name} |
| |
| @end@ # notifications |
| @end@ # new style code |
| |
| ********************************************************************** |
| * NOTE WELL: The code generated by mib2c is only a template. *YOU* * |
| * must fill in the code before it'll work most of the time. In many * |
| * cases, spots that MUST be edited within the files are marked with * |
| * /* XXX */ or /* TODO */ comments. * |
| ********************************************************************** |