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