Problem with mib2c, array-user development effort
"Rob Walter" <[email protected]>
| Newsgroups | gmane.network.net-snmp.user |
|---|---|
| Message-ID | <014b01c79174$997e65e0$d700a8c0@ASSETTWALTER> |
Hello.
I'm attempting to understand the basics of using mib2c to
generate sub-agent code for MIB tables. I have reached a point
where I need to request help.
Prior to this I have had success developing simple, though high
volume, private MIBs employing scalars; first with an integer only
experiment using "mib2c.int_watch.conf" then a combined integer
and string example using "mib2c.scalar.conf".
The table experiment involves a simple table of integers, conceptually
identical to "int my_array[256]". After some hacking I have gotten the
subagent to run and attach to the agent. And I can generate some
obvious activity. Unfortunately, my knowledge of NetSnmp debug
technique is quite weak; you may wish to suggest some readings (web or
otherwise) that I should pursue.
The following items comprise the pieces of the experiment:
(Each can be found, successively, by searching on "***PIECE #")
1) the MIB and its snmptranslate
I have very spotty knowledge of MIB writing; e.g. I was most surprised
to find that mib2c ignored my table until I renamed it so as to have it
end with the character string "Table".
2) the 3 files generated by
mib2c -c mib2c.array-user.conf test4Master
mib2c -c subagent.m2c test4Master
Note: I have attempted to make my modifications evident by
use of the tag "RJW"
3) the Makefile (adapted from a NetSnmp tutorial Makefile)
4) the subagent execution and snmp tool results against it.
This is the simplest possible array example I could dream up.
If we can get it working, I'd be delighted to donate it to your
group for use by other first-timers.
If you are willing to look at this, I'd appreciate it. If you
need more/different info (e.g. according to "snmpd -v"
we are using: NET-SNMP version: 5.3.0.1), just let me know.
***PIECE #1: the MIB and its snmptranslate
------------------------------------------
1
----------------------------------------------------------------------------
----
2 --
--
3 --
--
4 --
--
5 --
--
6 -- Copyright (C) 2006, 2007 ASSETT, Inc.
--
7 -- Copyright (C) 2006, 2007
--
8 -- Copyright (C) 2006, 2007
--
9 --
--
10 -- Proprietary and Confidential
--
11 --
--
12
----------------------------------------------------------------------------
----
13 --
--
14 -- MODULE: TPS MIB Tree Definition
--
15 --
--
16
----------------------------------------------------------------------------
----
17 --
--
18 -- $Header:
/home/cvsroot/sdhs/startup/snmp/NET-SNMP-S80TPS-MIB.txt,v 1.6 2007/02/01
16:42:25 plunkett Exp $
19 --
--
20
----------------------------------------------------------------------------
----
21 --! \file netSnmpS80Tps.cpp
22 --! \brief TPS MIB Tree
23 --!
24 --! \author Robert Walter
25 --! \ingroup startup
26
----------------------------------------------------------------------------
----
27
28 ROB-TEST4-MIB DEFINITIONS ::= BEGIN
29
30 -- MIB objects for managed items specific to S80 TPS cabinet.
31
32 IMPORTS
33 MODULE-IDENTITY, OBJECT-TYPE, Integer32 FROM SNMPv2-SMI
34 SnmpAdminString FROM SNMP-FRAMEWORK-MIB
35 netSnmp FROM NET-SNMP-MIB
36 RowStatus, StorageType FROM SNMPv2-TC
37 InetAddressType, InetAddress FROM INET-ADDRESS-MIB;
38
39 --
40 -- A brief description and update information about this mib.
41 --
42 robTest4 MODULE-IDENTITY
43 LAST-UPDATED "200704300000Z" -- 30 Apr 2007, midnight
44 ORGANIZATION "net-snmp"
45 CONTACT-INFO "postal: R. Walter, ASSETT Inc.
46 11220 Assett Loop
47 Manassas Va 20109
48
49 email: [email protected]"
50
51 DESCRIPTION "Mib for managing Rob's (edna) ~/net-snmp/test3/
specific objects"
52
53 ::= { netSnmp 9996 }
54
55 -- Note 9996 chosen since ../test3/ROB-TEST3-MIB.txt uses 9997 and
is in directory
56 -- search list, will cause conflict.
57
58 --
59 -- top level structure
60 -- Everything prefixed with "test4"
61 --
62
63 test4Master OBJECT IDENTIFIER ::= { robTest4 1 }
64 test4Slave OBJECT IDENTIFIER ::= { robTest4 2 }
65
66 test4MScalar OBJECT IDENTIFIER ::= { test4Master 1 }
67 test4MTbl OBJECT IDENTIFIER ::= { test4Master 2 }
68
69 test4SScalar OBJECT IDENTIFIER ::= { test4Slave 1 }
70 test4STbl OBJECT IDENTIFIER ::= { test4Slave 2 }
71
72 --
73 -- Master branch has 2 scalars, an integer an a string.
74 --
75
76 test4MstInt OBJECT-TYPE
77 SYNTAX Integer32
78 MAX-ACCESS read-write
79 STATUS current
80 DESCRIPTION "To allow verification of master only branch
access."
81 DEFVAL { 7 }
82 ::= { test4MScalar 1 }
83
84 test4MstTable OBJECT-TYPE
85 SYNTAX SEQUENCE OF Test4MstTEntry
86 MAX-ACCESS not-accessible
87 STATUS current
88 DESCRIPTION
89 "This table holds an array of 256 integer values"
90 ::= { test4MTbl 1 }
91
92 test4MstTEntry OBJECT-TYPE
93 SYNTAX Test4MstTEntry
94 MAX-ACCESS not-accessible
95 STATUS current
96 DESCRIPTION
97 "A row of one integer."
98 INDEX { test4MtIndex }
99 ::= {test4MstTable 1 }
100
101 Test4MstTEntry ::= SEQUENCE {
102 test4MtIndex Integer32,
103 test4MtValue Integer32
104 }
105
106 test4MtIndex OBJECT-TYPE
107 SYNTAX Integer32(1..256)
108 MAX-ACCESS not-accessible
109 STATUS current
110 DESCRIPTION
111 "Identifies the integer to be handled."
112 ::= { test4MstTEntry 1 }
113
114 test4MtValue OBJECT-TYPE
115 SYNTAX Integer32
116 MAX-ACCESS read-write
117 STATUS current
118 DESCRIPTION
119 "Hold an integer value."
120 DEFVAL { 0 }
121 ::= { test4MstTEntry 2 }
122
123 --
124 -- Slave branch has 2 scalars, an integer an a string.
125 --
126
127 test4SlvInt OBJECT-TYPE
128 SYNTAX Integer32
129 MAX-ACCESS read-write
130 STATUS current
131 DESCRIPTION "To allow verification of slave only branch access."
132 DEFVAL { 21 }
133 ::= { test4SScalar 1 }
134
135 test4SlvTable OBJECT-TYPE
136 SYNTAX SEQUENCE OF Test4SlvTEntry
137 MAX-ACCESS not-accessible
138 STATUS current
139 DESCRIPTION
140 "This table holds an array of 256 integer values"
141 ::= { test4STbl 1 }
142
143 test4SlvTEntry OBJECT-TYPE
144 SYNTAX Test4SlvTEntry
145 MAX-ACCESS not-accessible
146 STATUS current
147 DESCRIPTION
148 "A row of one integer."
149 INDEX { test4StIndex }
150 ::= {test4SlvTable 1 }
151
152 Test4SlvTEntry ::= SEQUENCE {
153 test4StIndex Integer32,
154 test4StValue Integer32
155 }
156
157 test4StIndex OBJECT-TYPE
158 SYNTAX Integer32(1..256)
159 MAX-ACCESS not-accessible
160 STATUS current
161 DESCRIPTION
162 "Identifies the integer to be handled."
163 ::= { test4SlvTEntry 1 }
164
165 test4STvalue OBJECT-TYPE
166 SYNTAX Integer32
167 MAX-ACCESS read-write
168 STATUS current
169 DESCRIPTION
170 "Hold an integer value."
171 DEFVAL { 0 }
172 ::= { test4SlvTEntry 2 }
173
174 -- END: Don't forget this!
175 END
[Rob edna:~/net-snmp/test4/test-c] $ snmptranslate -Tp -IR robTest4
+--robTest4(9996)
|
+--test4Master(1)
| |
| +--test4MScalar(1)
| | |
| | +-- -RW- Integer32 test4MstInt(1)
| |
| +--test4MTbl(2)
| |
| +--test4MstTable(1)
| |
| +--test4MstTEntry(1)
| | Index: test4MtIndex
| |
| +-- ---- Integer32 test4MtIndex(1)
| | Range: 1..256
| +-- -RW- Integer32 test4MtValue(2)
|
+--test4Slave(2)
|
+--test4SScalar(1)
| |
| +-- -RW- Integer32 test4SlvInt(1)
|
+--test4STbl(2)
|
+--test4SlvTable(1)
|
+--test4SlvTEntry(1)
| Index: test4StIndex
|
+-- ---- Integer32 test4StIndex(1)
| Range: 1..256
+-- -RW- Integer32 test4STvalue(2)
[Rob edna:~/net-snmp/test4/test-c] $
***PIECE #2: the 3 files generated
----------------------------------
We have 3 files, the beginning of each tagged with its name enclosed
within
<< >>:
1) test4Master_subagent.c (218 lines)
2) test4MstTable.h (121 lines)
3) test4MstTable.c (870 lines - sorry about the volume)
<<test4Master_subagent.c>>
--------------------------
1 /*
2 * Note: this file originally auto-generated by mbi2c using
3 * version : 1.7 $ of : subagent.m2c,v $
4 */
5 /*
6 * standard Net-SNMP includes
7 */
8 #include <net-snmp/net-snmp-config.h>
9 #include <net-snmp/net-snmp-includes.h>
10 #include <net-snmp/agent/net-snmp-agent-includes.h>
11
12 /*
13 * include our parent header
14 */
15 // 05/04/2007 hmmm, mib2c gen'd inappropriate include?
16 //#include "test4Master.h"
17 #include "test4MstTable.h"
18
19 // 05/04/07 This always seems to be needed.
20 void netsnmp_enable_subagent(void);
21
22 #include <signal.h>
23
24 static int keep_running;
25
26 static RETSIGTYPE
27 stop_server(int a)
28 {
29 keep_running = 0;
30 }
31
32 static void
33 usage(void)
34 {
35 printf
36 ("usage: test4Master [-D<tokens>] [-f] [-L] [-M] [-H]
[LISTENING ADDRESSES]\n"
37 "\t-f Do not fork() from the calling shell.\n"
38 "\t-DTOKEN[,TOKEN,...]\n"
39 "\t\tTurn on debugging output for the given TOKEN(s).\n"
40 "\t\tWithout any tokens specified, it defaults to
printing\n"
41 "\t\tall the tokens (which is equivalent to the keyword
'ALL').\n"
42 "\t\tYou might want to try ALL for extremely verbose
output.\n"
43 "\t\tNote: You can't put a space between the -D and the
TOKENs.\n"
44 "\t-H\tDisplay a list of configuration file directives\n"
45 "\t\tunderstood by the agent and then exit.\n"
46 "\t-M\tRun as a normal SNMP Agent instead of an AgentX
sub-agent.\n"
47 "\t-x ADDRESS\tconnect to master agent at ADDRESS (default
/var/agentx/master).\n"
48 "\t-L\tDo not open a log file; print all messages to
stderr.\n");
49 exit(0);
50 }
51
52 int
53 main(int argc, char **argv)
54 {
55 int agentx_subagent = 1; /* change this if
you want to be a SNMP master agent */
56 /*
57 * Defs for arg-handling code: handles setting of policy-related
variables
58 */
59 int ch;
60 extern char *optarg;
61 int dont_fork = 0, use_syslog = 0;
62 char *agentx_socket = NULL;
63
64 while ((ch = getopt(argc, argv, "D:fHLMx:")) != EOF)
65 switch (ch) {
66 case 'D':
67 debug_register_tokens(optarg);
68 snmp_set_do_debugging(1);
69 break;
70 case 'f':
71 dont_fork = 1;
72 break;
73 case 'H':
74
75 // 05/07/07 I should never hit this, so ignore.
76 printf ("\n H argv - should not see this!\n");
77 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
78 NETSNMP_DS_AGENT_NO_ROOT_ACCESS,
1);
79 init_agent("test4Master"); /* register our .conf
handlers */
80
81 // init_test4Master();
82 init_test4MstTable(); // replace original call to
"init_test4Master()"
83
84 init_snmp("test4Master");
85 fprintf(stderr, "Configuration directives
understood:\n");
86 read_config_print_usage(" ");
87 exit(0);
88 case 'M':
89 agentx_subagent = 0;
90 break;
91 case 'L':
92 use_syslog = 0; /* use stderr */
93 break;
94 case 'x':
95 agentx_socket = optarg;
96 break;
97 default:
98 fprintf(stderr, "unknown option %c\n", ch);
99 usage();
100 }
101
102 if (optind < argc) {
103 int i;
104 /*
105 * There are optional transport addresses on the command
line.
106 */
107 DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind,
argc));
108 for (i = optind; i < argc; i++) {
109 char *c, *astring;
110 if ((c =
netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
111 NETSNMP_DS_AGENT_PORTS)))
{
112 astring = malloc(strlen(c) + 2 + strlen(argv[i]));
113 if (astring == NULL) {
114 fprintf(stderr, "malloc failure processing
argv[%d]\n",
115 i);
116 exit(1);
117 }
118 sprintf(astring, "%s,%s", c, argv[i]);
119 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
120 NETSNMP_DS_AGENT_PORTS,
astring);
121 SNMP_FREE(astring);
122 } else {
123 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
124 NETSNMP_DS_AGENT_PORTS,
argv[i]);
125 }
126 }
127 DEBUGMSGTL(("snmpd/main", "port spec: %s\n",
128 netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
129 NETSNMP_DS_AGENT_PORTS)));
130 }
131
132 /*
133 * we're an agentx subagent?
134 */
135 if (agentx_subagent) {
136 /*
137 * make us a agentx client.
138 */
139 netsnmp_enable_subagent();
140 if (NULL != agentx_socket)
141 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
142 NETSNMP_DS_AGENT_X_SOCKET,
143 agentx_socket);
144 }
145
146 snmp_disable_log();
147 if (use_syslog)
148 snmp_enable_calllog();
149 else
150 snmp_enable_stderrlog();
151
152 /*
153 * daemonize
154 */
155 if (!dont_fork) {
156 int rc = netsnmp_daemonize(1, !use_syslog);
157 if (rc)
158 exit(-1);
159 }
160
161 /*
162 * initialize tcp/ip if necessary
163 */
164 SOCK_STARTUP;
165
166 /*
167 * initialize the agent library
168 */
169 // init_agent("test4Master");
170 init_agent("test4MstTable"); // 05/07/07 RJW wild guess.
171
172 /*
173 * init test4Master mib code
174 */
175 // init_test4Master();
176 init_test4MstTable(); // replace original call to
"init_test4Master()"
177
178 /*
179 * read test4Master.conf files.
180 */
181 // init_snmp("test4Master");
182 init_snmp("test4MstTable"); // 05/07/07 RJW wild guess.
183
184 /*
185 * If we're going to be a snmp master agent, initial the ports
186 */
187 if (!agentx_subagent)
188 init_master_agent(); /* open the port to listen on
(defaults to udp:161) */
189
190 /*
191 * In case we recevie a request to stop (kill -TERM or kill
-INT)
192 */
193 keep_running = 1;
194 signal(SIGTERM, stop_server);
195 signal(SIGINT, stop_server);
196
197 /*
198 * you're main loop here...
199 */
200 while (keep_running) {
201 /*
202 * if you use select(), see snmp_select_info() in
snmp_api(3)
203 */
204 /*
205 * --- OR ---
206 */
207 agent_check_and_process(1); /* 0 == don't block */
208 }
209
210 /*
211 * at shutdown time
212 */
213 // snmp_shutdown("test4Master");
214 snmp_shutdown("test4MstTable"); // 05/07/07 RJW wild guess.
215
216 SOCK_CLEANUP;
217 exit(0);
218 }
<<test4MstTable.h>>
-------------------
1
2
3 /*
4 * Note: this file originally auto-generated by mib2c using
5 * : mib2c.array-user.conf,v 5.26 2005/04/26 22:13:28 rstory
Exp $
6 *
7 * $Id:$
8 *
9 * Yes, there is lots of code here that you might not use. But it is
much
10 * easier to remove code than to add it!
11 */
12 #ifndef TEST4MSTTABLE_H
13 #define TEST4MSTTABLE_H
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19
20 #include <net-snmp/net-snmp-config.h>
21 #include <net-snmp/library/container.h>
22 #include <net-snmp/agent/table_array.h>
23
24 /** Index test4MtIndex is internal */
25
26 typedef struct test4MstTable_context_s {
27 netsnmp_index index;
28 /** THIS MUST BE FIRST!!! */
29
30 /*************************************************************
31 * You can store data internally in this structure.
32 *
33 * TODO: You will probably have to fix a few types here...
34 */
35 /** INTEGER32 = ASN_INTEGER */
36 long test4MtIndex;
37
38 /** INTEGER32 = ASN_INTEGER */
39 long test4MtValue;
40
41
42 /*
43 * OR
44 *
45 * Keep a pointer to your data
46 */
47 void *data;
48
49 /*
50 *add anything else you want here
51 */
52
53 } test4MstTable_context;
54
55 /*************************************************************
56 * function declarations
57 */
58 void init_test4MstTable(void);
59 void initialize_table_test4MstTable(void);
60 const test4MstTable_context
*test4MstTable_get_by_idx(netsnmp_index *);
61 const test4MstTable_context
*test4MstTable_get_by_idx_rs(netsnmp_index
62 *,
63 int
64
row_status);
65 int test4MstTable_get_value(netsnmp_request_info *,
66 netsnmp_index *,
67
netsnmp_table_request_info *);
68
69
70 /*************************************************************
71 * oid declarations
72 */
73 extern oid test4MstTable_oid[];
74 extern size_t test4MstTable_oid_len;
75
76 #define test4MstTable_TABLE_OID 1,3,6,1,4,1,8072,9996,1,2,1
77
78 /*************************************************************
79 * column number definitions for table test4MstTable
80 */
81 #define COLUMN_TEST4MTINDEX 1
82 #define COLUMN_TEST4MTVALUE 2
83 #define test4MstTable_COL_MIN 2
84 #define test4MstTable_COL_MAX 2
85
86 /*
87 * comment out the following line if you don't want a custom
sort
88 */
89 // 05/07/2007 RJW no custom sort code.
90 //#define test4MstTable_CUSTOM_SORT
91
92 int
test4MstTable_extract_index(test4MstTable_context *
93 ctx, netsnmp_index *
hdr);
94
95 void test4MstTable_set_reserve1(netsnmp_request_group
*);
96 void test4MstTable_set_reserve2(netsnmp_request_group
*);
97 void test4MstTable_set_action(netsnmp_request_group
*);
98 void test4MstTable_set_commit(netsnmp_request_group
*);
99 void test4MstTable_set_free(netsnmp_request_group *);
100 void test4MstTable_set_undo(netsnmp_request_group *);
101
102 test4MstTable_context
103 *test4MstTable_duplicate_row(test4MstTable_context *);
104 netsnmp_index *test4MstTable_delete_row(test4MstTable_context
*);
105
106 int test4MstTable_can_delete(test4MstTable_context *
107 undo_ctx,
108 test4MstTable_context *
109 row_ctx,
110 netsnmp_request_group *
rg);
111
112
113
114 #ifdef test4MstTable_CUSTOM_SORT
115 test4MstTable_context *test4MstTable_get(const char *name, int
len);
116 #endif
117
118 #ifdef __cplusplus
119 }
120 #endif
121 #endif /** TEST4MSTTABLE_H */
<<test4MstTable.c >>
--------------------
1 /*
2 * Note: this file originally auto-generated by mib2c using
3 * : mib2c.array-user.conf,v 5.26 2005/04/26 22:13:28 rstory
Exp $
4 *
5 * $Id:$
6 *
7 *
8 * For help understanding NET-SNMP in general, please check the
9 * documentation and FAQ at:
10 *
11 * http://www.net-snmp.org/
12 *
13 *
14 * For help understanding this code, the agent and how it processes
15 * requests, please check the following references.
16 *
17 * http://www.net-snmp.org/tutorial-5/
18 *
19 *
20 * You can also join the #net-snmp channel on irc.freenode.net
21 * and ask for help there.
22 *
23 *
24 * And if all else fails, send a detailed message to the developers
25 * describing the problem you are having to:
26 *
27 * [email protected]
28 *
29 *
30 * Yes, there is lots of code here that you might not use. But it is
much
31 * easier to remove code than to add it!
32 */
33 #include <net-snmp/net-snmp-config.h>
34 #include <net-snmp/net-snmp-includes.h>
35 #include <net-snmp/agent/net-snmp-agent-includes.h>
36
37 #include <net-snmp/library/snmp_assert.h>
38
39 #include "test4MstTable.h"
40
41 static netsnmp_handler_registration *my_handler = NULL;
42 static netsnmp_table_array_callbacks cb;
43
44 oid test4MstTable_oid[] = { test4MstTable_TABLE_OID };
45 size_t test4MstTable_oid_len =
OID_LENGTH(test4MstTable_oid);
46
47 // 05/07/07 RJW: guessing that these are effectively row items, and
48 // I need 256 of them. Good luck.
49 static test4MstTable_context mst4_tbl_array[256];
50
51
52 #ifdef test4MstTable_CUSTOM_SORT
53 /************************************************************
54 * keep binary tree to find context by name
55 */
56 static int test4MstTable_cmp(const void *lhs, const void *rhs);
57
58 /************************************************************
59 * compare two context pointers here. Return -1 if lhs < rhs,
60 * 0 if lhs == rhs, and 1 if lhs > rhs.
61 */
62 static int
63 test4MstTable_cmp(const void *lhs, const void *rhs)
64 {
65 test4MstTable_context *context_l = (test4MstTable_context *)
lhs;
66 test4MstTable_context *context_r = (test4MstTable_context *)
rhs;
67
68 // RJW: diagnostic
69 printf ("\nEntering test4MstTable_cmp().\n");
70
71 /*
72 * check primary key, then secondary. Add your own code if
73 * there are more than 2 keys
74 */
75 int rc;
76
77 /*
78 * TODO: implement compare. Remove this ifdef code and
79 * add your own code here.
80 */
81 #ifdef TABLE_CONTAINER_TODO
82 snmp_log(LOG_ERR,
83 "test4MstTable_compare not implemented! Container order
undefined\n");
84 return 0;
85 #endif
86
87 /*
88 * EXAMPLE (assuming you want to sort on a name):
89 *
90 * rc = strcmp( context_l->xxName, context_r->xxName );
91 *
92 * if(rc)
93 * return rc;
94 *
95 * TODO: fix secondary keys (or delete if there are none)
96 *
97 * if(context_l->yy < context_r->yy)
98 * return -1;
99 *
100 * return (context_l->yy == context_r->yy) ? 0 : 1;
101 */
102 }
103
104 /************************************************************
105 * search tree
106 */
107 /** TODO: set additional indexes as parameters */
108 test4MstTable_context *
109 test4MstTable_get(const char *name, int len)
110 {
111 test4MstTable_context tmp;
112
113 // RJW: Diagnostic
114 printf ("\nEntering test4MstTable_get(), should never see
this.\n");
115
116 /** we should have a custom container */
117 netsnmp_assert(cb.container->next != NULL);
118
119 /*
120 * TODO: implement compare. Remove this ifdef code and
121 * add your own code here.
122 */
123 #ifdef TABLE_CONTAINER_TODO
124 snmp_log(LOG_ERR, "test4MstTable_get not implemented!\n");
125 return NULL;
126 #endif
127
128 /*
129 * EXAMPLE:
130 *
131 * if(len > sizeof(tmp.xxName))
132 * return NULL;
133 *
134 * strncpy( tmp.xxName, name, sizeof(tmp.xxName) );
135 * tmp.xxName_len = len;
136 *
137 * return CONTAINER_FIND(cb.container->next, &tmp);
138 */
139 }
140 #endif
141
142
143 /************************************************************
144 * Initializes the test4MstTable module
145 */
146 void
147 init_test4MstTable(void)
148 {
149 // RJW: debug stuff, recall this copied from the netsnmp library
150 // container_binary_array.c
151 typedef struct binary_array_table_s {
152 size_t max_size; /* Size of the current
data table */
153 size_t count; /* Index of the next free
entry */
154 u_int flags; /* flags */
155 int dirty;
156 int data_size; /* Size of an individual
entry */
157 void **data; /* The table itself */
158 } binary_array_table;
159
160 // 05/07/07 RJW: will need this below
161 test4MstTable_context * new_row;
162 int i;
163 oid my_oid[4];
164
165 // RJW: debug support
166 binary_array_table *t;
167
168 initialize_table_test4MstTable();
169
170 /*
171 * TODO: perform any startup stuff here, such as
172 * populating the table with initial data.
173 *
174 * test4MstTable_context * new_row = create_row(index);
175 * CONTAINER_INSERT(cb.container,new_row);
176 */
177
178 // 05/07/07 RJW let's try to set the offending flag. Wonder what
this
179 // "duplicate stuff" is all about...
180 t = (binary_array_table*)((cb.container)->container_data);
181 t->flags |= CONTAINER_KEY_ALLOW_DUPLICATES;
182
183 // 05/07/07 RJW: well, test is for 256 table rows of one integer
each
184 for (i=1; i<257; i++)
185 {
186 // 05/04/07 this "new_row = create_row(i)" is somewhat
misleading, I need
187 // to implement it in fact, using mst4_tbl_array[256]
as a first
188 // guess since I thought mallocs were bothersome.
189 my_oid[0] = i;
190 mst4_tbl_array[i-1].index.oids = my_oid;
191 mst4_tbl_array[i-1].index.len = 1;
192 mst4_tbl_array[i-1].test4MtIndex = i;
193 mst4_tbl_array[i-1].test4MtValue = i; // possible verify init
val, tho recall mib says 0
194 new_row = &mst4_tbl_array[i-1];
195 CONTAINER_INSERT(cb.container,new_row);
196 }
197
198 }
199
200 /************************************************************
201 * the *_row_copy routine
202 */
203 static int
204 test4MstTable_row_copy(test4MstTable_context * dst,
205 test4MstTable_context * src)
206 {
207
208 // 05/07/07 RJW investigatory.
209 printf ("\n Enter test4MstTable_row_copy()\n");
210
211 if (!dst || !src)
212 return 1;
213
214 /*
215 * copy index, if provided
216 */
217 if (dst->index.oids)
218 free(dst->index.oids);
219 if (snmp_clone_mem((void *) &dst->index.oids, src->index.oids,
220 src->index.len * sizeof(oid))) {
221 dst->index.oids = NULL;
222 return 1;
223 }
224 dst->index.len = src->index.len;
225
226
227 /*
228 * copy components into the context structure
229 */
230 dst->test4MtIndex = src->test4MtIndex;
231
232 dst->test4MtValue = src->test4MtValue;
233
234 // 05/07/07 RJW investigatory.
235 printf ("\n Clean exit test4MstTable_row_copy()\n");
236
237 return 0;
238 }
239
240 /**
241 * the *_extract_index routine
242 *
243 * This routine is called when a set request is received for an
index
244 * that was not found in the table container. Here, we parse the oid
245 * in the the individual index components and copy those indexes to
the
246 * context. Then we make sure the indexes for the new row are valid.
247 */
248 int
249 test4MstTable_extract_index(test4MstTable_context * ctx,
250 netsnmp_index * hdr)
251 {
252 /*
253 * temporary local storage for extracting oid index
254 *
255 * extract index uses varbinds (netsnmp_variable_list) to parse
256 * the index OID into the individual components for each index
part.
257 */
258 netsnmp_variable_list var_test4MtIndex;
259 int err;
260
261 // RJW: Diagnostic
262 printf ("\nEnter test4MstTable_extract_index().\n");
263
264 /*
265 * copy index, if provided
266 */
267 if (hdr) {
268 netsnmp_assert(ctx->index.oids == NULL);
269 if ((hdr->len > MAX_OID_LEN) ||
270 snmp_clone_mem((void *) &ctx->index.oids, hdr->oids,
271 hdr->len * sizeof(oid))) {
272 return -1;
273 }
274 ctx->index.len = hdr->len;
275 }
276
277 /*
278 * initialize variable that will hold each component of the
index.
279 * If there are multiple indexes for the table, the
variable_lists
280 * need to be linked together, in order.
281 */
282 memset(&var_test4MtIndex, 0x00, sizeof(var_test4MtIndex));
283 var_test4MtIndex.type = ASN_INTEGER; /* type hint for
parse_oid_indexes */
284 /** TODO: link this index to the next, or NULL for the last
one */
285 #ifdef TABLE_CONTAINER_TODO
286 snmp_log(LOG_ERR,
287 "test4MstTable_extract_index index list not
implemented!\n");
288 return 0;
289 #else
290 // 05/04/07 RJW: Conserned about this since I have it pointing
to itself, but
291 // don't expect this code to execute.
292 // var_test4MTindex.next_variable = &var_XX;
293
294 printf ("\n No idea how to set this,
test4MstTable_extract_index().\n");
295 var_test4MtIndex.next_variable = &var_test4MtIndex;
296 #endif
297
298
299 /*
300 * parse the oid into the individual index components
301 */
302 err = parse_oid_indexes(hdr->oids, hdr->len, &var_test4MtIndex);
303 if (err == SNMP_ERR_NOERROR) {
304 /*
305 * copy index components into the context structure
306 */
307 ctx->test4MtIndex = *var_test4MtIndex.val.integer;
308
309
310 /*
311 * TODO: check index for valid values. For EXAMPLE:
312 *
313 * if ( *var_test4MtIndex.val.integer != XXX ) {
314 * err = -1;
315 * }
316 */
317 }
318
319 /*
320 * parsing may have allocated memory. free it.
321 */
322 snmp_reset_var_buffers(&var_test4MtIndex);
323
324 return err;
325 }
326
327 /************************************************************
328 * the *_can_delete routine is called to determine if a row
329 * can be deleted.
330 *
331 * return 1 if the row can be deleted
332 * return 0 if the row cannot be deleted
333 */
334 int
335 test4MstTable_can_delete(test4MstTable_context * undo_ctx,
336 test4MstTable_context * row_ctx,
337 netsnmp_request_group * rg)
338 {
339
340 /*
341 * TODO: check for other deletion requirements here
342 */
343 return 1;
344 }
345
346
347 /************************************************************
348 * the *_duplicate row routine
349 */
350 test4MstTable_context *
351 test4MstTable_duplicate_row(test4MstTable_context * row_ctx)
352 {
353 test4MstTable_context *dup;
354
355 // 05/07/07 RJW investigatory.
356 printf ("\n Enter t4MstTable_duplicate_row)\n");
357
358 if (!row_ctx)
359 return NULL;
360
361 dup = SNMP_MALLOC_TYPEDEF(test4MstTable_context);
362 if (!dup)
363 return NULL;
364
365 if (test4MstTable_row_copy(dup, row_ctx)) {
366 free(dup);
367 dup = NULL;
368 }
369
370 // 05/07/07 RJW investigatory.
371 printf ("\n Clean exit t4MstTable_duplicate_row)\n");
372
373 return dup;
374 }
375
376 /************************************************************
377 * the *_delete_row method is called to delete a row.
378 */
379 netsnmp_index *
380 test4MstTable_delete_row(test4MstTable_context * ctx)
381 {
382 /*
383 * netsnmp_mutex_destroy(ctx->lock);
384 */
385
386 if (ctx->index.oids)
387 free(ctx->index.oids);
388
389 /*
390 * TODO: release any memory you allocated here...
391 */
392
393 /*
394 * release header
395 */
396 free(ctx);
397
398 return NULL;
399 }
400
401
402 /************************************************************
403 * RESERVE is used to check the syntax of all the variables
404 * provided, that the values being set are sensible and consistent,
405 * and to allocate any resources required for performing the SET.
406 * After this stage, the expectation is that the set ought to
407 * succeed, though this is not guaranteed. (In fact, with the UCD
408 * agent, this is done in two passes - RESERVE1, and
409 * RESERVE2, to allow for dependancies between variables).
410 *
411 * BEFORE calling this routine, the agent will call duplicate_row
412 * to create a copy of the row (unless this is a new row; i.e.
413 * row_created == 1).
414 *
415 * next state -> SET_RESERVE2 || SET_FREE
416 */
417 void
418 test4MstTable_set_reserve1(netsnmp_request_group * rg)
419 {
420 test4MstTable_context *row_ctx =
421 (test4MstTable_context *) rg->existing_row;
422
423 // 05/07/07 RJW: make complains "unused..."
424 // test4MstTable_context *undo_ctx =
425 // (test4MstTable_context *) rg->undo_info;
426 netsnmp_variable_list *var;
427 netsnmp_request_group_item *current;
428 int rc;
429
430
431 /*
432 * TODO: loop through columns, check syntax and lengths. For
433 * columns which have no dependencies, you could also move
434 * the value/range checking here to attempt to catch error
435 * cases as early as possible.
436 */
437 for (current = rg->list; current; current = current->next) {
438
439 var = current->ri->requestvb;
440 rc = SNMP_ERR_NOERROR;
441
442 switch (current->tri->colnum) {
443
444 case COLUMN_TEST4MTVALUE:
445 /** INTEGER32 = ASN_INTEGER */
446 rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
447 sizeof(row_ctx->
448
test4MtValue));
449 break;
450
451 default:/** We shouldn't get here */
452 rc = SNMP_ERR_GENERR;
453 snmp_log(LOG_ERR, "unknown column in "
454 "test4MstTable_set_reserve1\n");
455 }
456
457 if (rc)
458 netsnmp_set_mode_request_error(MODE_SET_BEGIN,
current->ri,
459 rc);
460 rg->status = SNMP_MAX(rg->status, current->ri->status);
461 }
462
463 /*
464 * done with all the columns. Could check row related
465 * requirements here.
466 */
467 }
468
469 void
470 test4MstTable_set_reserve2(netsnmp_request_group * rg)
471 {
472 // 05/07/07 RJW: make complains "unused..."
473 // test4MstTable_context *row_ctx =
474 // (test4MstTable_context *) rg->existing_row;
475 // test4MstTable_context *undo_ctx =
476 // (test4MstTable_context *) rg->undo_info;
477
478 netsnmp_request_group_item *current;
479 netsnmp_variable_list *var;
480 int rc;
481
482 rg->rg_void = rg->list->ri;
483
484 /*
485 * TODO: loop through columns, check for valid
486 * values and any range constraints.
487 */
488 for (current = rg->list; current; current = current->next) {
489
490 var = current->ri->requestvb;
491 rc = SNMP_ERR_NOERROR;
492
493 switch (current->tri->colnum) {
494
495 case COLUMN_TEST4MTVALUE:
496 /** INTEGER32 = ASN_INTEGER */
497 /*
498 * TODO: routine to check valid values
499 *
500 * EXAMPLE:
501 *
502 * if ( *var->val.integer != XXX ) {
503 * rc = SNMP_ERR_INCONSISTENTVALUE;
504 * rc = SNMP_ERR_BADVALUE;
505 * }
506 */
507 break;
508
509 default:/** We shouldn't get here */
510 netsnmp_assert(0); /** why wasn't this caught in
reserve1? */
511 }
512
513 if (rc)
514 netsnmp_set_mode_request_error(MODE_SET_BEGIN,
current->ri,
515 rc);
516 }
517
518 /*
519 * done with all the columns. Could check row related
520 * requirements here.
521 */
522 }
523
524 /************************************************************
525 * Assuming that the RESERVE phases were successful, the next
526 * stage is indicated by the action value ACTION. This is used
527 * to actually implement the set operation. However, this must
528 * either be done into temporary (persistent) storage, or the
529 * previous value stored similarly, in case any of the subsequent
530 * ACTION calls fail.
531 *
532 * In your case, changes should be made to row_ctx. A copy of
533 * the original row is in undo_ctx.
534 */
535 void
536 test4MstTable_set_action(netsnmp_request_group * rg)
537 {
538 netsnmp_variable_list *var;
539 test4MstTable_context *row_ctx =
540 (test4MstTable_context *) rg->existing_row;
541
542 // 05/07/07 RJW: make complains "unused..."
543 // test4MstTable_context *undo_ctx =
544 // (test4MstTable_context *) rg->undo_info;
545 netsnmp_request_group_item *current;
546
547 // RJW: Diagnostic
548 printf ("\nEnter test4MstTable_set_action()\n");
549
550 /*
551 * TODO: loop through columns, copy varbind values
552 * to context structure for the row.
553 */
554 for (current = rg->list; current; current = current->next) {
555
556 var = current->ri->requestvb;
557
558 switch (current->tri->colnum) {
559
560 case COLUMN_TEST4MTVALUE:
561 /** INTEGER32 = ASN_INTEGER */
562 row_ctx->test4MtValue = *var->val.integer;
563 break;
564
565 default:/** We shouldn't get here */
566 netsnmp_assert(0); /** why wasn't this caught in
reserve1? */
567 }
568 }
569
570 /*
571 * done with all the columns. Could check row related
572 * requirements here.
573 */
574 /*
575 * TODO: if you have dependencies on other tables, this would be
576 * a good place to check those, too.
577 */
578 }
579
580 /************************************************************
581 * Only once the ACTION phase has completed successfully, can
582 * the final COMMIT phase be run. This is used to complete any
583 * writes that were done into temporary storage, and then release
584 * any allocated resources. Note that all the code in this phase
585 * should be "safe" code that cannot possibly fail (cue
586 * hysterical laughter). The whole intent of the ACTION/COMMIT
587 * division is that all of the fallible code should be done in
588 * the ACTION phase, so that it can be backed out if necessary.
589 *
590 * BEFORE calling this routine, the agent will update the
591 * container (inserting a row if row_created == 1, or removing
592 * the row if row_deleted == 1).
593 *
594 * AFTER calling this routine, the agent will delete the
595 * undo_info.
596 */
597 void
598 test4MstTable_set_commit(netsnmp_request_group * rg)
599 {
600 netsnmp_variable_list *var;
601
602 // 05/04/07 RJW: make complains "unused..."
603 // test4MstTable_context *row_ctx =
604 // (test4MstTable_context *) rg->existing_row;
605 // test4MstTable_context *undo_ctx =
606 // (test4MstTable_context *) rg->undo_info;
607
608 netsnmp_request_group_item *current;
609
610 /*
611 * loop through columns
612 */
613 for (current = rg->list; current; current = current->next) {
614
615 var = current->ri->requestvb;
616
617 switch (current->tri->colnum) {
618
619 case COLUMN_TEST4MTVALUE:
620 /** INTEGER32 = ASN_INTEGER */
621 break;
622
623 default:/** We shouldn't get here */
624 netsnmp_assert(0); /** why wasn't this caught in
reserve1? */
625 }
626 }
627
628 /*
629 * done with all the columns. Could check row related
630 * requirements here.
631 */
632 }
633
634 /************************************************************
635 * If either of the RESERVE calls fail, the write routines
636 * are called again with the FREE action, to release any resources
637 * that have been allocated. The agent will then return a failure
638 * response to the requesting application.
639 *
640 * AFTER calling this routine, the agent will delete undo_info.
641 */
642 void
643 test4MstTable_set_free(netsnmp_request_group * rg)
644 {
645 netsnmp_variable_list *var;
646
647 // 05/04/07 RJW: make complains row_ctx & undo_ctx unused,
comment out.
648 // test4MstTable_context *row_ctx =
649 // (test4MstTable_context *) rg->existing_row;
650 // test4MstTable_context *undo_ctx =
651 // (test4MstTable_context *) rg->undo_info;
652
653 netsnmp_request_group_item *current;
654
655 /*
656 * loop through columns
657 */
658 for (current = rg->list; current; current = current->next) {
659
660 var = current->ri->requestvb;
661
662 switch (current->tri->colnum) {
663
664 case COLUMN_TEST4MTVALUE:
665 /** INTEGER32 = ASN_INTEGER */
666 break;
667
668 default:/** We shouldn't get here */
669 /** should have been logged in reserve1 */
670
671 // weird, cannot have naked default at end.
672 break;
673 }
674 }
675
676 /*
677 * done with all the columns. Could check row related
678 * requirements here.
679 */
680 }
681
682 /************************************************************
683 * If the ACTION phase does fail (for example due to an apparently
684 * valid, but unacceptable value, or an unforeseen problem), then
685 * the list of write routines are called again, with the UNDO
686 * action. This requires the routine to reset the value that was
687 * changed to its previous value (assuming it was actually changed),
688 * and then to release any resources that had been allocated. As
689 * with the FREE phase, the agent will then return an indication
690 * of the error to the requesting application.
691 *
692 * BEFORE calling this routine, the agent will update the container
693 * (remove any newly inserted row, re-insert any removed row).
694 *
695 * AFTER calling this routing, the agent will call row_copy
696 * to restore the data in existing_row from the date in undo_info.
697 * Then undo_info will be deleted (or existing row, if row_created
698 * == 1).
699 */
700 void
701 test4MstTable_set_undo(netsnmp_request_group * rg)
702 {
703 netsnmp_variable_list *var;
704
705 // 05/04/07 RJW: make complains row_ctx & undo_ctx unused, so
comment out.
706 // test4MstTable_context *row_ctx =
707 // (test4MstTable_context *) rg->existing_row;
708 // test4MstTable_context *undo_ctx =
709 // (test4MstTable_context *) rg->undo_info;
710
711 netsnmp_request_group_item *current;
712
713 /*
714 * loop through columns
715 */
716 for (current = rg->list; current; current = current->next) {
717
718 var = current->ri->requestvb;
719
720 switch (current->tri->colnum) {
721
722 case COLUMN_TEST4MTVALUE:
723 /** INTEGER32 = ASN_INTEGER */
724 break;
725
726 default:/** We shouldn't get here */
727 netsnmp_assert(0); /** why wasn't this caught in
reserve1? */
728 }
729 }
730
731 /*
732 * done with all the columns. Could check row related
733 * requirements here.
734 */
735 }
736
737
738
739 /************************************************************
740 *
741 * Initialize the test4MstTable table by defining its contents and
how it's structured
742 */
743 void
744 initialize_table_test4MstTable(void)
745 {
746 netsnmp_table_registration_info *table_info;
747
748 if (my_handler) {
749 snmp_log(LOG_ERR,
750 "initialize_table_test4MstTable_handler called
again\n");
751 return;
752 }
753
754 memset(&cb, 0x00, sizeof(cb));
755
756 /** create the table structure itself */
757 table_info =
SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
758
759 my_handler =
netsnmp_create_handler_registration("test4MstTable",
760
netsnmp_table_array_helper_handler,
761
test4MstTable_oid,
762
test4MstTable_oid_len,
763
HANDLER_CAN_RWRITE);
764
765 if (!my_handler || !table_info) {
766 snmp_log(LOG_ERR, "malloc failed in "
767 "initialize_table_test4MstTable_handler\n");
768 return; /** mallocs failed */
769 }
770
771 /***************************************************
772 * Setting up the table's definition
773 */
774 /*
775 * TODO: add any external indexes here.
776 */
777
778 /*
779 * internal indexes
780 */
781 /** index: test4MtIndex */
782 netsnmp_table_helper_add_index(table_info, ASN_INTEGER);
783
784 table_info->min_column = test4MstTable_COL_MIN;
785 table_info->max_column = test4MstTable_COL_MAX;
786
787 /***************************************************
788 * registering the table with the master agent
789 */
790 cb.get_value = test4MstTable_get_value;
791 cb.container = netsnmp_container_find("test4MstTable_primary:"
792 "test4MstTable:"
793 "table_container");
794 #ifdef test4MstTable_CUSTOM_SORT
795 netsnmp_container_add_index(cb.container,
796 netsnmp_container_find
797 ("test4MstTable_custom:"
"test4MstTable:"
798 "table_container"));
799 cb.container->next->compare = test4MstTable_cmp;
800 #endif
801 cb.can_set = 1;
802 cb.duplicate_row = (UserRowMethod *)
test4MstTable_duplicate_row;
803 cb.delete_row = (UserRowMethod *) test4MstTable_delete_row;
804 cb.row_copy = (Netsnmp_User_Row_Operation *)
test4MstTable_row_copy;
805
806 cb.can_delete = (Netsnmp_User_Row_Action *)
test4MstTable_can_delete;
807
808 cb.set_reserve1 = test4MstTable_set_reserve1;
809 cb.set_reserve2 = test4MstTable_set_reserve2;
810 cb.set_action = test4MstTable_set_action;
811 cb.set_commit = test4MstTable_set_commit;
812 cb.set_free = test4MstTable_set_free;
813 cb.set_undo = test4MstTable_set_undo;
814 DEBUGMSGTL(("initialize_table_test4MstTable",
815 "Registering table test4MstTable " "as a table
array\n"));
816 netsnmp_table_container_register(my_handler, table_info, &cb,
817 cb.container, 1);
818 }
819
820 /************************************************************
821 * test4MstTable_get_value
822 *
823 * This routine is called for get requests to copy the data
824 * from the context to the varbind for the request. If the
825 * context has been properly maintained, you don't need to
826 * change in code in this fuction.
827 */
828 int
829 test4MstTable_get_value(netsnmp_request_info *request,
830 netsnmp_index * item,
831 netsnmp_table_request_info *table_info)
832 {
833 netsnmp_variable_list *var = request->requestvb;
834 test4MstTable_context *context = (test4MstTable_context *) item;
835
836 // 05/07/07 RJW temp debug
837 printf ("\nEnter test4MstTable_get_value().\n");
838
839 switch (table_info->colnum) {
840
841 case COLUMN_TEST4MTVALUE:
842 /** INTEGER32 = ASN_INTEGER */
843 // 05/07/07 RJW: apparently mib2c is out of sync with
net-snmp lib, the
844 // 3rd arg of this should be u_char, not char.
845 snmp_set_var_typed_value(var, ASN_INTEGER,
846 (u_char *) &context->test4MtValue,
847 sizeof(context->test4MtValue));
848 break;
849
850 default:/** We shouldn't get here */
851 snmp_log(LOG_ERR, "unknown column in "
852 "test4MstTable_get_value\n");
853 return SNMP_ERR_GENERR;
854 }
855
856 // 05/07/07 RJW temp debug
857 printf ("\nClean exit test4MstTable_get_value().\n");
858
859 return SNMP_ERR_NOERROR;
860 }
861
862 /************************************************************
863 * test4MstTable_get_by_idx
864 */
865 const test4MstTable_context *
866 test4MstTable_get_by_idx(netsnmp_index * hdr)
867 {
868 return (const test4MstTable_context *)
869 CONTAINER_FIND(cb.container, hdr);
870 }
[Rob edna:~/net-snmp/test4/test-c] $
***PIECE #3: the Makefile
-------------------------
[Rob edna:~/net-snmp/test4/test-c] $ cat Makefile
#
# 11/22/2006 - from
www.net-snmp.org/tutorial/tutorial-5/toolkit/demoapp/Makefile
#
# Recall "ldd", e.g: $ ldd /usr/sbin/snmpd
#
# Warning: you may need more libraries than are included here on the
# build line. The agent frequently needs various libraries in order
# to compile pieces of it, but is OS dependent and we can't list all
# the combinations here. Instead, look at the libraries that were
# used when linking the snmpd master agent and copy those to this
# file.
#
# 05/03/2007 - Adapt to current "test4/test-a" effort.
#
CC=gcc
OBJS2=test4Master_subagent.o test4MstTable.o
TARGETS=test4Mst
CFLAGS=-I. `net-snmp-config --cflags`
BUILDLIBS=`net-snmp-config --libs`
BUILDAGENTLIBS=`net-snmp-config --agent-libs`
# shared library flags (assumes gcc)
DLFLAGS=-fPIC -shared
all: $(TARGETS)
test4Mst: $(OBJS2)
$(CC) -o test4Mst $(OBJS2) $(BUILDAGENTLIBS)
clean:
rm $(OBJS2) $(TARGETS)
[Rob edna:~/net-snmp/test4/test-c]
***PIECE #4: the subagent execution and snmp tool results against it
--------------------------------------------------------------------
[Rob edna:~/net-snmp/test4/test-c] $ ps awwux | grep test4Mst
1066 12927 0.0 0.0 3860 776 pts/7 S+ 16:59 0:00 grep
test4Mst
[Rob edna:~/net-snmp/test4/test-c] $ su
Password:
edna:/home/rob.walter/net-snmp/test4/test-c # ./test4Mst
edna:/home/rob.walter/net-snmp/test4/test-c # NET-SNMP version 5.3.0.1
AgentX subagent connected
edna:/home/rob.walter/net-snmp/test4/test-c # exit
exit
[Rob edna:~/net-snmp/test4/test-c] $ ps awwux | grep test4Mst
root 12950 0.6 0.1 31432 4492 ? S 16:59 0:00 ./test4Mst
1066 12952 0.0 0.0 3864 776 pts/7 S+ 16:59 0:00 grep
test4Mst
[Rob edna:~/net-snmp/test4/test-c] $
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $ snmpwalk -v 1 -c public localhost
test4MstTable
ROB-TEST4-MIB::test4MtValue.0 = INTEGER: 171
ROB-TEST4-MIB::test4MtValue.0 = INTEGER: 44
Error: OID not increasing: ROB-TEST4-MIB::test4MtValue.0
>= ROB-TEST4-MIB::test4MtValue.0
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $ snmpgetnext -c public -v 1 -Ob
localhost test4MstTable.0
ROB-TEST4-MIB::test4MtValue.0 = INTEGER: 171
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $
The preceding is quite suspicious. Appears to treat the item as if it
were
a scalar. I do not know how to interpret the error "OID not increasing".
In contrast the following is a truncation of the "well known" ifTable.
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $ snmpwalk -v 1 -c public localhost
ifTable
[Rob edna:~/SW_tests/snmp/net-snmp-5.4] $
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.4 = INTEGER: 4
IF-MIB::ifIndex.5 = INTEGER: 5
IF-MIB::ifIndex.6 = INTEGER: 6
IF-MIB::ifDescr.1 = STRING: lo
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users