Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 1 | /* |
| 2 | * agent_index.c |
| 3 | * |
| 4 | * Maintain a registry of index allocations |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 5 | * (Primarily required for AgentX support, |
| 6 | * but it could be more widely useable). |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
| 9 | |
Wes Hardaker | eb6d4fc | 2002-01-04 21:00:48 +0000 | [diff] [blame] | 10 | #include <net-snmp/net-snmp-config.h> |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 11 | #include <net-snmp/net-snmp-features.h> |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 12 | #include <signal.h> |
| 13 | #if HAVE_STRING_H |
| 14 | #include <string.h> |
| 15 | #endif |
| 16 | #if HAVE_STDLIB_H |
| 17 | #include <stdlib.h> |
| 18 | #endif |
| 19 | #include <sys/types.h> |
| 20 | #include <stdio.h> |
| 21 | #include <fcntl.h> |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 22 | #if TIME_WITH_SYS_TIME |
Bart Van Assche | 337360e | 2010-01-24 11:41:03 +0000 | [diff] [blame] | 23 | # include <sys/time.h> |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 24 | # include <time.h> |
| 25 | #else |
| 26 | # if HAVE_SYS_TIME_H |
| 27 | # include <sys/time.h> |
| 28 | # else |
| 29 | # include <time.h> |
| 30 | # endif |
| 31 | #endif |
Wes Hardaker | 9743e9f | 2001-10-11 21:01:50 +0000 | [diff] [blame] | 32 | #if HAVE_NETINET_IN_H |
| 33 | #include <netinet/in.h> |
| 34 | #endif |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 35 | |
Dave Shield | 1f17c99 | 2002-02-08 15:45:13 +0000 | [diff] [blame] | 36 | #include <net-snmp/net-snmp-includes.h> |
| 37 | #include <net-snmp/agent/net-snmp-agent-includes.h> |
Wes Hardaker | 40342b7 | 2002-01-14 16:05:52 +0000 | [diff] [blame] | 38 | #include <net-snmp/agent/agent_callbacks.h> |
| 39 | #include <net-snmp/agent/agent_index.h> |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 40 | |
| 41 | #include "snmpd.h" |
| 42 | #include "mibgroup/struct.h" |
Dave Shield | 1f17c99 | 2002-02-08 15:45:13 +0000 | [diff] [blame] | 43 | #include <net-snmp/agent/table.h> |
| 44 | #include <net-snmp/agent/table_iterator.h> |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 45 | |
| 46 | #ifdef USING_AGENTX_SUBAGENT_MODULE |
| 47 | #include "agentx/subagent.h" |
| 48 | #include "agentx/client.h" |
| 49 | #endif |
| 50 | |
Wes Hardaker | a8b1391 | 2011-02-26 01:22:21 +0000 | [diff] [blame] | 51 | netsnmp_feature_child_of(agent_index_all, libnetsnmpagent) |
| 52 | |
| 53 | netsnmp_feature_child_of(remove_index, agent_index_all) |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 54 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 55 | /* |
| 56 | * Initial support for index allocation |
| 57 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 58 | |
| 59 | struct snmp_index { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 60 | netsnmp_variable_list *varbind; /* or pointer to var_list ? */ |
| 61 | int allocated; |
| 62 | netsnmp_session *session; |
| 63 | struct snmp_index *next_oid; |
| 64 | struct snmp_index *prev_oid; |
| 65 | struct snmp_index *next_idx; |
| 66 | } *snmp_index_head = NULL; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 67 | |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 68 | extern netsnmp_session *main_session; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 69 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 70 | /* |
| 71 | * The caller is responsible for free()ing the memory returned by |
| 72 | * this function. |
| 73 | */ |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 74 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 75 | char * |
| 76 | register_string_index(oid * name, size_t name_len, char *cp) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 77 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 78 | netsnmp_variable_list varbind, *res; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 79 | |
| 80 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 81 | varbind.type = ASN_OCTET_STR; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 82 | snmp_set_var_objid(&varbind, name, name_len); |
| 83 | if (cp != ANY_STRING_INDEX) { |
| 84 | snmp_set_var_value(&varbind, (u_char *) cp, strlen(cp)); |
| 85 | res = register_index(&varbind, ALLOCATE_THIS_INDEX, main_session); |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 86 | } else { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 87 | res = register_index(&varbind, ALLOCATE_ANY_INDEX, main_session); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 88 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 89 | |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 90 | if (res == NULL) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 91 | return NULL; |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 92 | } else { |
Dave Shield | 30878de | 2010-06-12 10:26:13 +0000 | [diff] [blame] | 93 | char *rv = (char *)malloc(res->val_len + 1); |
Bart Van Assche | 90a1475 | 2009-12-28 18:03:23 +0000 | [diff] [blame] | 94 | if (rv) { |
| 95 | memcpy(rv, res->val.string, res->val_len); |
| 96 | rv[res->val_len] = 0; |
| 97 | } |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 98 | free(res); |
| 99 | return rv; |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 100 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 104 | register_int_index(oid * name, size_t name_len, int val) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 105 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 106 | netsnmp_variable_list varbind, *res; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 107 | |
| 108 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 109 | varbind.type = ASN_INTEGER; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 110 | snmp_set_var_objid(&varbind, name, name_len); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 111 | varbind.val.string = varbind.buf; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 112 | if (val != ANY_INTEGER_INDEX) { |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 113 | varbind.val_len = sizeof(long); |
| 114 | *varbind.val.integer = val; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 115 | res = register_index(&varbind, ALLOCATE_THIS_INDEX, main_session); |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 116 | } else { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 117 | res = register_index(&varbind, ALLOCATE_ANY_INDEX, main_session); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 118 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 119 | |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 120 | if (res == NULL) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 121 | return -1; |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 122 | } else { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 123 | int rv = *(res->val.integer); |
| 124 | free(res); |
| 125 | return rv; |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 126 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 127 | } |
| 128 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 129 | /* |
| 130 | * The caller is responsible for free()ing the memory returned by |
| 131 | * this function. |
| 132 | */ |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 133 | |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 134 | netsnmp_variable_list * |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 135 | register_oid_index(oid * name, size_t name_len, |
| 136 | oid * value, size_t value_len) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 137 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 138 | netsnmp_variable_list varbind; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 139 | |
| 140 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 141 | varbind.type = ASN_OBJECT_ID; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 142 | snmp_set_var_objid(&varbind, name, name_len); |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 143 | if (value != ANY_OID_INDEX) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 144 | snmp_set_var_value(&varbind, (u_char *) value, |
| 145 | value_len * sizeof(oid)); |
| 146 | return register_index(&varbind, ALLOCATE_THIS_INDEX, main_session); |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 147 | } else { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 148 | return register_index(&varbind, ALLOCATE_ANY_INDEX, main_session); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 149 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 150 | } |
| 151 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 152 | /* |
| 153 | * The caller is responsible for free()ing the memory returned by |
| 154 | * this function. |
| 155 | */ |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 156 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 157 | netsnmp_variable_list * |
| 158 | register_index(netsnmp_variable_list * varbind, int flags, |
| 159 | netsnmp_session * ss) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 160 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 161 | netsnmp_variable_list *rv = NULL; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 162 | struct snmp_index *new_index, *idxptr, *idxptr2; |
| 163 | struct snmp_index *prev_oid_ptr, *prev_idx_ptr; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 164 | int res, res2, i; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 165 | |
John Naylon | db64aeb | 2002-03-05 16:48:42 +0000 | [diff] [blame] | 166 | DEBUGMSGTL(("register_index", "register ")); |
| 167 | DEBUGMSGVAR(("register_index", varbind)); |
Magnus Fromreide | 759220f | 2008-05-10 09:55:02 +0000 | [diff] [blame] | 168 | DEBUGMSG(("register_index", "for session %8p\n", ss)); |
John Naylon | 9a60b41 | 2001-06-05 10:10:45 +0000 | [diff] [blame] | 169 | |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 170 | #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING) |
John Naylon | bb401c1 | 2002-05-15 12:53:01 +0000 | [diff] [blame] | 171 | if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, |
| 172 | NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 173 | return (agentx_register_index(ss, varbind, flags)); |
John Naylon | bb401c1 | 2002-05-15 12:53:01 +0000 | [diff] [blame] | 174 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 175 | #endif |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 176 | /* |
| 177 | * Look for the requested OID entry |
| 178 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 179 | prev_oid_ptr = NULL; |
| 180 | prev_idx_ptr = NULL; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 181 | res = 1; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 182 | res2 = 1; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 183 | for (idxptr = snmp_index_head; idxptr != NULL; |
| 184 | prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) { |
| 185 | if ((res = snmp_oid_compare(varbind->name, varbind->name_length, |
| 186 | idxptr->varbind->name, |
| 187 | idxptr->varbind->name_length)) <= 0) |
| 188 | break; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 189 | } |
| 190 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 191 | /* |
| 192 | * Found the OID - now look at the registered indices |
| 193 | */ |
| 194 | if (res == 0 && idxptr) { |
| 195 | if (varbind->type != idxptr->varbind->type) |
| 196 | return NULL; /* wrong type */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 197 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 198 | /* |
| 199 | * If we've been asked for an arbitrary new value, |
| 200 | * then find the end of the list. |
| 201 | * If we've been asked for any arbitrary value, |
| 202 | * then look for an unused entry, and use that. |
| 203 | * If there aren't any, continue as for new. |
| 204 | * Otherwise, locate the given value in the (sorted) |
| 205 | * list of already allocated values |
| 206 | */ |
| 207 | if (flags & ALLOCATE_ANY_INDEX) { |
| 208 | for (idxptr2 = idxptr; idxptr2 != NULL; |
| 209 | prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { |
John Naylon | 496ba56 | 2001-06-19 16:44:38 +0000 | [diff] [blame] | 210 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 211 | if (flags == ALLOCATE_ANY_INDEX && !(idxptr2->allocated)) { |
| 212 | if ((rv = |
| 213 | snmp_clone_varbind(idxptr2->varbind)) != NULL) { |
| 214 | idxptr2->session = ss; |
| 215 | idxptr2->allocated = 1; |
| 216 | } |
| 217 | return rv; |
| 218 | } |
| 219 | } |
| 220 | } else { |
| 221 | for (idxptr2 = idxptr; idxptr2 != NULL; |
| 222 | prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { |
| 223 | switch (varbind->type) { |
| 224 | case ASN_INTEGER: |
| 225 | res2 = |
| 226 | (*varbind->val.integer - |
| 227 | *idxptr2->varbind->val.integer); |
| 228 | break; |
| 229 | case ASN_OCTET_STR: |
| 230 | i = SNMP_MIN(varbind->val_len, |
| 231 | idxptr2->varbind->val_len); |
| 232 | res2 = |
| 233 | memcmp(varbind->val.string, |
| 234 | idxptr2->varbind->val.string, i); |
| 235 | break; |
| 236 | case ASN_OBJECT_ID: |
| 237 | res2 = |
| 238 | snmp_oid_compare(varbind->val.objid, |
| 239 | varbind->val_len / sizeof(oid), |
| 240 | idxptr2->varbind->val.objid, |
| 241 | idxptr2->varbind->val_len / |
| 242 | sizeof(oid)); |
| 243 | break; |
| 244 | default: |
| 245 | return NULL; /* wrong type */ |
| 246 | } |
| 247 | if (res2 <= 0) |
| 248 | break; |
| 249 | } |
| 250 | if (res2 == 0) { |
| 251 | if (idxptr2->allocated) { |
| 252 | /* |
| 253 | * No good: the index is in use. |
| 254 | */ |
| 255 | return NULL; |
| 256 | } else { |
| 257 | /* |
| 258 | * Okay, it's unallocated, we can just claim ownership |
| 259 | * here. |
| 260 | */ |
| 261 | if ((rv = |
| 262 | snmp_clone_varbind(idxptr2->varbind)) != NULL) { |
| 263 | idxptr2->session = ss; |
| 264 | idxptr2->allocated = 1; |
| 265 | } |
| 266 | return rv; |
| 267 | } |
| 268 | } |
| 269 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 270 | } |
| 271 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 272 | /* |
| 273 | * OK - we've now located where the new entry needs to |
| 274 | * be fitted into the index registry tree |
| 275 | * To recap: |
| 276 | * 'prev_oid_ptr' points to the head of the OID index |
| 277 | * list prior to this one. If this is null, then |
| 278 | * it means that this is the first OID in the list. |
| 279 | * 'idxptr' points either to the head of this OID list, |
| 280 | * or the next OID (if this is a new OID request) |
| 281 | * These can be distinguished by the value of 'res'. |
| 282 | * |
| 283 | * 'prev_idx_ptr' points to the index entry that sorts |
| 284 | * immediately prior to the requested value (if any). |
| 285 | * If an arbitrary value is required, then this will |
| 286 | * point to the last allocated index. |
| 287 | * If this pointer is null, then either this is a new |
| 288 | * OID request, or the requested value is the first |
| 289 | * in the list. |
| 290 | * 'idxptr2' points to the next sorted index (if any) |
| 291 | * but is not actually needed any more. |
| 292 | * |
| 293 | * Clear? Good! |
| 294 | * I hope you've been paying attention. |
| 295 | * There'll be a test later :-) |
| 296 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 297 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 298 | /* |
| 299 | * We proceed by creating the new entry |
| 300 | * (by copying the entry provided) |
| 301 | */ |
| 302 | new_index = (struct snmp_index *) calloc(1, sizeof(struct snmp_index)); |
| 303 | if (new_index == NULL) |
| 304 | return NULL; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 305 | |
Magnus Fromreide | 465e8e6 | 2008-05-09 21:35:32 +0000 | [diff] [blame] | 306 | if (NULL == snmp_varlist_add_variable(&new_index->varbind, |
| 307 | varbind->name, |
| 308 | varbind->name_length, |
| 309 | varbind->type, |
| 310 | varbind->val.string, |
| 311 | varbind->val_len)) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 312 | /* |
| 313 | * if (snmp_clone_var( varbind, new_index->varbind ) != 0 ) |
| 314 | */ |
| 315 | free(new_index); |
| 316 | return NULL; |
| 317 | } |
| 318 | new_index->session = ss; |
| 319 | new_index->allocated = 1; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 320 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 321 | if (varbind->type == ASN_OCTET_STR && flags == ALLOCATE_THIS_INDEX) |
| 322 | new_index->varbind->val.string[new_index->varbind->val_len] = 0; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 323 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 324 | /* |
| 325 | * If we've been given a value, then we can use that, but |
| 326 | * otherwise, we need to create a new value for this entry. |
| 327 | * Note that ANY_INDEX and NEW_INDEX are both covered by this |
| 328 | * test (since NEW_INDEX & ANY_INDEX = ANY_INDEX, remember?) |
| 329 | */ |
| 330 | if (flags & ALLOCATE_ANY_INDEX) { |
| 331 | if (prev_idx_ptr) { |
| 332 | if (snmp_clone_var(prev_idx_ptr->varbind, new_index->varbind) |
| 333 | != 0) { |
| 334 | free(new_index); |
| 335 | return NULL; |
| 336 | } |
| 337 | } else |
| 338 | new_index->varbind->val.string = new_index->varbind->buf; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 339 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 340 | switch (varbind->type) { |
| 341 | case ASN_INTEGER: |
| 342 | if (prev_idx_ptr) { |
| 343 | (*new_index->varbind->val.integer)++; |
| 344 | } else |
| 345 | *(new_index->varbind->val.integer) = 1; |
| 346 | new_index->varbind->val_len = sizeof(long); |
| 347 | break; |
| 348 | case ASN_OCTET_STR: |
| 349 | if (prev_idx_ptr) { |
| 350 | i = new_index->varbind->val_len - 1; |
| 351 | while (new_index->varbind->buf[i] == 'z') { |
| 352 | new_index->varbind->buf[i] = 'a'; |
| 353 | i--; |
| 354 | if (i < 0) { |
| 355 | i = new_index->varbind->val_len; |
| 356 | new_index->varbind->buf[i] = 'a'; |
| 357 | new_index->varbind->buf[i + 1] = 0; |
| 358 | } |
| 359 | } |
| 360 | new_index->varbind->buf[i]++; |
| 361 | } else |
| 362 | strcpy((char *) new_index->varbind->buf, "aaaa"); |
| 363 | new_index->varbind->val_len = |
| 364 | strlen((char *) new_index->varbind->buf); |
| 365 | break; |
| 366 | case ASN_OBJECT_ID: |
| 367 | if (prev_idx_ptr) { |
| 368 | i = prev_idx_ptr->varbind->val_len / sizeof(oid) - 1; |
| 369 | while (new_index->varbind->val.objid[i] == 255) { |
| 370 | new_index->varbind->val.objid[i] = 1; |
| 371 | i--; |
| 372 | if (i == 0 && new_index->varbind->val.objid[0] == 2) { |
| 373 | new_index->varbind->val.objid[0] = 1; |
| 374 | i = new_index->varbind->val_len / sizeof(oid); |
| 375 | new_index->varbind->val.objid[i] = 0; |
| 376 | new_index->varbind->val_len += sizeof(oid); |
| 377 | } |
| 378 | } |
| 379 | new_index->varbind->val.objid[i]++; |
| 380 | } else { |
| 381 | /* |
| 382 | * If the requested OID name is small enough, |
| 383 | * * append another OID (1) and use this as the |
| 384 | * * default starting value for new indexes. |
| 385 | */ |
| 386 | if ((varbind->name_length + 1) * sizeof(oid) <= 40) { |
| 387 | for (i = 0; i < (int) varbind->name_length; i++) |
| 388 | new_index->varbind->val.objid[i] = |
| 389 | varbind->name[i]; |
| 390 | new_index->varbind->val.objid[varbind->name_length] = |
| 391 | 1; |
| 392 | new_index->varbind->val_len = |
| 393 | (varbind->name_length + 1) * sizeof(oid); |
| 394 | } else { |
| 395 | /* |
| 396 | * Otherwise use '.1.1.1.1...' |
| 397 | */ |
| 398 | i = 40 / sizeof(oid); |
| 399 | if (i > 4) |
| 400 | i = 4; |
| 401 | new_index->varbind->val_len = i * (sizeof(oid)); |
| 402 | for (i--; i >= 0; i--) |
| 403 | new_index->varbind->val.objid[i] = 1; |
| 404 | } |
| 405 | } |
| 406 | break; |
| 407 | default: |
| 408 | snmp_free_var(new_index->varbind); |
| 409 | free(new_index); |
| 410 | return NULL; /* Index type not supported */ |
| 411 | } |
| 412 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 413 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 414 | /* |
| 415 | * Try to duplicate the new varbind for return. |
| 416 | */ |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 417 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 418 | if ((rv = snmp_clone_varbind(new_index->varbind)) == NULL) { |
| 419 | snmp_free_var(new_index->varbind); |
| 420 | free(new_index); |
| 421 | return NULL; |
| 422 | } |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 423 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 424 | /* |
| 425 | * Right - we've set up the new entry. |
| 426 | * All that remains is to link it into the tree. |
| 427 | * There are a number of possible cases here, |
| 428 | * so watch carefully. |
| 429 | */ |
| 430 | if (prev_idx_ptr) { |
| 431 | new_index->next_idx = prev_idx_ptr->next_idx; |
| 432 | new_index->next_oid = prev_idx_ptr->next_oid; |
| 433 | prev_idx_ptr->next_idx = new_index; |
| 434 | } else { |
| 435 | if (res == 0 && idxptr) { |
| 436 | new_index->next_idx = idxptr; |
| 437 | new_index->next_oid = idxptr->next_oid; |
| 438 | } else { |
| 439 | new_index->next_idx = NULL; |
| 440 | new_index->next_oid = idxptr; |
| 441 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 442 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 443 | if (prev_oid_ptr) { |
| 444 | while (prev_oid_ptr) { |
| 445 | prev_oid_ptr->next_oid = new_index; |
| 446 | prev_oid_ptr = prev_oid_ptr->next_idx; |
| 447 | } |
| 448 | } else |
| 449 | snmp_index_head = new_index; |
| 450 | } |
John Naylon | a5bf331 | 2001-06-06 14:37:08 +0000 | [diff] [blame] | 451 | return rv; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 452 | } |
| 453 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 454 | /* |
| 455 | * Release an allocated index, |
| 456 | * to allow it to be used elsewhere |
| 457 | */ |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 458 | netsnmp_feature_child_of(release_index,netsnmp_unused) |
| 459 | #ifndef NETSNMP_FEATURE_REMOVE_RELEASE_INDEX |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 460 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 461 | release_index(netsnmp_variable_list * varbind) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 462 | { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 463 | return (unregister_index(varbind, TRUE, NULL)); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 464 | } |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 465 | #endif /* NETSNMP_FEATURE_REMOVE_RELEASE_INDEX */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 466 | |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 467 | #ifndef NETSNMP_FEATURE_REMOVE_REMOVE_INDEX |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 468 | /* |
| 469 | * Completely remove an allocated index, |
| 470 | * due to errors in the registration process. |
| 471 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 472 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 473 | remove_index(netsnmp_variable_list * varbind, netsnmp_session * ss) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 474 | { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 475 | return (unregister_index(varbind, FALSE, ss)); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 476 | } |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 477 | #endif /* NETSNMP_FEATURE_REMOVE_REMOVE_INDEX */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 478 | |
| 479 | void |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 480 | unregister_index_by_session(netsnmp_session * ss) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 481 | { |
| 482 | struct snmp_index *idxptr, *idxptr2; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 483 | for (idxptr = snmp_index_head; idxptr != NULL; |
| 484 | idxptr = idxptr->next_oid) |
| 485 | for (idxptr2 = idxptr; idxptr2 != NULL; |
| 486 | idxptr2 = idxptr2->next_idx) |
| 487 | if (idxptr2->session == ss) { |
| 488 | idxptr2->allocated = 0; |
| 489 | idxptr2->session = NULL; |
| 490 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 491 | } |
| 492 | |
| 493 | |
| 494 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 495 | unregister_index(netsnmp_variable_list * varbind, int remember, |
| 496 | netsnmp_session * ss) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 497 | { |
| 498 | struct snmp_index *idxptr, *idxptr2; |
| 499 | struct snmp_index *prev_oid_ptr, *prev_idx_ptr; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 500 | int res, res2, i; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 501 | |
| 502 | #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(TESTING) |
John Naylon | bb401c1 | 2002-05-15 12:53:01 +0000 | [diff] [blame] | 503 | if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, |
| 504 | NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 505 | return (agentx_unregister_index(ss, varbind)); |
John Naylon | bb401c1 | 2002-05-15 12:53:01 +0000 | [diff] [blame] | 506 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 507 | #endif |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 508 | /* |
| 509 | * Look for the requested OID entry |
| 510 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 511 | prev_oid_ptr = NULL; |
| 512 | prev_idx_ptr = NULL; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 513 | res = 1; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 514 | res2 = 1; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 515 | for (idxptr = snmp_index_head; idxptr != NULL; |
| 516 | prev_oid_ptr = idxptr, idxptr = idxptr->next_oid) { |
| 517 | if ((res = snmp_oid_compare(varbind->name, varbind->name_length, |
| 518 | idxptr->varbind->name, |
| 519 | idxptr->varbind->name_length)) <= 0) |
| 520 | break; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 521 | } |
| 522 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 523 | if (res != 0) |
| 524 | return INDEX_ERR_NOT_ALLOCATED; |
| 525 | if (varbind->type != idxptr->varbind->type) |
| 526 | return INDEX_ERR_WRONG_TYPE; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 527 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 528 | for (idxptr2 = idxptr; idxptr2 != NULL; |
| 529 | prev_idx_ptr = idxptr2, idxptr2 = idxptr2->next_idx) { |
Dave Shield | a32ca93 | 2013-01-08 16:42:54 +0000 | [diff] [blame] | 530 | switch (varbind->type) { |
| 531 | case ASN_INTEGER: |
| 532 | res2 = |
| 533 | (*varbind->val.integer - |
| 534 | *idxptr2->varbind->val.integer); |
| 535 | break; |
| 536 | case ASN_OCTET_STR: |
| 537 | i = SNMP_MIN(varbind->val_len, |
| 538 | idxptr2->varbind->val_len); |
| 539 | res2 = |
| 540 | memcmp(varbind->val.string, |
| 541 | idxptr2->varbind->val.string, i); |
| 542 | break; |
| 543 | case ASN_OBJECT_ID: |
| 544 | res2 = |
| 545 | snmp_oid_compare(varbind->val.objid, |
| 546 | varbind->val_len / sizeof(oid), |
| 547 | idxptr2->varbind->val.objid, |
| 548 | idxptr2->varbind->val_len / |
| 549 | sizeof(oid)); |
| 550 | break; |
| 551 | default: |
| 552 | return INDEX_ERR_WRONG_TYPE; /* wrong type */ |
| 553 | } |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 554 | if (res2 <= 0) |
| 555 | break; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 556 | } |
John Naylon | 496ba56 | 2001-06-19 16:44:38 +0000 | [diff] [blame] | 557 | if (res2 != 0 || (res2 == 0 && !idxptr2->allocated)) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 558 | return INDEX_ERR_NOT_ALLOCATED; |
John Naylon | 496ba56 | 2001-06-19 16:44:38 +0000 | [diff] [blame] | 559 | } |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 560 | if (ss != idxptr2->session) |
| 561 | return INDEX_ERR_WRONG_SESSION; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 562 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 563 | /* |
| 564 | * If this is a "normal" index unregistration, |
| 565 | * mark the index entry as unused, but leave |
| 566 | * it in situ. This allows differentiation |
| 567 | * between ANY_INDEX and NEW_INDEX |
| 568 | */ |
| 569 | if (remember) { |
| 570 | idxptr2->allocated = 0; /* Unused index */ |
| 571 | idxptr2->session = NULL; |
| 572 | return SNMP_ERR_NOERROR; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 573 | } |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 574 | /* |
| 575 | * If this is a failed attempt to register a |
| 576 | * number of indexes, the successful ones |
| 577 | * must be removed completely. |
| 578 | */ |
| 579 | if (prev_idx_ptr) { |
| 580 | prev_idx_ptr->next_idx = idxptr2->next_idx; |
| 581 | } else if (prev_oid_ptr) { |
| 582 | if (idxptr2->next_idx) /* Use p_idx_ptr as a temp variable */ |
| 583 | prev_idx_ptr = idxptr2->next_idx; |
| 584 | else |
| 585 | prev_idx_ptr = idxptr2->next_oid; |
| 586 | while (prev_oid_ptr) { |
| 587 | prev_oid_ptr->next_oid = prev_idx_ptr; |
| 588 | prev_oid_ptr = prev_oid_ptr->next_idx; |
| 589 | } |
| 590 | } else { |
| 591 | if (idxptr2->next_idx) |
| 592 | snmp_index_head = idxptr2->next_idx; |
| 593 | else |
| 594 | snmp_index_head = idxptr2->next_oid; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 595 | } |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 596 | snmp_free_var(idxptr2->varbind); |
| 597 | free(idxptr2); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 598 | return SNMP_ERR_NOERROR; |
| 599 | } |
| 600 | |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 601 | netsnmp_feature_child_of(unregister_indexes,netsnmp_unused) |
| 602 | #ifndef NETSNMP_FEATURE_REMOVE_UNREGISTER_INDEXES |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 603 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 604 | unregister_string_index(oid * name, size_t name_len, char *cp) |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 605 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 606 | netsnmp_variable_list varbind; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 607 | |
| 608 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 609 | varbind.type = ASN_OCTET_STR; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 610 | snmp_set_var_objid(&varbind, name, name_len); |
| 611 | snmp_set_var_value(&varbind, (u_char *) cp, strlen(cp)); |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 612 | return (unregister_index(&varbind, FALSE, main_session)); |
| 613 | } |
| 614 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 615 | int |
| 616 | unregister_int_index(oid * name, size_t name_len, int val) |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 617 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 618 | netsnmp_variable_list varbind; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 619 | |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 620 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 621 | varbind.type = ASN_INTEGER; |
| 622 | snmp_set_var_objid(&varbind, name, name_len); |
| 623 | varbind.val.string = varbind.buf; |
| 624 | varbind.val_len = sizeof(long); |
| 625 | *varbind.val.integer = val; |
| 626 | return (unregister_index(&varbind, FALSE, main_session)); |
| 627 | } |
| 628 | |
| 629 | int |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 630 | unregister_oid_index(oid * name, size_t name_len, |
| 631 | oid * value, size_t value_len) |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 632 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 633 | netsnmp_variable_list varbind; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 634 | |
| 635 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 636 | varbind.type = ASN_OBJECT_ID; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 637 | snmp_set_var_objid(&varbind, name, name_len); |
| 638 | snmp_set_var_value(&varbind, (u_char *) value, |
| 639 | value_len * sizeof(oid)); |
John Naylon | 481a309 | 2001-11-20 16:29:41 +0000 | [diff] [blame] | 640 | return (unregister_index(&varbind, FALSE, main_session)); |
| 641 | } |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 642 | #endif /* NETSNMP_FEATURE_REMOVE_UNREGISTER_INDEXES */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 643 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 644 | void |
| 645 | dump_idx_registry(void) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 646 | { |
| 647 | struct snmp_index *idxptr, *idxptr2; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 648 | u_char *sbuf = NULL, *ebuf = NULL; |
| 649 | size_t sbuf_len = 0, sout_len = 0, ebuf_len = 0, eout_len = 0; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 650 | |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 651 | if (snmp_index_head != NULL) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 652 | printf("\nIndex Allocations:\n"); |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 653 | } |
| 654 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 655 | for (idxptr = snmp_index_head; idxptr != NULL; |
| 656 | idxptr = idxptr->next_oid) { |
| 657 | sout_len = 0; |
| 658 | if (sprint_realloc_objid(&sbuf, &sbuf_len, &sout_len, 1, |
| 659 | idxptr->varbind->name, |
| 660 | idxptr->varbind->name_length)) { |
| 661 | printf("%s indexes:\n", sbuf); |
| 662 | } else { |
| 663 | printf("%s [TRUNCATED] indexes:\n", sbuf); |
| 664 | } |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 665 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 666 | for (idxptr2 = idxptr; idxptr2 != NULL; |
| 667 | idxptr2 = idxptr2->next_idx) { |
| 668 | switch (idxptr2->varbind->type) { |
| 669 | case ASN_INTEGER: |
John Naylon | a1a4a84 | 2002-07-10 09:35:38 +0000 | [diff] [blame] | 670 | printf(" %ld for session %8p, allocated %d\n", |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 671 | *idxptr2->varbind->val.integer, idxptr2->session, |
| 672 | idxptr2->allocated); |
| 673 | break; |
| 674 | case ASN_OCTET_STR: |
John Naylon | a1a4a84 | 2002-07-10 09:35:38 +0000 | [diff] [blame] | 675 | printf(" \"%s\" for session %8p, allocated %d\n", |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 676 | idxptr2->varbind->val.string, idxptr2->session, |
| 677 | idxptr2->allocated); |
| 678 | break; |
| 679 | case ASN_OBJECT_ID: |
| 680 | eout_len = 0; |
| 681 | if (sprint_realloc_objid(&ebuf, &ebuf_len, &eout_len, 1, |
| 682 | idxptr2->varbind->val.objid, |
| 683 | idxptr2->varbind->val_len / |
| 684 | sizeof(oid))) { |
John Naylon | a1a4a84 | 2002-07-10 09:35:38 +0000 | [diff] [blame] | 685 | printf(" %s for session %8p, allocated %d\n", ebuf, |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 686 | idxptr2->session, idxptr2->allocated); |
| 687 | } else { |
| 688 | printf |
John Naylon | a1a4a84 | 2002-07-10 09:35:38 +0000 | [diff] [blame] | 689 | (" %s [TRUNCATED] for sess %8p, allocated %d\n", |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 690 | ebuf, idxptr2->session, idxptr2->allocated); |
| 691 | } |
| 692 | break; |
| 693 | default: |
| 694 | printf("unsupported type (%d/0x%02x)\n", |
| 695 | idxptr2->varbind->type, idxptr2->varbind->type); |
| 696 | } |
| 697 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 698 | } |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 699 | |
| 700 | if (sbuf != NULL) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 701 | free(sbuf); |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 702 | } |
| 703 | if (ebuf != NULL) { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 704 | free(ebuf); |
John Naylon | 3bee5ee | 2002-02-27 12:35:42 +0000 | [diff] [blame] | 705 | } |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 706 | } |
| 707 | |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 708 | netsnmp_feature_child_of(count_indexes, netsnmp_unused) |
| 709 | #ifndef NETSNMP_FEATURE_REMOVE_UNUSED |
John Naylon | a5f53ae | 2001-06-20 13:44:18 +0000 | [diff] [blame] | 710 | unsigned long |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 711 | count_indexes(oid * name, size_t namelen, int include_unallocated) |
John Naylon | a5f53ae | 2001-06-20 13:44:18 +0000 | [diff] [blame] | 712 | { |
| 713 | struct snmp_index *i = NULL, *j = NULL; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 714 | unsigned long n = 0; |
John Naylon | a5f53ae | 2001-06-20 13:44:18 +0000 | [diff] [blame] | 715 | |
| 716 | for (i = snmp_index_head; i != NULL; i = i->next_oid) { |
Wes Hardaker | bb4d05c | 2002-08-15 15:14:22 +0000 | [diff] [blame] | 717 | if (netsnmp_oid_equals(name, namelen, |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 718 | i->varbind->name, |
| 719 | i->varbind->name_length) == 0) { |
| 720 | for (j = i; j != NULL; j = j->next_idx) { |
| 721 | if (j->allocated || include_unallocated) { |
| 722 | n++; |
| 723 | } |
| 724 | } |
| 725 | } |
John Naylon | a5f53ae | 2001-06-20 13:44:18 +0000 | [diff] [blame] | 726 | } |
| 727 | return n; |
| 728 | } |
Wes Hardaker | 3b14c59 | 2011-02-23 00:01:18 +0000 | [diff] [blame] | 729 | #endif /* NETSNMP_FEATURE_REMOVE_UNUSED */ |
John Naylon | a5f53ae | 2001-06-20 13:44:18 +0000 | [diff] [blame] | 730 | |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 731 | #ifdef TESTING |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 732 | netsnmp_variable_list varbind; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 733 | netsnmp_session main_sess, *main_session = &main_sess; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 734 | |
| 735 | void |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 736 | test_string_register(int n, char *cp) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 737 | { |
| 738 | varbind->name[4] = n; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 739 | if (register_string_index(varbind->name, varbind.name_length, cp) == |
| 740 | NULL) |
| 741 | printf("allocating %s failed\n", cp); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 742 | } |
| 743 | |
| 744 | void |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 745 | test_int_register(int n, int val) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 746 | { |
| 747 | varbind->name[4] = n; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 748 | if (register_int_index(varbind->name, varbind.name_length, val) == -1) |
| 749 | printf("allocating %d/%d failed\n", n, val); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 750 | } |
| 751 | |
| 752 | void |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 753 | test_oid_register(int n, int subid) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 754 | { |
Wes Hardaker | 73925b8 | 2002-03-09 00:28:07 +0000 | [diff] [blame] | 755 | netsnmp_variable_list *res; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 756 | |
| 757 | varbind->name[4] = n; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 758 | if (subid != -1) { |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 759 | varbind->val.objid[5] = subid; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 760 | res = register_oid_index(varbind->name, varbind.name_length, |
| 761 | varbind->val.objid, |
| 762 | varbind->val_len / sizeof(oid)); |
| 763 | } else |
| 764 | res = |
| 765 | register_oid_index(varbind->name, varbind.name_length, NULL, |
| 766 | 0); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 767 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 768 | if (res == NULL) |
| 769 | printf("allocating %d/%d failed\n", n, subid); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 770 | } |
| 771 | |
| 772 | void |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 773 | main(int argc, char argv[]) |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 774 | { |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 775 | oid name[] = { 1, 2, 3, 4, 0 }; |
| 776 | int i; |
| 777 | |
| 778 | memset(&varbind, 0, sizeof(netsnmp_variable_list)); |
| 779 | snmp_set_var_objid(&varbind, name, 5); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 780 | varbind->type = ASN_OCTET_STR; |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 781 | /* |
| 782 | * Test index structure linking: |
| 783 | * a) sorted by OID |
| 784 | */ |
| 785 | test_string_register(20, "empty OID"); |
| 786 | test_string_register(10, "first OID"); |
| 787 | test_string_register(40, "last OID"); |
| 788 | test_string_register(30, "middle OID"); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 789 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 790 | /* |
| 791 | * b) sorted by index value |
| 792 | */ |
| 793 | test_string_register(25, "eee: empty IDX"); |
| 794 | test_string_register(25, "aaa: first IDX"); |
| 795 | test_string_register(25, "zzz: last IDX"); |
| 796 | test_string_register(25, "mmm: middle IDX"); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 797 | printf("This next one should fail....\n"); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 798 | test_string_register(25, "eee: empty IDX"); /* duplicate */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 799 | printf("done\n"); |
| 800 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 801 | /* |
| 802 | * c) test initial index linking |
| 803 | */ |
| 804 | test_string_register(5, "eee: empty initial IDX"); |
| 805 | test_string_register(5, "aaa: replace initial IDX"); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 806 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 807 | /* |
| 808 | * Did it all work? |
| 809 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 810 | dump_idx_registry(); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 811 | unregister_index_by_session(main_session); |
| 812 | /* |
| 813 | * Now test index allocation |
| 814 | * a) integer values |
| 815 | */ |
| 816 | test_int_register(110, -1); /* empty */ |
| 817 | test_int_register(110, -1); /* append */ |
| 818 | test_int_register(110, 10); /* append exact */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 819 | printf("This next one should fail....\n"); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 820 | test_int_register(110, 10); /* exact duplicate */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 821 | printf("done\n"); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 822 | test_int_register(110, -1); /* append */ |
| 823 | test_int_register(110, 5); /* insert exact */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 824 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 825 | /* |
| 826 | * b) string values |
| 827 | */ |
| 828 | test_string_register(120, NULL); /* empty */ |
| 829 | test_string_register(120, NULL); /* append */ |
| 830 | test_string_register(120, "aaaz"); |
| 831 | test_string_register(120, NULL); /* minor rollover */ |
| 832 | test_string_register(120, "zzzz"); |
| 833 | test_string_register(120, NULL); /* major rollover */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 834 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 835 | /* |
| 836 | * c) OID values |
| 837 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 838 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 839 | test_oid_register(130, -1); /* empty */ |
| 840 | test_oid_register(130, -1); /* append */ |
| 841 | |
| 842 | varbind->val_len = varbind.name_length * sizeof(oid); |
| 843 | memcpy(varbind->buf, varbind.name, varbind.val_len); |
| 844 | varbind->val.objid = (oid *) varbind.buf; |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 845 | varbind->val_len += sizeof(oid); |
| 846 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 847 | test_oid_register(130, 255); /* append exact */ |
| 848 | test_oid_register(130, -1); /* minor rollover */ |
| 849 | test_oid_register(130, 100); /* insert exact */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 850 | printf("This next one should fail....\n"); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 851 | test_oid_register(130, 100); /* exact duplicate */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 852 | printf("done\n"); |
| 853 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 854 | varbind->val.objid = (oid *) varbind.buf; |
| 855 | for (i = 0; i < 6; i++) |
| 856 | varbind->val.objid[i] = 255; |
| 857 | varbind->val.objid[0] = 1; |
| 858 | test_oid_register(130, 255); /* set up rollover */ |
| 859 | test_oid_register(130, -1); /* medium rollover */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 860 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 861 | for (i = 0; i < 6; i++) |
| 862 | varbind->val.objid[i] = 255; |
| 863 | varbind->val.objid[0] = 2; |
| 864 | test_oid_register(130, 255); /* set up rollover */ |
| 865 | test_oid_register(130, -1); /* major rollover */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 866 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 867 | /* |
| 868 | * Did it all work? |
| 869 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 870 | dump_idx_registry(); |
| 871 | |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 872 | /* |
| 873 | * Test the various "invalid" requests |
| 874 | * (unsupported types, mis-matched types, etc) |
| 875 | */ |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 876 | printf("The rest of these should fail....\n"); |
Wes Hardaker | 6d1f602 | 2002-04-20 07:08:20 +0000 | [diff] [blame] | 877 | test_oid_register(110, -1); |
| 878 | test_oid_register(110, 100); |
| 879 | test_oid_register(120, -1); |
| 880 | test_oid_register(120, 100); |
| 881 | test_string_register(110, NULL); |
| 882 | test_string_register(110, "aaaa"); |
| 883 | test_string_register(130, NULL); |
| 884 | test_string_register(130, "aaaa"); |
| 885 | test_int_register(120, -1); |
| 886 | test_int_register(120, 1); |
| 887 | test_int_register(130, -1); |
| 888 | test_int_register(130, 1); |
Dave Shield | e42fbdf | 2000-05-12 15:15:37 +0000 | [diff] [blame] | 889 | printf("done - this dump should be the same as before\n"); |
| 890 | dump_idx_registry(); |
| 891 | } |
| 892 | #endif |