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/stash_cache.h> 00013 #include <net-snmp/agent/stash_to_next.h> 00014 00026 netsnmp_mib_handler * 00027 netsnmp_get_stash_to_next_handler(void) 00028 { 00029 netsnmp_mib_handler *handler = 00030 netsnmp_create_handler("stash_to_next", 00031 netsnmp_stash_to_next_helper); 00032 00033 if (NULL != handler) 00034 handler->flags |= MIB_HANDLER_AUTO_NEXT; 00035 00036 return handler; 00037 } 00038 00040 int 00041 netsnmp_stash_to_next_helper(netsnmp_mib_handler *handler, 00042 netsnmp_handler_registration *reginfo, 00043 netsnmp_agent_request_info *reqinfo, 00044 netsnmp_request_info *requests) 00045 { 00046 00047 int ret = SNMP_ERR_NOERROR; 00048 int namelen; 00049 int finished = 0; 00050 netsnmp_oid_stash_node **cinfo; 00051 netsnmp_variable_list *vb; 00052 netsnmp_request_info *reqtmp; 00053 00054 /* 00055 * this code depends on AUTO_NEXT being set 00056 */ 00057 netsnmp_assert(handler->flags & MIB_HANDLER_AUTO_NEXT); 00058 00059 /* 00060 * Don't do anything for any modes except GET_STASH. Just return, 00061 * and the agent will call the next handler (AUTO_NEXT). 00062 * 00063 * If the handler chain already supports GET_STASH, we don't 00064 * need to do anything here either. Once again, we just return 00065 * and the agent will call the next handler (AUTO_NEXT). 00066 * 00067 * Otherwise, we munge the mode to GET_NEXT, and call the 00068 * next handler ourselves, repeatedly until we've retrieved the 00069 * full contents of the table or subtree. 00070 * Then restore the mode and return to the calling handler 00071 * (setting AUTO_NEXT_OVERRRIDE so the agent knows what we did). 00072 */ 00073 if (MODE_GET_STASH == reqinfo->mode) { 00074 if ( reginfo->modes & HANDLER_CAN_STASH ) { 00075 return ret; 00076 } 00077 cinfo = netsnmp_extract_stash_cache( reqinfo ); 00078 reqtmp = SNMP_MALLOC_TYPEDEF(netsnmp_request_info); 00079 vb = reqtmp->requestvb = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); 00080 vb->type = ASN_NULL; 00081 snmp_set_var_objid( vb, reginfo->rootoid, reginfo->rootoid_len ); 00082 00083 reqinfo->mode = MODE_GETNEXT; 00084 while (!finished) { 00085 ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, reqtmp); 00086 namelen = SNMP_MIN(vb->name_length, reginfo->rootoid_len); 00087 if ( !snmp_oid_compare( reginfo->rootoid, reginfo->rootoid_len, 00088 vb->name, namelen) && 00089 vb->type != ASN_NULL && vb->type != SNMP_ENDOFMIBVIEW ) { 00090 /* 00091 * This result is relevant so save it, and prepare 00092 * the request varbind for the next query. 00093 */ 00094 netsnmp_oid_stash_add_data( cinfo, vb->name, vb->name_length, 00095 snmp_clone_varbind( vb )); 00096 /* 00097 * Tidy up the response structure, 00098 * ready for retrieving the next entry 00099 */ 00100 netsnmp_free_all_list_data(reqtmp->parent_data); 00101 reqtmp->parent_data = NULL; 00102 reqtmp->processed = 0; 00103 vb->type = ASN_NULL; 00104 } else { 00105 finished = 1; 00106 } 00107 } 00108 reqinfo->mode = MODE_GET_STASH; 00109 00110 /* 00111 * let the handler chain processing know that we've already 00112 * called the next handler 00113 */ 00114 handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE; 00115 } 00116 00117 return ret; 00118 }
1.3.9.1
Last modified: Thursday, 01-Mar-2007 16:20:08 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.