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