bsnmpmap.c revision 301653
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: stable/10/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c 301653 2016-06-08 17:27:38Z ngie $
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
50extern int _bsnmptools_debug;
51#define	DEBUG	if (_bsnmptools_debug) fprintf
52
53/* Allocate memory and initialize list. */
54struct snmp_mappings *
55snmp_mapping_init(void)
56{
57	struct snmp_mappings *m;
58
59	if ((m = calloc(1, sizeof(struct snmp_mappings))) == NULL) {
60		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
61		return (NULL);
62	}
63
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
80void
81enum_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
99void
100snmp_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
111static void
112snmp_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
130void
131snmp_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
145static void
146snmp_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
161static void
162snmp_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
176int
177snmp_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
199static void
200snmp_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
215void
216snmp_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
231static void
232snmp_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. */
248struct enum_pairs *
249enum_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 */
266int32_t
267enum_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 = calloc(1, sizeof(struct enum_pair))) == NULL) {
272		syslog(LOG_ERR, "calloc() failed: %s", strerror(errno));
273		return (-1);
274	}
275
276	if ((e_new->enum_str = strdup(enum_str)) == NULL) {
277		syslog(LOG_ERR, "strdup() failed: %s", strerror(errno));
278		free(e_new);
279		return (-1);
280	}
281
282	e_new->enum_val = enum_val;
283	STAILQ_INSERT_TAIL(headp, e_new, link);
284
285	return (1);
286
287}
288
289/*
290 * Insert an entry in a list - entries are lexicographicaly order by asn_oid.
291 * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already
292 * exists. Error cheking is left to calling function.
293 */
294static int
295snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry)
296{
297	int32_t rc;
298	struct snmp_oid2str *temp, *prev;
299
300	if (entry == NULL)
301		return(-1);
302
303	if ((prev = SLIST_FIRST(headp)) == NULL ||
304	    asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
305		SLIST_INSERT_HEAD(headp, entry, link);
306		return (1);
307	} else
308		rc = -1;	/* Make the compiler happy. */
309
310	SLIST_FOREACH(temp, headp, link) {
311		if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
312			break;
313		prev = temp;
314		rc = -1;
315	}
316
317	switch (rc) {
318	    case 0:
319		/* Ops, matching OIDs - hope the rest info also matches. */
320		if (strncmp(temp->string, entry->string, entry->strlen)) {
321			syslog(LOG_INFO, "Matching OIDs with different string "
322			    "mappings: old - %s, new - %s", temp->string,
323			    entry->string);
324			return (-1);
325		}
326		/*
327		 * Ok, we have that already.
328		 * As long as the strings match - don't complain.
329		 */
330		return (0);
331
332	    case 1:
333		SLIST_INSERT_AFTER(temp, entry, link);
334		break;
335
336	    case -1:
337		SLIST_INSERT_AFTER(prev, entry, link);
338		break;
339
340	    default:
341		/* NOTREACHED */
342		return (-1);
343	}
344
345	return (1);
346}
347
348int32_t
349snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
350{
351	if (snmptoolctx != NULL && snmptoolctx->mappings)
352		return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry));
353
354	return (-1);
355}
356
357static int32_t
358snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
359{
360	if (snmptoolctx != NULL && snmptoolctx->mappings)
361		return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry));
362
363	return (-1);
364}
365
366static int32_t
367snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
368{
369	if (snmptoolctx != NULL && snmptoolctx->mappings)
370		return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry));
371
372	return (-1);
373}
374
375static int32_t
376snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
377{
378	if (snmptoolctx != NULL && snmptoolctx->mappings)
379		return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry));
380
381	return (-1);
382}
383
384static int32_t
385snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
386{
387	if (snmptoolctx != NULL && snmptoolctx->mappings)
388		return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry));
389
390	return (-1);
391}
392
393static int32_t
394snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
395{
396	if (snmptoolctx != NULL && snmptoolctx->mappings)
397		return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry));
398
399	return (-1);
400}
401
402static int32_t
403snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
404{
405	if (snmptoolctx != NULL && snmptoolctx->mappings)
406		return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry));
407
408	return (-1);
409}
410
411static int32_t
412snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
413{
414	if (snmptoolctx != NULL && snmptoolctx->mappings)
415		return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry));
416
417	return (-1);
418}
419
420static int32_t
421snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
422{
423	if (snmptoolctx != NULL && snmptoolctx->mappings)
424		return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry));
425
426	return (-1);
427}
428
429int32_t
430snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
431{
432	if (snmptoolctx != NULL && snmptoolctx->mappings)
433		return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry));
434
435	return (-1);
436}
437
438int32_t
439snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
440{
441	switch (entry->syntax) {
442		case SNMP_SYNTAX_INTEGER:
443			return (snmp_int_insert(snmptoolctx, entry));
444		case SNMP_SYNTAX_OCTETSTRING:
445			return (snmp_oct_insert(snmptoolctx, entry));
446		case SNMP_SYNTAX_OID:
447			return (snmp_oid_insert(snmptoolctx, entry));
448		case SNMP_SYNTAX_IPADDRESS:
449			return (snmp_ip_insert(snmptoolctx, entry));
450		case SNMP_SYNTAX_COUNTER:
451			return (snmp_cnt_insert(snmptoolctx, entry));
452		case SNMP_SYNTAX_GAUGE:
453			return (snmp_gauge_insert(snmptoolctx, entry));
454		case SNMP_SYNTAX_TIMETICKS:
455			return (snmp_tick_insert(snmptoolctx, entry));
456		case SNMP_SYNTAX_COUNTER64:
457			return (snmp_cnt64_insert(snmptoolctx, entry));
458		default:
459			break;
460	}
461
462	return (-1);
463}
464
465static int32_t
466snmp_index_insert(struct snmp_idxlist *headp, struct index *idx)
467{
468	if (headp == NULL || idx == NULL)
469		return (-1);
470
471	STAILQ_INSERT_TAIL(headp, idx, link);
472	return (1);
473}
474
475int32_t
476snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums,
477    enum snmp_syntax syntax, enum snmp_tc tc)
478{
479	struct index *idx;
480
481	if ((idx = calloc(1, sizeof(struct index))) == NULL) {
482		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
483		return (-1);
484	}
485
486	if (snmp_index_insert(headp, idx) < 0) {
487		free(idx);
488		return (-1);
489	}
490
491	idx->syntax = syntax;
492	idx->snmp_enum = enums;
493	idx->tc = tc;
494
495	return (1);
496}
497
498int32_t
499snmp_table_insert(struct snmp_toolinfo *snmptoolctx,
500    struct snmp_index_entry *entry)
501{
502	int32_t rc;
503	struct snmp_index_entry *temp, *prev;
504
505	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL ||
506	    entry == NULL)
507		return(-1);
508
509	if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL ||
510	    asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
511		SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link);
512		return (1);
513	} else
514		rc = -1;	/* Make the compiler happy. */
515
516	SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) {
517		if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
518			break;
519		prev = temp;
520		rc = -1;
521	}
522
523	switch (rc) {
524	    case 0:
525		/* Ops, matching OIDs - hope the rest info also matches. */
526		if (strncmp(temp->string, entry->string, entry->strlen)) {
527			syslog(LOG_INFO, "Matching OIDs with different string "
528			    "mapping - old - %s, new - %s", temp->string,
529			    entry->string);
530			return (-1);
531		}
532		return(0);
533
534	    case 1:
535		SLIST_INSERT_AFTER(temp, entry, link);
536		break;
537
538	    case -1:
539		SLIST_INSERT_AFTER(prev, entry, link);
540		break;
541
542	    default:
543		/* NOTREACHED */
544		return (-1);
545	}
546
547	return (1);
548}
549
550struct enum_type *
551snmp_enumtc_init(char *name)
552{
553	struct enum_type *enum_tc;
554
555	if ((enum_tc = calloc(1, sizeof(struct enum_type))) == NULL) {
556		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
557		return (NULL);
558	}
559
560	if ((enum_tc->name = strdup(name)) == NULL) {
561		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
562		free(enum_tc);
563		return (NULL);
564	}
565
566	return (enum_tc);
567}
568
569void
570snmp_enumtc_free(struct enum_type *tc)
571{
572	if (tc->name)
573		free(tc->name);
574	if (tc->snmp_enum)
575		enum_pairs_free(tc->snmp_enum);
576	free(tc);
577}
578
579void
580snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry)
581{
582	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
583		return;	/* XXX no error handling? */
584
585	SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link);
586}
587
588struct enum_type *
589snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name)
590{
591	struct enum_type *temp;
592
593	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
594		return (NULL);
595
596	SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) {
597		if (strcmp(temp->name, name) == 0)
598			return (temp);
599	}
600	return (NULL);
601}
602
603static void
604snmp_mapping_dumplist(struct snmp_mapping *headp)
605{
606	char buf[ASN_OIDSTRLEN];
607	struct snmp_oid2str *entry;
608
609	if (headp == NULL)
610		return;
611
612	SLIST_FOREACH(entry,headp,link) {
613		memset(buf, 0, sizeof(buf));
614		asn_oid2str_r(&(entry->var), buf);
615		fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
616		    entry->syntax, entry->access ,entry->strlen);
617		fprintf(stderr," - %s \n", (entry->table_idx == NULL)?
618		    "No table":entry->table_idx->string);
619	}
620}
621
622static void
623snmp_mapping_dumptable(struct snmp_table_index *headp)
624{
625	char buf[ASN_OIDSTRLEN];
626	struct snmp_index_entry *entry;
627
628	if (headp == NULL)
629		return;
630
631	SLIST_FOREACH(entry, headp, link) {
632		memset(buf, 0, sizeof(buf));
633		asn_oid2str_r(&(entry->var), buf);
634		fprintf(stderr,"%s - %s - %d - ", buf, entry->string,
635		    entry->strlen);
636		snmp_dump_indexlist(&(entry->index_list));
637	}
638}
639
640void
641snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */)
642{
643	if (!_bsnmptools_debug)
644		return;
645
646	if (snmptoolctx == NULL) {
647		fprintf(stderr,"No snmptool context!\n");
648		return;
649	}
650
651	if (snmptoolctx->mappings == NULL) {
652		fprintf(stderr,"No mappings!\n");
653		return;
654	}
655
656	fprintf(stderr,"snmp_nodelist:\n");
657	snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist);
658
659	fprintf(stderr,"snmp_intlist:\n");
660	snmp_mapping_dumplist(&snmptoolctx->snmp_intlist);
661
662	fprintf(stderr,"snmp_octlist:\n");
663	snmp_mapping_dumplist(&snmptoolctx->snmp_octlist);
664
665	fprintf(stderr,"snmp_oidlist:\n");
666	snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist);
667
668	fprintf(stderr,"snmp_iplist:\n");
669	snmp_mapping_dumplist(&snmptoolctx->snmp_iplist);
670
671	fprintf(stderr,"snmp_ticklist:\n");
672	snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist);
673
674	fprintf(stderr,"snmp_cntlist:\n");
675	snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist);
676
677	fprintf(stderr,"snmp_gaugelist:\n");
678	snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist);
679
680	fprintf(stderr,"snmp_cnt64list:\n");
681	snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list);
682
683	fprintf(stderr,"snmp_enumlist:\n");
684	snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist);
685
686	fprintf(stderr,"snmp_tablelist:\n");
687	snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist);
688}
689
690char *
691enum_string_lookup(struct enum_pairs *headp, int32_t enum_val)
692{
693	struct enum_pair *temp;
694
695	if (headp == NULL)
696		return (NULL);
697
698	STAILQ_FOREACH(temp, headp, link) {
699		if (temp->enum_val == enum_val)
700			return (temp->enum_str);
701	}
702
703	return (NULL);
704}
705
706int32_t
707enum_number_lookup(struct enum_pairs *headp, char *e_str)
708{
709	struct enum_pair *tmp;
710
711	if (headp == NULL)
712		return (-1);
713
714	STAILQ_FOREACH(tmp, headp, link)
715		if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0)
716			return (tmp->enum_val);
717
718	return (-1);
719}
720
721static int32_t
722snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s)
723{
724	struct snmp_oid2str *temp;
725
726	if (headp == NULL)
727		return (-1);
728
729	SLIST_FOREACH(temp, headp, link)
730		if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0)
731			break;
732
733	if ((s->info = temp) == NULL)
734		return (-1);
735
736	return (1);
737}
738
739/* provided an asn_oid find the corresponding string for it */
740static int32_t
741snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s)
742{
743	struct snmp_oid2str *temp;
744
745	if (headp == NULL)
746		return (-1);
747
748	SLIST_FOREACH(temp,headp,link) {
749		if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) ||
750		    (asn_is_suboid(&(temp->var), &(s->val.var)))) {
751			s->info = temp;
752			return (1);
753		}
754	}
755
756	return (-1);
757}
758
759int32_t
760snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
761{
762	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
763		return (-1);
764
765	switch (s->val.syntax) {
766		case SNMP_SYNTAX_INTEGER:
767			return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s));
768		case SNMP_SYNTAX_OCTETSTRING:
769			return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s));
770		case SNMP_SYNTAX_OID:
771			return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s));
772		case SNMP_SYNTAX_IPADDRESS:
773			return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s));
774		case SNMP_SYNTAX_COUNTER:
775			return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s));
776		case SNMP_SYNTAX_GAUGE:
777			return (snmp_lookup_leaf(
778			    &snmptoolctx->snmp_gaugelist, s));
779		case SNMP_SYNTAX_TIMETICKS:
780			return (snmp_lookup_leaf(
781			    &snmptoolctx->snmp_ticklist, s));
782		case SNMP_SYNTAX_COUNTER64:
783			return (snmp_lookup_leaf(
784			    &snmptoolctx->snmp_cnt64list, s));
785		case SNMP_SYNTAX_NOSUCHOBJECT:
786			/* FALLTHROUGH */
787		case SNMP_SYNTAX_NOSUCHINSTANCE:
788			/* FALLTHROUGH */
789		case SNMP_SYNTAX_ENDOFMIBVIEW:
790			return (snmp_lookup_allstring(snmptoolctx, s));
791		default:
792			warnx("Unknown syntax - %d", s->val.syntax);
793			break;
794	}
795
796	return (-1);
797}
798
799int32_t
800snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
801{
802	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
803		return (-1);
804
805	return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s));
806}
807
808int32_t
809snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
810{
811	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
812		return (-1);
813
814	return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s));
815}
816
817int32_t
818snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
819{
820	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
821		return (-1);
822
823	return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s));
824}
825
826int32_t
827snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
828{
829	if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
830		return (-1);
831
832	if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0)
833		return (1);
834	if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0)
835		return (1);
836	if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0)
837		return (1);
838	if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0)
839		return (1);
840	if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0)
841		return (1);
842	if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0)
843		return (1);
844	if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0)
845		return (1);
846	if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0)
847		return (1);
848	if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
849		return (1);
850	if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
851		return (1);
852
853	return (-1);
854}
855
856int32_t
857snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx,
858    struct snmp_object *s)
859{
860	if (snmptoolctx == NULL)
861		return (-1);
862
863	if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
864		return (1);
865	if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
866		return (1);
867
868	return (-1);
869}
870
871static int32_t
872snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid)
873{
874	struct snmp_oid2str *temp;
875
876	if (hp == NULL)
877		return (-1);
878
879	SLIST_FOREACH(temp, hp, link) {
880		if (temp->strlen != strlen(oid))
881			continue;
882
883		if (strncmp(temp->string, oid, temp->strlen))
884			continue;
885
886		s->val.syntax = temp->syntax;
887		s->info = temp;
888		asn_append_oid(&(s->val.var), &(temp->var));
889		return (1);
890	}
891
892	return (-1);
893}
894
895static int32_t
896snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx,
897    struct snmp_table_index *headp, struct snmp_object *s, char *oid)
898{
899	struct snmp_index_entry *temp;
900
901	if (snmptoolctx == NULL || headp == NULL)
902		return (-1);
903
904	SLIST_FOREACH(temp, headp, link) {
905		if (temp->strlen != strlen(oid))
906			continue;
907
908		if (strncmp(temp->string, oid, temp->strlen))
909			continue;
910
911		/*
912		 * Another hack here - if we were given a table name
913		 * return the corresponding pointer to it's entry.
914		 * That should not change the reponce we'll get.
915		 */
916		s->val.syntax = SNMP_SYNTAX_NULL;
917		asn_append_oid(&(s->val.var), &(temp->var));
918		if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0)
919			return (1);
920		else
921			return (-1);
922	}
923
924	return (-1);
925}
926
927int32_t
928snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
929    char *oid)
930{
931	if (snmptoolctx == NULL || s == NULL || oid == NULL)
932		return (-1);
933
934	if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0)
935		return (1);
936	if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0)
937		return (1);
938	if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0)
939		return (1);
940	if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0)
941		return (1);
942	if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0)
943		return (1);
944	if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0)
945		return (1);
946	if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0)
947		return (1);
948	if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0)
949		return (1);
950	if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0)
951		return (1);
952	if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist,
953	    s, oid) > 0)
954		return (1);
955
956	return (-1);
957}
958
959int32_t
960snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
961    char *oid)
962{
963	if (snmptoolctx == NULL || s == NULL)
964		return (-1);
965
966	return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid));
967}
968
969int32_t
970snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
971    char *oid)
972{
973	if (snmptoolctx == NULL || s == NULL)
974		return (-1);
975
976	switch (s->val.syntax) {
977		case SNMP_SYNTAX_INTEGER:
978			return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist,
979			    s, oid));
980		case SNMP_SYNTAX_OCTETSTRING:
981			return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist,
982			    s, oid));
983		case SNMP_SYNTAX_OID:
984			return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist,
985			    s, oid));
986		case SNMP_SYNTAX_IPADDRESS:
987			return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist,
988			    s, oid));
989		case SNMP_SYNTAX_COUNTER:
990			return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist,
991			    s, oid));
992		case SNMP_SYNTAX_GAUGE:
993			return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist,
994			    s, oid));
995		case SNMP_SYNTAX_TIMETICKS:
996			return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist,
997			    s, oid));
998		case SNMP_SYNTAX_COUNTER64:
999			return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list,
1000			    s, oid));
1001		case SNMP_SYNTAX_NULL:
1002			return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist,
1003			    s, oid));
1004		default:
1005			warnx("Unknown syntax - %d", s->val.syntax);
1006			break;
1007	}
1008
1009	return (-1);
1010}
1011