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. */ 51struct snmp_mappings * 52snmp_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 77void 78enum_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 96void 97snmp_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 108static void 109snmp_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 127void 128snmp_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 142static void 143snmp_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 158static void 159snmp_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 173int 174snmp_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 196static void 197snmp_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 212void 213snmp_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 228static void 229snmp_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. */ 245struct enum_pairs * 246enum_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 */ 263int32_t 264enum_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 */ 291static int 292snmp_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 345int32_t 346snmp_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 354static int32_t 355snmp_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 363static int32_t 364snmp_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 372static int32_t 373snmp_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 381static int32_t 382snmp_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 390static int32_t 391snmp_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 399static int32_t 400snmp_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 408static int32_t 409snmp_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 417static int32_t 418snmp_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 426int32_t 427snmp_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 435int32_t 436snmp_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 462static int32_t 463snmp_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 472int32_t 473snmp_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 495int32_t 496snmp_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 547struct enum_type * 548snmp_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 566void 567snmp_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 576void 577snmp_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 585struct enum_type * 586snmp_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 600static void 601snmp_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 619static void 620snmp_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 637void 638snmp_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 687char * 688enum_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 703int32_t 704enum_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 718static int32_t 719snmp_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 */ 737static int32_t 738snmp_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 756int32_t 757snmp_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 796int32_t 797snmp_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 805int32_t 806snmp_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 814int32_t 815snmp_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 823int32_t 824snmp_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 853int32_t 854snmp_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 868static int32_t 869snmp_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 892static int32_t 893snmp_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 924int32_t 925snmp_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 956int32_t 957snmp_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 966int32_t 967snmp_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