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