]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / usr.sbin / bsnmpd / tools / libbsnmptools / bsnmpmap.c
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 = 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
79 void
80 enum_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
98 void
99 snmp_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
110 static void
111 snmp_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
129 void
130 snmp_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
144 static void
145 snmp_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
160 static void
161 snmp_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
175 int
176 snmp_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
198 static void
199 snmp_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
214 void
215 snmp_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
230 static void
231 snmp_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. */
247 struct enum_pairs *
248 enum_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  */
265 int32_t
266 enum_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  */
293 static int
294 snmp_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
347 int32_t
348 snmp_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
356 static int32_t
357 snmp_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
365 static int32_t
366 snmp_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
374 static int32_t
375 snmp_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
383 static int32_t
384 snmp_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
392 static int32_t
393 snmp_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
401 static int32_t
402 snmp_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
410 static int32_t
411 snmp_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
419 static int32_t
420 snmp_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
428 int32_t
429 snmp_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
437 int32_t
438 snmp_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
464 static int32_t
465 snmp_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
474 int32_t
475 snmp_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
497 int32_t
498 snmp_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
549 struct enum_type *
550 snmp_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
568 void
569 snmp_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
578 void
579 snmp_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
587 struct enum_type *
588 snmp_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
602 static void
603 snmp_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
621 static void
622 snmp_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
639 void
640 snmp_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
689 char *
690 enum_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
705 int32_t
706 enum_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
720 static int32_t
721 snmp_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 */
739 static int32_t
740 snmp_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
758 int32_t
759 snmp_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
798 int32_t
799 snmp_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
807 int32_t
808 snmp_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
816 int32_t
817 snmp_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
825 int32_t
826 snmp_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
855 int32_t
856 snmp_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
870 static int32_t
871 snmp_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
894 static int32_t
895 snmp_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
926 int32_t
927 snmp_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
958 int32_t
959 snmp_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
968 int32_t
969 snmp_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 }