header_complex.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:17k
- /*
- * header complex: More complex storage and data sorting for mib modules
- */
- #include <net-snmp/net-snmp-config.h>
- #include <sys/types.h>
- #if HAVE_WINSOCK_H
- #include <winsock.h>
- #endif
- #if HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/agent/net-snmp-agent-includes.h>
- #include "header_complex.h"
- int
- header_complex_generate_varoid(netsnmp_variable_list * var)
- {
- int i;
- if (var->name == NULL) {
- /*
- * assume cached value is correct
- */
- switch (var->type) {
- case ASN_INTEGER:
- case ASN_COUNTER:
- case ASN_GAUGE:
- case ASN_TIMETICKS:
- var->name_length = 1;
- var->name = (oid *) malloc(sizeof(oid));
- if (var->name == NULL)
- return SNMPERR_GENERR;
- var->name[0] = *(var->val.integer);
- break;
- case ASN_PRIV_IMPLIED_OBJECT_ID:
- var->name_length = var->val_len / sizeof(oid);
- var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
- if (var->name == NULL)
- return SNMPERR_GENERR;
- for (i = 0; i < (int) var->name_length; i++)
- var->name[i] = var->val.objid[i];
- break;
- case ASN_OBJECT_ID:
- var->name_length = var->val_len / sizeof(oid) + 1;
- var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
- if (var->name == NULL)
- return SNMPERR_GENERR;
- var->name[0] = var->name_length - 1;
- for (i = 0; i < (int) var->name_length - 1; i++)
- var->name[i + 1] = var->val.objid[i];
- break;
- case ASN_PRIV_IMPLIED_OCTET_STR:
- var->name_length = var->val_len;
- var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
- if (var->name == NULL)
- return SNMPERR_GENERR;
- for (i = 0; i < (int) var->val_len; i++)
- var->name[i] = (oid) var->val.string[i];
- break;
- case ASN_OPAQUE:
- case ASN_OCTET_STR:
- var->name_length = var->val_len + 1;
- var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
- if (var->name == NULL)
- return SNMPERR_GENERR;
- var->name[0] = (oid) var->val_len;
- for (i = 0; i < (int) var->val_len; i++)
- var->name[i + 1] = (oid) var->val.string[i];
- break;
- default:
- DEBUGMSGTL(("header_complex_generate_varoid",
- "invalid asn type: %dn", var->type));
- return SNMPERR_GENERR;
- }
- }
- if (var->name_length > MAX_OID_LEN) {
- DEBUGMSGTL(("header_complex_generate_varoid",
- "Something terribly wrong, namelen = %dn",
- var->name_length));
- return SNMPERR_GENERR;
- }
- return SNMPERR_SUCCESS;
- }
- /*
- * header_complex_parse_oid(): parses an index to the usmTable to
- * break it down into a engineID component and a name component.
- * The results are stored in the data pointer, as a varbindlist:
- *
- *
- * returns 1 if an error is encountered, or 0 if successful.
- */
- int
- header_complex_parse_oid(oid * oidIndex, size_t oidLen,
- netsnmp_variable_list * data)
- {
- netsnmp_variable_list *var = data;
- int i, itmp;
- while (var && oidLen > 0) {
- switch (var->type) {
- case ASN_INTEGER:
- case ASN_COUNTER:
- case ASN_GAUGE:
- case ASN_TIMETICKS:
- var->val.integer = (long *) calloc(1, sizeof(long));
- if (var->val.string == NULL)
- return SNMPERR_GENERR;
- *var->val.integer = (long) *oidIndex++;
- var->val_len = sizeof(long);
- oidLen--;
- DEBUGMSGTL(("header_complex_parse_oid",
- "Parsed int(%d): %dn", var->type,
- *var->val.integer));
- break;
- case ASN_OBJECT_ID:
- case ASN_PRIV_IMPLIED_OBJECT_ID:
- if (var->type == ASN_PRIV_IMPLIED_OBJECT_ID) {
- itmp = oidLen;
- } else {
- itmp = (long) *oidIndex++;
- oidLen--;
- if (itmp > (int) oidLen)
- return SNMPERR_GENERR;
- }
- if (itmp == 0)
- break; /* zero length strings shouldn't malloc */
- var->val_len = itmp * sizeof(oid);
- var->val.objid = (oid *) calloc(1, var->val_len);
- if (var->val.objid == NULL)
- return SNMPERR_GENERR;
- for (i = 0; i < itmp; i++)
- var->val.objid[i] = (u_char) * oidIndex++;
- oidLen -= itmp;
- DEBUGMSGTL(("header_complex_parse_oid", "Parsed oid: "));
- DEBUGMSGOID(("header_complex_parse_oid", var->val.objid,
- var->val_len / sizeof(oid)));
- DEBUGMSG(("header_complex_parse_oid", "n"));
- break;
- case ASN_OPAQUE:
- case ASN_OCTET_STR:
- case ASN_PRIV_IMPLIED_OCTET_STR:
- if (var->type == ASN_PRIV_IMPLIED_OCTET_STR) {
- itmp = oidLen;
- } else {
- itmp = (long) *oidIndex++;
- oidLen--;
- if (itmp > (int) oidLen)
- return SNMPERR_GENERR;
- }
- if (itmp == 0)
- break; /* zero length strings shouldn't malloc */
- /*
- * malloc by size+1 to allow a null to be appended.
- */
- var->val_len = itmp;
- var->val.string = (u_char *) calloc(1, itmp + 1);
- if (var->val.string == NULL)
- return SNMPERR_GENERR;
- for (i = 0; i < itmp; i++)
- var->val.string[i] = (u_char) * oidIndex++;
- var->val.string[itmp] = ' ';
- oidLen -= itmp;
- DEBUGMSGTL(("header_complex_parse_oid",
- "Parsed str(%d): %sn", var->type,
- var->val.string));
- break;
- default:
- DEBUGMSGTL(("header_complex_parse_oid",
- "invalid asn type: %dn", var->type));
- return SNMPERR_GENERR;
- }
- var = var->next_variable;
- }
- if (var != NULL || oidLen > 0)
- return SNMPERR_GENERR;
- return SNMPERR_SUCCESS;
- }
- void
- header_complex_generate_oid(oid * name, /* out */
- size_t * length, /* out */
- oid * prefix,
- size_t prefix_len,
- netsnmp_variable_list * data)
- {
- oid *oidptr;
- netsnmp_variable_list *var;
- if (prefix) {
- memcpy(name, prefix, prefix_len * sizeof(oid));
- oidptr = (name + (prefix_len));
- *length = prefix_len;
- } else {
- oidptr = name;
- *length = 0;
- }
- for (var = data; var != NULL; var = var->next_variable) {
- header_complex_generate_varoid(var);
- memcpy(oidptr, var->name, sizeof(oid) * var->name_length);
- oidptr = oidptr + var->name_length;
- *length += var->name_length;
- }
- DEBUGMSGTL(("header_complex_generate_oid", "generated: "));
- DEBUGMSGOID(("header_complex_generate_oid", name, *length));
- DEBUGMSG(("header_complex_generate_oid", "n"));
- }
- /*
- * finds the data in "datalist" stored at "index"
- */
- void *
- header_complex_get(struct header_complex_index *datalist,
- netsnmp_variable_list * index)
- {
- oid searchfor[MAX_OID_LEN];
- size_t searchfor_len;
- header_complex_generate_oid(searchfor, /* out */
- &searchfor_len, /* out */
- NULL, 0, index);
- return header_complex_get_from_oid(datalist, searchfor, searchfor_len);
- }
- void *
- header_complex_get_from_oid(struct header_complex_index *datalist,
- oid * searchfor, size_t searchfor_len)
- {
- struct header_complex_index *nptr;
- for (nptr = datalist; nptr != NULL; nptr = nptr->next) {
- if (netsnmp_oid_equals(searchfor, searchfor_len,
- nptr->name, nptr->namelen) == 0)
- return nptr->data;
- }
- return NULL;
- }
- void *
- header_complex(struct header_complex_index *datalist,
- struct variable *vp,
- oid * name,
- size_t * length,
- int exact, size_t * var_len, WriteMethod ** write_method)
- {
- struct header_complex_index *nptr, *found = NULL;
- oid indexOid[MAX_OID_LEN];
- size_t len;
- int result;
- /*
- * set up some nice defaults for the user
- */
- if (write_method)
- *write_method = NULL;
- if (var_len)
- *var_len = sizeof(long);
- for (nptr = datalist; nptr != NULL && found == NULL; nptr = nptr->next) {
- if (vp) {
- memcpy(indexOid, vp->name, vp->namelen * sizeof(oid));
- memcpy(indexOid + vp->namelen, nptr->name,
- nptr->namelen * sizeof(oid));
- len = vp->namelen + nptr->namelen;
- } else {
- memcpy(indexOid, nptr->name, nptr->namelen * sizeof(oid));
- len = nptr->namelen;
- }
- result = snmp_oid_compare(name, *length, indexOid, len);
- DEBUGMSGTL(("header_complex", "Checking: "));
- DEBUGMSGOID(("header_complex", indexOid, len));
- DEBUGMSG(("header_complex", "n"));
- if (exact) {
- if (result == 0) {
- found = nptr;
- }
- } else {
- if (result == 0) {
- /*
- * found an exact match. Need the next one for !exact
- */
- if (nptr->next)
- found = nptr->next;
- } else if (result == -1) {
- found = nptr;
- }
- }
- }
- if (found) {
- if (vp) {
- memcpy(name, vp->name, vp->namelen * sizeof(oid));
- memcpy(name + vp->namelen, found->name,
- found->namelen * sizeof(oid));
- *length = vp->namelen + found->namelen;
- } else {
- memcpy(name, found->name, found->namelen * sizeof(oid));
- *length = found->namelen;
- }
- return found->data;
- }
- return NULL;
- }
- struct header_complex_index *
- header_complex_add_data(struct header_complex_index **thedata,
- netsnmp_variable_list * var, void *data)
- {
- oid newoid[MAX_OID_LEN];
- size_t newoid_len;
- struct header_complex_index *ret;
- if (thedata == NULL || var == NULL || data == NULL)
- return NULL;
- header_complex_generate_oid(newoid, &newoid_len, NULL, 0, var);
- ret =
- header_complex_add_data_by_oid(thedata, newoid, newoid_len, data);
- /*
- * free the variable list, but not the enclosed data! it's not ours!
- */
- snmp_free_varbind(var);
- return (ret);
- }
- struct header_complex_index *
- header_complex_add_data_by_oid(struct header_complex_index **thedata,
- oid * newoid, size_t newoid_len, void *data)
- {
- struct header_complex_index *hciptrn, *hciptrp, *ourself;
- if (thedata == NULL || newoid == NULL || data == NULL)
- return NULL;
- for (hciptrn = *thedata, hciptrp = NULL;
- hciptrn != NULL; hciptrp = hciptrn, hciptrn = hciptrn->next)
- /*
- * XXX: check for == and error (overlapping table entries)
- */
- if (snmp_oid_compare
- (hciptrn->name, hciptrn->namelen, newoid, newoid_len)
- > 0)
- break;
- /*
- * nptr should now point to the spot that we need to add ourselves
- * in front of, and pptr should be our new 'prev'.
- */
- /*
- * create ourselves
- */
- ourself = (struct header_complex_index *)
- SNMP_MALLOC_STRUCT(header_complex_index);
- /*
- * change our pointers
- */
- ourself->prev = hciptrp;
- ourself->next = hciptrn;
- if (ourself->next)
- ourself->next->prev = ourself;
- if (ourself->prev)
- ourself->prev->next = ourself;
- ourself->data = data;
- ourself->name = snmp_duplicate_objid(newoid, newoid_len);
- ourself->namelen = newoid_len;
- /*
- * rewind to the head of the list and return it (since the new head
- * could be us, we need to notify the above routine who the head now is.
- */
- for (hciptrp = ourself; hciptrp->prev != NULL;
- hciptrp = hciptrp->prev);
- *thedata = hciptrp;
- DEBUGMSGTL(("header_complex_add_data", "adding something...n"));
- return hciptrp;
- }
- /*
- * extracts an entry from the storage space (removing it from future
- * accesses) and returns the data stored there
- *
- * Modifies "thetop" pointer as needed (and if present) if were
- * extracting the first node.
- */
- void *
- header_complex_extract_entry(struct header_complex_index **thetop,
- struct header_complex_index *thespot)
- {
- struct header_complex_index *hciptrp, *hciptrn;
- void *retdata = thespot->data;
- if (thespot == NULL) {
- DEBUGMSGTL(("header_complex_extract_entry",
- "Null pointer asked to be extractedn"));
- return NULL;
- }
- hciptrp = thespot->prev;
- hciptrn = thespot->next;
- if (hciptrp)
- hciptrp->next = hciptrn;
- else if (thetop)
- *thetop = hciptrn;
- if (hciptrn)
- hciptrn->prev = hciptrp;
- if (thespot->name)
- free(thespot->name);
- free(thespot);
- return retdata;
- }
- /*
- * wipe out a single entry
- */
- void
- header_complex_free_entry(struct header_complex_index *theentry,
- HeaderComplexCleaner * cleaner)
- {
- void *data;
- data = header_complex_extract_entry(NULL, theentry);
- (*cleaner) (data);
- }
- /*
- * completely wipe out all entries in our data store
- */
- void
- header_complex_free_all(struct header_complex_index *thestuff,
- HeaderComplexCleaner * cleaner)
- {
- struct header_complex_index *hciptr, *hciptrn;
- for (hciptr = thestuff; hciptr != NULL; hciptr = hciptrn) {
- hciptrn = hciptr->next; /* need to extract this before deleting it */
- header_complex_free_entry(hciptr, cleaner);
- }
- }
- struct header_complex_index *
- header_complex_find_entry(struct header_complex_index *thestuff,
- void *theentry)
- {
- struct header_complex_index *hciptr;
- for (hciptr = thestuff; hciptr != NULL && hciptr->data != theentry;
- hciptr = hciptr->next);
- return hciptr;
- }
- #ifdef TESTING
- void
- header_complex_dump(struct header_complex_index *thestuff)
- {
- struct header_complex_index *hciptr;
- oid oidsave[MAX_OID_LEN];
- size_t len;
- for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
- DEBUGMSGTL(("header_complex_dump", "var: "));
- header_complex_generate_oid(oidsave, &len, NULL, 0, hciptr->);
- DEBUGMSGOID(("header_complex_dump", oidsave, len));
- DEBUGMSG(("header_complex_dump", "n"));
- }
- }
- main()
- {
- oid oidsave[MAX_OID_LEN];
- int len = MAX_OID_LEN, len2;
- netsnmp_variable_list *vars;
- long ltmp = 4242, ltmp2 = 88, ltmp3 = 1, ltmp4 = 4200;
- oid ourprefix[] = { 1, 2, 3, 4 };
- oid testparse[] = { 4, 116, 101, 115, 116, 4200 };
- int ret;
- char *string = "wes", *string2 = "dawn", *string3 = "test";
- struct header_complex_index *thestorage = NULL;
- debug_register_tokens("header_complex");
- snmp_set_do_debugging(1);
- vars = NULL;
- len2 = sizeof(ltmp);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp,
- len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- vars = NULL;
- len2 = strlen(string);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string, len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- vars = NULL;
- len2 = sizeof(ltmp2);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp2,
- len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- vars = NULL;
- len2 = strlen(string2);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string2,
- len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- vars = NULL;
- len2 = sizeof(ltmp3);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp3,
- len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- vars = NULL;
- len2 = strlen(string3);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, string3,
- len2);
- len2 = sizeof(ltmp4);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, (char *) <mp4,
- len2);
- header_complex_add_data(&thestorage, vars, ourprefix);
- header_complex_dump(thestorage);
- vars = NULL;
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_INTEGER, NULL, 0);
- ret =
- header_complex_parse_oid(testparse,
- sizeof(testparse) / sizeof(oid), vars);
- DEBUGMSGTL(("header_complex_test", "parse returned %d...n", ret));
- }
- #endif