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