1 /*
2  * Note: this file originally auto-generated by mib2c using
3  *        : mib2c.scalar.conf,v 1.8 2004/10/14 12:57:34 dts12 Exp $
4  */
5 
6 #include <net-snmp/net-snmp-config.h>
7 #include <net-snmp/net-snmp-features.h>
8 #include <net-snmp/net-snmp-includes.h>
9 #include <net-snmp/agent/net-snmp-agent-includes.h>
10 
11 #include <net-snmp/data_access/ip_scalars.h>
12 
13 #include "ip_scalars.h"
14 
15 static int
16 handle_ipForwarding(netsnmp_mib_handler *handler,
17                     netsnmp_handler_registration *reginfo,
18                     netsnmp_agent_request_info *reqinfo,
19                     netsnmp_request_info *requests);
20 
21 static int
22 handle_ipDefaultTTL(netsnmp_mib_handler *handler,
23                     netsnmp_handler_registration *reginfo,
24                     netsnmp_agent_request_info *reqinfo,
25                     netsnmp_request_info *requests);
26 
27 static int
28 handle_ipv6IpForwarding(netsnmp_mib_handler *handler,
29                         netsnmp_handler_registration *reginfo,
30                         netsnmp_agent_request_info *reqinfo,
31                         netsnmp_request_info *requests);
32 
33 static int
34 handle_ipv6IpDefaultHopLimit(netsnmp_mib_handler *handler,
35                              netsnmp_handler_registration *reginfo,
36                              netsnmp_agent_request_info *reqinfo,
37                              netsnmp_request_info *requests);
38 
39 static int ipAddressSpinLockValue;
40 
41 static int
42 handle_ipAddressSpinLock(netsnmp_mib_handler *handler,
43                          netsnmp_handler_registration *reginfo,
44                          netsnmp_agent_request_info *reqinfo,
45                          netsnmp_request_info *requests);
46 
47 /** Initializes the ip module */
48 void
init_ip_scalars(void)49 init_ip_scalars(void)
50 {
51     static oid 	    ipForwarding_oid[] = { 1, 3, 6, 1, 2, 1, 4, 1 };
52     static oid 	    ipDefaultTTL_oid[] = { 1, 3, 6, 1, 2, 1, 4, 2 };
53     static oid      ipv6IpForwarding_oid[] = { 1, 3, 6, 1, 2, 1, 4, 25 };
54     static oid      ipv6IpDefaultHopLimit_oid[] = { 1, 3, 6, 1, 2, 1, 4, 26 };
55     static oid      ipAddressSpinLock_oid[] = { 1, 3, 6, 1, 2, 1, 4, 33 };
56 
57     DEBUGMSGTL(("ip_scalar", "Initializing\n"));
58 
59     netsnmp_register_scalar(netsnmp_create_handler_registration
60                              ("ipForwarding", handle_ipForwarding,
61                               ipForwarding_oid,
62                               OID_LENGTH(ipForwarding_oid),
63                               HANDLER_CAN_RWRITE));
64 
65     netsnmp_register_scalar(netsnmp_create_handler_registration
66                              ("ipDefaultTTL", handle_ipDefaultTTL,
67                               ipDefaultTTL_oid,
68                               OID_LENGTH(ipDefaultTTL_oid),
69                               HANDLER_CAN_RWRITE));
70 
71     netsnmp_register_scalar(netsnmp_create_handler_registration
72                             ("ipv6IpForwarding", handle_ipv6IpForwarding,
73                              ipv6IpForwarding_oid,
74                              OID_LENGTH(ipv6IpForwarding_oid),
75                              HANDLER_CAN_RWRITE));
76 
77     netsnmp_register_scalar(netsnmp_create_handler_registration
78                             ("ipv6IpDefaultHopLimit", handle_ipv6IpDefaultHopLimit,
79                              ipv6IpDefaultHopLimit_oid,
80                              OID_LENGTH(ipv6IpDefaultHopLimit_oid),
81                              HANDLER_CAN_RWRITE));
82 
83     netsnmp_register_scalar(netsnmp_create_handler_registration
84                             ("ipAddressSpinLock", handle_ipAddressSpinLock,
85                              ipAddressSpinLock_oid,
86                              OID_LENGTH(ipAddressSpinLock_oid),
87                              HANDLER_CAN_RWRITE));
88 
89     /* Initialize spin lock with random value */
90     ipAddressSpinLockValue = netsnmp_random();
91 
92 }
93 
94 static int
handle_ipForwarding(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)95 handle_ipForwarding(netsnmp_mib_handler *handler,
96                           netsnmp_handler_registration *reginfo,
97                           netsnmp_agent_request_info   *reqinfo,
98                           netsnmp_request_info         *requests)
99 {
100     int      rc;
101     u_long   value;
102 
103     /* We are never called for a GETNEXT if it's registered as a
104        "instance", as it's "magically" handled for us.  */
105 
106     /* a instance handler also only hands us one request at a time, so
107        we don't need to loop over a list of requests; we'll only get one. */
108 
109     switch(reqinfo->mode) {
110 
111         case MODE_GET:
112             rc = netsnmp_arch_ip_scalars_ipForwarding_get(&value);
113             if (rc != 0) {
114                 netsnmp_set_request_error(reqinfo, requests,
115                                       SNMP_NOSUCHINSTANCE);
116             }
117             else {
118                 value = value ? 1 : 2;
119                 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
120                                      (u_char *)&value, sizeof(value));
121             }
122             break;
123 
124 #ifndef NETSNMP_NO_WRITE_SUPPORT
125         /*
126          * SET REQUEST
127          *
128          * multiple states in the transaction.  See:
129          * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
130          */
131         case MODE_SET_RESERVE1:
132             break;
133 
134         case MODE_SET_RESERVE2:
135             /*
136              * store old info for undo later
137              */
138             rc = netsnmp_arch_ip_scalars_ipForwarding_get(&value);
139             if (rc < 0) {
140                 netsnmp_set_request_error(reqinfo, requests,
141                                           SNMP_ERR_NOCREATION);
142             } else {
143                 u_long *value_save;
144                 value_save = netsnmp_memdup(&value, sizeof(value));
145                 if ( NULL == value_save )
146                     netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE);
147                 else
148                     netsnmp_request_add_list_data(requests,
149                                                   netsnmp_create_data_list
150                                                   ("ipfw", value_save,
151                                                   free));
152 	    }
153             break;
154 
155         case MODE_SET_FREE:
156             /* XXX: free resources allocated in RESERVE1 and/or
157                RESERVE2.  Something failed somewhere, and the states
158                below won't be called. */
159             break;
160 
161         case MODE_SET_ACTION:
162             /* XXX: perform the value change here */
163             value =  *(requests->requestvb->val.integer);
164             rc = netsnmp_arch_ip_scalars_ipForwarding_set(value);
165             if ( 0 != rc ) {
166                 netsnmp_set_request_error(reqinfo, requests, rc);
167             }
168             break;
169 
170         case MODE_SET_COMMIT:
171             break;
172 
173         case MODE_SET_UNDO:
174              value =
175                  *((u_long *) netsnmp_request_get_list_data(requests,
176                                                             "ipfw"));
177              rc = netsnmp_arch_ip_scalars_ipForwarding_set(value);
178              if ( 0 != rc ) {
179                  netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED);
180              }
181              break;
182 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
183 
184         default:
185             /* we should never get here, so this is a really bad error */
186             snmp_log(LOG_ERR, "unknown mode (%d) in handle_ipForwarding\n", reqinfo->mode );
187             return SNMP_ERR_GENERR;
188     }
189 
190     return SNMP_ERR_NOERROR;
191 }
192 
193 
194 static int
handle_ipDefaultTTL(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)195 handle_ipDefaultTTL(netsnmp_mib_handler *handler,
196                     netsnmp_handler_registration *reginfo,
197                     netsnmp_agent_request_info   *reqinfo,
198                     netsnmp_request_info         *requests)
199 {
200     int      rc;
201     u_long   value;
202 
203     /* We are never called for a GETNEXT if it's registered as a
204        "instance", as it's "magically" handled for us.  */
205 
206     /* a instance handler also only hands us one request at a time, so
207        we don't need to loop over a list of requests; we'll only get one. */
208 
209     switch(reqinfo->mode) {
210 
211         case MODE_GET:
212             rc = netsnmp_arch_ip_scalars_ipDefaultTTL_get(&value);
213             if (rc != 0) {
214                 netsnmp_set_request_error(reqinfo, requests,
215                                       SNMP_NOSUCHINSTANCE);
216             }
217             else {
218                 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
219                                      (u_char *)&value, sizeof(value));
220             }
221             break;
222 
223 #ifndef NETSNMP_NO_WRITE_SUPPORT
224         /*
225          * SET REQUEST
226          *
227          * multiple states in the transaction.  See:
228          * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
229          */
230         case MODE_SET_RESERVE1:
231             break;
232 
233         case MODE_SET_RESERVE2:
234             /*
235              * store old info for undo later
236              */
237             rc = netsnmp_arch_ip_scalars_ipDefaultTTL_get(&value);
238             if (rc < 0) {
239                 netsnmp_set_request_error(reqinfo, requests,
240                                           SNMP_ERR_NOCREATION);
241             } else {
242                 u_long *value_save;
243                 value_save = netsnmp_memdup(&value, sizeof(value));
244                 if ( NULL == value_save )
245                     netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE);
246                 else
247                     netsnmp_request_add_list_data(requests,
248                                                   netsnmp_create_data_list
249                                                   ("ipttl", value_save,
250                                                   free));
251 	    }
252             break;
253 
254         case MODE_SET_FREE:
255             /* XXX: free resources allocated in RESERVE1 and/or
256                RESERVE2.  Something failed somewhere, and the states
257                below won't be called. */
258             break;
259 
260         case MODE_SET_ACTION:
261             /* XXX: perform the value change here */
262             value =  *(requests->requestvb->val.integer);
263             rc = netsnmp_arch_ip_scalars_ipDefaultTTL_set(value);
264             if ( 0 != rc ) {
265                 netsnmp_set_request_error(reqinfo, requests, rc);
266             }
267             break;
268 
269         case MODE_SET_COMMIT:
270             break;
271 
272         case MODE_SET_UNDO:
273              value =
274                  *((u_long *) netsnmp_request_get_list_data(requests,
275                                                             "ipttl"));
276              rc = netsnmp_arch_ip_scalars_ipDefaultTTL_set(value);
277              if ( 0 != rc ) {
278                  netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED);
279              }
280              break;
281 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
282 
283         default:
284             /* we should never get here, so this is a really bad error */
285             snmp_log(LOG_ERR, "unknown mode (%d) in handle_ipDefaultTTL\n", reqinfo->mode );
286             return SNMP_ERR_GENERR;
287     }
288 
289     return SNMP_ERR_NOERROR;
290 }
291 
292 
293 static int
handle_ipv6IpForwarding(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)294 handle_ipv6IpForwarding(netsnmp_mib_handler *handler,
295                         netsnmp_handler_registration *reginfo,
296                         netsnmp_agent_request_info *reqinfo,
297                         netsnmp_request_info *requests)
298 {
299     int      rc;
300     u_long   value;
301 
302     /*
303      * We are never called for a GETNEXT if it's registered as a
304      * "instance", as it's "magically" handled for us.
305      */
306 
307     /*
308      * a instance handler also only hands us one request at a time, so
309      * we don't need to loop over a list of requests; we'll only get one.
310      */
311     switch (reqinfo->mode) {
312 
313     case MODE_GET:
314         rc = netsnmp_arch_ip_scalars_ipv6IpForwarding_get(&value);
315         if (rc != 0) {
316             netsnmp_set_request_error(reqinfo, requests,
317                                       SNMP_NOSUCHINSTANCE);
318         }
319         else {
320             value = value ? 1 : 2;
321             snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
322                                      (u_char *)&value, sizeof(value));
323         }
324         break;
325 
326 #ifndef NETSNMP_NO_WRITE_SUPPORT
327         /*
328          * SET REQUEST
329          *
330          * multiple states in the transaction.  See:
331          * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
332          */
333     case MODE_SET_RESERVE1:
334         break;
335 
336     case MODE_SET_RESERVE2:
337         /*
338          * store old info for undo later
339          */
340         rc = netsnmp_arch_ip_scalars_ipv6IpForwarding_get(&value);
341         if (rc < 0) {
342             netsnmp_set_request_error(reqinfo, requests,
343                                       SNMP_ERR_NOCREATION);
344         }
345         else {
346             u_long *value_save;
347 
348             value_save = netsnmp_memdup(&value, sizeof(value));
349             if ( NULL == value_save ) {
350                 netsnmp_set_request_error(reqinfo, requests,
351                                           SNMP_ERR_RESOURCEUNAVAILABLE);
352             }
353             else {
354                 netsnmp_request_add_list_data(requests,
355                                               netsnmp_create_data_list
356                                               ("ip6fw", value_save,
357                                                free));
358             }
359         }
360         break;
361 
362     case MODE_SET_FREE:
363         break;
364 
365     case MODE_SET_ACTION:
366         value =  *(requests->requestvb->val.integer);
367         rc = netsnmp_arch_ip_scalars_ipv6IpForwarding_set(value);
368         if ( 0 != rc ) {
369             netsnmp_set_request_error(reqinfo, requests, rc );
370         }
371         break;
372 
373     case MODE_SET_COMMIT:
374         break;
375 
376     case MODE_SET_UNDO:
377         value =
378             *((u_long *) netsnmp_request_get_list_data(requests,
379                                                        "ip6fw"));
380         rc = netsnmp_arch_ip_scalars_ipv6IpForwarding_set(value);
381         if ( 0 != rc ) {
382             netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED);
383         }
384         break;
385 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
386 
387     default:
388         /*
389          * we should never get here, so this is a really bad error
390          */
391         snmp_log(LOG_ERR, "unknown mode (%d) in handle_ipv6IpForwarding\n",
392                  reqinfo->mode);
393         return SNMP_ERR_GENERR;
394     }
395 
396     return SNMP_ERR_NOERROR;
397 }
398 
399 
400 static int
handle_ipAddressSpinLock(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)401 handle_ipAddressSpinLock(netsnmp_mib_handler *handler,
402                           netsnmp_handler_registration *reginfo,
403                           netsnmp_agent_request_info   *reqinfo,
404                           netsnmp_request_info         *requests)
405 {
406     long   value;
407 
408     /* We are never called for a GETNEXT if it's registered as a
409        "instance", as it's "magically" handled for us.  */
410 
411     /* a instance handler also only hands us one request at a time, so
412        we don't need to loop over a list of requests; we'll only get one. */
413 
414     switch(reqinfo->mode) {
415 
416         case MODE_GET:
417             snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
418                                      (u_char *)&ipAddressSpinLockValue,
419                                      sizeof(ipAddressSpinLockValue));
420             break;
421 
422 #ifndef NETSNMP_NO_WRITE_SUPPORT
423         /*
424          * SET REQUEST
425          *
426          * multiple states in the transaction.  See:
427          * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
428          */
429         case MODE_SET_RESERVE1:
430         case MODE_SET_RESERVE2:
431             /* just check the value */
432             value =  *(requests->requestvb->val.integer);
433             if (value != ipAddressSpinLockValue)
434                 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_INCONSISTENTVALUE);
435             break;
436 
437         case MODE_SET_FREE:
438             break;
439 
440         case MODE_SET_ACTION:
441             /* perform the final spinlock check and increase its value */
442             value =  *(requests->requestvb->val.integer);
443             if (value != ipAddressSpinLockValue) {
444                 netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_INCONSISTENTVALUE);
445             } else {
446                 ipAddressSpinLockValue++;
447                 /* and check it for overflow */
448                 if (ipAddressSpinLockValue > 2147483647 || ipAddressSpinLockValue < 0)
449                     ipAddressSpinLockValue = 0;
450             }
451             break;
452 
453         case MODE_SET_COMMIT:
454             break;
455 
456         case MODE_SET_UNDO:
457              break;
458 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
459 
460         default:
461             /* we should never get here, so this is a really bad error */
462             snmp_log(LOG_ERR, "unknown mode (%d) in handle_ipAddressSpinLock\n", reqinfo->mode );
463             return SNMP_ERR_GENERR;
464     }
465 
466     return SNMP_ERR_NOERROR;
467 }
468 
469 
470 static int
handle_ipv6IpDefaultHopLimit(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)471 handle_ipv6IpDefaultHopLimit(netsnmp_mib_handler *handler,
472                              netsnmp_handler_registration *reginfo,
473                              netsnmp_agent_request_info *reqinfo,
474                              netsnmp_request_info *requests)
475 {
476     u_long          value;
477     int             rc;
478     /*
479      * We are never called for a GETNEXT if it's registered as a
480      * "instance", as it's "magically" handled for us.
481      */
482 
483     /*
484      * a instance handler also only hands us one request at a time, so
485      * we don't need to loop over a list of requests; we'll only get one.
486      */
487 
488     switch (reqinfo->mode) {
489 
490     case MODE_GET:
491 
492         rc = netsnmp_arch_ip_scalars_ipv6IpDefaultHopLimit_get(&value);
493         if (rc != 0) {
494             netsnmp_set_request_error(reqinfo, requests,
495                                   SNMP_NOSUCHINSTANCE);
496         }
497         else {
498             snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
499                                  (u_char *)&value, sizeof(value));
500         }
501 
502         break;
503 
504 #ifdef NOTYET
505         /*
506          * SET REQUEST
507          *
508          * multiple states in the transaction.  See:
509          * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
510          */
511     case MODE_SET_RESERVE1:
512         /*
513          * or you could use netsnmp_check_vb_type_and_size instead
514          */
515         rc = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER);
516         if (rc != SNMP_ERR_NOERROR) {
517             netsnmp_set_request_error(reqinfo, requests, rc);
518         }
519         break;
520 
521     case MODE_SET_RESERVE2:
522         /*
523          * XXX malloc "undo" storage buffer
524          */
525         if ( /* XXX if malloc, or whatever, failed: */ ) {
526             netsnmp_set_request_error(reqinfo, requests,
527                                       SNMP_ERR_RESOURCEUNAVAILABLE);
528         }
529         break;
530 
531     case MODE_SET_FREE:
532         /*
533          * XXX: free resources allocated in RESERVE1 and/or
534          * RESERVE2.  Something failed somewhere, and the states
535          * below won't be called.
536          */
537         break;
538 
539     case MODE_SET_ACTION:
540         /*
541          * XXX: perform the value change here
542          */
543         if ( /* XXX: error? */ ) {
544             netsnmp_set_request_error(reqinfo, requests, /* some error */
545                                       );
546         }
547         break;
548 
549     case MODE_SET_COMMIT:
550         /*
551          * XXX: delete temporary storage
552          */
553         if ( /* XXX: error? */ ) {
554             /*
555              * try _really_really_ hard to never get to this point
556              */
557             netsnmp_set_request_error(reqinfo, requests,
558                                       SNMP_ERR_COMMITFAILED);
559         }
560         break;
561 
562     case MODE_SET_UNDO:
563         /*
564          * XXX: UNDO and return to previous value for the object
565          */
566         if ( /* XXX: error? */ ) {
567             /*
568              * try _really_really_ hard to never get to this point
569              */
570             netsnmp_set_request_error(reqinfo, requests,
571                                       SNMP_ERR_UNDOFAILED);
572         }
573         break;
574 #endif
575 
576     default:
577         /*
578          * we should never get here, so this is a really bad error
579          */
580         snmp_log(LOG_ERR,
581                  "unknown mode (%d) in handle_ipv6IpDefaultHopLimit\n",
582                  reqinfo->mode);
583         return SNMP_ERR_GENERR;
584     }
585 
586     return SNMP_ERR_NOERROR;
587 }
588