📄 parse.c
字号:
fprintf(f, "Children of %s(%ld):\n", tree->label, tree->subid);
count++;
for(tp = tree->child_list; tp; tp = tp->next_peer){
for(i = 0; i < count; i++)
fprintf(f, " ");
fprintf(f, "%s:%s(%ld) type=%d",
module_name(tp->module_list[0], modbuf),
tp->label, tp->subid, tp->type);
if (tp->tc_index != -1) fprintf(f, " tc=%d", tp->tc_index);
if (tp->hint) fprintf(f, " hint=%s", tp->hint);
if (tp->units) fprintf(f, " units=%s", tp->units);
if (tp->number_modules > 1) {
fprintf(f, " modules:");
for (i = 1; i < tp->number_modules; i++)
fprintf(f, " %s", module_name(tp->module_list[i], modbuf));
}
fprintf(f, "\n");
}
for(tp = tree->child_list; tp; tp = tp->next_peer){
if (tp->child_list)
print_subtree(f, tp, count);
}
}
void
print_ascii_dump_tree(FILE *f,
struct tree *tree,
int count)
{
struct tree *tp;
count++;
for(tp = tree->child_list; tp; tp = tp->next_peer){
fprintf(f, "%s OBJECT IDENTIFIER ::= { %s %ld }\n", tp->label, tree->label, tp->subid);
}
for(tp = tree->child_list; tp; tp = tp->next_peer){
if (tp->child_list)
print_ascii_dump_tree(f, tp, count);
}
}
static int translation_table[256];
static void
build_translation_table()
{
int count;
for(count = 0; count < 256; count++){
switch(count){
case OBJID:
translation_table[count] = TYPE_OBJID;
break;
case OCTETSTR:
translation_table[count] = TYPE_OCTETSTR;
break;
case INTEGER:
translation_table[count] = TYPE_INTEGER;
break;
case NETADDR:
translation_table[count] = TYPE_IPADDR;
break;
case IPADDR:
translation_table[count] = TYPE_IPADDR;
break;
case COUNTER:
translation_table[count] = TYPE_COUNTER;
break;
case GAUGE:
translation_table[count] = TYPE_GAUGE;
break;
case TIMETICKS:
translation_table[count] = TYPE_TIMETICKS;
break;
case KW_OPAQUE:
translation_table[count] = TYPE_OPAQUE;
break;
case NUL:
translation_table[count] = TYPE_NULL;
break;
case COUNTER64:
translation_table[count] = TYPE_COUNTER64;
break;
case BITSTRING:
translation_table[count] = TYPE_BITSTRING;
break;
case NSAPADDRESS:
translation_table[count] = TYPE_NSAPADDRESS;
break;
case UINTEGER32:
translation_table[count] = TYPE_UINTEGER;
break;
default:
translation_table[count] = TYPE_OTHER;
break;
}
}
}
static void
init_tree_roots()
{
struct tree *tp, *lasttp;
int base_modid;
int hash;
base_modid = which_module("SNMPv2-SMI");
if (base_modid == -1 )
base_modid = which_module("RFC1155-SMI");
if (base_modid == -1 )
base_modid = which_module("RFC1213-MIB");
/* build root node */
tp = (struct tree *) calloc(1, sizeof(struct tree));
if (tp == NULL) return;
tp->label = strdup("joint-iso-ccitt");
tp->modid = base_modid;
tp->number_modules = 1;
tp->module_list = &(tp->modid);
tp->subid = 2;
tp->tc_index = -1;
set_function(tp); /* from mib.c */
hash = NBUCKET(name_hash(tp->label));
tp->next = tbuckets[hash];
tbuckets[hash] = tp;
lasttp = tp;
root_imports[0].label = strdup( tp->label );
root_imports[0].modid = base_modid;
/* build root node */
tp = (struct tree *) calloc(1, sizeof(struct tree));
if (tp == NULL) return;
tp->next_peer = lasttp;
tp->label = strdup("ccitt");
tp->modid = base_modid;
tp->number_modules = 1;
tp->module_list = &(tp->modid);
tp->subid = 0;
tp->tc_index = -1;
set_function(tp); /* from mib.c */
hash = NBUCKET(name_hash(tp->label));
tp->next = tbuckets[hash];
tbuckets[hash] = tp;
lasttp = tp;
root_imports[1].label = strdup( tp->label );
root_imports[1].modid = base_modid;
/* build root node */
tp = (struct tree *) calloc(1, sizeof(struct tree));
if (tp == NULL) return;
tp->next_peer = lasttp;
tp->label = strdup("iso");
tp->modid = base_modid;
tp->number_modules = 1;
tp->module_list = &(tp->modid);
tp->subid = 1;
tp->tc_index = -1;
set_function(tp); /* from mib.c */
hash = NBUCKET(name_hash(tp->label));
tp->next = tbuckets[hash];
tbuckets[hash] = tp;
lasttp = tp;
root_imports[2].label = strdup( tp->label );
root_imports[2].modid = base_modid;
tree_head = tp;
}
#ifdef STRICT_MIB_PARSEING
#define label_compare strcasecmp
#else
#define label_compare strcmp
#endif
struct tree *
find_tree_node(const char *name,
int modid)
{
struct tree *tp, *headtp;
int count, *int_p;
if (!name || !*name)
return(NULL);
headtp = tbuckets[NBUCKET(name_hash(name))];
for ( tp = headtp ; tp ; tp=tp->next ) {
if ( !label_compare(tp->label, name) ) {
if ( modid == -1 ) /* Any module */
return(tp);
for (int_p = tp->module_list, count=0 ;
count < tp->number_modules ;
++count, ++int_p )
if ( *int_p == modid )
return(tp);
}
}
return(NULL);
}
/* computes a value which represents how close name1 is to name2.
* high scores mean a worse match.
* (yes, the algorithm sucks!)
*/
#define MAX_BAD 0xffffff
u_int
compute_match(const char *search_base, const char *key) {
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
int rc;
regex_t parsetree;
regmatch_t pmatch;
rc=regcomp(&parsetree, key, REG_ICASE | REG_EXTENDED);
if (rc == 0)
rc=regexec(&parsetree, search_base, 1, &pmatch, 0);
regfree(&parsetree);
if (rc == 0) {
/* found */
return pmatch.rm_so;
}
#else /* use our own wildcard matcher */
/* first find the longest matching substring (ick) */
char *first = NULL, *result = NULL, *entry;
const char *position;
char *newkey = strdup(key);
entry = strtok( newkey, "*" );
position = search_base;
while ( entry ) {
result = strcasestr(position, entry);
if (result == NULL) {
free(newkey);
return MAX_BAD;
}
if (first == NULL)
first = result;
position = result + strlen(entry);
entry = strtok( NULL, "*" );
}
free(newkey);
if (result)
return(first-search_base);
#endif
/* not found */
return MAX_BAD;
}
/*
* Find the tree node that best matches the pattern string.
* Use the "reported" flag such that only one match
* is attempted for every node.
*
* Warning! This function may recurse.
*
* Caller _must_ invoke clear_tree_flags before first call
* to this function. This function may be called multiple times
* to ensure that the entire tree is traversed.
*/
struct tree *
find_best_tree_node(const char *pattrn, struct tree *tree_top, u_int *match)
{
struct tree *tp, *best_so_far = NULL, *retptr;
u_int old_match=MAX_BAD, new_match=MAX_BAD;
if (!pattrn || !*pattrn)
return(NULL);
if (!tree_top)
tree_top = get_tree_head();
for ( tp = tree_top ; tp ; tp=tp->next_peer ) {
if (!tp->reported)
new_match = compute_match(tp->label, pattrn);
tp->reported = 1;
if (new_match < old_match) {
best_so_far = tp;
old_match = new_match;
}
if (new_match == 0)
break; /* this is the best result we can get */
if (tp->child_list) {
retptr = find_best_tree_node(pattrn, tp->child_list, &new_match);
if (new_match < old_match) {
best_so_far = retptr;
old_match = new_match;
}
if (new_match == 0)
break; /* this is the best result we can get */
}
}
if (match)
*match = old_match;
return(best_so_far);
}
static void
merge_anon_children(struct tree *tp1,
struct tree *tp2)
/* NB: tp1 is the 'anonymous' node */
{
struct tree *child1, *child2, *previous;
for ( child1 = tp1->child_list ; child1 ; ) {
for ( child2 = tp2->child_list, previous = NULL ;
child2 ; previous = child2, child2 = child2->next_peer ) {
if ( child1->subid == child2->subid ) {
/*
* Found 'matching' children,
* so merge them
*/
if ( !strncmp( child1->label, ANON, ANON_LEN)) {
merge_anon_children( child1, child2 );
child1->child_list = NULL;
previous = child1; /* Finished with 'child1' */
child1 = child1->next_peer;
free_tree( previous );
goto next;
}
else if ( !strncmp( child2->label, ANON, ANON_LEN)) {
merge_anon_children( child2, child1 );
if ( previous )
previous->next_peer = child2->next_peer;
else
tp2->child_list = child2->next_peer;
free_tree(child2);
previous = child1; /* Move 'child1' to 'tp2' */
child1 = child1->next_peer;
previous->next_peer = tp2->child_list;
tp2->child_list = previous;
for ( previous = tp2->child_list ;
previous ;
previous = previous->next_peer )
previous->parent = tp2;
goto next;
}
else if ( !label_compare( child1->label, child2->label) ) {
if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))
snmp_log(LOG_WARNING, "Warning: %s.%ld is both %s and %s (%s)\n",
tp2->label, child1->subid,
child1->label, child2->label, File);
continue;
}
else {
/*
* Two copies of the same node.
* 'child2' adopts the children of 'child1'
*/
if ( child2->child_list ) {
for ( previous = child2->child_list ;
previous->next_peer ;
previous = previous->next_peer )
; /* Find the end of the list */
previous->next_peer = child1->child_list;
}
else
child2->child_list = child1->child_list;
for ( previous = child1->child_list ;
previous ;
previous = previous->next_peer )
previous->parent = child2;
child1->child_list = NULL;
previous = child1; /* Finished with 'child1' */
child1 = child1->next_peer;
free_tree( previous );
goto next;
}
}
}
/*
* If no match, move 'child1' to 'tp2' child_list
*/
if ( child1 ) {
previous = child1;
child1 = child1->next_peer;
previous->parent = tp2;
previous->next_peer = tp2->child_list;
tp2->child_list = previous;
}
next:;
}
}
/*
* Find all the children of root in the list of nodes. Link them into the
* tree and out of the nodes list.
*/
static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -