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