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