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