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 *
snmp_mapping_init(void)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
enum_pairs_free(struct enum_pairs * headp)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
snmp_mapping_entryfree(struct snmp_oid2str * entry)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
snmp_mapping_listfree(struct snmp_mapping * headp)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
snmp_index_listfree(struct snmp_idxlist * headp)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
snmp_mapping_table_listfree(struct snmp_table_index * headp)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
snmp_enumtc_listfree(struct snmp_enum_tc * headp)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
snmp_mapping_free(struct snmp_toolinfo * snmptoolctx)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
snmp_dump_enumpairs(struct enum_pairs * headp)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
snmp_dump_oid2str(struct snmp_oid2str * entry)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
snmp_dump_indexlist(struct snmp_idxlist * headp)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 *
enum_pairs_init(void)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
enum_pair_insert(struct enum_pairs * headp,int32_t enum_val,char * enum_str)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
snmp_mapping_insert(struct snmp_mapping * headp,struct snmp_oid2str * entry)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
snmp_node_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_int_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_oct_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_oid_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_ip_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_tick_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_cnt_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_gauge_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_cnt64_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_enum_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_leaf_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * entry)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
snmp_index_insert(struct snmp_idxlist * headp,struct index * idx)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
snmp_syntax_insert(struct snmp_idxlist * headp,struct enum_pairs * enums,enum snmp_syntax syntax,enum snmp_tc tc)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
snmp_table_insert(struct snmp_toolinfo * snmptoolctx,struct snmp_index_entry * entry)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 *
snmp_enumtc_init(char * name)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
snmp_enumtc_free(struct enum_type * tc)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
snmp_enumtc_insert(struct snmp_toolinfo * snmptoolctx,struct enum_type * entry)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 *
snmp_enumtc_lookup(struct snmp_toolinfo * snmptoolctx,char * name)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
snmp_mapping_dumplist(struct snmp_mapping * headp)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
snmp_mapping_dumptable(struct snmp_table_index * headp)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
snmp_mapping_dump(struct snmp_toolinfo * snmptoolctx)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 *
enum_string_lookup(struct enum_pairs * headp,int32_t enum_val)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
enum_number_lookup(struct enum_pairs * headp,char * e_str)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
snmp_lookuplist_string(struct snmp_mapping * headp,struct snmp_object * s)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
snmp_lookup_leaf(struct snmp_mapping * headp,struct snmp_object * s)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
snmp_lookup_leafstring(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_enumstring(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_oidstring(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_nodestring(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_allstring(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_nonleaf_string(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s)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
snmp_lookup_oidlist(struct snmp_mapping * hp,struct snmp_object * s,char * oid)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
snmp_lookup_tablelist(struct snmp_toolinfo * snmptoolctx,struct snmp_table_index * headp,struct snmp_object * s,char * oid)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
snmp_lookup_oidall(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s,char * oid)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
snmp_lookup_enumoid(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s,char * oid)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
snmp_lookup_oid(struct snmp_toolinfo * snmptoolctx,struct snmp_object * s,char * oid)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 }
1010