Index: head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c =================================================================== --- head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c (revision 299700) +++ head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c (revision 299701) @@ -1,1018 +1,1017 @@ /*- * Copyright (c) 2006 The FreeBSD Project * All rights reserved. * * Author: Shteryana Shopova * * Redistribution of this software and documentation and use in source and * binary forms, with or without modification, are permitted provided that * the following conditions are met: * * 1. Redistributions of source code or documentation must retain the above * copyright notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bsnmptc.h" #include "bsnmptools.h" -extern int _bsnmptools_debug; #define DEBUG if (_bsnmptools_debug) fprintf /* Allocate memory and initialize list. */ struct snmp_mappings * snmp_mapping_init(void) { struct snmp_mappings *m; if ((m = malloc(sizeof(struct snmp_mappings))) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); return (NULL); } memset(m, 0, sizeof(struct snmp_mappings)); return (m); } #define snmp_nodelist mappings->nodelist #define snmp_intlist mappings->intlist #define snmp_octlist mappings->octlist #define snmp_oidlist mappings->oidlist #define snmp_iplist mappings->iplist #define snmp_ticklist mappings->ticklist #define snmp_cntlist mappings->cntlist #define snmp_gaugelist mappings->gaugelist #define snmp_cnt64list mappings->cnt64list #define snmp_enumlist mappings->enumlist #define snmp_tablelist mappings->tablelist #define snmp_tclist mappings->tclist void enum_pairs_free(struct enum_pairs *headp) { struct enum_pair *e; if (headp == NULL) return; while ((e = STAILQ_FIRST(headp)) != NULL) { STAILQ_REMOVE_HEAD(headp, link); if (e->enum_str) free(e->enum_str); free(e); } free(headp); } void snmp_mapping_entryfree(struct snmp_oid2str *entry) { if (entry->string) free(entry->string); if (entry->tc == SNMP_TC_OWN) enum_pairs_free(entry->snmp_enum); free(entry); } static void snmp_mapping_listfree(struct snmp_mapping *headp) { struct snmp_oid2str *p; while ((p = SLIST_FIRST(headp)) != NULL) { SLIST_REMOVE_HEAD(headp, link); if (p->string) free(p->string); if (p->tc == SNMP_TC_OWN) enum_pairs_free(p->snmp_enum); free(p); } SLIST_INIT(headp); } void snmp_index_listfree(struct snmp_idxlist *headp) { struct index *i; while ((i = STAILQ_FIRST(headp)) != NULL) { STAILQ_REMOVE_HEAD(headp, link); if (i->tc == SNMP_TC_OWN) enum_pairs_free(i->snmp_enum); free(i); } STAILQ_INIT(headp); } static void snmp_mapping_table_listfree(struct snmp_table_index *headp) { struct snmp_index_entry *t; while ((t = SLIST_FIRST(headp)) != NULL) { SLIST_REMOVE_HEAD(headp, link); if (t->string) free(t->string); snmp_index_listfree(&(t->index_list)); free(t); } } static void snmp_enumtc_listfree(struct snmp_enum_tc *headp) { struct enum_type *t; while ((t = SLIST_FIRST(headp)) != NULL) { SLIST_REMOVE_HEAD(headp, link); if (t->name) free(t->name); enum_pairs_free(t->snmp_enum); free(t); } } int snmp_mapping_free(struct snmp_toolinfo *snmptoolctx) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) return (-1); snmp_mapping_listfree(&snmptoolctx->snmp_nodelist); snmp_mapping_listfree(&snmptoolctx->snmp_intlist); snmp_mapping_listfree(&snmptoolctx->snmp_octlist); snmp_mapping_listfree(&snmptoolctx->snmp_oidlist); snmp_mapping_listfree(&snmptoolctx->snmp_iplist); snmp_mapping_listfree(&snmptoolctx->snmp_ticklist); snmp_mapping_listfree(&snmptoolctx->snmp_cntlist); snmp_mapping_listfree(&snmptoolctx->snmp_gaugelist); snmp_mapping_listfree(&snmptoolctx->snmp_cnt64list); snmp_mapping_listfree(&snmptoolctx->snmp_enumlist); snmp_mapping_table_listfree(&snmptoolctx->snmp_tablelist); snmp_enumtc_listfree(&snmptoolctx->snmp_tclist); free(snmptoolctx->mappings); return (0); } static void snmp_dump_enumpairs(struct enum_pairs *headp) { struct enum_pair *entry; if (headp == NULL) return; fprintf(stderr,"enums: "); STAILQ_FOREACH(entry, headp, link) fprintf(stderr,"%d - %s, ", entry->enum_val, (entry->enum_str == NULL)?"NULL":entry->enum_str); fprintf(stderr,"; "); } void snmp_dump_oid2str(struct snmp_oid2str *entry) { char buf[ASN_OIDSTRLEN]; if (entry != NULL) { memset(buf, 0, sizeof(buf)); asn_oid2str_r(&(entry->var), buf); DEBUG(stderr, "%s - %s - %d - %d - %d", buf, entry->string, entry->syntax, entry->access, entry->strlen); snmp_dump_enumpairs(entry->snmp_enum); DEBUG(stderr,"%s \n", (entry->table_idx == NULL)?"No table": entry->table_idx->string); } } static void snmp_dump_indexlist(struct snmp_idxlist *headp) { struct index *entry; if (headp == NULL) return; STAILQ_FOREACH(entry, headp, link) { fprintf(stderr,"%d, ", entry->syntax); snmp_dump_enumpairs(entry->snmp_enum); } fprintf(stderr,"\n"); } /* Initialize the enum pairs list of a oid2str entry. */ struct enum_pairs * enum_pairs_init(void) { struct enum_pairs *snmp_enum; if ((snmp_enum = malloc(sizeof(struct enum_pairs))) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); return (NULL); } STAILQ_INIT(snmp_enum); return (snmp_enum); } /* * Given a number and string, allocate memory for a (int, string) pair and add * it to the given oid2str mapping entry's enum pairs list. */ int32_t enum_pair_insert(struct enum_pairs *headp, int32_t enum_val, char *enum_str) { struct enum_pair *e_new; if ((e_new = malloc(sizeof(struct enum_pair))) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); return (-1); } memset(e_new, 0, sizeof(struct enum_pair)); if ((e_new->enum_str = malloc(strlen(enum_str) + 1)) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); free(e_new); return (-1); } e_new->enum_val = enum_val; strlcpy(e_new->enum_str, enum_str, strlen(enum_str) + 1); STAILQ_INSERT_TAIL(headp, e_new, link); return (1); } /* * Insert an entry in a list - entries are lexicographicaly order by asn_oid. * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already * exists. Error cheking is left to calling function. */ static int snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry) { int32_t rc; struct snmp_oid2str *temp, *prev; if (entry == NULL) return(-1); if ((prev = SLIST_FIRST(headp)) == NULL || asn_compare_oid(&(entry->var), &(prev->var)) < 0) { SLIST_INSERT_HEAD(headp, entry, link); return (1); } else rc = -1; /* Make the compiler happy. */ SLIST_FOREACH(temp, headp, link) { if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0) break; prev = temp; rc = -1; } switch (rc) { case 0: /* Ops, matching OIDs - hope the rest info also matches. */ if (strncmp(temp->string, entry->string, entry->strlen)) { syslog(LOG_INFO, "Matching OIDs with different string " "mappings: old - %s, new - %s", temp->string, entry->string); return (-1); } /* * Ok, we have that already. * As long as the strings match - don't complain. */ return (0); case 1: SLIST_INSERT_AFTER(temp, entry, link); break; case -1: SLIST_INSERT_AFTER(prev, entry, link); break; default: /* NOTREACHED */ return (-1); } return (1); } int32_t snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry)); return (-1); } static int32_t snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry)); return (-1); } static int32_t snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry)); return (-1); } static int32_t snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry)); return (-1); } static int32_t snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry)); return (-1); } static int32_t snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry)); return (-1); } static int32_t snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry)); return (-1); } static int32_t snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry)); return (-1); } static int32_t snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry)); return (-1); } int32_t snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { if (snmptoolctx != NULL && snmptoolctx->mappings) return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry)); return (-1); } int32_t snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry) { switch (entry->syntax) { case SNMP_SYNTAX_INTEGER: return (snmp_int_insert(snmptoolctx, entry)); case SNMP_SYNTAX_OCTETSTRING: return (snmp_oct_insert(snmptoolctx, entry)); case SNMP_SYNTAX_OID: return (snmp_oid_insert(snmptoolctx, entry)); case SNMP_SYNTAX_IPADDRESS: return (snmp_ip_insert(snmptoolctx, entry)); case SNMP_SYNTAX_COUNTER: return (snmp_cnt_insert(snmptoolctx, entry)); case SNMP_SYNTAX_GAUGE: return (snmp_gauge_insert(snmptoolctx, entry)); case SNMP_SYNTAX_TIMETICKS: return (snmp_tick_insert(snmptoolctx, entry)); case SNMP_SYNTAX_COUNTER64: return (snmp_cnt64_insert(snmptoolctx, entry)); default: break; } return (-1); } static int32_t snmp_index_insert(struct snmp_idxlist *headp, struct index *idx) { if (headp == NULL || idx == NULL) return (-1); STAILQ_INSERT_TAIL(headp, idx, link); return (1); } int32_t snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums, enum snmp_syntax syntax, enum snmp_tc tc) { struct index *idx; if ((idx = malloc(sizeof(struct index))) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); return (-1); } memset(idx, 0, sizeof(struct index)); if (snmp_index_insert(headp, idx) < 0) { free(idx); return (-1); } idx->syntax = syntax; idx->snmp_enum = enums; idx->tc = tc; return (1); } int32_t snmp_table_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_index_entry *entry) { int32_t rc; struct snmp_index_entry *temp, *prev; if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || entry == NULL) return(-1); if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL || asn_compare_oid(&(entry->var), &(prev->var)) < 0) { SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link); return (1); } else rc = -1; /* Make the compiler happy. */ SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) { if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0) break; prev = temp; rc = -1; } switch (rc) { case 0: /* Ops, matching OIDs - hope the rest info also matches. */ if (strncmp(temp->string, entry->string, entry->strlen)) { syslog(LOG_INFO, "Matching OIDs with different string " "mapping - old - %s, new - %s", temp->string, entry->string); return (-1); } return(0); case 1: SLIST_INSERT_AFTER(temp, entry, link); break; case -1: SLIST_INSERT_AFTER(prev, entry, link); break; default: /* NOTREACHED */ return (-1); } return (1); } struct enum_type * snmp_enumtc_init(char *name) { struct enum_type *enum_tc; if ((enum_tc = malloc(sizeof(struct enum_type))) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); return (NULL); } memset(enum_tc, 0, sizeof(struct enum_type)); if ((enum_tc->name = malloc(strlen(name) + 1)) == NULL) { syslog(LOG_ERR, "malloc() failed: %s", strerror(errno)); free(enum_tc); return (NULL); } strlcpy(enum_tc->name, name, strlen(name) + 1); return (enum_tc); } void snmp_enumtc_free(struct enum_type *tc) { if (tc->name) free(tc->name); if (tc->snmp_enum) enum_pairs_free(tc->snmp_enum); free(tc); } void snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) return; /* XXX no error handling? */ SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link); } struct enum_type * snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name) { struct enum_type *temp; if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) return (NULL); SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) { if (strcmp(temp->name, name) == 0) return (temp); } return (NULL); } static void snmp_mapping_dumplist(struct snmp_mapping *headp) { char buf[ASN_OIDSTRLEN]; struct snmp_oid2str *entry; if (headp == NULL) return; SLIST_FOREACH(entry,headp,link) { memset(buf, 0, sizeof(buf)); asn_oid2str_r(&(entry->var), buf); fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string, entry->syntax, entry->access ,entry->strlen); fprintf(stderr," - %s \n", (entry->table_idx == NULL)? "No table":entry->table_idx->string); } } static void snmp_mapping_dumptable(struct snmp_table_index *headp) { char buf[ASN_OIDSTRLEN]; struct snmp_index_entry *entry; if (headp == NULL) return; SLIST_FOREACH(entry, headp, link) { memset(buf, 0, sizeof(buf)); asn_oid2str_r(&(entry->var), buf); fprintf(stderr,"%s - %s - %d - ", buf, entry->string, entry->strlen); snmp_dump_indexlist(&(entry->index_list)); } } void snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */) { if (!_bsnmptools_debug) return; if (snmptoolctx == NULL) { fprintf(stderr,"No snmptool context!\n"); return; } if (snmptoolctx->mappings == NULL) { fprintf(stderr,"No mappings!\n"); return; } fprintf(stderr,"snmp_nodelist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist); fprintf(stderr,"snmp_intlist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_intlist); fprintf(stderr,"snmp_octlist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_octlist); fprintf(stderr,"snmp_oidlist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist); fprintf(stderr,"snmp_iplist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_iplist); fprintf(stderr,"snmp_ticklist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist); fprintf(stderr,"snmp_cntlist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist); fprintf(stderr,"snmp_gaugelist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist); fprintf(stderr,"snmp_cnt64list:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list); fprintf(stderr,"snmp_enumlist:\n"); snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist); fprintf(stderr,"snmp_tablelist:\n"); snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist); } char * enum_string_lookup(struct enum_pairs *headp, int32_t enum_val) { struct enum_pair *temp; if (headp == NULL) return (NULL); STAILQ_FOREACH(temp, headp, link) { if (temp->enum_val == enum_val) return (temp->enum_str); } return (NULL); } int32_t enum_number_lookup(struct enum_pairs *headp, char *e_str) { struct enum_pair *tmp; if (headp == NULL) return (-1); STAILQ_FOREACH(tmp, headp, link) if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0) return (tmp->enum_val); return (-1); } static int32_t snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s) { struct snmp_oid2str *temp; if (headp == NULL) return (-1); SLIST_FOREACH(temp, headp, link) if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0) break; if ((s->info = temp) == NULL) return (-1); return (1); } /* provided an asn_oid find the corresponding string for it */ static int32_t snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s) { struct snmp_oid2str *temp; if (headp == NULL) return (-1); SLIST_FOREACH(temp,headp,link) { if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) || (asn_is_suboid(&(temp->var), &(s->val.var)))) { s->info = temp; return (1); } } return (-1); } int32_t snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) return (-1); switch (s->val.syntax) { case SNMP_SYNTAX_INTEGER: return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s)); case SNMP_SYNTAX_OCTETSTRING: return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s)); case SNMP_SYNTAX_OID: return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s)); case SNMP_SYNTAX_IPADDRESS: return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s)); case SNMP_SYNTAX_COUNTER: return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s)); case SNMP_SYNTAX_GAUGE: return (snmp_lookup_leaf( &snmptoolctx->snmp_gaugelist, s)); case SNMP_SYNTAX_TIMETICKS: return (snmp_lookup_leaf( &snmptoolctx->snmp_ticklist, s)); case SNMP_SYNTAX_COUNTER64: return (snmp_lookup_leaf( &snmptoolctx->snmp_cnt64list, s)); case SNMP_SYNTAX_NOSUCHOBJECT: /* FALLTHROUGH */ case SNMP_SYNTAX_NOSUCHINSTANCE: /* FALLTHROUGH */ case SNMP_SYNTAX_ENDOFMIBVIEW: return (snmp_lookup_allstring(snmptoolctx, s)); default: warnx("Unknown syntax - %d", s->val.syntax); break; } return (-1); } int32_t snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) return (-1); return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s)); } int32_t snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) return (-1); return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s)); } int32_t snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL) return (-1); return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s)); } int32_t snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL || snmptoolctx->mappings == NULL) return (-1); if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0) return (1); if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0) return (1); if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0) return (1); if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0) return (1); return (-1); } int32_t snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s) { if (snmptoolctx == NULL) return (-1); if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0) return (1); if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0) return (1); return (-1); } static int32_t snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid) { struct snmp_oid2str *temp; if (hp == NULL) return (-1); SLIST_FOREACH(temp, hp, link) { if (temp->strlen != strlen(oid)) continue; if (strncmp(temp->string, oid, temp->strlen)) continue; s->val.syntax = temp->syntax; s->info = temp; asn_append_oid(&(s->val.var), &(temp->var)); return (1); } return (-1); } static int32_t snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx, struct snmp_table_index *headp, struct snmp_object *s, char *oid) { struct snmp_index_entry *temp; if (snmptoolctx == NULL || headp == NULL) return (-1); SLIST_FOREACH(temp, headp, link) { if (temp->strlen != strlen(oid)) continue; if (strncmp(temp->string, oid, temp->strlen)) continue; /* * Another hack here - if we were given a table name * return the corresponding pointer to it's entry. * That should not change the reponce we'll get. */ s->val.syntax = SNMP_SYNTAX_NULL; asn_append_oid(&(s->val.var), &(temp->var)); if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0) return (1); else return (-1); } return (-1); } int32_t snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, char *oid) { if (snmptoolctx == NULL || s == NULL || oid == NULL) return (-1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0) return (1); if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0) return (1); if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist, s, oid) > 0) return (1); return (-1); } int32_t snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, char *oid) { if (snmptoolctx == NULL || s == NULL) return (-1); return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid)); } int32_t snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s, char *oid) { if (snmptoolctx == NULL || s == NULL) return (-1); switch (s->val.syntax) { case SNMP_SYNTAX_INTEGER: return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid)); case SNMP_SYNTAX_OCTETSTRING: return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid)); case SNMP_SYNTAX_OID: return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid)); case SNMP_SYNTAX_IPADDRESS: return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid)); case SNMP_SYNTAX_COUNTER: return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid)); case SNMP_SYNTAX_GAUGE: return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid)); case SNMP_SYNTAX_TIMETICKS: return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid)); case SNMP_SYNTAX_COUNTER64: return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid)); case SNMP_SYNTAX_NULL: return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid)); default: warnx("Unknown syntax - %d", s->val.syntax); break; } return (-1); } Index: head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h =================================================================== --- head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h (revision 299700) +++ head/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h (revision 299701) @@ -1,333 +1,333 @@ /*- * Copyright (c) 2005-2006 The FreeBSD Project * All rights reserved. * * Author: Shteryana Shopova * * Redistribution of this software and documentation and use in source and * binary forms, with or without modification, are permitted provided that * the following conditions are met: * * 1. Redistributions of source code or documentation must retain the above * copyright notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Helper functions common for all tools. * * $FreeBSD$ */ #ifndef _BSNMP_TOOLS_H_ #define _BSNMP_TOOLS_H_ /* From asn1.h + 1 byte for trailing zero. */ #define MAX_OCTSTRING_LEN ASN_MAXOCTETSTRING + 1 #define MAX_CMD_SYNTAX_LEN 12 /* Arbitrary upper limit on node names and function names - gensnmptree.c. */ #define MAXSTR 1000 /* Should be enough to fetch the biggest allowed octet string. */ #define MAX_BUFF_SIZE (ASN_MAXOCTETSTRING + 50) #define SNMP_DEFS_DIR "/usr/share/snmp/defs/" #define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock" #define SNMP_MAX_REPETITIONS 10 enum snmp_access { SNMP_ACCESS_NONE = 0, SNMP_ACCESS_GET, SNMP_ACCESS_SET, SNMP_ACCESS_GETSET, }; /* A structure for integer-string enumerations. */ struct enum_pair { int32_t enum_val; char *enum_str; STAILQ_ENTRY(enum_pair) link; }; STAILQ_HEAD(enum_pairs, enum_pair); struct enum_type { char *name; uint32_t syntax; int32_t is_enum; int32_t is_bits; struct enum_pairs *snmp_enum; SLIST_ENTRY(enum_type) link; }; SLIST_HEAD(snmp_enum_tc, enum_type); struct index { enum snmp_tc tc; enum snmp_syntax syntax; struct enum_pairs *snmp_enum; STAILQ_ENTRY(index) link; }; STAILQ_HEAD(snmp_idxlist, index); struct snmp_index_entry { char *string; uint32_t strlen; struct asn_oid var; struct snmp_idxlist index_list; SLIST_ENTRY(snmp_index_entry) link; }; /* Information needed for oid to string conversion. */ struct snmp_oid2str { char *string; uint32_t strlen; enum snmp_tc tc; enum snmp_syntax syntax; enum snmp_access access; struct asn_oid var; /* A pointer to a entry from the table list - OK if NULL. */ struct snmp_index_entry *table_idx; /* * A singly-linked tail queue of all (int, string) pairs - * for INTEGER syntax only. */ struct enum_pairs *snmp_enum; SLIST_ENTRY(snmp_oid2str) link; }; /* A structure to hold each oid input by user. */ struct snmp_object { /* Flag - if set, the variable caused error in a previous request. */ int32_t error; /* * A pointer in the mapping lists - not used if OIDs are input as * numericals. */ struct snmp_oid2str *info; /* A snmp value to hold the actual oid, syntax and value. */ struct snmp_value val; SLIST_ENTRY(snmp_object) link; }; struct fname { char *name; int32_t done; struct asn_oid cut; SLIST_ENTRY(fname) link; }; SLIST_HEAD(snmp_mapping, snmp_oid2str); SLIST_HEAD(fname_list, fname); SLIST_HEAD(snmp_table_index, snmp_index_entry); /* * Keep a list for every syntax type. */ struct snmp_mappings { /* The list containing all non-leaf nodes. */ struct snmp_mapping nodelist; /* INTEGER/INTEGER32 types. */ struct snmp_mapping intlist; /* OCTETSTRING types. */ struct snmp_mapping octlist; /* OID types. */ struct snmp_mapping oidlist; /* IPADDRESS types. */ struct snmp_mapping iplist; /* TIMETICKS types. */ struct snmp_mapping ticklist; /* COUNTER types. */ struct snmp_mapping cntlist; /* GAUGE types. */ struct snmp_mapping gaugelist; /* COUNTER64 types. */ struct snmp_mapping cnt64list; /* ENUM values for oid types. */ struct snmp_mapping enumlist; /* Description of all table entry types. */ struct snmp_table_index tablelist; /* Defined enumerated textual conventions. */ struct snmp_enum_tc tclist; }; struct snmp_toolinfo { uint32_t flags; /* Number of initially input OIDs. */ int32_t objects; /* List of all input OIDs. */ SLIST_HEAD(snmp_objectlist, snmp_object) snmp_objectlist; /* All known OID to string mapping data. */ struct snmp_mappings *mappings; /* A list of .defs filenames to search oid<->string mapping. */ struct fname_list filelist; /* SNMPv3 USM user credentials */ char *passwd; }; /* XXX we might want to get away with this and will need to touch * XXX the MACROS then too */ extern struct snmp_toolinfo snmptool; /* Definitions for some flags' bits. */ #define OUTPUT_BITS 0x00000003 /* bits 0-1 for output type */ #define NUMERIC_BIT 0x00000004 /* bit 2 for numeric oids */ #define RETRY_BIT 0x00000008 /* bit 3 for retry on error response */ #define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */ #define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */ #define EDISCOVER_BIT 0x00000020 /* bit 5 for SNMP Engine Discovery */ #define LOCALKEY_BIT 0x00000040 /* bit 6 for using localized key */ /* 0x00000080 */ /* bit 7 reserved */ #define PDUTYPE_BITS 0x00000f00 /* bits 8-11 for pdu type */ /* 0x0000f000 */ /* bit 12-15 reserved */ #define MAXREP_BITS 0x00ff0000 /* bits 16-23 for max-repetit. value */ #define NONREP_BITS 0xff000000 /* bits 24-31 for non-repeaters value */ #define OUTPUT_SHORT 0x0 #define OUTPUT_VERBOSE 0x1 #define OUTPUT_TABULAR 0x2 #define OUTPUT_QUIET 0x3 /* Macros for playing with flags' bits. */ #define SET_OUTPUT(ctx, type) ((ctx)->flags |= ((type) & OUTPUT_BITS)) #define GET_OUTPUT(ctx) ((ctx)->flags & OUTPUT_BITS) #define SET_NUMERIC(ctx) ((ctx)->flags |= NUMERIC_BIT) #define ISSET_NUMERIC(ctx) ((ctx)->flags & NUMERIC_BIT) #define SET_RETRY(ctx) ((ctx)->flags |= RETRY_BIT) #define ISSET_RETRY(ctx) ((ctx)->flags & RETRY_BIT) #define SET_ERRIGNORE(ctx) ((ctx)->flags |= ERRIGNORE_BIT) #define ISSET_ERRIGNORE(ctx) ((ctx)->flags & ERRIGNORE_BIT) #define SET_EDISCOVER(ctx) ((ctx)->flags |= EDISCOVER_BIT) #define ISSET_EDISCOVER(ctx) ((ctx)->flags & EDISCOVER_BIT) #define SET_LOCALKEY(ctx) ((ctx)->flags |= LOCALKEY_BIT) #define ISSET_LOCALKEY(ctx) ((ctx)->flags & LOCALKEY_BIT) #define SET_PDUTYPE(ctx, type) (((ctx)->flags |= (((type) & 0xf) << 8))) #define GET_PDUTYPE(ctx) (((ctx)->flags & PDUTYPE_BITS) >> 8) #define SET_MAXREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 16))) #define GET_MAXREP(ctx) (((ctx)->flags & MAXREP_BITS) >> 16) #define SET_NONREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 24))) #define GET_NONREP(ctx) (((ctx)->flags & NONREP_BITS) >> 24) - +extern int _bsnmptools_debug; extern const struct asn_oid IsoOrgDod_OID; int snmptool_init(struct snmp_toolinfo *); int32_t snmp_import_file(struct snmp_toolinfo *, struct fname *); int32_t snmp_import_all(struct snmp_toolinfo *); int32_t add_filename(struct snmp_toolinfo *, const char *, const struct asn_oid *, int32_t); void free_filelist(struct snmp_toolinfo *); void snmp_tool_freeall(struct snmp_toolinfo *); void snmp_import_dump(int); /* bsnmpmap.c */ struct snmp_mappings *snmp_mapping_init(void); int32_t snmp_mapping_free(struct snmp_toolinfo *); void snmp_index_listfree(struct snmp_idxlist *); void snmp_dump_oid2str(struct snmp_oid2str *); int32_t snmp_node_insert(struct snmp_toolinfo *, struct snmp_oid2str *); int32_t snmp_leaf_insert(struct snmp_toolinfo *, struct snmp_oid2str *); int32_t snmp_enum_insert(struct snmp_toolinfo *, struct snmp_oid2str *); struct enum_pairs *enum_pairs_init(void); void enum_pairs_free(struct enum_pairs *); void snmp_mapping_entryfree(struct snmp_oid2str *); int32_t enum_pair_insert(struct enum_pairs *, int32_t, char *); char *enum_string_lookup(struct enum_pairs *, int32_t); int32_t enum_number_lookup(struct enum_pairs *, char *); int32_t snmp_syntax_insert(struct snmp_idxlist *, struct enum_pairs *, enum snmp_syntax, enum snmp_tc); int32_t snmp_table_insert(struct snmp_toolinfo *, struct snmp_index_entry *); struct enum_type *snmp_enumtc_init(char *); void snmp_enumtc_free(struct enum_type *); void snmp_enumtc_insert(struct snmp_toolinfo *, struct enum_type *); struct enum_type *snmp_enumtc_lookup(struct snmp_toolinfo *, char *); void snmp_mapping_dump(struct snmp_toolinfo *); int32_t snmp_lookup_leafstring(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_enumstring(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_oidstring(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_nonleaf_string(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_allstring(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_nodestring(struct snmp_toolinfo *, struct snmp_object *); int32_t snmp_lookup_oidall(struct snmp_toolinfo *, struct snmp_object *, char *); int32_t snmp_lookup_enumoid(struct snmp_toolinfo *, struct snmp_object *, char *); int32_t snmp_lookup_oid(struct snmp_toolinfo *, struct snmp_object *, char *); /* Functions parsing common options for all tools. */ int32_t parse_server(char *); int32_t parse_timeout(char *); int32_t parse_retry(char *); int32_t parse_version(char *); int32_t parse_local_path(char *); int32_t parse_buflen(char *); int32_t parse_debug(void); int32_t parse_discovery(struct snmp_toolinfo *); int32_t parse_local_key(struct snmp_toolinfo *); int32_t parse_num_oids(struct snmp_toolinfo *); int32_t parse_file(struct snmp_toolinfo *, char *); int32_t parse_include(struct snmp_toolinfo *, char *); int32_t parse_output(struct snmp_toolinfo *, char *); int32_t parse_errors(struct snmp_toolinfo *); int32_t parse_skip_access(struct snmp_toolinfo *); int32_t parse_authentication(struct snmp_toolinfo *, char *); int32_t parse_privacy(struct snmp_toolinfo *, char *); int32_t parse_context(struct snmp_toolinfo *, char *); int32_t parse_user_security(struct snmp_toolinfo *, char *); typedef int32_t (*snmp_verify_inoid_f) (struct snmp_toolinfo *, struct snmp_object *, char *); int32_t snmp_object_add(struct snmp_toolinfo *, snmp_verify_inoid_f, char *); int32_t snmp_object_remove(struct snmp_toolinfo *, struct asn_oid *oid); int32_t snmp_object_seterror(struct snmp_toolinfo *, struct snmp_value *, int32_t); enum snmp_syntax parse_syntax(char *); char *snmp_parse_suboid(char *, struct asn_oid *); char *snmp_parse_index(struct snmp_toolinfo *, char *, struct snmp_object *); int32_t snmp_parse_numoid(char *, struct asn_oid *); int32_t snmp_suboid_append(struct asn_oid *, asn_subid_t); int32_t snmp_suboid_pop(struct asn_oid *); typedef int32_t (*snmp_verify_vbind_f) (struct snmp_toolinfo *, struct snmp_pdu *, struct snmp_object *); typedef int32_t (*snmp_add_vbind_f) (struct snmp_pdu *, struct snmp_object *); int32_t snmp_pdu_add_bindings(struct snmp_toolinfo *, snmp_verify_vbind_f, snmp_add_vbind_f, struct snmp_pdu *, int32_t); int32_t snmp_parse_get_resp(struct snmp_pdu *, struct snmp_pdu *); int32_t snmp_parse_getbulk_resp(struct snmp_pdu *, struct snmp_pdu *); int32_t snmp_parse_getnext_resp(struct snmp_pdu *, struct snmp_pdu *); int32_t snmp_parse_resp(struct snmp_pdu *, struct snmp_pdu *); int32_t snmp_output_numval(struct snmp_toolinfo *, struct snmp_value *, struct snmp_oid2str *); void snmp_output_val(struct snmp_value *); int32_t snmp_output_resp(struct snmp_toolinfo *, struct snmp_pdu *, struct asn_oid *); void snmp_output_err_resp(struct snmp_toolinfo *, struct snmp_pdu *); void snmp_output_engine(void); void snmp_output_keys(void); #endif /* _BSNMP_TOOLS_H_ */