]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
MFC r299764,r299765,r299767,r299769,r299770,r299774,r299802,r299803,r299805,r299814:
[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 extern int _bsnmptools_debug;
51 #define DEBUG   if (_bsnmptools_debug) fprintf
52
53 /* Allocate memory and initialize list. */
54 struct snmp_mappings *
55 snmp_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
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 = calloc(1, sizeof(struct enum_pair))) == NULL) {
272                 syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
273                 return (-1);
274         }
275
276         if ((e_new->enum_str = strdup(enum_str)) == NULL) {
277                 syslog(LOG_ERR, "malloc() 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  */
294 static int
295 snmp_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
348 int32_t
349 snmp_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
357 static int32_t
358 snmp_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
366 static int32_t
367 snmp_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
375 static int32_t
376 snmp_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
384 static int32_t
385 snmp_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
393 static int32_t
394 snmp_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
402 static int32_t
403 snmp_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
411 static int32_t
412 snmp_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
420 static int32_t
421 snmp_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
429 int32_t
430 snmp_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
438 int32_t
439 snmp_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
465 static int32_t
466 snmp_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
475 int32_t
476 snmp_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
498 int32_t
499 snmp_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
550 struct enum_type *
551 snmp_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
569 void
570 snmp_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
579 void
580 snmp_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
588 struct enum_type *
589 snmp_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
603 static void
604 snmp_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
622 static void
623 snmp_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
640 void 
641 snmp_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
690 char *
691 enum_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
706 int32_t
707 enum_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
721 static int32_t
722 snmp_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 */
740 static int32_t
741 snmp_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
759 int32_t
760 snmp_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
799 int32_t
800 snmp_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
808 int32_t
809 snmp_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
817 int32_t
818 snmp_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
826 int32_t
827 snmp_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
856 int32_t
857 snmp_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
871 static int32_t
872 snmp_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
895 static int32_t
896 snmp_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
927 int32_t
928 snmp_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
959 int32_t
960 snmp_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
969 int32_t
970 snmp_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 }