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 = calloc(1, sizeof(struct enum_pair))) == NULL) { 272 syslog(LOG_ERR, "calloc() failed: %s", strerror(errno)); 273 return (-1); 274 } 275 276 if ((e_new->enum_str = strdup(enum_str)) == NULL) { 277 syslog(LOG_ERR, "strdup() failed: %s", strerror(errno)); 278 free(e_new); 279 return (-1); 280 } 281 282 e_new->enum_val = enum_val; 283 STAILQ_INSERT_TAIL(headp, e_new, link); 284 285 return (1); 286 287 } 288 289 /* 290 * Insert an entry in a list - entries are lexicographicaly order by asn_oid. 291 * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already 292 * exists. Error cheking is left to calling function. 293 */ 294 static int 295 snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry) 296 { 297 int32_t rc; 298 struct snmp_oid2str *temp, *prev; 299 300 if (entry == NULL) 301 return(-1); 302 303 if ((prev = SLIST_FIRST(headp)) == NULL || 304 asn_compare_oid(&(entry->var), &(prev->var)) < 0) { 305 SLIST_INSERT_HEAD(headp, entry, link); 306 return (1); 307 } else 308 rc = -1; /* Make the compiler happy. */ 309 310 SLIST_FOREACH(temp, headp, link) { 311 if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0) 312 break; 313 prev = temp; 314 rc = -1; 315 } 316 317 switch (rc) { 318 case 0: 319 /* Ops, matching OIDs - hope the rest info also matches. */ 320 if (strncmp(temp->string, entry->string, entry->strlen)) { 321 syslog(LOG_INFO, "Matching OIDs with different string " 322 "mappings: old - %s, new - %s", temp->string, 323 entry->string); 324 return (-1); 325 } 326 /* 327 * Ok, we have that already. 328 * As long as the strings match - don't complain. 329 */ 330 return (0); 331 332 case 1: 333 SLIST_INSERT_AFTER(temp, entry, link); 334 break; 335 336 case -1: 337 SLIST_INSERT_AFTER(prev, entry, link); 338 break; 339 340 default: 341 /* NOTREACHED */ 342 return (-1); 343 } 344 345 return (1); 346 } 347 348 int32_t 349 snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 350 { 351 if (snmptoolctx != NULL && snmptoolctx->mappings) 352 return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry)); 353 354 return (-1); 355 } 356 357 static int32_t 358 snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 359 { 360 if (snmptoolctx != NULL && snmptoolctx->mappings) 361 return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry)); 362 363 return (-1); 364 } 365 366 static int32_t 367 snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 368 { 369 if (snmptoolctx != NULL && snmptoolctx->mappings) 370 return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry)); 371 372 return (-1); 373 } 374 375 static int32_t 376 snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 377 { 378 if (snmptoolctx != NULL && snmptoolctx->mappings) 379 return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry)); 380 381 return (-1); 382 } 383 384 static int32_t 385 snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 386 { 387 if (snmptoolctx != NULL && snmptoolctx->mappings) 388 return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry)); 389 390 return (-1); 391 } 392 393 static int32_t 394 snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 395 { 396 if (snmptoolctx != NULL && snmptoolctx->mappings) 397 return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry)); 398 399 return (-1); 400 } 401 402 static int32_t 403 snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 404 { 405 if (snmptoolctx != NULL && snmptoolctx->mappings) 406 return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry)); 407 408 return (-1); 409 } 410 411 static int32_t 412 snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 413 { 414 if (snmptoolctx != NULL && snmptoolctx->mappings) 415 return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry)); 416 417 return (-1); 418 } 419 420 static int32_t 421 snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 422 { 423 if (snmptoolctx != NULL && snmptoolctx->mappings) 424 return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry)); 425 426 return (-1); 427 } 428 429 int32_t 430 snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 431 { 432 if (snmptoolctx != NULL && snmptoolctx->mappings) 433 return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry)); 434 435 return (-1); 436 } 437 438 int32_t 439 snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) 440 { 441 switch (entry->syntax) { 442 case SNMP_SYNTAX_INTEGER: 443 return (snmp_int_insert(snmptoolctx, entry)); 444 case SNMP_SYNTAX_OCTETSTRING: 445 return (snmp_oct_insert(snmptoolctx, entry)); 446 case SNMP_SYNTAX_OID: 447 return (snmp_oid_insert(snmptoolctx, entry)); 448 case SNMP_SYNTAX_IPADDRESS: 449 return (snmp_ip_insert(snmptoolctx, entry)); 450 case SNMP_SYNTAX_COUNTER: 451 return (snmp_cnt_insert(snmptoolctx, entry)); 452 case SNMP_SYNTAX_GAUGE: 453 return (snmp_gauge_insert(snmptoolctx, entry)); 454 case SNMP_SYNTAX_TIMETICKS: 455 return (snmp_tick_insert(snmptoolctx, entry)); 456 case SNMP_SYNTAX_COUNTER64: 457 return (snmp_cnt64_insert(snmptoolctx, entry)); 458 default: 459 break; 460 } 461 462 return (-1); 463 } 464 465 static int32_t 466 snmp_index_insert(struct snmp_idxlist *headp, struct index *idx) 467 { 468 if (headp == NULL || idx == NULL) 469 return (-1); 470 471 STAILQ_INSERT_TAIL(headp, idx, link); 472 return (1); 473 } 474 475 int32_t 476 snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums, 477 enum snmp_syntax syntax, enum snmp_tc tc) 478 { 479 struct index *idx; 480 481 if ((idx = malloc(sizeof(struct index))) == NULL) { 482 syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); 483 return (-1); 484 } 485 486 memset(idx, 0, sizeof(struct index)); 487 488 if (snmp_index_insert(headp, idx) < 0) { 489 free(idx); 490 return (-1); 491 } 492 493 idx->syntax = syntax; 494 idx->snmp_enum = enums; 495 idx->tc = tc; 496 497 return (1); 498 } 499 500 int32_t 501 snmp_table_insert(struct snmp_toolinfo *snmptoolctx, 502 struct snmp_index_entry *entry) 503 { 504 int32_t rc; 505 struct snmp_index_entry *temp, *prev; 506 507 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || 508 entry == NULL) 509 return(-1); 510 511 if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL || 512 asn_compare_oid(&(entry->var), &(prev->var)) < 0) { 513 SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link); 514 return (1); 515 } else 516 rc = -1; /* Make the compiler happy. */ 517 518 SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) { 519 if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0) 520 break; 521 prev = temp; 522 rc = -1; 523 } 524 525 switch (rc) { 526 case 0: 527 /* Ops, matching OIDs - hope the rest info also matches. */ 528 if (strncmp(temp->string, entry->string, entry->strlen)) { 529 syslog(LOG_INFO, "Matching OIDs with different string " 530 "mapping - old - %s, new - %s", temp->string, 531 entry->string); 532 return (-1); 533 } 534 return(0); 535 536 case 1: 537 SLIST_INSERT_AFTER(temp, entry, link); 538 break; 539 540 case -1: 541 SLIST_INSERT_AFTER(prev, entry, link); 542 break; 543 544 default: 545 /* NOTREACHED */ 546 return (-1); 547 } 548 549 return (1); 550 } 551 552 struct enum_type * 553 snmp_enumtc_init(char *name) 554 { 555 struct enum_type *enum_tc; 556 557 if ((enum_tc = calloc(1, sizeof(struct enum_type))) == NULL) { 558 syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); 559 return (NULL); 560 } 561 562 if ((enum_tc->name = strdup(name)) == NULL) { 563 syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); 564 free(enum_tc); 565 return (NULL); 566 } 567 568 return (enum_tc); 569 } 570 571 void 572 snmp_enumtc_free(struct enum_type *tc) 573 { 574 if (tc->name) 575 free(tc->name); 576 if (tc->snmp_enum) 577 enum_pairs_free(tc->snmp_enum); 578 free(tc); 579 } 580 581 void 582 snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry) 583 { 584 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) 585 return; /* XXX no error handling? */ 586 587 SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link); 588 } 589 590 struct enum_type * 591 snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name) 592 { 593 struct enum_type *temp; 594 595 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) 596 return (NULL); 597 598 SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) { 599 if (strcmp(temp->name, name) == 0) 600 return (temp); 601 } 602 return (NULL); 603 } 604 605 static void 606 snmp_mapping_dumplist(struct snmp_mapping *headp) 607 { 608 char buf[ASN_OIDSTRLEN]; 609 struct snmp_oid2str *entry; 610 611 if (headp == NULL) 612 return; 613 614 SLIST_FOREACH(entry,headp,link) { 615 memset(buf, 0, sizeof(buf)); 616 asn_oid2str_r(&(entry->var), buf); 617 fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string, 618 entry->syntax, entry->access ,entry->strlen); 619 fprintf(stderr," - %s \n", (entry->table_idx == NULL)? 620 "No table":entry->table_idx->string); 621 } 622 } 623 624 static void 625 snmp_mapping_dumptable(struct snmp_table_index *headp) 626 { 627 char buf[ASN_OIDSTRLEN]; 628 struct snmp_index_entry *entry; 629 630 if (headp == NULL) 631 return; 632 633 SLIST_FOREACH(entry, headp, link) { 634 memset(buf, 0, sizeof(buf)); 635 asn_oid2str_r(&(entry->var), buf); 636 fprintf(stderr,"%s - %s - %d - ", buf, entry->string, 637 entry->strlen); 638 snmp_dump_indexlist(&(entry->index_list)); 639 } 640 } 641 642 void 643 snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */) 644 { 645 if (!_bsnmptools_debug) 646 return; 647 648 if (snmptoolctx == NULL) { 649 fprintf(stderr,"No snmptool context!\n"); 650 return; 651 } 652 653 if (snmptoolctx->mappings == NULL) { 654 fprintf(stderr,"No mappings!\n"); 655 return; 656 } 657 658 fprintf(stderr,"snmp_nodelist:\n"); 659 snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist); 660 661 fprintf(stderr,"snmp_intlist:\n"); 662 snmp_mapping_dumplist(&snmptoolctx->snmp_intlist); 663 664 fprintf(stderr,"snmp_octlist:\n"); 665 snmp_mapping_dumplist(&snmptoolctx->snmp_octlist); 666 667 fprintf(stderr,"snmp_oidlist:\n"); 668 snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist); 669 670 fprintf(stderr,"snmp_iplist:\n"); 671 snmp_mapping_dumplist(&snmptoolctx->snmp_iplist); 672 673 fprintf(stderr,"snmp_ticklist:\n"); 674 snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist); 675 676 fprintf(stderr,"snmp_cntlist:\n"); 677 snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist); 678 679 fprintf(stderr,"snmp_gaugelist:\n"); 680 snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist); 681 682 fprintf(stderr,"snmp_cnt64list:\n"); 683 snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list); 684 685 fprintf(stderr,"snmp_enumlist:\n"); 686 snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist); 687 688 fprintf(stderr,"snmp_tablelist:\n"); 689 snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist); 690 } 691 692 char * 693 enum_string_lookup(struct enum_pairs *headp, int32_t enum_val) 694 { 695 struct enum_pair *temp; 696 697 if (headp == NULL) 698 return (NULL); 699 700 STAILQ_FOREACH(temp, headp, link) { 701 if (temp->enum_val == enum_val) 702 return (temp->enum_str); 703 } 704 705 return (NULL); 706 } 707 708 int32_t 709 enum_number_lookup(struct enum_pairs *headp, char *e_str) 710 { 711 struct enum_pair *tmp; 712 713 if (headp == NULL) 714 return (-1); 715 716 STAILQ_FOREACH(tmp, headp, link) 717 if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0) 718 return (tmp->enum_val); 719 720 return (-1); 721 } 722 723 static int32_t 724 snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s) 725 { 726 struct snmp_oid2str *temp; 727 728 if (headp == NULL) 729 return (-1); 730 731 SLIST_FOREACH(temp, headp, link) 732 if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0) 733 break; 734 735 if ((s->info = temp) == NULL) 736 return (-1); 737 738 return (1); 739 } 740 741 /* provided an asn_oid find the corresponding string for it */ 742 static int32_t 743 snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s) 744 { 745 struct snmp_oid2str *temp; 746 747 if (headp == NULL) 748 return (-1); 749 750 SLIST_FOREACH(temp,headp,link) { 751 if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) || 752 (asn_is_suboid(&(temp->var), &(s->val.var)))) { 753 s->info = temp; 754 return (1); 755 } 756 } 757 758 return (-1); 759 } 760 761 int32_t 762 snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) 763 { 764 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) 765 return (-1); 766 767 switch (s->val.syntax) { 768 case SNMP_SYNTAX_INTEGER: 769 return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s)); 770 case SNMP_SYNTAX_OCTETSTRING: 771 return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s)); 772 case SNMP_SYNTAX_OID: 773 return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s)); 774 case SNMP_SYNTAX_IPADDRESS: 775 return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s)); 776 case SNMP_SYNTAX_COUNTER: 777 return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s)); 778 case SNMP_SYNTAX_GAUGE: 779 return (snmp_lookup_leaf( 780 &snmptoolctx->snmp_gaugelist, s)); 781 case SNMP_SYNTAX_TIMETICKS: 782 return (snmp_lookup_leaf( 783 &snmptoolctx->snmp_ticklist, s)); 784 case SNMP_SYNTAX_COUNTER64: 785 return (snmp_lookup_leaf( 786 &snmptoolctx->snmp_cnt64list, s)); 787 case SNMP_SYNTAX_NOSUCHOBJECT: 788 /* FALLTHROUGH */ 789 case SNMP_SYNTAX_NOSUCHINSTANCE: 790 /* FALLTHROUGH */ 791 case SNMP_SYNTAX_ENDOFMIBVIEW: 792 return (snmp_lookup_allstring(snmptoolctx, s)); 793 default: 794 warnx("Unknown syntax - %d", s->val.syntax); 795 break; 796 } 797 798 return (-1); 799 } 800 801 int32_t 802 snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) 803 { 804 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) 805 return (-1); 806 807 return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s)); 808 } 809 810 int32_t 811 snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) 812 { 813 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) 814 return (-1); 815 816 return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s)); 817 } 818 819 int32_t 820 snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) 821 { 822 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) 823 return (-1); 824 825 return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s)); 826 } 827 828 int32_t 829 snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) 830 { 831 if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) 832 return (-1); 833 834 if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0) 835 return (1); 836 if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0) 837 return (1); 838 if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0) 839 return (1); 840 if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0) 841 return (1); 842 if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0) 843 return (1); 844 if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0) 845 return (1); 846 if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0) 847 return (1); 848 if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0) 849 return (1); 850 if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0) 851 return (1); 852 if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0) 853 return (1); 854 855 return (-1); 856 } 857 858 int32_t 859 snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx, 860 struct snmp_object *s) 861 { 862 if (snmptoolctx == NULL) 863 return (-1); 864 865 if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0) 866 return (1); 867 if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0) 868 return (1); 869 870 return (-1); 871 } 872 873 static int32_t 874 snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid) 875 { 876 struct snmp_oid2str *temp; 877 878 if (hp == NULL) 879 return (-1); 880 881 SLIST_FOREACH(temp, hp, link) { 882 if (temp->strlen != strlen(oid)) 883 continue; 884 885 if (strncmp(temp->string, oid, temp->strlen)) 886 continue; 887 888 s->val.syntax = temp->syntax; 889 s->info = temp; 890 asn_append_oid(&(s->val.var), &(temp->var)); 891 return (1); 892 } 893 894 return (-1); 895 } 896 897 static int32_t 898 snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx, 899 struct snmp_table_index *headp, struct snmp_object *s, char *oid) 900 { 901 struct snmp_index_entry *temp; 902 903 if (snmptoolctx == NULL || headp == NULL) 904 return (-1); 905 906 SLIST_FOREACH(temp, headp, link) { 907 if (temp->strlen != strlen(oid)) 908 continue; 909 910 if (strncmp(temp->string, oid, temp->strlen)) 911 continue; 912 913 /* 914 * Another hack here - if we were given a table name 915 * return the corresponding pointer to it's entry. 916 * That should not change the reponce we'll get. 917 */ 918 s->val.syntax = SNMP_SYNTAX_NULL; 919 asn_append_oid(&(s->val.var), &(temp->var)); 920 if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0) 921 return (1); 922 else 923 return (-1); 924 } 925 926 return (-1); 927 } 928 929 int32_t 930 snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, 931 char *oid) 932 { 933 if (snmptoolctx == NULL || s == NULL || oid == NULL) 934 return (-1); 935 936 if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0) 937 return (1); 938 if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0) 939 return (1); 940 if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0) 941 return (1); 942 if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0) 943 return (1); 944 if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0) 945 return (1); 946 if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0) 947 return (1); 948 if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0) 949 return (1); 950 if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0) 951 return (1); 952 if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0) 953 return (1); 954 if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist, 955 s, oid) > 0) 956 return (1); 957 958 return (-1); 959 } 960 961 int32_t 962 snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, 963 char *oid) 964 { 965 if (snmptoolctx == NULL || s == NULL) 966 return (-1); 967 968 return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid)); 969 } 970 971 int32_t 972 snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, 973 char *oid) 974 { 975 if (snmptoolctx == NULL || s == NULL) 976 return (-1); 977 978 switch (s->val.syntax) { 979 case SNMP_SYNTAX_INTEGER: 980 return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, 981 s, oid)); 982 case SNMP_SYNTAX_OCTETSTRING: 983 return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, 984 s, oid)); 985 case SNMP_SYNTAX_OID: 986 return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, 987 s, oid)); 988 case SNMP_SYNTAX_IPADDRESS: 989 return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, 990 s, oid)); 991 case SNMP_SYNTAX_COUNTER: 992 return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, 993 s, oid)); 994 case SNMP_SYNTAX_GAUGE: 995 return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, 996 s, oid)); 997 case SNMP_SYNTAX_TIMETICKS: 998 return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, 999 s, oid)); 1000 case SNMP_SYNTAX_COUNTER64: 1001 return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, 1002 s, oid)); 1003 case SNMP_SYNTAX_NULL: 1004 return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, 1005 s, oid)); 1006 default: 1007 warnx("Unknown syntax - %d", s->val.syntax); 1008 break; 1009 } 1010 1011 return (-1); 1012 } 1013