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 50extern int _bsnmptools_debug; 51#define DEBUG if (_bsnmptools_debug) fprintf 52 53/* Allocate memory and initialize list. */ 54struct snmp_mappings * 55snmp_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 81void 82enum_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 100void 101snmp_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 112static void 113snmp_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 131void 132snmp_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 146static void 147snmp_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 162static void 163snmp_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 177int 178snmp_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 200static void 201snmp_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 216void 217snmp_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 232static void 233snmp_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. */ 249struct enum_pairs * 250enum_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 */ 267int32_t 268enum_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 */ 298static int 299snmp_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 352int32_t 353snmp_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 361static int32_t 362snmp_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 370static int32_t 371snmp_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 379static int32_t 380snmp_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 388static int32_t 389snmp_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 397static int32_t 398snmp_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 406static int32_t 407snmp_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 415static int32_t 416snmp_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 424static int32_t 425snmp_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 433int32_t 434snmp_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 442int32_t 443snmp_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 469static int32_t 470snmp_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 479int32_t 480snmp_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 504int32_t 505snmp_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 556struct enum_type * 557snmp_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 577void 578snmp_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 587void 588snmp_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 596struct enum_type * 597snmp_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 611static void 612snmp_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 630static void 631snmp_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 648void 649snmp_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 698char * 699enum_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 714int32_t 715enum_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 729static int32_t 730snmp_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 */ 748static int32_t 749snmp_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 767int32_t 768snmp_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 807int32_t 808snmp_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 816int32_t 817snmp_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 825int32_t 826snmp_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 834int32_t 835snmp_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 864int32_t 865snmp_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 879static int32_t 880snmp_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 903static int32_t 904snmp_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 935int32_t 936snmp_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 967int32_t 968snmp_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 977int32_t 978snmp_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} 1019