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