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 * 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 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 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 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 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 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 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 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 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 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 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 * 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 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 checking is left to calling function. 292 */ 293 static int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 * 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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