xref: /freebsd/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c (revision 20f8619da05e2775ef7b381c5df080d621fa8332)
1 /*-
2  * Copyright (c) 2006 The FreeBSD Project
3  * All rights reserved.
4  *
5  * Author: Shteryana Shopova <syrinx@FreeBSD.org>
6  *
7  * Redistribution of this software and documentation and use in source and
8  * binary forms, with or without modification, are permitted provided that
9  * the following conditions are met:
10  *
11  * 1. Redistributions of source code or documentation must retain the above
12  *    copyright notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 #include <sys/param.h>
33 #include <sys/queue.h>
34 #include <sys/uio.h>
35 
36 #include <ctype.h>
37 #include <err.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <syslog.h>
43 #include <unistd.h>
44 
45 #include <bsnmp/asn1.h>
46 #include <bsnmp/snmp.h>
47 #include "bsnmptc.h"
48 #include "bsnmptools.h"
49 
50 #define	DEBUG	if (_bsnmptools_debug) fprintf
51 
52 /* Allocate memory and initialize list. */
53 struct snmp_mappings *
54 snmp_mapping_init(void)
55 {
56 	struct snmp_mappings *m;
57 
58 	if ((m = malloc(sizeof(struct snmp_mappings))) == NULL) {
59 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
60 		return (NULL);
61 	}
62 
63 	memset(m, 0, sizeof(struct snmp_mappings));
64 	return (m);
65 }
66 
67 #define		snmp_nodelist	mappings->nodelist
68 #define		snmp_intlist	mappings->intlist
69 #define		snmp_octlist	mappings->octlist
70 #define		snmp_oidlist	mappings->oidlist
71 #define		snmp_iplist	mappings->iplist
72 #define		snmp_ticklist	mappings->ticklist
73 #define		snmp_cntlist	mappings->cntlist
74 #define		snmp_gaugelist	mappings->gaugelist
75 #define		snmp_cnt64list	mappings->cnt64list
76 #define		snmp_enumlist	mappings->enumlist
77 #define		snmp_tablelist	mappings->tablelist
78 #define		snmp_tclist	mappings->tclist
79 
80 void
81 enum_pairs_free(struct enum_pairs *headp)
82 {
83 	struct enum_pair *e;
84 
85 	if (headp == NULL)
86 		return;
87 
88 	while ((e = STAILQ_FIRST(headp)) != NULL) {
89 		STAILQ_REMOVE_HEAD(headp, link);
90 
91 		if (e->enum_str)
92 			free(e->enum_str);
93 		free(e);
94 	}
95 
96 	free(headp);
97 }
98 
99 void
100 snmp_mapping_entryfree(struct snmp_oid2str *entry)
101 {
102 	if (entry->string)
103 		free(entry->string);
104 
105 	if (entry->tc == SNMP_TC_OWN)
106 		enum_pairs_free(entry->snmp_enum);
107 
108 	free(entry);
109 }
110 
111 static void
112 snmp_mapping_listfree(struct snmp_mapping *headp)
113 {
114 	struct snmp_oid2str *p;
115 
116 	while ((p = SLIST_FIRST(headp)) != NULL) {
117 		SLIST_REMOVE_HEAD(headp, link);
118 
119 		if (p->string)
120 			free(p->string);
121 
122 		if (p->tc == SNMP_TC_OWN)
123 			enum_pairs_free(p->snmp_enum);
124 		free(p);
125 	}
126 
127 	SLIST_INIT(headp);
128 }
129 
130 void
131 snmp_index_listfree(struct snmp_idxlist *headp)
132 {
133 	struct index *i;
134 
135 	while ((i = STAILQ_FIRST(headp)) != NULL) {
136 		STAILQ_REMOVE_HEAD(headp, link);
137 		if (i->tc == SNMP_TC_OWN)
138 			enum_pairs_free(i->snmp_enum);
139 		free(i);
140 	}
141 
142 	STAILQ_INIT(headp);
143 }
144 
145 static void
146 snmp_mapping_table_listfree(struct snmp_table_index *headp)
147 {
148 	struct snmp_index_entry *t;
149 
150 	while ((t = SLIST_FIRST(headp)) != NULL) {
151 		SLIST_REMOVE_HEAD(headp, link);
152 
153 		if (t->string)
154 			free(t->string);
155 
156 		snmp_index_listfree(&(t->index_list));
157 		free(t);
158 	}
159 }
160 
161 static void
162 snmp_enumtc_listfree(struct snmp_enum_tc *headp)
163 {
164 	struct enum_type *t;
165 
166 	while ((t = SLIST_FIRST(headp)) != NULL) {
167 		SLIST_REMOVE_HEAD(headp, link);
168 
169 		if (t->name)
170 			free(t->name);
171 		enum_pairs_free(t->snmp_enum);
172 		free(t);
173 	}
174 }
175 
176 int
177 snmp_mapping_free(struct snmp_toolinfo *snmptoolctx)
178 {
179 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
180 		return (-1);
181 
182 	snmp_mapping_listfree(&snmptoolctx->snmp_nodelist);
183 	snmp_mapping_listfree(&snmptoolctx->snmp_intlist);
184 	snmp_mapping_listfree(&snmptoolctx->snmp_octlist);
185 	snmp_mapping_listfree(&snmptoolctx->snmp_oidlist);
186 	snmp_mapping_listfree(&snmptoolctx->snmp_iplist);
187 	snmp_mapping_listfree(&snmptoolctx->snmp_ticklist);
188 	snmp_mapping_listfree(&snmptoolctx->snmp_cntlist);
189 	snmp_mapping_listfree(&snmptoolctx->snmp_gaugelist);
190 	snmp_mapping_listfree(&snmptoolctx->snmp_cnt64list);
191 	snmp_mapping_listfree(&snmptoolctx->snmp_enumlist);
192 	snmp_mapping_table_listfree(&snmptoolctx->snmp_tablelist);
193 	snmp_enumtc_listfree(&snmptoolctx->snmp_tclist);
194 	free(snmptoolctx->mappings);
195 
196 	return (0);
197 }
198 
199 static void
200 snmp_dump_enumpairs(struct enum_pairs *headp)
201 {
202 	struct enum_pair *entry;
203 
204 	if (headp == NULL)
205 		return;
206 
207 	fprintf(stderr,"enums: ");
208 	STAILQ_FOREACH(entry, headp, link)
209 		fprintf(stderr,"%d - %s, ", entry->enum_val,
210 		    (entry->enum_str == NULL)?"NULL":entry->enum_str);
211 
212 	fprintf(stderr,"; ");
213 }
214 
215 void
216 snmp_dump_oid2str(struct snmp_oid2str *entry)
217 {
218 	char buf[ASN_OIDSTRLEN];
219 
220 	if (entry != NULL) {
221 		memset(buf, 0, sizeof(buf));
222 		asn_oid2str_r(&(entry->var), buf);
223 		DEBUG(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
224 		    entry->syntax, entry->access, entry->strlen);
225 		snmp_dump_enumpairs(entry->snmp_enum);
226 		DEBUG(stderr,"%s \n", (entry->table_idx == NULL)?"No table":
227 		    entry->table_idx->string);
228 	}
229 }
230 
231 static void
232 snmp_dump_indexlist(struct snmp_idxlist *headp)
233 {
234 	struct index *entry;
235 
236 	if (headp == NULL)
237 		return;
238 
239 	STAILQ_FOREACH(entry, headp, link) {
240 		fprintf(stderr,"%d, ", entry->syntax);
241 		snmp_dump_enumpairs(entry->snmp_enum);
242 	}
243 
244 	fprintf(stderr,"\n");
245 }
246 
247 /* Initialize the enum pairs list of a oid2str entry. */
248 struct enum_pairs *
249 enum_pairs_init(void)
250 {
251 	struct enum_pairs *snmp_enum;
252 
253 	if ((snmp_enum = malloc(sizeof(struct enum_pairs))) == NULL) {
254 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
255 		return (NULL);
256 	}
257 
258 	STAILQ_INIT(snmp_enum);
259 	return (snmp_enum);
260 }
261 
262 /*
263  * Given a number and string, allocate memory for a (int, string) pair and add
264  * it to the given oid2str mapping entry's enum pairs list.
265  */
266 int32_t
267 enum_pair_insert(struct enum_pairs *headp, int32_t enum_val, char *enum_str)
268 {
269 	struct enum_pair *e_new;
270 
271 	if ((e_new = malloc(sizeof(struct enum_pair))) == NULL) {
272 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
273 		return (-1);
274 	}
275 
276 	memset(e_new, 0, sizeof(struct enum_pair));
277 
278 	if ((e_new->enum_str = malloc(strlen(enum_str) + 1)) == NULL) {
279 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
280 		free(e_new);
281 		return (-1);
282 	}
283 
284 	e_new->enum_val = enum_val;
285 	strlcpy(e_new->enum_str, enum_str, strlen(enum_str) + 1);
286 	STAILQ_INSERT_TAIL(headp, e_new, link);
287 
288 	return (1);
289 
290 }
291 
292 /*
293  * Insert an entry in a list - entries are lexicographicaly order by asn_oid.
294  * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already
295  * exists. Error cheking is left to calling function.
296  */
297 static int
298 snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry)
299 {
300 	int32_t rc;
301 	struct snmp_oid2str *temp, *prev;
302 
303 	if (entry == NULL)
304 		return(-1);
305 
306 	if ((prev = SLIST_FIRST(headp)) == NULL ||
307 	    asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
308 		SLIST_INSERT_HEAD(headp, entry, link);
309 		return (1);
310 	} else
311 		rc = -1;	/* Make the compiler happy. */
312 
313 	SLIST_FOREACH(temp, headp, link) {
314 		if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
315 			break;
316 		prev = temp;
317 		rc = -1;
318 	}
319 
320 	switch (rc) {
321 	    case 0:
322 		/* Ops, matching OIDs - hope the rest info also matches. */
323 		if (strncmp(temp->string, entry->string, entry->strlen)) {
324 			syslog(LOG_INFO, "Matching OIDs with different string "
325 			    "mappings: old - %s, new - %s", temp->string,
326 			    entry->string);
327 			return (-1);
328 		}
329 		/*
330 		 * Ok, we have that already.
331 		 * As long as the strings match - don't complain.
332 		 */
333 		return (0);
334 
335 	    case 1:
336 		SLIST_INSERT_AFTER(temp, entry, link);
337 		break;
338 
339 	    case -1:
340 		SLIST_INSERT_AFTER(prev, entry, link);
341 		break;
342 
343 	    default:
344 		/* NOTREACHED */
345 		return (-1);
346 	}
347 
348 	return (1);
349 }
350 
351 int32_t
352 snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
353 {
354 	if (snmptoolctx != NULL && snmptoolctx->mappings)
355 		return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry));
356 
357 	return (-1);
358 }
359 
360 static int32_t
361 snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
362 {
363 	if (snmptoolctx != NULL && snmptoolctx->mappings)
364 		return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry));
365 
366 	return (-1);
367 }
368 
369 static int32_t
370 snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
371 {
372 	if (snmptoolctx != NULL && snmptoolctx->mappings)
373 		return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry));
374 
375 	return (-1);
376 }
377 
378 static int32_t
379 snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
380 {
381 	if (snmptoolctx != NULL && snmptoolctx->mappings)
382 		return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry));
383 
384 	return (-1);
385 }
386 
387 static int32_t
388 snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
389 {
390 	if (snmptoolctx != NULL && snmptoolctx->mappings)
391 		return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry));
392 
393 	return (-1);
394 }
395 
396 static int32_t
397 snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
398 {
399 	if (snmptoolctx != NULL && snmptoolctx->mappings)
400 		return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry));
401 
402 	return (-1);
403 }
404 
405 static int32_t
406 snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
407 {
408 	if (snmptoolctx != NULL && snmptoolctx->mappings)
409 		return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry));
410 
411 	return (-1);
412 }
413 
414 static int32_t
415 snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
416 {
417 	if (snmptoolctx != NULL && snmptoolctx->mappings)
418 		return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry));
419 
420 	return (-1);
421 }
422 
423 static int32_t
424 snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
425 {
426 	if (snmptoolctx != NULL && snmptoolctx->mappings)
427 		return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry));
428 
429 	return (-1);
430 }
431 
432 int32_t
433 snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
434 {
435 	if (snmptoolctx != NULL && snmptoolctx->mappings)
436 		return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry));
437 
438 	return (-1);
439 }
440 
441 int32_t
442 snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
443 {
444 	switch (entry->syntax) {
445 		case SNMP_SYNTAX_INTEGER:
446 			return (snmp_int_insert(snmptoolctx, entry));
447 		case SNMP_SYNTAX_OCTETSTRING:
448 			return (snmp_oct_insert(snmptoolctx, entry));
449 		case SNMP_SYNTAX_OID:
450 			return (snmp_oid_insert(snmptoolctx, entry));
451 		case SNMP_SYNTAX_IPADDRESS:
452 			return (snmp_ip_insert(snmptoolctx, entry));
453 		case SNMP_SYNTAX_COUNTER:
454 			return (snmp_cnt_insert(snmptoolctx, entry));
455 		case SNMP_SYNTAX_GAUGE:
456 			return (snmp_gauge_insert(snmptoolctx, entry));
457 		case SNMP_SYNTAX_TIMETICKS:
458 			return (snmp_tick_insert(snmptoolctx, entry));
459 		case SNMP_SYNTAX_COUNTER64:
460 			return (snmp_cnt64_insert(snmptoolctx, entry));
461 		default:
462 			break;
463 	}
464 
465 	return (-1);
466 }
467 
468 static int32_t
469 snmp_index_insert(struct snmp_idxlist *headp, struct index *idx)
470 {
471 	if (headp == NULL || idx == NULL)
472 		return (-1);
473 
474 	STAILQ_INSERT_TAIL(headp, idx, link);
475 	return (1);
476 }
477 
478 int32_t
479 snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums,
480     enum snmp_syntax syntax, enum snmp_tc tc)
481 {
482 	struct index *idx;
483 
484 	if ((idx = malloc(sizeof(struct index))) == NULL) {
485 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
486 		return (-1);
487 	}
488 
489 	memset(idx, 0, sizeof(struct index));
490 
491 	if (snmp_index_insert(headp, idx) < 0) {
492 		free(idx);
493 		return (-1);
494 	}
495 
496 	idx->syntax = syntax;
497 	idx->snmp_enum = enums;
498 	idx->tc = tc;
499 
500 	return (1);
501 }
502 
503 int32_t
504 snmp_table_insert(struct snmp_toolinfo *snmptoolctx,
505     struct snmp_index_entry *entry)
506 {
507 	int32_t rc;
508 	struct snmp_index_entry *temp, *prev;
509 
510 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL ||
511 	    entry == NULL)
512 		return(-1);
513 
514 	if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL ||
515 	    asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
516 		SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link);
517 		return (1);
518 	} else
519 		rc = -1;	/* Make the compiler happy. */
520 
521 	SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) {
522 		if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
523 			break;
524 		prev = temp;
525 		rc = -1;
526 	}
527 
528 	switch (rc) {
529 	    case 0:
530 		/* Ops, matching OIDs - hope the rest info also matches. */
531 		if (strncmp(temp->string, entry->string, entry->strlen)) {
532 			syslog(LOG_INFO, "Matching OIDs with different string "
533 			    "mapping - old - %s, new - %s", temp->string,
534 			    entry->string);
535 			return (-1);
536 		}
537 		return(0);
538 
539 	    case 1:
540 		SLIST_INSERT_AFTER(temp, entry, link);
541 		break;
542 
543 	    case -1:
544 		SLIST_INSERT_AFTER(prev, entry, link);
545 		break;
546 
547 	    default:
548 		/* NOTREACHED */
549 		return (-1);
550 	}
551 
552 	return (1);
553 }
554 
555 struct enum_type *
556 snmp_enumtc_init(char *name)
557 {
558 	struct enum_type *enum_tc;
559 
560 	if ((enum_tc = malloc(sizeof(struct enum_type))) == NULL) {
561 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
562 		return (NULL);
563 	}
564 
565 	memset(enum_tc, 0, sizeof(struct enum_type));
566 	if ((enum_tc->name = malloc(strlen(name) + 1)) == NULL) {
567 		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
568 		free(enum_tc);
569 		return (NULL);
570 	}
571 	strlcpy(enum_tc->name, name, strlen(name) + 1);
572 
573 	return (enum_tc);
574 }
575 
576 void
577 snmp_enumtc_free(struct enum_type *tc)
578 {
579 	if (tc->name)
580 		free(tc->name);
581 	if (tc->snmp_enum)
582 		enum_pairs_free(tc->snmp_enum);
583 	free(tc);
584 }
585 
586 void
587 snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry)
588 {
589 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
590 		return;	/* XXX no error handling? */
591 
592 	SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link);
593 }
594 
595 struct enum_type *
596 snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name)
597 {
598 	struct enum_type *temp;
599 
600 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
601 		return (NULL);
602 
603 	SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) {
604 		if (strcmp(temp->name, name) == 0)
605 			return (temp);
606 	}
607 	return (NULL);
608 }
609 
610 static void
611 snmp_mapping_dumplist(struct snmp_mapping *headp)
612 {
613 	char buf[ASN_OIDSTRLEN];
614 	struct snmp_oid2str *entry;
615 
616 	if (headp == NULL)
617 		return;
618 
619 	SLIST_FOREACH(entry,headp,link) {
620 		memset(buf, 0, sizeof(buf));
621 		asn_oid2str_r(&(entry->var), buf);
622 		fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
623 		    entry->syntax, entry->access ,entry->strlen);
624 		fprintf(stderr," - %s \n", (entry->table_idx == NULL)?
625 		    "No table":entry->table_idx->string);
626 	}
627 }
628 
629 static void
630 snmp_mapping_dumptable(struct snmp_table_index *headp)
631 {
632 	char buf[ASN_OIDSTRLEN];
633 	struct snmp_index_entry *entry;
634 
635 	if (headp == NULL)
636 		return;
637 
638 	SLIST_FOREACH(entry, headp, link) {
639 		memset(buf, 0, sizeof(buf));
640 		asn_oid2str_r(&(entry->var), buf);
641 		fprintf(stderr,"%s - %s - %d - ", buf, entry->string,
642 		    entry->strlen);
643 		snmp_dump_indexlist(&(entry->index_list));
644 	}
645 }
646 
647 void
648 snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */)
649 {
650 	if (!_bsnmptools_debug)
651 		return;
652 
653 	if (snmptoolctx == NULL) {
654 		fprintf(stderr,"No snmptool context!\n");
655 		return;
656 	}
657 
658 	if (snmptoolctx->mappings == NULL) {
659 		fprintf(stderr,"No mappings!\n");
660 		return;
661 	}
662 
663 	fprintf(stderr,"snmp_nodelist:\n");
664 	snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist);
665 
666 	fprintf(stderr,"snmp_intlist:\n");
667 	snmp_mapping_dumplist(&snmptoolctx->snmp_intlist);
668 
669 	fprintf(stderr,"snmp_octlist:\n");
670 	snmp_mapping_dumplist(&snmptoolctx->snmp_octlist);
671 
672 	fprintf(stderr,"snmp_oidlist:\n");
673 	snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist);
674 
675 	fprintf(stderr,"snmp_iplist:\n");
676 	snmp_mapping_dumplist(&snmptoolctx->snmp_iplist);
677 
678 	fprintf(stderr,"snmp_ticklist:\n");
679 	snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist);
680 
681 	fprintf(stderr,"snmp_cntlist:\n");
682 	snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist);
683 
684 	fprintf(stderr,"snmp_gaugelist:\n");
685 	snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist);
686 
687 	fprintf(stderr,"snmp_cnt64list:\n");
688 	snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list);
689 
690 	fprintf(stderr,"snmp_enumlist:\n");
691 	snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist);
692 
693 	fprintf(stderr,"snmp_tablelist:\n");
694 	snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist);
695 }
696 
697 char *
698 enum_string_lookup(struct enum_pairs *headp, int32_t enum_val)
699 {
700 	struct enum_pair *temp;
701 
702 	if (headp == NULL)
703 		return (NULL);
704 
705 	STAILQ_FOREACH(temp, headp, link) {
706 		if (temp->enum_val == enum_val)
707 			return (temp->enum_str);
708 	}
709 
710 	return (NULL);
711 }
712 
713 int32_t
714 enum_number_lookup(struct enum_pairs *headp, char *e_str)
715 {
716 	struct enum_pair *tmp;
717 
718 	if (headp == NULL)
719 		return (-1);
720 
721 	STAILQ_FOREACH(tmp, headp, link)
722 		if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0)
723 			return (tmp->enum_val);
724 
725 	return (-1);
726 }
727 
728 static int32_t
729 snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s)
730 {
731 	struct snmp_oid2str *temp;
732 
733 	if (headp == NULL)
734 		return (-1);
735 
736 	SLIST_FOREACH(temp, headp, link)
737 		if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0)
738 			break;
739 
740 	if ((s->info = temp) == NULL)
741 		return (-1);
742 
743 	return (1);
744 }
745 
746 /* provided an asn_oid find the corresponding string for it */
747 static int32_t
748 snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s)
749 {
750 	struct snmp_oid2str *temp;
751 
752 	if (headp == NULL)
753 		return (-1);
754 
755 	SLIST_FOREACH(temp,headp,link) {
756 		if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) ||
757 		    (asn_is_suboid(&(temp->var), &(s->val.var)))) {
758 			s->info = temp;
759 			return (1);
760 		}
761 	}
762 
763 	return (-1);
764 }
765 
766 int32_t
767 snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
768 {
769 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
770 		return (-1);
771 
772 	switch (s->val.syntax) {
773 		case SNMP_SYNTAX_INTEGER:
774 			return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s));
775 		case SNMP_SYNTAX_OCTETSTRING:
776 			return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s));
777 		case SNMP_SYNTAX_OID:
778 			return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s));
779 		case SNMP_SYNTAX_IPADDRESS:
780 			return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s));
781 		case SNMP_SYNTAX_COUNTER:
782 			return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s));
783 		case SNMP_SYNTAX_GAUGE:
784 			return (snmp_lookup_leaf(
785 			    &snmptoolctx->snmp_gaugelist, s));
786 		case SNMP_SYNTAX_TIMETICKS:
787 			return (snmp_lookup_leaf(
788 			    &snmptoolctx->snmp_ticklist, s));
789 		case SNMP_SYNTAX_COUNTER64:
790 			return (snmp_lookup_leaf(
791 			    &snmptoolctx->snmp_cnt64list, s));
792 		case SNMP_SYNTAX_NOSUCHOBJECT:
793 			/* FALLTHROUGH */
794 		case SNMP_SYNTAX_NOSUCHINSTANCE:
795 			/* FALLTHROUGH */
796 		case SNMP_SYNTAX_ENDOFMIBVIEW:
797 			return (snmp_lookup_allstring(snmptoolctx, s));
798 		default:
799 			warnx("Unknown syntax - %d", s->val.syntax);
800 			break;
801 	}
802 
803 	return (-1);
804 }
805 
806 int32_t
807 snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
808 {
809 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
810 		return (-1);
811 
812 	return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s));
813 }
814 
815 int32_t
816 snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
817 {
818 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
819 		return (-1);
820 
821 	return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s));
822 }
823 
824 int32_t
825 snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
826 {
827 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
828 		return (-1);
829 
830 	return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s));
831 }
832 
833 int32_t
834 snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
835 {
836 	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
837 		return (-1);
838 
839 	if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0)
840 		return (1);
841 	if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0)
842 		return (1);
843 	if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0)
844 		return (1);
845 	if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0)
846 		return (1);
847 	if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0)
848 		return (1);
849 	if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0)
850 		return (1);
851 	if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0)
852 		return (1);
853 	if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0)
854 		return (1);
855 	if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
856 		return (1);
857 	if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
858 		return (1);
859 
860 	return (-1);
861 }
862 
863 int32_t
864 snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx,
865     struct snmp_object *s)
866 {
867 	if (snmptoolctx == NULL)
868 		return (-1);
869 
870 	if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
871 		return (1);
872 	if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
873 		return (1);
874 
875 	return (-1);
876 }
877 
878 static int32_t
879 snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid)
880 {
881 	struct snmp_oid2str *temp;
882 
883 	if (hp == NULL)
884 		return (-1);
885 
886 	SLIST_FOREACH(temp, hp, link) {
887 		if (temp->strlen != strlen(oid))
888 			continue;
889 
890 		if (strncmp(temp->string, oid, temp->strlen))
891 			continue;
892 
893 		s->val.syntax = temp->syntax;
894 		s->info = temp;
895 		asn_append_oid(&(s->val.var), &(temp->var));
896 		return (1);
897 	}
898 
899 	return (-1);
900 }
901 
902 static int32_t
903 snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx,
904     struct snmp_table_index *headp, struct snmp_object *s, char *oid)
905 {
906 	struct snmp_index_entry *temp;
907 
908 	if (snmptoolctx == NULL || headp == NULL)
909 		return (-1);
910 
911 	SLIST_FOREACH(temp, headp, link) {
912 		if (temp->strlen != strlen(oid))
913 			continue;
914 
915 		if (strncmp(temp->string, oid, temp->strlen))
916 			continue;
917 
918 		/*
919 		 * Another hack here - if we were given a table name
920 		 * return the corresponding pointer to it's entry.
921 		 * That should not change the reponce we'll get.
922 		 */
923 		s->val.syntax = SNMP_SYNTAX_NULL;
924 		asn_append_oid(&(s->val.var), &(temp->var));
925 		if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0)
926 			return (1);
927 		else
928 			return (-1);
929 	}
930 
931 	return (-1);
932 }
933 
934 int32_t
935 snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
936     char *oid)
937 {
938 	if (snmptoolctx == NULL || s == NULL || oid == NULL)
939 		return (-1);
940 
941 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0)
942 		return (1);
943 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0)
944 		return (1);
945 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0)
946 		return (1);
947 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0)
948 		return (1);
949 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0)
950 		return (1);
951 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0)
952 		return (1);
953 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0)
954 		return (1);
955 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0)
956 		return (1);
957 	if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0)
958 		return (1);
959 	if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist,
960 	    s, oid) > 0)
961 		return (1);
962 
963 	return (-1);
964 }
965 
966 int32_t
967 snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
968     char *oid)
969 {
970 	if (snmptoolctx == NULL || s == NULL)
971 		return (-1);
972 
973 	return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid));
974 }
975 
976 int32_t
977 snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
978     char *oid)
979 {
980 	if (snmptoolctx == NULL || s == NULL)
981 		return (-1);
982 
983 	switch (s->val.syntax) {
984 		case SNMP_SYNTAX_INTEGER:
985 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist,
986 			    s, oid));
987 		case SNMP_SYNTAX_OCTETSTRING:
988 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist,
989 			    s, oid));
990 		case SNMP_SYNTAX_OID:
991 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist,
992 			    s, oid));
993 		case SNMP_SYNTAX_IPADDRESS:
994 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist,
995 			    s, oid));
996 		case SNMP_SYNTAX_COUNTER:
997 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist,
998 			    s, oid));
999 		case SNMP_SYNTAX_GAUGE:
1000 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist,
1001 			    s, oid));
1002 		case SNMP_SYNTAX_TIMETICKS:
1003 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist,
1004 			    s, oid));
1005 		case SNMP_SYNTAX_COUNTER64:
1006 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list,
1007 			    s, oid));
1008 		case SNMP_SYNTAX_NULL:
1009 			return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist,
1010 			    s, oid));
1011 		default:
1012 			warnx("Unknown syntax - %d", s->val.syntax);
1013 			break;
1014 	}
1015 
1016 	return (-1);
1017 }
1018