00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00020 #define IN_SNMP_VARS_C
00021
00022 #include <net-snmp/net-snmp-config.h>
00023 #include <signal.h>
00024 #if HAVE_STRING_H
00025 #include <string.h>
00026 #endif
00027 #if HAVE_STDLIB_H
00028 #include <stdlib.h>
00029 #endif
00030 #include <sys/types.h>
00031 #include <stdio.h>
00032 #include <fcntl.h>
00033 #if HAVE_WINSOCK_H
00034 #include <winsock.h>
00035 #endif
00036 #if TIME_WITH_SYS_TIME
00037 # ifdef WIN32
00038 # include <sys/timeb.h>
00039 # else
00040 # include <sys/time.h>
00041 # endif
00042 # include <time.h>
00043 #else
00044 # if HAVE_SYS_TIME_H
00045 # include <sys/time.h>
00046 # else
00047 # include <time.h>
00048 # endif
00049 #endif
00050 #if HAVE_NETINET_IN_H
00051 #include <netinet/in.h>
00052 #endif
00053
00054 #include <net-snmp/net-snmp-includes.h>
00055 #include <net-snmp/agent/net-snmp-agent-includes.h>
00056 #include <net-snmp/agent/agent_callbacks.h>
00057
00058 #include "snmpd.h"
00059 #include "mibgroup/struct.h"
00060 #include <net-snmp/agent/old_api.h>
00061 #include <net-snmp/agent/null.h>
00062 #include <net-snmp/agent/table.h>
00063 #include <net-snmp/agent/table_iterator.h>
00064 #include <net-snmp/agent/agent_registry.h>
00065 #include "mib_module_includes.h"
00066
00067 #ifdef USING_AGENTX_SUBAGENT_MODULE
00068 #include "agentx/subagent.h"
00069 #include "agentx/client.h"
00070 #endif
00071
00072
00073
00074 #define SUBTREE_DEFAULT_CACHE_SIZE 8
00075 #define SUBTREE_MAX_CACHE_SIZE 32
00076 int lookup_cache_size = 0;
00077
00078 typedef struct lookup_cache_s {
00079 netsnmp_subtree *next;
00080 netsnmp_subtree *previous;
00081 } lookup_cache;
00082
00083 typedef struct lookup_cache_context_s {
00084 char *context;
00085 struct lookup_cache_context_s *next;
00086 int thecachecount;
00087 int currentpos;
00088 lookup_cache cache[SUBTREE_MAX_CACHE_SIZE];
00089 } lookup_cache_context;
00090
00091 static lookup_cache_context *thecontextcache = NULL;
00092
00104 void
00105 netsnmp_set_lookup_cache_size(int newsize) {
00106 if (newsize < 0)
00107 lookup_cache_size = SUBTREE_DEFAULT_CACHE_SIZE;
00108 else if (newsize < SUBTREE_MAX_CACHE_SIZE)
00109 lookup_cache_size = newsize;
00110 else
00111 lookup_cache_size = SUBTREE_MAX_CACHE_SIZE;
00112 }
00113
00117 int
00118 netsnmp_get_lookup_cache_size(void) {
00119 return lookup_cache_size;
00120 }
00121
00122 NETSNMP_STATIC_INLINE lookup_cache_context *
00123 get_context_lookup_cache(const char *context) {
00124 lookup_cache_context *ptr;
00125 if (!context)
00126 context = "";
00127
00128 for(ptr = thecontextcache; ptr; ptr = ptr->next) {
00129 if (strcmp(ptr->context, context) == 0)
00130 break;
00131 }
00132 if (!ptr) {
00133 if (netsnmp_subtree_find_first(context)) {
00134 ptr = SNMP_MALLOC_TYPEDEF(lookup_cache_context);
00135 ptr->next = thecontextcache;
00136 ptr->context = strdup(context);
00137 thecontextcache = ptr;
00138 } else {
00139 return NULL;
00140 }
00141 }
00142 return ptr;
00143 }
00144
00145 NETSNMP_STATIC_INLINE void
00146 lookup_cache_add(const char *context,
00147 netsnmp_subtree *next, netsnmp_subtree *previous) {
00148 lookup_cache_context *cptr;
00149
00150 if ((cptr = get_context_lookup_cache(context)) == NULL)
00151 return;
00152
00153 if (cptr->thecachecount < lookup_cache_size)
00154 cptr->thecachecount++;
00155
00156 cptr->cache[cptr->currentpos].next = next;
00157 cptr->cache[cptr->currentpos].previous = previous;
00158
00159 if (++cptr->currentpos >= lookup_cache_size)
00160 cptr->currentpos = 0;
00161 }
00162
00163 NETSNMP_STATIC_INLINE void
00164 lookup_cache_replace(lookup_cache *ptr,
00165 netsnmp_subtree *next, netsnmp_subtree *previous) {
00166
00167 ptr->next = next;
00168 ptr->previous = previous;
00169 }
00170
00171 NETSNMP_STATIC_INLINE lookup_cache *
00172 lookup_cache_find(const char *context, oid *name, size_t name_len,
00173 int *retcmp) {
00174 lookup_cache_context *cptr;
00175 lookup_cache *ret = NULL;
00176 int cmp;
00177 int i;
00178
00179 if ((cptr = get_context_lookup_cache(context)) == NULL)
00180 return NULL;
00181
00182 for(i = 0; i < cptr->thecachecount && i < lookup_cache_size; i++) {
00183 if (cptr->cache[i].previous->start_a)
00184 cmp = snmp_oid_compare(name, name_len,
00185 cptr->cache[i].previous->start_a,
00186 cptr->cache[i].previous->start_len);
00187 else
00188 cmp = 1;
00189 if (cmp >= 0) {
00190 *retcmp = cmp;
00191 ret = &(cptr->cache[i]);
00192 }
00193 }
00194 return ret;
00195 }
00196
00197 NETSNMP_STATIC_INLINE void
00198 invalidate_lookup_cache(const char *context) {
00199 lookup_cache_context *cptr;
00200 if ((cptr = get_context_lookup_cache(context)) != NULL) {
00201 cptr->thecachecount = 0;
00202 cptr->currentpos = 0;
00203 }
00204 }
00205
00206
00207
00208 static void register_mib_detach_node(netsnmp_subtree *s);
00209 subtree_context_cache *context_subtrees = NULL;
00210
00211 void
00212 netsnmp_subtree_free(netsnmp_subtree *a)
00213 {
00214 if (a != NULL) {
00215 if (a->variables != NULL && netsnmp_oid_equals(a->name_a, a->namelen,
00216 a->start_a, a->start_len) == 0) {
00217 SNMP_FREE(a->variables);
00218 }
00219 SNMP_FREE(a->name_a);
00220 a->namelen = 0;
00221 SNMP_FREE(a->start_a);
00222 a->start_len = 0;
00223 SNMP_FREE(a->end_a);
00224 a->end_len = 0;
00225 SNMP_FREE(a->label_a);
00226 netsnmp_handler_registration_free(a->reginfo);
00227 a->reginfo = NULL;
00228 SNMP_FREE(a);
00229 }
00230 }
00231
00232 netsnmp_subtree *
00233 netsnmp_subtree_deepcopy(netsnmp_subtree *a)
00234 {
00235 netsnmp_subtree *b = (netsnmp_subtree *)calloc(1, sizeof(netsnmp_subtree));
00236
00237 if (b != NULL) {
00238 memcpy(b, a, sizeof(netsnmp_subtree));
00239 b->name_a = snmp_duplicate_objid(a->name_a, a->namelen);
00240 b->start_a = snmp_duplicate_objid(a->start_a, a->start_len);
00241 b->end_a = snmp_duplicate_objid(a->end_a, a->end_len);
00242 b->label_a = strdup(a->label_a);
00243
00244 if (b->name_a == NULL || b->start_a == NULL ||
00245 b->end_a == NULL || b->label_a == NULL) {
00246 netsnmp_subtree_free(b);
00247 return NULL;
00248 }
00249
00250 if (a->variables != NULL) {
00251 b->variables = (struct variable *)malloc(a->variables_len *
00252 a->variables_width);
00253 if (b->variables != NULL) {
00254 memcpy(b->variables, a->variables,a->variables_len*a->variables_width);
00255 } else {
00256 netsnmp_subtree_free(b);
00257 return NULL;
00258 }
00259 }
00260
00261 if (a->reginfo != NULL) {
00262 b->reginfo = netsnmp_handler_registration_dup(a->reginfo);
00263 if (b->reginfo == NULL) {
00264 netsnmp_subtree_free(b);
00265 return NULL;
00266 }
00267 }
00268 }
00269 return b;
00270 }
00271
00272 subtree_context_cache *
00273 get_top_context_cache(void)
00274 {
00275 return context_subtrees;
00276 }
00277
00278 netsnmp_subtree *
00279 netsnmp_subtree_find_first(const char *context_name)
00280 {
00281 subtree_context_cache *ptr;
00282
00283 if (!context_name) {
00284 context_name = "";
00285 }
00286
00287 DEBUGMSGTL(("subtree", "looking for subtree for context: \"%s\"\n",
00288 context_name));
00289 for (ptr = context_subtrees; ptr != NULL; ptr = ptr->next) {
00290 if (ptr->context_name != NULL &&
00291 strcmp(ptr->context_name, context_name) == 0) {
00292 DEBUGMSGTL(("subtree", "found one for: \"%s\"\n", context_name));
00293 return ptr->first_subtree;
00294 }
00295 }
00296 DEBUGMSGTL(("subtree", "didn't find a subtree for context: \"%s\"\n",
00297 context_name));
00298 return NULL;
00299 }
00300
00301 netsnmp_subtree *
00302 add_subtree(netsnmp_subtree *new_tree, const char *context_name)
00303 {
00304 subtree_context_cache *ptr = SNMP_MALLOC_TYPEDEF(subtree_context_cache);
00305
00306 if (!context_name) {
00307 context_name = "";
00308 }
00309
00310 if (!ptr) {
00311 return NULL;
00312 }
00313
00314 DEBUGMSGTL(("subtree", "adding subtree for context: \"%s\"\n",
00315 context_name));
00316
00317 ptr->next = context_subtrees;
00318 ptr->first_subtree = new_tree;
00319 ptr->context_name = strdup(context_name);
00320 context_subtrees = ptr;
00321
00322 return ptr->first_subtree;
00323 }
00324
00325 netsnmp_subtree *
00326 netsnmp_subtree_replace_first(netsnmp_subtree *new_tree,
00327 const char *context_name)
00328 {
00329 subtree_context_cache *ptr;
00330 if (!context_name) {
00331 context_name = "";
00332 }
00333 for (ptr = context_subtrees; ptr != NULL; ptr = ptr->next) {
00334 if (ptr->context_name != NULL &&
00335 strcmp(ptr->context_name, context_name) == 0) {
00336 ptr->first_subtree = new_tree;
00337 return ptr->first_subtree;
00338 }
00339 }
00340 return add_subtree(new_tree, context_name);
00341 }
00342
00343 NETSNMP_INLINE void
00344 netsnmp_subtree_change_next(netsnmp_subtree *ptr, netsnmp_subtree *thenext)
00345 {
00346 ptr->next = thenext;
00347 if (thenext)
00348 netsnmp_oid_compare_ll(ptr->start_a,
00349 ptr->start_len,
00350 thenext->start_a,
00351 thenext->start_len,
00352 &thenext->oid_off);
00353 }
00354
00355 NETSNMP_INLINE void
00356 netsnmp_subtree_change_prev(netsnmp_subtree *ptr, netsnmp_subtree *theprev)
00357 {
00358 ptr->prev = theprev;
00359 if (theprev)
00360 netsnmp_oid_compare_ll(theprev->start_a,
00361 theprev->start_len,
00362 ptr->start_a,
00363 ptr->start_len,
00364 &ptr->oid_off);
00365 }
00366
00367 int
00368 netsnmp_subtree_compare(const netsnmp_subtree *ap, const netsnmp_subtree *bp)
00369 {
00370 return snmp_oid_compare(ap->name_a, ap->namelen, bp->name_a, bp->namelen);
00371 }
00372
00373 void
00374 netsnmp_subtree_join(netsnmp_subtree *root)
00375 {
00376 netsnmp_subtree *s, *tmp, *c, *d;
00377
00378 while (root != NULL) {
00379 s = root->next;
00380 while (s != NULL && root->reginfo == s->reginfo) {
00381 tmp = s->next;
00382 DEBUGMSGTL(("subtree", "root start "));
00383 DEBUGMSGOID(("subtree", root->start_a, root->start_len));
00384 DEBUGMSG(("subtree", " (original end "));
00385 DEBUGMSGOID(("subtree", root->end_a, root->end_len));
00386 DEBUGMSG(("subtree", ")\n"));
00387 DEBUGMSGTL(("subtree", " JOINING to "));
00388 DEBUGMSGOID(("subtree", s->start_a, s->start_len));
00389
00390 SNMP_FREE(root->end_a);
00391 root->end_a = s->end_a;
00392 root->end_len = s->end_len;
00393 s->end_a = NULL;
00394
00395 for (c = root; c != NULL; c = c->children) {
00396 netsnmp_subtree_change_next(c, s->next);
00397 }
00398 for (c = s; c != NULL; c = c->children) {
00399 netsnmp_subtree_change_prev(c, root);
00400 }
00401 DEBUGMSG(("subtree", " so new end "));
00402 DEBUGMSGOID(("subtree", root->end_a, root->end_len));
00403 DEBUGMSG(("subtree", "\n"));
00404
00405
00406
00407 for (c = s->children; c != NULL; c = d) {
00408 d = c->children;
00409 netsnmp_subtree_free(c);
00410 }
00411 netsnmp_subtree_free(s);
00412 s = tmp;
00413 }
00414 root = root->next;
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423 netsnmp_subtree *
00424 netsnmp_subtree_split(netsnmp_subtree *current, oid name[], int name_len)
00425 {
00426 struct variable *vp = NULL;
00427 netsnmp_subtree *new_sub, *ptr;
00428 int i = 0, rc = 0, rc2 = 0;
00429 size_t common_len = 0;
00430 char *cp;
00431 oid *tmp_a, *tmp_b;
00432
00433 if (snmp_oid_compare(name, name_len, current->end_a, current->end_len)>0) {
00434
00435 return NULL;
00436 }
00437
00438 new_sub = netsnmp_subtree_deepcopy(current);
00439 if (new_sub == NULL) {
00440 return NULL;
00441 }
00442
00443
00444 tmp_a = snmp_duplicate_objid(name, name_len);
00445 if (tmp_a == NULL) {
00446 netsnmp_subtree_free(new_sub);
00447 return NULL;
00448 }
00449 tmp_b = snmp_duplicate_objid(name, name_len);
00450 if (tmp_b == NULL) {
00451 netsnmp_subtree_free(new_sub);
00452 SNMP_FREE(tmp_a);
00453 return NULL;
00454 }
00455
00456 SNMP_FREE(current->end_a);
00457 current->end_a = tmp_a;
00458 current->end_len = name_len;
00459 if (new_sub->start_a != NULL) {
00460 SNMP_FREE(new_sub->start_a);
00461 }
00462 new_sub->start_a = tmp_b;
00463 new_sub->start_len = name_len;
00464
00465
00466 i = current->variables_len;
00467 current->variables_len = 0;
00468
00469 for (vp = current->variables; i > 0; i--) {
00470
00471
00472
00473 rc = snmp_oid_compare(vp->name, vp->namelen,
00474 name + current->namelen,
00475 name_len - current->namelen);
00476
00477 if (name_len - current->namelen > vp->namelen) {
00478 common_len = vp->namelen;
00479 } else {
00480 common_len = name_len - current->namelen;
00481 }
00482
00483 rc2 = snmp_oid_compare(vp->name, common_len,
00484 name + current->namelen, common_len);
00485
00486 if (rc >= 0) {
00487 break;
00488 }
00489
00490 current->variables_len++;
00491 if (rc2 < 0) {
00492 new_sub->variables_len--;
00493 cp = (char *) new_sub->variables;
00494 new_sub->variables = (struct variable *)(cp +
00495 new_sub->variables_width);
00496 }
00497 vp = (struct variable *) ((char *) vp + current->variables_width);
00498 }
00499
00500
00501 if (current->variables_len > 0 &&
00502 IS_DELEGATED((u_char) current->variables[0].type)) {
00503 new_sub->variables_len = 1;
00504 new_sub->variables = current->variables;
00505 }
00506
00507
00508 if (current->children) {
00509 new_sub->children = netsnmp_subtree_split(current->children,
00510 name, name_len);
00511 }
00512
00513
00514 for (ptr = current; ptr != NULL; ptr = ptr->children) {
00515 netsnmp_subtree_change_next(ptr, new_sub);
00516 }
00517 for (ptr = new_sub; ptr != NULL; ptr = ptr->children) {
00518 netsnmp_subtree_change_prev(ptr, current);
00519 }
00520 for (ptr = new_sub->next; ptr != NULL; ptr=ptr->children) {
00521 netsnmp_subtree_change_prev(ptr, new_sub);
00522 }
00523
00524 return new_sub;
00525 }
00526
00527 int
00528 netsnmp_subtree_load(netsnmp_subtree *new_sub, const char *context_name)
00529 {
00530 netsnmp_subtree *tree1, *tree2, *new2;
00531 netsnmp_subtree *prev, *next;
00532 int res, rc = 0;
00533
00534 if (new_sub == NULL) {
00535 return MIB_REGISTERED_OK;
00536 }
00537
00538 if (!netsnmp_subtree_find_first(context_name)) {
00539 static int inloop = 0;
00540 if (!inloop) {
00541 oid ccitt[1] = { 0 };
00542 oid iso[1] = { 1 };
00543 oid joint_ccitt_iso[1] = { 2 };
00544 inloop = 1;
00545 netsnmp_register_null_context(snmp_duplicate_objid(ccitt, 1), 1,
00546 context_name);
00547 netsnmp_register_null_context(snmp_duplicate_objid(iso, 1), 1,
00548 context_name);
00549 netsnmp_register_null_context(snmp_duplicate_objid(joint_ccitt_iso, 1),
00550 1, context_name);
00551 inloop = 0;
00552 }
00553 }
00554
00555
00556
00557
00558 tree1 = netsnmp_subtree_find(new_sub->start_a, new_sub->start_len,
00559 NULL, context_name);
00560
00561
00562
00563
00564 if (tree1 == NULL) {
00565 tree2 = netsnmp_subtree_find_next(new_sub->start_a, new_sub->start_len,
00566 NULL, context_name);
00567 } else {
00568 tree2 = tree1->next;
00569 }
00570
00571
00572
00573 if (tree1 == NULL) {
00574 new2 = NULL;
00575
00576 if (tree2 && snmp_oid_compare(new_sub->end_a, new_sub->end_len,
00577 tree2->start_a, tree2->start_len) > 0) {
00578 new2 = netsnmp_subtree_split(new_sub,
00579 tree2->start_a, tree2->start_len);
00580 }
00581
00582
00583
00584
00585 if (tree2) {
00586 netsnmp_subtree_change_prev(new_sub, tree2->prev);
00587 netsnmp_subtree_change_prev(tree2, new_sub);
00588 } else {
00589 netsnmp_subtree_change_prev(new_sub,
00590 netsnmp_subtree_find_prev(new_sub->start_a,
00591 new_sub->start_len, NULL, context_name));
00592
00593 if (new_sub->prev) {
00594 netsnmp_subtree_change_next(new_sub->prev, new_sub);
00595 } else {
00596 netsnmp_subtree_replace_first(new_sub, context_name);
00597 }
00598
00599 netsnmp_subtree_change_next(new_sub, tree2);
00600
00601
00602
00603 if (new2) {
00604 return netsnmp_subtree_load(new2, context_name);
00605 }
00606 }
00607 } else {
00608
00609
00610
00611
00612 if (netsnmp_oid_equals(new_sub->start_a, new_sub->start_len,
00613 tree1->start_a, tree1->start_len) != 0) {
00614 tree1 = netsnmp_subtree_split(tree1, new_sub->start_a,
00615 new_sub->start_len);
00616 }
00617
00618 if (tree1 == NULL) {
00619 return MIB_REGISTRATION_FAILED;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 rc = snmp_oid_compare(new_sub->end_a, new_sub->end_len,
00634 tree1->end_a, tree1->end_len);
00635
00636 switch (rc) {
00637
00638 case -1:
00639
00640 netsnmp_subtree_split(tree1, new_sub->end_a, new_sub->end_len);
00641
00642
00643 case 0:
00644
00645
00646
00647
00648
00649 prev = NULL;
00650 next = tree1;
00651
00652 while (next && next->namelen > new_sub->namelen) {
00653 prev = next;
00654 next = next->children;
00655 }
00656
00657 while (next && next->namelen == new_sub->namelen &&
00658 next->priority < new_sub->priority ) {
00659 prev = next;
00660 next = next->children;
00661 }
00662
00663 if (next && (next->namelen == new_sub->namelen) &&
00664 (next->priority == new_sub->priority)) {
00665 if (new_sub->namelen != 1)
00666 snmp_log(LOG_ERR, "duplicate registration (%s, %s)", next->label_a, new_sub->label_a);
00667 return MIB_DUPLICATE_REGISTRATION;
00668 }
00669
00670 if (prev) {
00671 prev->children = new_sub;
00672 new_sub->children = next;
00673 netsnmp_subtree_change_prev(new_sub, prev->prev);
00674 netsnmp_subtree_change_next(new_sub, prev->next);
00675 } else {
00676 new_sub->children = next;
00677 netsnmp_subtree_change_prev(new_sub, next->prev);
00678 netsnmp_subtree_change_next(new_sub, next->next);
00679
00680 for (next = new_sub->next; next != NULL;next = next->children){
00681 netsnmp_subtree_change_prev(next, new_sub);
00682 }
00683
00684 for (prev = new_sub->prev; prev != NULL;prev = prev->children){
00685 netsnmp_subtree_change_next(prev, new_sub);
00686 }
00687 }
00688 break;
00689
00690 case 1:
00691
00692 new2 = netsnmp_subtree_split(new_sub, tree1->end_a,tree1->end_len);
00693 res = netsnmp_subtree_load(new_sub, context_name);
00694 if (res != MIB_REGISTERED_OK) {
00695 netsnmp_subtree_free(new2);
00696 return res;
00697 }
00698 return netsnmp_subtree_load(new2, context_name);
00699 }
00700 }
00701 return 0;
00702 }
00703
00704
00705
00706
00707 int
00708 netsnmp_register_mib(const char *moduleName,
00709 struct variable *var,
00710 size_t varsize,
00711 size_t numvars,
00712 oid * mibloc,
00713 size_t mibloclen,
00714 int priority,
00715 int range_subid,
00716 oid range_ubound,
00717 netsnmp_session * ss,
00718 const char *context,
00719 int timeout,
00720 int flags,
00721 netsnmp_handler_registration *reginfo,
00722 int perform_callback)
00723 {
00724 netsnmp_subtree *subtree, *sub2;
00725 int res, i;
00726 struct register_parameters reg_parms;
00727 int old_lookup_cache_val = netsnmp_get_lookup_cache_size();
00728
00729 if (moduleName == NULL ||
00730 mibloc == NULL) {
00731
00732 netsnmp_handler_registration_free(reginfo);
00733 return MIB_REGISTRATION_FAILED;
00734 }
00735 subtree = (netsnmp_subtree *)calloc(1, sizeof(netsnmp_subtree));
00736 if (subtree == NULL) {
00737 netsnmp_handler_registration_free(reginfo);
00738 return MIB_REGISTRATION_FAILED;
00739 }
00740
00741 DEBUGMSGTL(("register_mib", "registering \"%s\" at ", moduleName));
00742 DEBUGMSGOIDRANGE(("register_mib", mibloc, mibloclen, range_subid,
00743 range_ubound));
00744 DEBUGMSG(("register_mib", " with context \"%s\"\n",
00745 SNMP_STRORNULL(context)));
00746
00747
00748
00749
00750
00751
00752
00753 if( ((NULL == context) && (NULL != reginfo->contextName)) ||
00754 ((NULL != context) && (NULL == reginfo->contextName)) ||
00755 ( ((NULL != context) && (NULL != reginfo->contextName)) &&
00756 (0 != strcmp(context, reginfo->contextName))) ) {
00757 snmp_log(LOG_WARNING,"context passed during registration does not "
00758 "equal the reginfo contextName! ('%s' != '%s')\n",
00759 context, reginfo->contextName);
00760 netsnmp_assert(!"register context == reginfo->contextName");
00761 }
00762
00763
00764
00765 subtree->reginfo = reginfo;
00766 subtree->name_a = snmp_duplicate_objid(mibloc, mibloclen);
00767 subtree->start_a = snmp_duplicate_objid(mibloc, mibloclen);
00768 subtree->end_a = snmp_duplicate_objid(mibloc, mibloclen);
00769 subtree->label_a = strdup(moduleName);
00770 if (subtree->name_a == NULL || subtree->start_a == NULL ||
00771 subtree->end_a == NULL || subtree->label_a == NULL) {
00772 netsnmp_subtree_free(subtree);
00773 return MIB_REGISTRATION_FAILED;
00774 }
00775 subtree->namelen = (u_char)mibloclen;
00776 subtree->start_len = (u_char)mibloclen;
00777 subtree->end_len = (u_char)mibloclen;
00778 subtree->end_a[mibloclen - 1]++;
00779
00780 if (var != NULL) {
00781 subtree->variables = (struct variable *)malloc(varsize*numvars);
00782 if (subtree->variables == NULL) {
00783 netsnmp_subtree_free(subtree);
00784 return MIB_REGISTRATION_FAILED;
00785 }
00786 memcpy(subtree->variables, var, numvars*varsize);
00787 subtree->variables_len = numvars;
00788 subtree->variables_width = varsize;
00789 }
00790 subtree->priority = priority;
00791 subtree->timeout = timeout;
00792 subtree->range_subid = range_subid;
00793 subtree->range_ubound = range_ubound;
00794 subtree->session = ss;
00795 subtree->flags = (u_char)flags;
00796 subtree->flags |= SUBTREE_ATTACHED;
00797 subtree->global_cacheid = reginfo->global_cacheid;
00798
00799 netsnmp_set_lookup_cache_size(0);
00800 res = netsnmp_subtree_load(subtree, context);
00801
00802
00803
00804
00805 if (res == MIB_REGISTERED_OK && range_subid != 0) {
00806 for (i = mibloc[range_subid - 1] + 1; i <= (int)range_ubound; i++) {
00807 sub2 = netsnmp_subtree_deepcopy(subtree);
00808
00809 if (sub2 == NULL) {
00810 unregister_mib_context(mibloc, mibloclen, priority,
00811 range_subid, range_ubound, context);
00812 netsnmp_set_lookup_cache_size(old_lookup_cache_val);
00813 invalidate_lookup_cache(context);
00814 return MIB_REGISTRATION_FAILED;
00815 }
00816
00817 sub2->name_a[range_subid - 1] = i;
00818 sub2->start_a[range_subid - 1] = i;
00819 sub2->end_a[range_subid - 1] = i;
00820 if (range_subid == (int)mibloclen) {
00821 ++sub2->end_a[range_subid - 1];
00822 }
00823 sub2->flags |= SUBTREE_ATTACHED;
00824 sub2->global_cacheid = reginfo->global_cacheid;
00825
00826 sub2->reginfo->rootoid[range_subid - 1] = i;
00827
00828 res = netsnmp_subtree_load(sub2, context);
00829 if (res != MIB_REGISTERED_OK) {
00830 unregister_mib_context(mibloc, mibloclen, priority,
00831 range_subid, range_ubound, context);
00832 netsnmp_subtree_free(sub2);
00833 netsnmp_set_lookup_cache_size(old_lookup_cache_val);
00834 invalidate_lookup_cache(context);
00835 return res;
00836 }
00837 }
00838 } else if (res == MIB_DUPLICATE_REGISTRATION ||
00839 res == MIB_REGISTRATION_FAILED) {
00840 netsnmp_set_lookup_cache_size(old_lookup_cache_val);
00841 invalidate_lookup_cache(context);
00842 netsnmp_subtree_free(subtree);
00843 return res;
00844 }
00845
00846
00847
00848
00849 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00850 NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT) {
00851 extern struct snmp_session *main_session;
00852 if (main_session == NULL) {
00853 register_mib_detach_node(subtree);
00854 }
00855 }
00856
00857 if (res == MIB_REGISTERED_OK && perform_callback) {
00858 memset(®_parms, 0x0, sizeof(reg_parms));
00859 reg_parms.name = mibloc;
00860 reg_parms.namelen = mibloclen;
00861 reg_parms.priority = priority;
00862 reg_parms.range_subid = range_subid;
00863 reg_parms.range_ubound = range_ubound;
00864 reg_parms.timeout = timeout;
00865 reg_parms.flags = (u_char) flags;
00866 reg_parms.contextName = context;
00867 reg_parms.session = ss;
00868 reg_parms.reginfo = reginfo;
00869 reg_parms.contextName = context;
00870 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
00871 SNMPD_CALLBACK_REGISTER_OID, ®_parms);
00872 }
00873
00874 netsnmp_set_lookup_cache_size(old_lookup_cache_val);
00875 invalidate_lookup_cache(context);
00876 return res;
00877 }
00878
00879
00880
00881
00882
00883 static void
00884 register_mib_reattach_node(netsnmp_subtree *s)
00885 {
00886 if ((s != NULL) && (s->namelen > 1) && !(s->flags & SUBTREE_ATTACHED)) {
00887 struct register_parameters reg_parms;
00888
00889
00890
00891 memset(®_parms, 0x0, sizeof(reg_parms));
00892
00893
00894
00895
00896 reg_parms.name = s->name_a;
00897 reg_parms.namelen = s->namelen;
00898 reg_parms.priority = s->priority;
00899 reg_parms.range_subid = s->range_subid;
00900 reg_parms.range_ubound = s->range_ubound;
00901 reg_parms.timeout = s->timeout;
00902 reg_parms.flags = s->flags;
00903 reg_parms.session = s->session;
00904 reg_parms.reginfo = s->reginfo;
00905
00906 if ((NULL != s->reginfo) && (NULL != s->reginfo->contextName))
00907 reg_parms.contextName = s->reginfo->contextName;
00908 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
00909 SNMPD_CALLBACK_REGISTER_OID, ®_parms);
00910 s->flags |= SUBTREE_ATTACHED;
00911 }
00912 }
00913
00914
00915
00916
00917
00918 void
00919 register_mib_reattach(void)
00920 {
00921 netsnmp_subtree *s, *t;
00922 subtree_context_cache *ptr;
00923
00924 for (ptr = context_subtrees; ptr; ptr = ptr->next) {
00925 for (s = ptr->first_subtree; s != NULL; s = s->next) {
00926 register_mib_reattach_node(s);
00927 for (t = s->children; t != NULL; t = t->children) {
00928 register_mib_reattach_node(t);
00929 }
00930 }
00931 }
00932 }
00933
00934
00935
00936
00937
00938 static void
00939 register_mib_detach_node(netsnmp_subtree *s)
00940 {
00941 if (s != NULL) {
00942 s->flags = s->flags & ~SUBTREE_ATTACHED;
00943 }
00944 }
00945
00946
00947
00948
00949
00950
00951
00952 void
00953 register_mib_detach(void)
00954 {
00955 netsnmp_subtree *s, *t;
00956 subtree_context_cache *ptr;
00957 for (ptr = context_subtrees; ptr; ptr = ptr->next) {
00958 for (s = ptr->first_subtree; s != NULL; s = s->next) {
00959 register_mib_detach_node(s);
00960 for (t = s->children; t != NULL; t = t->children) {
00961 register_mib_detach_node(t);
00962 }
00963 }
00964 }
00965 }
00966
00967 int
00968 register_mib_context(const char *moduleName,
00969 struct variable *var,
00970 size_t varsize,
00971 size_t numvars,
00972 oid * mibloc,
00973 size_t mibloclen,
00974 int priority,
00975 int range_subid,
00976 oid range_ubound,
00977 netsnmp_session * ss,
00978 const char *context, int timeout, int flags)
00979 {
00980 return netsnmp_register_old_api(moduleName, var, varsize, numvars,
00981 mibloc, mibloclen, priority,
00982 range_subid, range_ubound, ss, context,
00983 timeout, flags);
00984 }
00985
00986 int
00987 register_mib_range(const char *moduleName,
00988 struct variable *var,
00989 size_t varsize,
00990 size_t numvars,
00991 oid * mibloc,
00992 size_t mibloclen,
00993 int priority,
00994 int range_subid, oid range_ubound, netsnmp_session * ss)
00995 {
00996 return register_mib_context(moduleName, var, varsize, numvars,
00997 mibloc, mibloclen, priority,
00998 range_subid, range_ubound, ss, "", -1, 0);
00999 }
01000
01001 int
01002 register_mib_priority(const char *moduleName,
01003 struct variable *var,
01004 size_t varsize,
01005 size_t numvars,
01006 oid * mibloc, size_t mibloclen, int priority)
01007 {
01008 return register_mib_range(moduleName, var, varsize, numvars,
01009 mibloc, mibloclen, priority, 0, 0, NULL);
01010 }
01011
01012 int
01013 register_mib(const char *moduleName,
01014 struct variable *var,
01015 size_t varsize,
01016 size_t numvars, oid * mibloc, size_t mibloclen)
01017 {
01018 return register_mib_priority(moduleName, var, varsize, numvars,
01019 mibloc, mibloclen, DEFAULT_MIB_PRIORITY);
01020 }
01021
01022 void
01023 netsnmp_subtree_unload(netsnmp_subtree *sub, netsnmp_subtree *prev, const char *context)
01024 {
01025 netsnmp_subtree *ptr;
01026
01027 DEBUGMSGTL(("register_mib", "unload("));
01028 if (sub != NULL) {
01029 DEBUGMSGOID(("register_mib", sub->start_a, sub->start_len));
01030 } else {
01031 DEBUGMSG(("register_mib", "[NIL]"));
01032 }
01033 DEBUGMSG(("register_mib", ", "));
01034 if (prev != NULL) {
01035 DEBUGMSGOID(("register_mib", prev->start_a, prev->start_len));
01036 } else {
01037 DEBUGMSG(("register_mib", "[NIL]"));
01038 }
01039 DEBUGMSG(("register_mib", ")\n"));
01040
01041 if (prev != NULL) {
01042 prev->children = sub->children;
01043 invalidate_lookup_cache(context);
01044 return;
01045 }
01046
01047
01048
01049
01050 if (sub->children == NULL) {
01051 for (ptr = sub->prev; ptr; ptr = ptr->children) {
01052 netsnmp_subtree_change_next(ptr, sub->next);
01053 }
01054 for (ptr = sub->next; ptr; ptr = ptr->children) {
01055 netsnmp_subtree_change_prev(ptr, sub->prev);
01056 }
01057
01058 if (sub->prev == NULL) {
01059 netsnmp_subtree_replace_first(sub->next, context);
01060 }
01061
01062 } else {
01063 for (ptr = sub->prev; ptr; ptr = ptr->children)
01064 netsnmp_subtree_change_next(ptr, sub->children);
01065 for (ptr = sub->next; ptr; ptr = ptr->children)
01066 netsnmp_subtree_change_prev(ptr, sub->children);
01067
01068 if (sub->prev == NULL) {
01069 netsnmp_subtree_replace_first(sub->children, context);
01070 }
01071 }
01072 invalidate_lookup_cache(context);
01073 }
01074
01104 int
01105 unregister_mib_context(oid * name, size_t len, int priority,
01106 int range_subid, oid range_ubound,
01107 const char *context)
01108 {
01109 netsnmp_subtree *list, *myptr;
01110 netsnmp_subtree *prev, *child, *next;
01111 struct register_parameters reg_parms;
01112 int old_lookup_cache_val = netsnmp_get_lookup_cache_size();
01113 int unregistering = 1;
01114 int orig_subid_val = -1;
01115
01116 netsnmp_set_lookup_cache_size(0);
01117
01118 if ((range_subid != 0) && (range_subid <= len))
01119 orig_subid_val = name[range_subid-1];
01120
01121 while(unregistering){
01122 DEBUGMSGTL(("register_mib", "unregistering "));
01123 DEBUGMSGOIDRANGE(("register_mib", name, len, range_subid, range_ubound));
01124 DEBUGMSG(("register_mib", "\n"));
01125
01126 list = netsnmp_subtree_find(name, len, netsnmp_subtree_find_first(context),
01127 context);
01128 if (list == NULL) {
01129 return MIB_NO_SUCH_REGISTRATION;
01130 }
01131
01132 for (child = list, prev = NULL; child != NULL;
01133 prev = child, child = child->children) {
01134 if (netsnmp_oid_equals(child->name_a, child->namelen, name, len) == 0 &&
01135 child->priority == priority) {
01136 break;
01137 }
01138 }
01139
01140 if (child == NULL) {
01141 return MIB_NO_SUCH_REGISTRATION;
01142 }
01143
01144 netsnmp_subtree_unload(child, prev, context);
01145 myptr = child;
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 for (list = myptr->next; list != NULL; list = next) {
01158 next = list->next;
01159 for (child = list, prev = NULL; child != NULL;
01160 prev = child, child = child->children) {
01161 if ((netsnmp_oid_equals(child->name_a, child->namelen,
01162 name, len) == 0) &&
01163 (child->priority == priority)) {
01164 netsnmp_subtree_unload(child, prev, context);
01165 netsnmp_subtree_free(child);
01166 break;
01167 }
01168 }
01169 if (child == NULL)
01170 break;
01171 }
01172
01173
01174 if (orig_subid_val != -1){
01175 if (++name[range_subid-1] >= orig_subid_val+range_ubound)
01176 {
01177 unregistering=0;
01178 name[range_subid-1] = orig_subid_val;
01179 }
01180 }
01181 else {
01182 unregistering=0;
01183 }
01184 }
01185
01186 memset(®_parms, 0x0, sizeof(reg_parms));
01187 reg_parms.name = name;
01188 reg_parms.namelen = len;
01189 reg_parms.priority = priority;
01190 reg_parms.range_subid = range_subid;
01191 reg_parms.range_ubound = range_ubound;
01192 reg_parms.flags = 0x00;
01193 reg_parms.contextName = context;
01194 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01195 SNMPD_CALLBACK_UNREGISTER_OID, ®_parms);
01196
01197 netsnmp_subtree_free(myptr);
01198 netsnmp_set_lookup_cache_size(old_lookup_cache_val);
01199 invalidate_lookup_cache(context);
01200 return MIB_UNREGISTERED_OK;
01201 }
01202
01203 int
01204 netsnmp_unregister_mib_table_row(oid * name, size_t len, int priority,
01205 int var_subid, oid range_ubound,
01206 const char *context)
01207 {
01208 netsnmp_subtree *list, *myptr, *futureptr;
01209 netsnmp_subtree *prev, *child;
01210 struct register_parameters reg_parms;
01211 oid range_lbound = name[var_subid - 1];
01212
01213 DEBUGMSGTL(("register_mib", "unregistering "));
01214 DEBUGMSGOIDRANGE(("register_mib", name, len, var_subid, range_ubound));
01215 DEBUGMSG(("register_mib", "\n"));
01216
01217 for (; name[var_subid - 1] <= range_ubound; name[var_subid - 1]++) {
01218 list = netsnmp_subtree_find(name, len,
01219 netsnmp_subtree_find_first(context), context);
01220
01221 if (list == NULL) {
01222 continue;
01223 }
01224
01225 for (child = list, prev = NULL; child != NULL;
01226 prev = child, child = child->children) {
01227
01228 if (netsnmp_oid_equals(child->name_a, child->namelen,
01229 name, len) == 0 &&
01230 (child->priority == priority)) {
01231 break;
01232 }
01233 }
01234
01235 if (child == NULL) {
01236 continue;
01237 }
01238
01239 netsnmp_subtree_unload(child, prev, context);
01240 myptr = child;
01241
01242 for (list = myptr->next; list != NULL; list = futureptr) {
01243
01244 futureptr = list->next;
01245
01246
01247 for (child = list, prev = NULL; child != NULL;
01248 prev = child, child = child->children) {
01249
01250 if (netsnmp_oid_equals(child->name_a, child->namelen,
01251 name, len) == 0 &&
01252 (child->priority == priority)) {
01253 netsnmp_subtree_unload(child, prev, context);
01254 netsnmp_subtree_free(child);
01255 break;
01256 }
01257 }
01258
01259
01260 if (child == NULL) {
01261 break;
01262 }
01263 }
01264 netsnmp_subtree_free(myptr);
01265 }
01266
01267 name[var_subid - 1] = range_lbound;
01268 memset(®_parms, 0x0, sizeof(reg_parms));
01269 reg_parms.name = name;
01270 reg_parms.namelen = len;
01271 reg_parms.priority = priority;
01272 reg_parms.range_subid = var_subid;
01273 reg_parms.range_ubound = range_ubound;
01274 reg_parms.flags = 0x00;
01275 reg_parms.contextName = context;
01276 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01277 SNMPD_CALLBACK_UNREGISTER_OID, ®_parms);
01278
01279 return 0;
01280 }
01281
01282 int
01283 unregister_mib_range(oid * name, size_t len, int priority,
01284 int range_subid, oid range_ubound)
01285 {
01286 return unregister_mib_context(name, len, priority, range_subid,
01287 range_ubound, "");
01288 }
01289
01290 int
01291 unregister_mib_priority(oid * name, size_t len, int priority)
01292 {
01293 return unregister_mib_range(name, len, priority, 0, 0);
01294 }
01295
01296 int
01297 unregister_mib(oid * name, size_t len)
01298 {
01299 return unregister_mib_priority(name, len, DEFAULT_MIB_PRIORITY);
01300 }
01301
01302 void
01303 unregister_mibs_by_session(netsnmp_session * ss)
01304 {
01305 netsnmp_subtree *list, *list2;
01306 netsnmp_subtree *child, *prev, *next_child;
01307 struct register_parameters rp;
01308 subtree_context_cache *contextptr;
01309
01310 DEBUGMSGTL(("register_mib", "unregister_mibs_by_session(%p) ctxt \"%s\"\n",
01311 ss, (ss && ss->contextName) ? ss->contextName : "[NIL]"));
01312
01313 for (contextptr = get_top_context_cache(); contextptr != NULL;
01314 contextptr = contextptr->next) {
01315 for (list = contextptr->first_subtree; list != NULL; list = list2) {
01316 list2 = list->next;
01317
01318 for (child = list, prev = NULL; child != NULL; child = next_child){
01319 next_child = child->children;
01320
01321 if (((!ss || ss->flags & SNMP_FLAGS_SUBSESSION) &&
01322 child->session == ss) ||
01323 (!(!ss || ss->flags & SNMP_FLAGS_SUBSESSION) && child->session &&
01324 child->session->subsession == ss)) {
01325
01326 memset(&rp,0x0,sizeof(rp));
01327 rp.name = child->name_a;
01328 child->name_a = NULL;
01329 rp.namelen = child->namelen;
01330 rp.priority = child->priority;
01331 rp.range_subid = child->range_subid;
01332 rp.range_ubound = child->range_ubound;
01333 rp.timeout = child->timeout;
01334 rp.flags = child->flags;
01335 if ((NULL != child->reginfo) &&
01336 (NULL != child->reginfo->contextName))
01337 rp.contextName = child->reginfo->contextName;
01338
01339 if (child->reginfo != NULL) {
01340
01341
01342
01343 child->reginfo->handler->myvoid = NULL;
01344 netsnmp_handler_registration_free(child->reginfo);
01345 child->reginfo = NULL;
01346 }
01347
01348 netsnmp_subtree_unload(child, prev, contextptr->context_name);
01349 netsnmp_subtree_free(child);
01350
01351 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01352 SNMPD_CALLBACK_UNREGISTER_OID, &rp);
01353 SNMP_FREE(rp.name);
01354 } else {
01355 prev = child;
01356 }
01357 }
01358 }
01359 netsnmp_subtree_join(contextptr->first_subtree);
01360 }
01361 }
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 int
01373 in_a_view(oid *name, size_t *namelen, netsnmp_pdu *pdu, int type)
01374 {
01375 struct view_parameters view_parms;
01376
01377 if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01378
01379 return VACM_SUCCESS;
01380 }
01381
01382
01383
01384
01385 #ifndef NETSNMP_DISABLE_SNMPV1
01386 if (pdu->version == SNMP_VERSION_1 && type == ASN_COUNTER64) {
01387 return VACM_NOTINVIEW;
01388 }
01389 #endif
01390
01391 view_parms.pdu = pdu;
01392 view_parms.name = name;
01393 if (namelen != NULL) {
01394 view_parms.namelen = *namelen;
01395 } else {
01396 view_parms.namelen = 0;
01397 }
01398 view_parms.errorcode = 0;
01399 view_parms.check_subtree = 0;
01400
01401 switch (pdu->version) {
01402 #ifndef NETSNMP_DISABLE_SNMPV1
01403 case SNMP_VERSION_1:
01404 #endif
01405 #ifndef NETSNMP_DISABLE_SNMPV2C
01406 case SNMP_VERSION_2c:
01407 #endif
01408 case SNMP_VERSION_3:
01409 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01410 SNMPD_CALLBACK_ACM_CHECK, &view_parms);
01411 return view_parms.errorcode;
01412 }
01413 return VACM_NOSECNAME;
01414 }
01415
01416
01417
01418
01419
01420
01421 int
01422 check_access(netsnmp_pdu *pdu)
01423 {
01424 struct view_parameters view_parms;
01425 view_parms.pdu = pdu;
01426 view_parms.name = NULL;
01427 view_parms.namelen = 0;
01428 view_parms.errorcode = 0;
01429 view_parms.check_subtree = 0;
01430
01431 if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01432
01433 return 0;
01434 }
01435
01436 switch (pdu->version) {
01437 #ifndef NETSNMP_DISABLE_SNMPV1
01438 case SNMP_VERSION_1:
01439 #endif
01440 #ifndef NETSNMP_DISABLE_SNMPV2C
01441 case SNMP_VERSION_2c:
01442 #endif
01443 case SNMP_VERSION_3:
01444 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01445 SNMPD_CALLBACK_ACM_CHECK_INITIAL, &view_parms);
01446 return view_parms.errorcode;
01447 }
01448 return 1;
01449 }
01450
01458 int
01459 netsnmp_acm_check_subtree(netsnmp_pdu *pdu, oid *name, size_t namelen)
01460 {
01461 struct view_parameters view_parms;
01462 view_parms.pdu = pdu;
01463 view_parms.name = name;
01464 view_parms.namelen = namelen;
01465 view_parms.errorcode = 0;
01466 view_parms.check_subtree = 1;
01467
01468 if (pdu->flags & UCD_MSG_FLAG_ALWAYS_IN_VIEW) {
01469
01470 return 0;
01471 }
01472
01473 switch (pdu->version) {
01474 #ifndef NETSNMP_DISABLE_SNMPV1
01475 case SNMP_VERSION_1:
01476 #endif
01477 #ifndef NETSNMP_DISABLE_SNMPV2C
01478 case SNMP_VERSION_2c:
01479 #endif
01480 case SNMP_VERSION_3:
01481 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
01482 SNMPD_CALLBACK_ACM_CHECK_SUBTREE, &view_parms);
01483 return view_parms.errorcode;
01484 }
01485 return 1;
01486 }
01487
01488 netsnmp_subtree *
01489 netsnmp_subtree_find_prev(oid *name, size_t len, netsnmp_subtree *subtree,
01490 const char *context_name)
01491 {
01492 lookup_cache *lookup_cache = NULL;
01493 netsnmp_subtree *myptr = NULL, *previous = NULL;
01494 int cmp = 1;
01495 size_t ll_off = 0;
01496
01497 if (subtree) {
01498 myptr = subtree;
01499 } else {
01500
01501 if (lookup_cache_size) {
01502 lookup_cache = lookup_cache_find(context_name, name, len, &cmp);
01503 if (lookup_cache) {
01504 myptr = lookup_cache->next;
01505 previous = lookup_cache->previous;
01506 }
01507 if (!myptr)
01508 myptr = netsnmp_subtree_find_first(context_name);
01509 } else {
01510 myptr = netsnmp_subtree_find_first(context_name);
01511 }
01512 }
01513
01514
01515
01516
01517
01518 #ifndef __alpha
01519 #define WTEST_OPTIMIZATION 1
01520 #endif
01521 #ifdef WTEST_OPTIMIZATION
01522 DEBUGMSGTL(("wtest","oid in: "));
01523 DEBUGMSGOID(("wtest", name, len));
01524 DEBUGMSG(("wtest","\n"));
01525 #endif
01526 for (; myptr != NULL; previous = myptr, myptr = myptr->next) {
01527 #ifdef WTEST_OPTIMIZATION
01528
01529
01530
01531
01532
01533 DEBUGMSGTL(("wtest","oid cmp: "));
01534 DEBUGMSGOID(("wtest", myptr->start_a, myptr->start_len));
01535 DEBUGMSG(("wtest"," --- off = %lu, in off = %lu test = %d\n",
01536 (unsigned long)myptr->oid_off, (unsigned long)ll_off,
01537 !(ll_off && myptr->oid_off &&
01538 myptr->oid_off > ll_off)));
01539 if (!(ll_off && myptr->oid_off && myptr->oid_off > ll_off) &&
01540 netsnmp_oid_compare_ll(name, len,
01541 myptr->start_a, myptr->start_len,
01542 &ll_off) < 0) {
01543 #else
01544 if (snmp_oid_compare(name, len, myptr->start_a, myptr->start_len) < 0) {
01545 #endif
01546 if (lookup_cache_size && previous && cmp) {
01547 if (lookup_cache) {
01548 lookup_cache_replace(lookup_cache, myptr, previous);
01549 } else {
01550 lookup_cache_add(context_name, myptr, previous);
01551 }
01552 }
01553 return previous;
01554 }
01555 }
01556 return previous;
01557 }
01558
01559 netsnmp_subtree *
01560 netsnmp_subtree_find_next(oid *name, size_t len,
01561 netsnmp_subtree *subtree, const char *context_name)
01562 {
01563 netsnmp_subtree *myptr = NULL;
01564
01565 myptr = netsnmp_subtree_find_prev(name, len, subtree, context_name);
01566
01567 if (myptr != NULL) {
01568 myptr = myptr->next;
01569 while (myptr != NULL && (myptr->variables == NULL ||
01570 myptr->variables_len == 0)) {
01571 myptr = myptr->next;
01572 }
01573 return myptr;
01574 } else if (subtree != NULL && snmp_oid_compare(name, len,
01575 subtree->start_a, subtree->start_len) < 0) {
01576 return subtree;
01577 } else {
01578 return NULL;
01579 }
01580 }
01581
01582 netsnmp_subtree *
01583 netsnmp_subtree_find(oid *name, size_t len, netsnmp_subtree *subtree,
01584 const char *context_name)
01585 {
01586 netsnmp_subtree *myptr;
01587
01588 myptr = netsnmp_subtree_find_prev(name, len, subtree, context_name);
01589 if (myptr && myptr->end_a &&
01590 snmp_oid_compare(name, len, myptr->end_a, myptr->end_len)<0) {
01591 return myptr;
01592 }
01593
01594 return NULL;
01595 }
01596
01597 netsnmp_session *
01598 get_session_for_oid(oid *name, size_t len, const char *context_name)
01599 {
01600 netsnmp_subtree *myptr;
01601
01602 myptr = netsnmp_subtree_find_prev(name, len,
01603 netsnmp_subtree_find_first(context_name),
01604 context_name);
01605
01606 while (myptr && myptr->variables == NULL) {
01607 myptr = myptr->next;
01608 }
01609
01610 if (myptr == NULL) {
01611 return NULL;
01612 } else {
01613 return myptr->session;
01614 }
01615 }
01616
01617 void
01618 setup_tree(void)
01619 {
01620 oid ccitt[1] = { 0 };
01621 oid iso[1] = { 1 };
01622 oid joint_ccitt_iso[1] = { 2 };
01623
01624 #ifdef USING_AGENTX_SUBAGENT_MODULE
01625 int role = netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
01626 NETSNMP_DS_AGENT_ROLE);
01627
01628 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE,
01629 MASTER_AGENT);
01630 #endif
01631
01632
01633
01634
01635
01636 netsnmp_register_null(snmp_duplicate_objid(ccitt, 1), 1);
01637 netsnmp_register_null(snmp_duplicate_objid(iso, 1), 1);
01638 netsnmp_register_null(snmp_duplicate_objid(joint_ccitt_iso, 1), 1);
01639
01640 #ifdef USING_AGENTX_SUBAGENT_MODULE
01641 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE,
01642 role);
01643 #endif
01644 }
01645
01646 int
01647 remove_tree_entry (oid *name, size_t len) {
01648
01649 netsnmp_subtree *sub = NULL;
01650
01651 if ((sub = netsnmp_subtree_find(name, len, NULL, "")) == NULL) {
01652 return MIB_NO_SUCH_REGISTRATION;
01653 }
01654
01655 return unregister_mib_context(name, len, sub->priority,
01656 sub->range_subid, sub->range_ubound, "");
01657
01658 }
01659
01660
01661 void
01662 shutdown_tree(void) {
01663 oid ccitt[1] = { 0 };
01664 oid iso[1] = { 1 };
01665 oid joint_ccitt_iso[1] = { 2 };
01666
01667 DEBUGMSGTL(("agent_registry", "shut down tree\n"));
01668
01669 remove_tree_entry(joint_ccitt_iso, 1);
01670 remove_tree_entry(iso, 1);
01671 remove_tree_entry(ccitt, 1);
01672
01673 }
01674
01675 void
01676 clear_subtree (netsnmp_subtree *sub) {
01677
01678 netsnmp_subtree *nxt;
01679
01680 if (sub == NULL)
01681 return;
01682
01683 for(nxt = sub; nxt;) {
01684 if (nxt->children != NULL) {
01685 clear_subtree(nxt->children);
01686 }
01687 sub = nxt;
01688 nxt = nxt->next;
01689 netsnmp_subtree_free(sub);
01690 }
01691
01692 }
01693
01694 void
01695 clear_lookup_cache(void) {
01696
01697 lookup_cache_context *ptr = NULL, *next = NULL;
01698
01699 ptr = thecontextcache;
01700 while (ptr) {
01701 next = ptr->next;
01702 SNMP_FREE(ptr->context);
01703 SNMP_FREE(ptr);
01704 ptr = next;
01705 }
01706 thecontextcache = NULL;
01707 }
01708
01709 void
01710 clear_context(void) {
01711
01712 subtree_context_cache *ptr = NULL, *next = NULL;
01713
01714 DEBUGMSGTL(("agent_registry", "clear context\n"));
01715
01716 ptr = get_top_context_cache();
01717 while (ptr) {
01718 next = ptr->next;
01719
01720 if (ptr->first_subtree) {
01721 clear_subtree(ptr->first_subtree);
01722 }
01723
01724 SNMP_FREE(ptr->context_name);
01725 SNMP_FREE(ptr);
01726
01727 ptr = next;
01728 }
01729 context_subtrees = NULL;
01730 clear_lookup_cache();
01731 }
01732
01733 extern void dump_idx_registry(void);
01734 void
01735 dump_registry(void)
01736 {
01737 struct variable *vp = NULL;
01738 netsnmp_subtree *myptr, *myptr2;
01739 u_char *s = NULL, *e = NULL, *v = NULL;
01740 size_t sl = 256, el = 256, vl = 256, sl_o = 0, el_o = 0, vl_o = 0;
01741 int i = 0;
01742
01743 if ((s = (u_char *) calloc(sl, 1)) != NULL &&
01744 (e = (u_char *) calloc(sl, 1)) != NULL &&
01745 (v = (u_char *) calloc(sl, 1)) != NULL) {
01746
01747 subtree_context_cache *ptr;
01748 for (ptr = context_subtrees; ptr; ptr = ptr->next) {
01749 printf("Subtrees for Context: %s\n", ptr->context_name);
01750 for (myptr = ptr->first_subtree; myptr != NULL;
01751 myptr = myptr->next) {
01752 sl_o = el_o = vl_o = 0;
01753
01754 if (!sprint_realloc_objid(&s, &sl, &sl_o, 1,
01755 myptr->start_a,
01756 myptr->start_len)) {
01757 break;
01758 }
01759 if (!sprint_realloc_objid(&e, &el, &el_o, 1,
01760 myptr->end_a,
01761 myptr->end_len)) {
01762 break;
01763 }
01764
01765 if (myptr->variables) {
01766 printf("%02x ( %s - %s ) [", myptr->flags, s, e);
01767 for (i = 0, vp = myptr->variables;
01768 i < myptr->variables_len; i++) {
01769 vl_o = 0;
01770 if (!sprint_realloc_objid
01771 (&v, &vl, &vl_o, 1, vp->name, vp->namelen)) {
01772 break;
01773 }
01774 printf("%s, ", v);
01775 vp = (struct variable *) ((char *) vp +
01776 myptr->variables_width);
01777 }
01778 printf("]\n");
01779 } else {
01780 printf("%02x %s - %s \n", myptr->flags, s, e);
01781 }
01782 for (myptr2 = myptr; myptr2 != NULL;
01783 myptr2 = myptr2->children) {
01784 if (myptr2->label_a && myptr2->label_a[0]) {
01785 if (strcmp(myptr2->label_a, "old_api") == 0) {
01786 struct variable *vp =
01787 myptr2->reginfo->handler->myvoid;
01788
01789 if (!sprint_realloc_objid(&s, &sl, &sl_o, 1,
01790 vp->name, vp->namelen)) {
01791 continue;
01792 }
01793 printf("\t%s[%s] %p var %s\n", myptr2->label_a,
01794 myptr2->reginfo->handlerName ?
01795 myptr2->reginfo->handlerName : "no-name",
01796 myptr2->reginfo, s);
01797 } else {
01798 printf("\t%s %s %p\n", myptr2->label_a,
01799 myptr2->reginfo->handlerName ?
01800 myptr2->reginfo->handlerName : "no-handler-name",
01801 myptr2->reginfo);
01802 }
01803 }
01804 }
01805 }
01806 }
01807 }
01808
01809 if (s != NULL) {
01810 SNMP_FREE(s);
01811 }
01812 if (e != NULL) {
01813 SNMP_FREE(e);
01814 }
01815 if (v != NULL) {
01816 SNMP_FREE(v);
01817 }
01818
01819 dump_idx_registry();
01820 }
01821
01822 int external_signal_scheduled[NUM_EXTERNAL_SIGS];
01823 void (*external_signal_handler[NUM_EXTERNAL_SIGS]) (int);
01824
01825 #ifndef WIN32
01826
01827
01828
01829
01830
01831
01832 RETSIGTYPE
01833 agent_SIGCHLD_handler(int sig)
01834 {
01835 external_signal_scheduled[SIGCHLD]++;
01836 #ifndef HAVE_SIGACTION
01837
01838
01839
01840
01841
01842 signal(SIGCHLD, agent_SIGCHLD_handler);
01843 #endif
01844 }
01845
01846 int
01847 register_signal(int sig, void (*func) (int))
01848 {
01849
01850 switch (sig) {
01851 #if defined(SIGCHLD)
01852 case SIGCHLD:
01853 #ifdef HAVE_SIGACTION
01854 {
01855 static struct sigaction act;
01856 act.sa_handler = agent_SIGCHLD_handler;
01857 sigemptyset(&act.sa_mask);
01858 act.sa_flags = 0;
01859 sigaction(SIGCHLD, &act, NULL);
01860 }
01861 #else
01862 signal(SIGCHLD, agent_SIGCHLD_handler);
01863 #endif
01864 break;
01865 #endif
01866 default:
01867 snmp_log(LOG_CRIT,
01868 "register_signal: signal %d cannot be handled\n", sig);
01869 return SIG_REGISTRATION_FAILED;
01870 }
01871
01872 external_signal_handler[sig] = func;
01873 external_signal_scheduled[sig] = 0;
01874
01875 DEBUGMSGTL(("register_signal", "registered signal %d\n", sig));
01876 return SIG_REGISTERED_OK;
01877 }
01878
01879 int
01880 unregister_signal(int sig)
01881 {
01882 signal(sig, SIG_DFL);
01883 DEBUGMSGTL(("unregister_signal", "unregistered signal %d\n", sig));
01884 return SIG_UNREGISTERED_OK;
01885 }
01886
01887 #endif
01888