net-snmp 5.7
bulk_to_next.c
00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #include <net-snmp/net-snmp-includes.h>
00004 #include <net-snmp/agent/net-snmp-agent-includes.h>
00005 
00006 #include <net-snmp/agent/bulk_to_next.h>
00007 
00020 netsnmp_mib_handler *
00021 netsnmp_get_bulk_to_next_handler(void)
00022 {
00023     netsnmp_mib_handler *handler =
00024         netsnmp_create_handler("bulk_to_next",
00025                                netsnmp_bulk_to_next_helper);
00026 
00027     if (NULL != handler)
00028         handler->flags |= MIB_HANDLER_AUTO_NEXT;
00029 
00030     return handler;
00031 }
00032 
00035 void
00036 netsnmp_bulk_to_next_fix_requests(netsnmp_request_info *requests)
00037 {
00038     netsnmp_request_info *request;
00039     /*
00040      * Make sure that:
00041      *    - repeats remain
00042      *    - last handler provided an answer
00043      *    - answer didn't exceed range end (ala check_getnext_results)
00044      *    - there is a next variable
00045      * then
00046      * update the varbinds for the next request series 
00047      */
00048     for (request = requests; request; request = request->next) {
00049         if (request->repeat > 0 &&
00050             request->requestvb->type != ASN_NULL &&
00051             request->requestvb->type != ASN_PRIV_RETRY &&
00052             (snmp_oid_compare(request->requestvb->name,
00053                               request->requestvb->name_length,
00054                               request->range_end,
00055                               request->range_end_len) < 0) &&
00056             request->requestvb->next_variable ) {
00057             request->repeat--;
00058             snmp_set_var_objid(request->requestvb->next_variable,
00059                                request->requestvb->name,
00060                                request->requestvb->name_length);
00061             request->requestvb = request->requestvb->next_variable;
00062             request->requestvb->type = ASN_PRIV_RETRY;
00063             /*
00064              * if inclusive == 2, it was set in check_getnext_results for
00065              * the previous requestvb. Now that we've moved on, clear it.
00066              */
00067             if (2 == request->inclusive)
00068                 request->inclusive = 0;
00069         }
00070     }
00071 }
00072 
00074 int
00075 netsnmp_bulk_to_next_helper(netsnmp_mib_handler *handler,
00076                             netsnmp_handler_registration *reginfo,
00077                             netsnmp_agent_request_info *reqinfo,
00078                             netsnmp_request_info *requests)
00079 {
00080 
00081     int             ret = SNMP_ERR_NOERROR;
00082 
00083     /*
00084      * this code depends on AUTO_NEXT being set
00085      */
00086     netsnmp_assert(handler->flags & MIB_HANDLER_AUTO_NEXT);
00087 
00088     /*
00089      * don't do anything for any modes besides GETBULK. Just return, and
00090      * the agent will call the next handler (AUTO_NEXT).
00091      *
00092      * for GETBULK, we munge the mode, call the next handler ourselves
00093      * (setting AUTO_NEXT_OVERRRIDE so the agent knows what we did),
00094      * restore the mode and fix up the requests.
00095      */
00096     if(MODE_GETBULK == reqinfo->mode) {
00097 
00098         DEBUGIF("bulk_to_next") {
00099             netsnmp_request_info *req = requests;
00100             while(req) {
00101                 DEBUGMSGTL(("bulk_to_next", "Got request: "));
00102                 DEBUGMSGOID(("bulk_to_next", req->requestvb->name,
00103                              req->requestvb->name_length));
00104                 DEBUGMSG(("bulk_to_next", "\n"));
00105                 req = req->next;
00106             }
00107         }
00108 
00109         reqinfo->mode = MODE_GETNEXT;
00110         ret =
00111             netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
00112         reqinfo->mode = MODE_GETBULK;
00113 
00114         /*
00115          * update the varbinds for the next request series 
00116          */
00117         netsnmp_bulk_to_next_fix_requests(requests);
00118 
00119         /*
00120          * let agent handler know that we've already called next handler
00121          */
00122         handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
00123     }
00124 
00125     return ret;
00126 }
00127 
00132 void
00133 netsnmp_init_bulk_to_next_helper(void)
00134 {
00135     netsnmp_register_handler_by_name("bulk_to_next",
00136                                      netsnmp_get_bulk_to_next_handler());
00137 }