net-snmp 5.7
|
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 }