00001 #include <net-snmp/net-snmp-config.h>
00002
00003 #include <stdlib.h>
00004 #if HAVE_STRING_H
00005 #include <string.h>
00006 #else
00007 #include <strings.h>
00008 #endif
00009
00010 #include <net-snmp/net-snmp-includes.h>
00011 #include <net-snmp/agent/net-snmp-agent-includes.h>
00012
00013 #include <net-snmp/agent/scalar_group.h>
00014 #include <net-snmp/agent/scalar.h>
00015 #include <net-snmp/agent/serialize.h>
00016 #include <net-snmp/agent/read_only.h>
00017
00023 netsnmp_mib_handler *
00024 netsnmp_get_scalar_group_handler(oid first, oid last)
00025 {
00026 netsnmp_mib_handler *ret = NULL;
00027 netsnmp_scalar_group *sgroup = NULL;
00028
00029 ret = netsnmp_create_handler("scalar_group",
00030 netsnmp_scalar_group_helper_handler);
00031 if (ret) {
00032 sgroup = SNMP_MALLOC_TYPEDEF(netsnmp_scalar_group);
00033 if (NULL == sgroup) {
00034 netsnmp_handler_free(ret);
00035 ret = NULL;
00036 }
00037 else {
00038 sgroup->lbound = first;
00039 sgroup->ubound = last;
00040 ret->myvoid = (void *)sgroup;
00041 }
00042 }
00043 return ret;
00044 }
00045
00046 int
00047 netsnmp_register_scalar_group(netsnmp_handler_registration *reginfo,
00048 oid first, oid last)
00049 {
00050 netsnmp_inject_handler(reginfo, netsnmp_get_instance_handler());
00051 netsnmp_inject_handler(reginfo, netsnmp_get_scalar_handler());
00052 netsnmp_inject_handler(reginfo, netsnmp_get_scalar_group_handler(first, last));
00053 return netsnmp_register_serialize(reginfo);
00054 }
00055
00056
00057 int
00058 netsnmp_scalar_group_helper_handler(netsnmp_mib_handler *handler,
00059 netsnmp_handler_registration *reginfo,
00060 netsnmp_agent_request_info *reqinfo,
00061 netsnmp_request_info *requests)
00062 {
00063 netsnmp_variable_list *var = requests->requestvb;
00064
00065 netsnmp_scalar_group *sgroup = (netsnmp_scalar_group *)handler->myvoid;
00066 int ret, cmp;
00067 int namelen;
00068 oid subid, root_tmp[MAX_OID_LEN], *root_save;
00069
00070 DEBUGMSGTL(("helper:scalar_group", "Got request:\n"));
00071 namelen = SNMP_MIN(requests->requestvb->name_length,
00072 reginfo->rootoid_len);
00073 cmp = snmp_oid_compare(requests->requestvb->name, namelen,
00074 reginfo->rootoid, reginfo->rootoid_len);
00075
00076 DEBUGMSGTL(( "helper:scalar_group", " cmp=%d, oid:", cmp));
00077 DEBUGMSGOID(("helper:scalar_group", var->name, var->name_length));
00078 DEBUGMSG(( "helper:scalar_group", "\n"));
00079
00080
00081
00082
00083
00084
00085 memcpy(root_tmp, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid));
00086 root_tmp[reginfo->rootoid_len + 1] = 0;
00087 root_save = reginfo->rootoid;
00088
00089 ret = SNMP_ERR_NOCREATION;
00090 switch (reqinfo->mode) {
00091
00092
00093
00094
00095
00096 case MODE_GET:
00097 ret = SNMP_NOSUCHOBJECT;
00098
00099
00100 case MODE_SET_RESERVE1:
00101 case MODE_SET_RESERVE2:
00102 case MODE_SET_ACTION:
00103 case MODE_SET_COMMIT:
00104 case MODE_SET_UNDO:
00105 case MODE_SET_FREE:
00106 if (cmp != 0 ||
00107 requests->requestvb->name_length <= reginfo->rootoid_len) {
00108
00109
00110
00111
00112 netsnmp_set_request_error(reqinfo, requests, ret);
00113 return SNMP_ERR_NOERROR;
00114 } else {
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 subid = requests->requestvb->name[reginfo->rootoid_len];
00126 if (subid < sgroup->lbound ||
00127 subid > sgroup->ubound) {
00128 netsnmp_set_request_error(reqinfo, requests, ret);
00129 return SNMP_ERR_NOERROR;
00130 }
00131 root_tmp[reginfo->rootoid_len++] = subid;
00132 reginfo->rootoid = root_tmp;
00133 ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
00134 requests);
00135 reginfo->rootoid = root_save;
00136 reginfo->rootoid_len--;
00137 return ret;
00138 }
00139 break;
00140
00141 case MODE_GETNEXT:
00142
00143
00144
00145
00146
00147
00148
00149 if (cmp < 0 ||
00150 requests->requestvb->name_length <= reginfo->rootoid_len) {
00151 subid = sgroup->lbound;
00152 } else if (requests->requestvb->name_length == reginfo->rootoid_len+1)
00153 subid = requests->requestvb->name[reginfo->rootoid_len];
00154 else
00155 subid = requests->requestvb->name[reginfo->rootoid_len]+1;
00156
00157
00158
00159
00160 if (subid > sgroup->ubound)
00161 return SNMP_ERR_NOERROR;
00162
00163 root_tmp[reginfo->rootoid_len++] = subid;
00164 reginfo->rootoid = root_tmp;
00165 ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
00166 requests);
00167
00168
00169
00170
00171 if (!requests->delegated &&
00172 (requests->requestvb->type == ASN_NULL ||
00173 requests->requestvb->type == SNMP_NOSUCHOBJECT ||
00174 requests->requestvb->type == SNMP_NOSUCHINSTANCE)) {
00175 snmp_set_var_objid(requests->requestvb,
00176 reginfo->rootoid, reginfo->rootoid_len);
00177 requests->requestvb->name[reginfo->rootoid_len-1] = ++subid;
00178 requests->requestvb->type = ASN_PRIV_RETRY;
00179 }
00180 reginfo->rootoid = root_save;
00181 reginfo->rootoid_len--;
00182 return ret;
00183 }
00184
00185
00186
00187 return SNMP_ERR_GENERR;
00188 }
00189