|
1 /* |
|
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * |
|
4 * U.S. Government Rights - Commercial software. Government users are subject |
|
5 * to the Sun Microsystems, Inc. standard license agreement and applicable |
|
6 * provisions of the FAR and its supplements. |
|
7 * |
|
8 * |
|
9 * This distribution may include materials developed by third parties. Sun, |
|
10 * Sun Microsystems, the Sun logo and Solaris are trademarks or registered |
|
11 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. |
|
12 * |
|
13 */ |
|
14 |
|
15 /* |
|
16 * Note: this file originally auto-generated by mib2c using |
|
17 * : mib2c.scalar.conf,v 1.5 2002/07/18 14:18:52 dts12 Exp $ |
|
18 */ |
|
19 |
|
20 #include <sys/types.h> |
|
21 #include <sys/stat.h> |
|
22 #include <fcntl.h> |
|
23 #include <net-snmp/net-snmp-config.h> |
|
24 #include <net-snmp/net-snmp-includes.h> |
|
25 #include <net-snmp/agent/net-snmp-agent-includes.h> |
|
26 #include "demo_module_7.h" |
|
27 |
|
28 static long fileX_data = 111; // Hardcoded size of fileX context name string |
|
29 static long fileY_data = 999; // Hardcoded size of fileY context name string |
|
30 |
|
31 static long PRIORITY = 0; |
|
32 static long SUB_ID = 0; |
|
33 static long RANGE_UBOUND = 0; |
|
34 |
|
35 // Gets size of file |
|
36 static oid me1filesize_oid[] = { 1,3,6,1,4,1,42,2,2,4,4,6,1,1,0 }; |
|
37 |
|
38 // Registers a context |
|
39 static oid me1createContext_oid[] = { 1,3,6,1,4,1,42,2,2,4,4,6,1,2,0 }; |
|
40 |
|
41 // Unregisters a context |
|
42 static oid me1removeContext_oid[] = { 1,3,6,1,4,1,42,2,2,4,4,6,1,3,0 }; |
|
43 |
|
44 // Name of file whose size should be returned |
|
45 char *filename; |
|
46 |
|
47 /* |
|
48 This example module registers context name strings that represent files. |
|
49 Get requests to these contexts will retrieve the size of the file. |
|
50 |
|
51 The module can be dynamically updated to register new file names, by |
|
52 issuing an snmpset command. You do not need to edit the module in |
|
53 application passes the file name to the module by issuing an snmpset |
|
54 command, such as the following: |
|
55 |
|
56 snmpset -v 3 -u < user_name > -n "< file_name >" |
|
57 -l authNoPriv -A " <password >" < agent_host_name > |
|
58 < createContext OID > . |
|
59 |
|
60 The module registers the set_createContext handler to handle incoming |
|
61 snmp set requests for this OID. The set_createContext handler registers |
|
62 the new filename as a context string in the contextName member of the |
|
63 netsnmp_registration_handler struct for the filesize_oid. |
|
64 |
|
65 Subsequent snmpget requests for the size of the file will |
|
66 return its size in blocks: For example: |
|
67 |
|
68 snmpget -v 3 -u < user_name > -n "< file_name >" |
|
69 -l authNoPriv -A "< password >" < agent_host_name > |
|
70 < filesize_oid > */ |
|
71 |
|
72 |
|
73 /* Initializes the filesize module */ |
|
74 |
|
75 void |
|
76 init_demo_module_7(void) |
|
77 { |
|
78 |
|
79 char *filexcon = "fileX"; |
|
80 char *fileycon = "fileY"; |
|
81 |
|
82 |
|
83 netsnmp_handler_registration *myreg1; |
|
84 int status; |
|
85 |
|
86 /* |
|
87 Create a read-only registration handler named filesize, |
|
88 which calls the get_filesize function to service snmp requests |
|
89 for the me1filesize_oid object. The OID_LENGTH argument |
|
90 calculates the length of the me1filesize_oid. */ |
|
91 DEBUGMSGTL(("demo_module_7", "Initializing\n")); |
|
92 myreg1 = netsnmp_create_handler_registration |
|
93 ("filesize", |
|
94 get_filesize, |
|
95 me1filesize_oid, |
|
96 OID_LENGTH(me1filesize_oid), |
|
97 HANDLER_CAN_RONLY); |
|
98 |
|
99 myreg1->contextName = filexcon; |
|
100 status = netsnmp_register_read_only_instance(myreg1); |
|
101 DEBUGMSGTL(("demo_module_7", "init reg1 status %d:\n", status)); |
|
102 |
|
103 |
|
104 myreg1 = netsnmp_create_handler_registration |
|
105 ("filesize", |
|
106 get_filesize, |
|
107 me1filesize_oid, |
|
108 OID_LENGTH(me1filesize_oid), |
|
109 HANDLER_CAN_RONLY); |
|
110 |
|
111 myreg1->contextName = fileycon; |
|
112 status = netsnmp_register_read_only_instance(myreg1); |
|
113 DEBUGMSGTL(("demo_module_7", "init reg2 status %d:\n", status)); |
|
114 |
|
115 |
|
116 /* |
|
117 Create a read-write registration handler named filesize, |
|
118 which calls the set_createContext function to service snmp requests |
|
119 for the me1createContext_oid object. The OID_LENGTH argument |
|
120 calculates the length of the me1createContext_oid. */ |
|
121 myreg1 = netsnmp_create_handler_registration |
|
122 ("filesize", |
|
123 set_createContext, |
|
124 me1createContext_oid, |
|
125 OID_LENGTH(me1createContext_oid), |
|
126 HANDLER_CAN_RWRITE); |
|
127 |
|
128 status = netsnmp_register_instance(myreg1); |
|
129 DEBUGMSGTL(("filesize", "init reg3 status %d:\n", status)); |
|
130 |
|
131 /* |
|
132 Create a read-write registration handler named filesize, |
|
133 which calls the set_removeContext function to service snmp requests |
|
134 for the me1removeContext_oid object. The OID_LENGTH argument |
|
135 calculates the length of the me1removeContext_oid. */ |
|
136 myreg1 = netsnmp_create_handler_registration |
|
137 ("filesize", |
|
138 set_removeContext, |
|
139 me1removeContext_oid, |
|
140 OID_LENGTH(me1removeContext_oid), |
|
141 HANDLER_CAN_RWRITE); |
|
142 |
|
143 status = netsnmp_register_instance(myreg1); |
|
144 DEBUGMSGTL(("demo_module_7", "init reg4 status %d:\n", status)); |
|
145 } |
|
146 |
|
147 /* |
|
148 This handler handles set requests on the m1createContext_oid |
|
149 by registering a context. The handler extracts the string from |
|
150 the snmp set request and uses it to register a new context for |
|
151 the mefilesize_oid. |
|
152 |
|
153 This handler handles get requests by returning the last context |
|
154 name that was registered. |
|
155 |
|
156 For detailed info. on net-snmp set processing, |
|
157 see "http://www.net-snmp.org/tutorial-5/toolkit/mib_module/index.html" |
|
158 net-snmp call each SNMP mode in sequence. The case statement |
|
159 transfers control to the default: case when no other condition |
|
160 is satisfied. */ |
|
161 |
|
162 int |
|
163 set_createContext(netsnmp_mib_handler *handler, |
|
164 netsnmp_handler_registration *reginfo, |
|
165 netsnmp_agent_request_info *reqinfo, |
|
166 netsnmp_request_info *requests) |
|
167 { |
|
168 |
|
169 netsnmp_handler_registration *myreg; |
|
170 char *context_names[256]; |
|
171 int status; |
|
172 DEBUGMSGTL(("demo_module_7", "set_createContext CALLED\n")); |
|
173 DEBUGMSGTL(("demo_module_7", "reqinfo->mode = %d\n", reqinfo->mode)); |
|
174 switch (reqinfo -> mode) { |
|
175 |
|
176 case MODE_SET_RESERVE1: |
|
177 break; |
|
178 |
|
179 case MODE_SET_RESERVE2: |
|
180 break; |
|
181 |
|
182 case MODE_SET_FREE: |
|
183 break; |
|
184 |
|
185 case MODE_SET_ACTION: |
|
186 |
|
187 DEBUGMSGTL(("demo_module_7", "MODE_SET_ACTION CALLED\n")); |
|
188 DEBUGMSGTL(("demo_module_7", "requests->requestvb->val = %s\n", |
|
189 (u_char *) requests->requestvb->val.string)); |
|
190 |
|
191 // You must allocate memory for this variable because |
|
192 // the unregister_mib function frees it. |
|
193 filename = malloc(requests->requestvb->val_len + 1); |
|
194 snprintf(filename, requests->requestvb->val_len + 1, "%s", |
|
195 (u_char *) requests->requestvb->val.string); |
|
196 filename[requests->requestvb->val_len + 1] = '\0'; |
|
197 |
|
198 DEBUGMSGTL(("demo_module_7", "filename = %s\n", filename)); |
|
199 |
|
200 /* |
|
201 Create a registration handler for the me1filesize_oid |
|
202 object in the new context name specified by |
|
203 the snmp set on the me1createContext OID. */ |
|
204 myreg = netsnmp_create_handler_registration |
|
205 ("test", get_test, me1filesize_oid, |
|
206 OID_LENGTH(me1filesize_oid), |
|
207 HANDLER_CAN_RONLY); |
|
208 myreg->contextName = filename; |
|
209 status = netsnmp_register_read_only_instance(myreg); |
|
210 DEBUGMSGTL(("demo_module_7", "status %d:\n", status)); |
|
211 break; |
|
212 |
|
213 case MODE_SET_COMMIT: |
|
214 break; |
|
215 |
|
216 case MODE_SET_UNDO: |
|
217 /* |
|
218 Not handling the undo case because we don't care about |
|
219 multi-phase sets for this example. */ |
|
220 break; |
|
221 |
|
222 case MODE_GET: |
|
223 snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, |
|
224 (u_char *)filename, sizeof (filename)); |
|
225 |
|
226 default: |
|
227 /* we should never get here, so this is a really bad error */ |
|
228 DEBUGMSGTL(("demo_module_7", "default CALLED\n")); |
|
229 } |
|
230 |
|
231 return (SNMP_ERR_NOERROR); |
|
232 } |
|
233 |
|
234 /* |
|
235 This handler handles set requests on the m1removeContext_oid |
|
236 for detailed info. on net-snmp set processing, |
|
237 see "http://www.net-snmp.org/tutorial-5/toolkit/mib_module/index.html" |
|
238 net-snmp call each SNMP mode in sequence. The case statement |
|
239 transfers control to the default: case when no other condition |
|
240 is satisfied. */ |
|
241 |
|
242 int |
|
243 set_removeContext(netsnmp_mib_handler *handler, |
|
244 netsnmp_handler_registration *reginfo, |
|
245 netsnmp_agent_request_info *reqinfo, |
|
246 netsnmp_request_info *requests) |
|
247 { |
|
248 DEBUGMSGTL(("demo_module_7", "remove_filesize CALLED\n")); |
|
249 switch (reqinfo->mode) { |
|
250 case MODE_SET_RESERVE1: |
|
251 break; |
|
252 case MODE_SET_RESERVE2: |
|
253 break; |
|
254 case MODE_SET_ACTION: |
|
255 DEBUGMSGTL(("demo_module_7", |
|
256 "remove_filesize MODE_SET_ACTION CALLED\n")); |
|
257 DEBUGMSGTL(("demo_module_7", |
|
258 "remove_filesize MODE_SET_ACTION CALLED\n")); |
|
259 snprintf(filename, requests->requestvb->val_len + 1, |
|
260 "%s", (u_char *) requests->requestvb->val.string); |
|
261 filename[requests->requestvb->val_len + 1] = '\0'; |
|
262 DEBUGMSGTL(("demo_module_7", |
|
263 "filename after snmpset = %s:\n", |
|
264 filename)); |
|
265 unregister_mib_context(me1filesize_oid, |
|
266 OID_LENGTH(me1filesize_oid), |
|
267 PRIORITY, SUB_ID, RANGE_UBOUND, |
|
268 filename); |
|
269 break; |
|
270 |
|
271 case MODE_SET_COMMIT: |
|
272 break; |
|
273 |
|
274 case MODE_SET_FREE: |
|
275 break; |
|
276 |
|
277 case MODE_SET_UNDO: |
|
278 /* |
|
279 Not handling the undo case because we don't care about |
|
280 multi-phase sets for this example. */ |
|
281 break; |
|
282 |
|
283 default: |
|
284 /* |
|
285 we should never get here, so this |
|
286 is a really bad error */ |
|
287 DEBUGMSGTL(("demo_module_7", "set_removeContext CALLED\n")); |
|
288 } |
|
289 return (SNMP_ERR_NOERROR); |
|
290 } |
|
291 |
|
292 |
|
293 |
|
294 int |
|
295 get_filesize(netsnmp_mib_handler *handler, |
|
296 netsnmp_handler_registration *reginfo, |
|
297 netsnmp_agent_request_info *reqinfo, |
|
298 netsnmp_request_info *requests) |
|
299 { |
|
300 /* |
|
301 This handler is never called for a getnext |
|
302 if it is registered as an instance. An instance |
|
303 handler only delivers one request at a time, so |
|
304 we do not need to loop over a list of requests. */ |
|
305 |
|
306 DEBUGMSGTL(("demo_module_7", "get_filesize CALLED\n")); |
|
307 DEBUGMSGTL(("demo_module_7", "INCOMING CONTEXT NAME = %s:\n", |
|
308 reginfo->contextName)); |
|
309 |
|
310 switch (reqinfo->mode) { |
|
311 |
|
312 case MODE_GET: |
|
313 |
|
314 if (strcmp(reginfo->contextName, "fileX") == 0) |
|
315 snmp_set_var_typed_value(requests->requestvb, |
|
316 ASN_INTEGER, (u_char *) &fileX_data |
|
317 /* pointer to the scalar's data */, |
|
318 sizeof (fileX_data) |
|
319 /* the length of the data in bytes */); |
|
320 |
|
321 else if (strcmp(reginfo->contextName, "fileY") == 0) |
|
322 snmp_set_var_typed_value(requests->requestvb, |
|
323 ASN_INTEGER, (u_char *) &fileY_data |
|
324 /* Pointer to the scalar's data */, |
|
325 sizeof (fileY_data) |
|
326 /* Length of the data in bytes */); |
|
327 break; |
|
328 |
|
329 default: |
|
330 /* |
|
331 We should never get here, so this is a really bad error */ |
|
332 return (SNMP_ERR_GENERR); |
|
333 } |
|
334 |
|
335 return (SNMP_ERR_NOERROR); |
|
336 } |
|
337 |
|
338 int |
|
339 get_test(netsnmp_mib_handler *handler, |
|
340 netsnmp_handler_registration *reginfo, |
|
341 netsnmp_agent_request_info *reqinfo, |
|
342 netsnmp_request_info *requests) |
|
343 { |
|
344 /* |
|
345 This handler is called to handle snmpset requests for a new |
|
346 context name in the me1filesize_oid. If it is called to |
|
347 handle snmp get requests, the handler does not need to |
|
348 handle a GETNEXT if it is registered as an |
|
349 instance handler. Instance handlers only deliver one request |
|
350 at a time, so we do not need to loop over a list of requests. */ |
|
351 |
|
352 struct stat buf; |
|
353 static int fd = 0; |
|
354 DEBUGMSGTL(("demo_module_7", "get_test CALLED\n")); |
|
355 DEBUGMSGTL(("demo_module_7", "INCOMING CONTEXT NAME = %s:\n", |
|
356 reginfo->contextName)); |
|
357 switch (reqinfo->mode) { |
|
358 case MODE_GET: |
|
359 if (strcmp(reginfo->contextName, filename) == 0) |
|
360 // An open() for reading only returns without delay. |
|
361 if ((fd = open(filename, O_NONBLOCK | |
|
362 O_RDONLY)) == -1) |
|
363 DEBUGMSGTL(("demo_module_7", "ERROR\n")); |
|
364 |
|
365 if (fstat(fd, &buf) == -1) |
|
366 DEBUGMSGTL(("demo_module_7", "ERROR\n")); |
|
367 else |
|
368 DEBUGMSGTL(("demo_module_7", |
|
369 "FILE SIZE IN BYTES = %d:\n", |
|
370 buf.st_size)); |
|
371 |
|
372 snmp_set_var_typed_value(requests->requestvb, |
|
373 ASN_INTEGER, (u_char *) &buf.st_size |
|
374 /* Pointer to the scalar's data */, |
|
375 sizeof (buf.st_size) |
|
376 /* The length of the data in bytes*/); |
|
377 break; |
|
378 |
|
379 default: |
|
380 /* |
|
381 we should never get here, so this is a really bad error */ |
|
382 return (SNMP_ERR_GENERR); |
|
383 } |
|
384 return (SNMP_ERR_NOERROR); |
|
385 } |