| /* |
| * snmpTargetAddrEntry MIB |
| * |
| * This file was generated by mib2c and is intended for use as a mib module |
| * for the ucd-snmp snmpd agent. Edited by Michael Baer |
| * |
| * last changed 2/2/99. |
| */ |
| |
| #include <net-snmp/net-snmp-config.h> |
| #if HAVE_STRING_H |
| #include <string.h> |
| #else |
| #include <strings.h> |
| #endif |
| #include <stdlib.h> |
| #include <ctype.h> |
| |
| #include <net-snmp/net-snmp-includes.h> |
| #include <net-snmp/agent/net-snmp-agent-includes.h> |
| |
| #include "snmpTargetAddrEntry.h" |
| #include "util_funcs/header_generic.h" |
| |
| #define snmpTargetAddrOIDLen 11 /*This is base+column, |
| * i.e. everything but index */ |
| |
| static oid snmpTargetAddrOID[snmpTargetAddrOIDLen] = |
| { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1, 0 }; |
| |
| static unsigned long snmpTargetSpinLock = 0; |
| static struct targetAddrTable_struct *aAddrTable = NULL; |
| |
| |
| static int |
| store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg, |
| void *clientarg); |
| |
| /* |
| * Utility routines |
| */ |
| struct targetAddrTable_struct * |
| get_addrTable(void) |
| { |
| return aAddrTable; |
| } |
| |
| struct targetAddrTable_struct * |
| get_addrForName2(const char *name, unsigned char nameLen) |
| { |
| struct targetAddrTable_struct *ptr; |
| for (ptr = aAddrTable; ptr != NULL; ptr = ptr->next) { |
| if (ptr->nameLen == nameLen && |
| memcmp(ptr->nameData, name, nameLen) == 0) |
| return ptr; |
| } |
| return NULL; |
| } |
| |
| |
| /* |
| * TargetAddrTable_create creates and returns a pointer |
| * to a targetAddrTable_struct with default values set |
| */ |
| struct targetAddrTable_struct *snmpTargetAddrTable_create(void) |
| { |
| struct targetAddrTable_struct *newEntry; |
| |
| newEntry = malloc(sizeof(*newEntry)); |
| |
| if (newEntry) { |
| newEntry->nameData = NULL; |
| newEntry->nameLen = 0; |
| |
| newEntry->tDomainLen = 0; |
| newEntry->tAddress = NULL; |
| |
| newEntry->timeout = 1500; |
| newEntry->retryCount = 3; |
| |
| newEntry->tagList = strdup(""); |
| newEntry->params = NULL; |
| |
| newEntry->storageType = SNMP_STORAGE_NONVOLATILE; |
| newEntry->rowStatus = SNMP_ROW_NONEXISTENT; |
| newEntry->sess = NULL; |
| newEntry->next = NULL; |
| } |
| |
| return newEntry; |
| } /* snmpTargetAddrTable_create */ |
| |
| |
| /* |
| * TargetAddrTable_dispose frees the space allocated to a |
| * targetAddrTable_struct |
| */ |
| void |
| snmpTargetAddrTable_dispose(struct targetAddrTable_struct *reaped) |
| { |
| if (reaped->sess) |
| snmp_close(reaped->sess); |
| else |
| SNMP_FREE(reaped->tAddress); |
| SNMP_FREE(reaped->nameData); |
| SNMP_FREE(reaped->tagList); |
| SNMP_FREE(reaped->params); |
| |
| SNMP_FREE(reaped); |
| } /* snmpTargetAddrTable_dispose */ |
| |
| /* |
| * snmpTargetAddrTable_addToList adds a targetAddrTable_struct |
| * to a list passed in. The list is assumed to be in a sorted order, |
| * low to high and this procedure inserts a new struct in the proper |
| * location. Sorting uses OID values based on name. A new equal value |
| * overwrites a current one. |
| */ |
| void |
| snmpTargetAddrTable_addToList(struct targetAddrTable_struct *newEntry, |
| struct targetAddrTable_struct **listPtr) |
| { |
| static struct targetAddrTable_struct *curr_struct, *prev_struct; |
| int i; |
| |
| /* |
| * if the list is empty, add the new entry to the top |
| */ |
| if ((prev_struct = curr_struct = *listPtr) == NULL) { |
| *listPtr = newEntry; |
| return; |
| } else { |
| /* |
| * search through the list for an equal or greater OID value |
| */ |
| while (curr_struct != NULL) { |
| i = memcmp(newEntry->nameData, curr_struct->nameData, |
| newEntry->nameLen < curr_struct->nameLen ? |
| newEntry->nameLen : curr_struct->nameLen); |
| if (i == 0) { |
| if (newEntry->nameLen < curr_struct->nameLen) |
| i = -1; |
| else if (newEntry->nameLen > curr_struct->nameLen) |
| i = 1; |
| } |
| |
| if (i == 0) { /* Exact match, overwrite with new struct */ |
| newEntry->next = curr_struct->next; |
| /* |
| * if curr_struct is the top of the list |
| */ |
| if (*listPtr == curr_struct) |
| *listPtr = newEntry; |
| else |
| prev_struct->next = newEntry; |
| snmpTargetAddrTable_dispose(curr_struct); |
| return; |
| } else if (i < 0) { /* Found a greater OID, insert struct in front of it. */ |
| newEntry->next = curr_struct; |
| /* |
| * if curr_struct is the top of the list |
| */ |
| if (*listPtr == curr_struct) |
| *listPtr = newEntry; |
| else |
| prev_struct->next = newEntry; |
| return; |
| } |
| prev_struct = curr_struct; |
| curr_struct = curr_struct->next; |
| } |
| } |
| /* |
| * if we're here, no larger OID was ever found, insert on end of list |
| */ |
| prev_struct->next = newEntry; |
| } /* snmpTargeAddrTable_addToList */ |
| |
| |
| void |
| snmpTargetAddrTable_add(struct targetAddrTable_struct *newEntry) |
| { |
| snmpTargetAddrTable_addToList(newEntry, &aAddrTable); |
| } |
| |
| |
| /* |
| * snmpTargetAddrTable_remFromList removes a targetAddrTable_struct |
| * from the list passed in |
| */ |
| void |
| snmpTargetAddrTable_remFromList(struct targetAddrTable_struct *oldEntry, |
| struct targetAddrTable_struct **listPtr) |
| { |
| struct targetAddrTable_struct *tptr; |
| |
| if ((tptr = *listPtr) == NULL) |
| return; |
| else if (tptr == oldEntry) { |
| *listPtr = (*listPtr)->next; |
| snmpTargetAddrTable_dispose(tptr); |
| return; |
| } else { |
| while (tptr->next != NULL) { |
| if (tptr->next == oldEntry) { |
| tptr->next = tptr->next->next; |
| snmpTargetAddrTable_dispose(oldEntry); |
| return; |
| } |
| tptr = tptr->next; |
| } |
| } |
| } /* snmpTargetAddrTable_remFromList */ |
| |
| |
| /* |
| * lookup OID in the link list of Addr Table Entries |
| */ |
| struct targetAddrTable_struct * |
| search_snmpTargetAddrTable(oid * baseName, |
| size_t baseNameLen, |
| oid * name, size_t * length, int exact) |
| { |
| static struct targetAddrTable_struct *temp_struct; |
| int i; |
| size_t myOIDLen = 0; |
| oid newNum[128]; |
| |
| /* |
| * lookup entry in addrTable linked list, Get Current MIB ID |
| */ |
| memcpy(newNum, baseName, baseNameLen * sizeof(oid)); |
| |
| for (temp_struct = aAddrTable; temp_struct != NULL; |
| temp_struct = temp_struct->next) { |
| for (i = 0; i < temp_struct->nameLen; i++) { |
| newNum[baseNameLen + i] = (unsigned char)temp_struct->nameData[i]; |
| } |
| myOIDLen = baseNameLen + temp_struct->nameLen; |
| i = snmp_oid_compare(name, *length, newNum, myOIDLen); |
| /* |
| * Assumes that the linked list sorted by OID, low to high |
| */ |
| if ((i == 0 && exact != 0) || (i < 0 && exact == 0)) { |
| if (exact == 0) { |
| memcpy(name, newNum, myOIDLen * sizeof(oid)); |
| *length = myOIDLen; |
| } |
| return temp_struct; |
| } |
| } |
| return NULL; |
| } /* search_snmpTargetAddrTable */ |
| |
| |
| /* |
| * snmpTargetAddr_rowStatusCheck is boolean function that checks |
| * the status of a row's values in order to determine whether |
| * the row should be notReady or notInService. |
| */ |
| static int |
| snmpTargetAddr_rowStatusCheck(const struct targetAddrTable_struct *entry) |
| { |
| return entry->tDomainLen && entry->tAddress && entry->params; |
| } /* snmtpTargetAddrTable_rowStatusCheck */ |
| |
| |
| /* |
| * Init routines |
| */ |
| |
| /* |
| * this variable defines function callbacks and type return information |
| * for the snmpTargetAddrEntry mib |
| */ |
| |
| static const struct variable2 snmpTargetAddrEntry_variables[] = { |
| {SNMPTARGETADDRTDOMAIN, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTDOMAINCOLUMN}}, |
| {SNMPTARGETADDRTADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTADDRESSCOLUMN}}, |
| {SNMPTARGETADDRTIMEOUT, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTIMEOUTCOLUMN}}, |
| {SNMPTARGETADDRRETRYCOUNT, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRRETRYCOUNTCOLUMN}}, |
| {SNMPTARGETADDRTAGLIST, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTAGLISTCOLUMN}}, |
| {SNMPTARGETADDRPARAMS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRPARAMSCOLUMN}}, |
| {SNMPTARGETADDRSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRSTORAGETYPECOLUMN}}, |
| {SNMPTARGETADDRROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
| var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRROWSTATUSCOLUMN}}, |
| |
| }; |
| |
| static const struct variable2 snmpTargetSpinLock_var[] = { |
| {SNMPTARGETSPINLOCK, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
| var_targetSpinLock, 1, {1}} |
| }; |
| |
| static const oid snmpTargetSpinLock_oid[] = { 1, 3, 6, 1, 6, 3, 12, 1 }; |
| |
| /* |
| * now load this mib into the agents mib table |
| */ |
| static const oid snmpTargetAddrEntry_variables_oid[] = |
| { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1 }; |
| |
| |
| void |
| init_snmpTargetAddrEntry(void) |
| { |
| aAddrTable = NULL; |
| DEBUGMSGTL(("snmpTargetAddrEntry", "init\n")); |
| REGISTER_MIB("target/snmpTargetAddrEntry", |
| snmpTargetAddrEntry_variables, variable2, |
| snmpTargetAddrEntry_variables_oid); |
| REGISTER_MIB("target/snmpTargetSpinLock", snmpTargetSpinLock_var, |
| variable2, snmpTargetSpinLock_oid); |
| |
| snmpd_register_config_handler("targetAddr", |
| snmpd_parse_config_targetAddr, |
| (void (*)(void))0, NULL); |
| |
| /* |
| * we need to be called back later |
| */ |
| snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, |
| store_snmpTargetAddrEntry, NULL); |
| |
| } /* init_snmpTargetAddrEntry */ |
| |
| void |
| shutdown_snmpTargetAddrEntry(void) |
| { |
| struct targetAddrTable_struct *ptr; |
| struct targetAddrTable_struct *next; |
| |
| for (ptr = aAddrTable; ptr; ptr = next) { |
| next = ptr->next; |
| snmpTargetAddrTable_dispose(ptr); |
| } |
| aAddrTable = NULL; |
| |
| snmp_unregister_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, |
| store_snmpTargetAddrEntry, NULL, FALSE); |
| } |
| |
| int |
| snmpTargetAddr_addTDomain(struct targetAddrTable_struct *entry, char *cptr) |
| { |
| size_t len = 128; |
| |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no tDomain in config string\n")); |
| return (0); |
| } |
| |
| if (!read_objid(cptr, entry->tDomain, &len)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: tDomain unreadable in config string\n")); |
| return (0); |
| } |
| |
| /* |
| * spec check for oid 1-128 |
| */ |
| if (len < 1 || len > 128) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: tDomain out of range in config string\n")); |
| return (0); |
| } |
| |
| entry->tDomainLen = len; |
| return (1); |
| } /* snmpTargetAddr_addTDomain */ |
| |
| |
| int |
| snmpTargetAddr_addTAddress(struct targetAddrTable_struct *entry, |
| char *cptr, size_t len) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no tAddress in config string\n")); |
| return (0); |
| } else { |
| /* |
| * spec check for string 1-32 |
| */ |
| /* |
| * if (len < 1 || len > 32) { |
| * DEBUGMSGTL(("snmpTargetAddrEntry","ERROR snmpTargetAddrEntry: name out of range in config string\n")); |
| * return(0); |
| * } |
| */ |
| SNMP_FREE(entry->tAddress); |
| entry->tAddress = (u_char *) malloc(len); |
| entry->tAddressLen = len; |
| memcpy(entry->tAddress, cptr, len); |
| } |
| return (1); |
| } /* snmpTargetAddr_addTAddress */ |
| |
| |
| int |
| snmpTargetAddr_addTimeout(struct targetAddrTable_struct *entry, char *cptr) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetParamsEntry: no Timeout in config string\n")); |
| return (0); |
| } else if (!(isdigit((unsigned char)(*cptr)))) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargeParamsEntry: Timeout is not a digit in config string\n")); |
| return (0); |
| } |
| /* |
| * check Timeout >= 0 |
| */ |
| else if ((entry->timeout = (int) strtol(cptr, (char **) NULL, 0)) < 0) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargeParamsEntry: Timeout out of range in config string\n")); |
| return (0); |
| } |
| return (1); |
| } /* snmpTargetAddr_addTimeout */ |
| |
| |
| int |
| snmpTargetAddr_addRetryCount(struct targetAddrTable_struct *entry, |
| char *cptr) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetParamsEntry: no Retry Count in config string\n")); |
| return (0); |
| } else if (!(isdigit((unsigned char)(*cptr)))) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargeParamsEntry: Retry Count is not a digit in config string\n")); |
| return (0); |
| } |
| /* |
| * spec check 0..255 |
| */ |
| else { |
| entry->retryCount = (int) strtol(cptr, (char **) NULL, 0); |
| if ((entry->retryCount < 0) || (entry->retryCount > 255)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargeParamsEntry: Retry Count is out of range in config string\n")); |
| return (0); |
| } |
| } |
| return (1); |
| } /* snmpTargetAddr_addRetryCount */ |
| |
| |
| int |
| snmpTargetAddr_addTagList(struct targetAddrTable_struct *entry, char *cptr) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no tag list in config string\n")); |
| return (0); |
| } else { |
| size_t len = strlen(cptr); |
| /* |
| * spec check for string 0-255 |
| */ |
| if (len > 255) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: tag list out of range in config string\n")); |
| return (0); |
| } |
| SNMP_FREE(entry->tagList); |
| entry->tagList = strdup(cptr); |
| } |
| return (1); |
| } /* snmpTargetAddr_addTagList */ |
| |
| |
| int |
| snmpTargetAddr_addParams(struct targetAddrTable_struct *entry, char *cptr) |
| { |
| size_t len; |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no params in config string\n")); |
| return (0); |
| } else { |
| len = strlen(cptr); |
| /* |
| * spec check for string 1-32 |
| */ |
| if (len < 1 || len > 32) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: params out of range in config string\n")); |
| return (0); |
| } |
| entry->params = strdup(cptr); |
| } |
| return (1); |
| } /* snmpTargetAddr_addParams */ |
| |
| |
| int |
| snmpTargetAddr_addStorageType(struct targetAddrTable_struct *entry, |
| char *cptr) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no storage type in config " |
| "string\n")); |
| return (0); |
| } else if (!(isdigit((unsigned char)(*cptr)))) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: storage type is not a digit " |
| "in config string\n")); |
| return (0); |
| } |
| /* |
| * check that storage type is a possible value |
| */ |
| else if (((entry->storageType = (int) strtol(cptr, (char **) NULL, 0)) |
| != SNMP_STORAGE_OTHER) && |
| (entry->storageType != SNMP_STORAGE_VOLATILE) && |
| (entry->storageType != SNMP_STORAGE_NONVOLATILE) && |
| (entry->storageType != SNMP_STORAGE_PERMANENT) && |
| (entry->storageType != SNMP_STORAGE_READONLY)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: storage type not a valid " |
| "value of other(%d), volatile(%d), nonvolatile(%d), " |
| "permanent(%d), or readonly(%d) in config string.\n", |
| SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE, |
| SNMP_STORAGE_NONVOLATILE, SNMP_STORAGE_PERMANENT, |
| SNMP_STORAGE_READONLY)); |
| return (0); |
| } |
| return (1); |
| } /* snmpTargetAddr_addStorageType */ |
| |
| |
| int |
| snmpTargetAddr_addRowStatus(struct targetAddrTable_struct *entry, |
| char *cptr) |
| { |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no Row Status in config " |
| "string\n")); |
| return (0); |
| } else if (!(isdigit((unsigned char)(*cptr)))) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: Row Status is not a digit in " |
| "config string\n")); |
| return (0); |
| } |
| /* |
| * check that row status is a valid value |
| */ |
| else if (((entry->rowStatus = (int) strtol(cptr, (char **) NULL, 0)) |
| != SNMP_ROW_ACTIVE) && |
| (entry->rowStatus != SNMP_ROW_NOTINSERVICE) && |
| (entry->rowStatus != SNMP_ROW_NOTREADY)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: Row Status is not a valid " |
| "value of active(%d), notinservice(%d), or notready(%d) " |
| "in config string.\n", |
| SNMP_ROW_ACTIVE, SNMP_ROW_NOTINSERVICE, SNMP_ROW_NOTREADY)); |
| return (0); |
| } |
| return (1); |
| } /* snmpTargetAddr_addRowStatus */ |
| |
| |
| void |
| snmpd_parse_config_targetAddr(const char *token, char *char_ptr) |
| { |
| const char *cptr = char_ptr; |
| char buff[1024], *bptr; |
| struct targetAddrTable_struct *newEntry; |
| int i; |
| size_t bufl; |
| |
| newEntry = snmpTargetAddrTable_create(); |
| |
| cptr = skip_white_const(cptr); |
| if (cptr == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no name in config string\n")); |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| |
| bufl = 0; |
| cptr = read_config_read_octet_string_const(cptr, |
| (u_char**)&newEntry->nameData, |
| &bufl); |
| if (bufl < 1 || bufl > 32) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: name out of range in config " |
| "string\n")); |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| newEntry->nameLen = bufl; |
| |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addTDomain(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = |
| read_config_read_octet_string_const(cptr, |
| (u_char **) & newEntry->tAddress, |
| &newEntry->tAddressLen); |
| if (!cptr || !(newEntry->tAddress)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "ERROR snmpTargetAddrEntry: no TAddress in config string\n")); |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addTimeout(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addRetryCount(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addTagList(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addParams(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addStorageType(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| cptr = copy_nword_const(cptr, buff, sizeof(buff)); |
| if (snmpTargetAddr_addRowStatus(newEntry, buff) == 0) { |
| snmpTargetAddrTable_dispose(newEntry); |
| return; |
| } |
| bptr = buff; |
| bptr += sprintf(bptr, "snmp_parse_config_targetAddr, read: "); |
| bptr = read_config_save_octet_string(bptr, (u_char*)newEntry->nameData, |
| newEntry->nameLen); |
| *bptr++ = '\n'; |
| for (i = 0; i < newEntry->tDomainLen; i++) { |
| bptr += snprintf(bptr, buff + sizeof(buff) - bptr, |
| ".%d", (int) newEntry->tDomain[i]); |
| } |
| bptr += snprintf(bptr, buff + sizeof(buff) - bptr, |
| " %s %d %d %s %s %d %d\n", |
| newEntry->tAddress, newEntry->timeout, |
| newEntry->retryCount, newEntry->tagList, |
| newEntry->params, newEntry->storageType, |
| newEntry->rowStatus); |
| buff[ sizeof(buff) - 1 ] = 0; |
| DEBUGMSGTL(("snmpTargetAddrEntry", "%s", buff)); |
| |
| snmpTargetAddrTable_addToList(newEntry, &aAddrTable); |
| } /* snmpd_parse_config_target */ |
| |
| |
| /* |
| * Shutdown routines |
| */ |
| |
| |
| /* |
| * store_snmpTargetAddrEntry handles the persistent storage proccess |
| * for this MIB table. It writes out all the non-volatile rows |
| * to permanent storage on a shutdown |
| */ |
| static int |
| store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg, |
| void *clientarg) |
| { |
| const struct targetAddrTable_struct *curr_struct; |
| char line[1024], *cur, *ep = line + sizeof(line); |
| int i; |
| |
| curr_struct = aAddrTable; |
| while (curr_struct != NULL) { |
| if ((curr_struct->storageType == SNMP_STORAGE_NONVOLATILE || |
| curr_struct->storageType == SNMP_STORAGE_PERMANENT) && |
| (curr_struct->rowStatus == SNMP_ROW_ACTIVE || |
| curr_struct->rowStatus == SNMP_ROW_NOTINSERVICE)) { |
| cur = line + snprintf(line, sizeof(line), "targetAddr "); |
| cur = read_config_save_octet_string( |
| cur, (u_char*)curr_struct->nameData, curr_struct->nameLen); |
| *cur++ = ' '; |
| for (i = 0; i < curr_struct->tDomainLen; i++) { |
| cur += snprintf(cur, ep - cur, ".%i", |
| (int) curr_struct->tDomain[i]); |
| } |
| *cur++ = ' '; |
| cur = read_config_save_octet_string( |
| cur, curr_struct->tAddress, curr_struct->tAddressLen); |
| cur += snprintf(cur, ep - cur, " %i %i \"%s\" %s %i %i", |
| curr_struct->timeout, |
| curr_struct->retryCount, curr_struct->tagList, |
| curr_struct->params, curr_struct->storageType, |
| curr_struct->rowStatus); |
| line[ sizeof(line)-1 ] = 0; |
| |
| /* |
| * store to file |
| */ |
| snmpd_store_config(line); |
| } |
| |
| curr_struct = curr_struct->next; |
| } |
| |
| return SNMPERR_SUCCESS; |
| } /* store_snmpTargetAddrEntry */ |
| |
| |
| /* |
| * MIB table access routines |
| */ |
| |
| |
| u_char * |
| var_snmpTargetAddrEntry(struct variable * vp, |
| oid * name, |
| size_t * length, |
| int exact, |
| size_t * var_len, WriteMethod ** write_method) |
| { |
| |
| /* |
| * variables we may use later |
| */ |
| static long long_ret; |
| static char string[1500]; |
| static oid objid[128]; |
| struct targetAddrTable_struct *temp_struct; |
| int i = 0; |
| |
| /* |
| * Set up write_method first, in case we return NULL before getting to the |
| * switch (vp->magic) below. In some of these cases, we still want to call |
| * the appropriate write_method, if only to have it return the appropriate |
| * error. |
| */ |
| |
| switch (vp->magic) { |
| #ifndef NETSNMP_NO_WRITE_SUPPORT |
| case SNMPTARGETADDRTDOMAIN: |
| *write_method = write_snmpTargetAddrTDomain; |
| break; |
| case SNMPTARGETADDRTADDRESS: |
| *write_method = write_snmpTargetAddrTAddress; |
| break; |
| case SNMPTARGETADDRRETRYCOUNT: |
| *write_method = write_snmpTargetAddrRetryCount; |
| break; |
| case SNMPTARGETADDRTIMEOUT: |
| *write_method = write_snmpTargetAddrTimeout; |
| break; |
| case SNMPTARGETADDRTAGLIST: |
| *write_method = write_snmpTargetAddrTagList; |
| break; |
| case SNMPTARGETADDRPARAMS: |
| *write_method = write_snmpTargetAddrParams; |
| break; |
| case SNMPTARGETADDRSTORAGETYPE: |
| *write_method = write_snmpTargetAddrStorageType; |
| break; |
| case SNMPTARGETADDRROWSTATUS: |
| *write_method = write_snmpTargetAddrRowStatus; |
| break; |
| #endif /* !NETSNMP_NO_WRITE_SUPPORT */ |
| default: |
| *write_method = NULL; |
| } |
| |
| /* assume an integer and change later if not */ |
| *var_len = sizeof(long_ret); |
| |
| /* |
| * look for OID in current table |
| */ |
| if ((temp_struct = search_snmpTargetAddrTable(vp->name, vp->namelen, |
| name, length, |
| exact)) == NULL) { |
| return NULL; |
| } |
| |
| /* |
| * We found what we were looking for, either the next OID or the exact OID |
| */ |
| /* |
| * this is where we do the value assignments for the mib results. |
| */ |
| switch (vp->magic) { |
| case SNMPTARGETADDRTDOMAIN: |
| if (temp_struct->tDomainLen <= 0) { |
| return NULL; |
| } else { |
| for (i = 0; i < temp_struct->tDomainLen; i++) { |
| objid[i] = temp_struct->tDomain[i]; |
| } |
| *var_len = temp_struct->tDomainLen * sizeof(oid); |
| } |
| return (unsigned char *) objid; |
| |
| case SNMPTARGETADDRTADDRESS: |
| if (temp_struct->tAddress == NULL) |
| return NULL; |
| *var_len = temp_struct->tAddressLen; |
| return (unsigned char *) temp_struct->tAddress; |
| |
| case SNMPTARGETADDRTIMEOUT: |
| long_ret = temp_struct->timeout; |
| return (unsigned char *) &long_ret; |
| |
| case SNMPTARGETADDRRETRYCOUNT: |
| long_ret = temp_struct->retryCount; |
| return (unsigned char *) &long_ret; |
| |
| case SNMPTARGETADDRTAGLIST: |
| if (temp_struct->tagList != NULL) { |
| strlcpy(string, temp_struct->tagList, sizeof(string)); |
| *var_len = strlen(string); |
| return (unsigned char *) string; |
| } else { |
| return NULL; |
| } |
| |
| case SNMPTARGETADDRPARAMS: |
| if (temp_struct->params == NULL) |
| return NULL; |
| strlcpy(string, temp_struct->params, sizeof(string)); |
| *var_len = strlen(string); |
| return (unsigned char *) string; |
| |
| case SNMPTARGETADDRSTORAGETYPE: |
| long_ret = temp_struct->storageType; |
| return (unsigned char *) &long_ret; |
| |
| case SNMPTARGETADDRROWSTATUS: |
| long_ret = temp_struct->rowStatus; |
| return (unsigned char *) &long_ret; |
| |
| default: |
| DEBUGMSGTL(("snmpd", |
| "unknown sub-id %d in var_snmpTargetAddrEntry\n", |
| vp->magic)); |
| } |
| |
| return NULL; |
| } /* var_snmpTargetAddrEntry */ |
| |
| |
| #ifndef NETSNMP_NO_WRITE_SUPPORT |
| int |
| write_snmpTargetAddrTDomain(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| struct targetAddrTable_struct *target = NULL; |
| static oid old_oid[MAX_OID_LEN]; |
| static size_t old_oid_len; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_OBJECT_ID) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTDomain not ASN_OBJECT_ID\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if ((var_val_len > (MAX_OID_LEN * sizeof(oid))) || |
| (var_val_len % sizeof(oid) != 0)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTDomain: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTDOMAINCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTDomain: BAD OID!\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTDomain: row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| if (target->rowStatus == SNMP_ROW_ACTIVE) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTDomain: not allowed in active row.\n")); |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| |
| /* |
| * Finally, we're golden, save current value. |
| */ |
| |
| memcpy(old_oid, target->tDomain, |
| target->tDomainLen * sizeof(oid)); |
| old_oid_len = target->tDomainLen; |
| |
| memcpy((u_char *) target->tDomain, var_val, var_val_len); |
| target->tDomainLen = var_val_len / sizeof(oid); |
| |
| /* |
| * If row is new, check if its status can be updated. |
| */ |
| if ((target->rowStatus == SNMP_ROW_NOTREADY) && |
| (snmpTargetAddr_rowStatusCheck(target) != 0)) { |
| target->rowStatus = SNMP_ROW_NOTINSERVICE; |
| } |
| } |
| } else if (action == COMMIT) { |
| snmp_store_needed(NULL); |
| } else if (action == FREE || action == UNDO) { |
| /* |
| * Try to undo the SET here (abnormal usage of FREE clause) |
| */ |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTDOMAINCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) != NULL) { |
| if (target->storageType != SNMP_STORAGE_READONLY |
| && target->rowStatus != SNMP_ROW_ACTIVE) { |
| memcpy((u_char *) target->tDomain, (u_char *) old_oid, |
| (old_oid_len * sizeof(oid))); |
| target->tDomainLen = old_oid_len; |
| if (target->rowStatus == SNMP_ROW_NOTINSERVICE && |
| snmpTargetAddr_rowStatusCheck(target) == 0) { |
| target->rowStatus = SNMP_ROW_NOTREADY; |
| } |
| } |
| } |
| } |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrTDomain */ |
| |
| |
| int |
| write_snmpTargetAddrTAddress(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| struct targetAddrTable_struct *target = NULL; |
| static char *old_addr = NULL; |
| static size_t old_len = 0; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_OCTET_STR) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTAddress not ASN_OCTET_STR\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } else if (var_val_len < 1 || var_val_len > 255) { |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTADDRESSCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTAddress: BAD OID!\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTAddress: row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| if (target->rowStatus == SNMP_ROW_ACTIVE) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTAddress: not allowed in active row.\n")); |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| |
| old_addr = (char *) target->tAddress; |
| old_len = target->tAddressLen; |
| target->tAddress = (u_char *) malloc(var_val_len); |
| if (target->tAddress == NULL) { |
| return SNMP_ERR_RESOURCEUNAVAILABLE; |
| } |
| memcpy(target->tAddress, var_val, var_val_len); |
| target->tAddressLen = var_val_len; |
| |
| /* |
| * If row is new, check if its status can be updated. |
| */ |
| if ((target->rowStatus == SNMP_ROW_NOTREADY) && |
| (snmpTargetAddr_rowStatusCheck(target) != 0)) { |
| target->rowStatus = SNMP_ROW_NOTINSERVICE; |
| } |
| } |
| } else if (action == COMMIT) { |
| SNMP_FREE(old_addr); |
| old_addr = NULL; |
| snmp_store_needed(NULL); |
| } else if (action == FREE || action == UNDO) { |
| /* |
| * Try to undo the SET here (abnormal usage of FREE clause) |
| */ |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTADDRESSCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) != NULL) { |
| if (target->storageType != SNMP_STORAGE_READONLY |
| && target->rowStatus != SNMP_ROW_ACTIVE) { |
| SNMP_FREE(target->tAddress); |
| target->tAddress = (u_char *) old_addr; |
| target->tAddressLen = old_len; |
| if (target->rowStatus == SNMP_ROW_NOTINSERVICE && |
| snmpTargetAddr_rowStatusCheck(target) == 0) { |
| target->rowStatus = SNMP_ROW_NOTREADY; |
| } |
| } |
| } |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrTAddress */ |
| |
| |
| int |
| write_snmpTargetAddrTimeout(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| /* |
| * variables we may use later |
| */ |
| static long long_ret; |
| size_t size; |
| struct targetAddrTable_struct *temp_struct; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_INTEGER) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTimeout not ASN_INTEGER\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len > (size = sizeof(long_ret))) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTimeout: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| long_ret = *((long *) var_val); |
| if (long_ret < 0 || long_ret > 2147483647) { |
| return SNMP_ERR_WRONGVALUE; |
| } |
| } else if (action == RESERVE2) { |
| |
| /* |
| * spec check range, no spec check |
| */ |
| |
| /* |
| * Find row in linked list and check pertinent status... |
| */ |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTIMEOUTCOLUMN; |
| if ((temp_struct = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, &name_len, |
| 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTimeout : BAD OID\n")); |
| return SNMP_ERR_NOSUCHNAME; |
| } |
| /* |
| * row exists, check if it is changeable |
| */ |
| if (temp_struct->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTimeout : row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| } else if (action == COMMIT) { |
| /* |
| * Finally, we're golden, should we save value? |
| */ |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTIMEOUTCOLUMN; |
| if ((temp_struct = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, &name_len, |
| 1)) != NULL) { |
| temp_struct->timeout = long_ret; |
| } |
| snmp_store_needed(NULL); |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrTimeout */ |
| |
| |
| int |
| write_snmpTargetAddrRetryCount(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| static long long_ret; |
| struct targetAddrTable_struct *target; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_INTEGER) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrRetryCount not ASN_INTEGER\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len != sizeof(long)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrRetryCount: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| long_ret = *((long *) var_val); |
| if (long_ret < 0 || long_ret > 255) { |
| return SNMP_ERR_WRONGVALUE; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRRETRYCOUNTCOLUMN; |
| if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, |
| name, &name_len, |
| 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTimeout: BAD OID\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrRetryCount: row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| } |
| } else if (action == COMMIT) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRRETRYCOUNTCOLUMN; |
| if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, |
| name, &name_len, |
| 1)) != NULL) { |
| target->retryCount = long_ret; |
| } |
| snmp_store_needed(NULL); |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrRetryCount */ |
| |
| static int |
| is_delim(const char c) |
| { |
| return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b); |
| } |
| |
| int |
| snmpTagListValid(const char *tagList, const size_t tagListLen) |
| { |
| size_t i = 0; |
| int inTag = 0; |
| |
| |
| for (i = 0; i < tagListLen; i++) { |
| if (is_delim(tagList[i]) && !inTag) { |
| /* |
| * Either a leading delimiter or two consecutive delimiters. |
| */ |
| return 0; |
| } else if (is_delim(tagList[i]) && inTag) { |
| inTag = 0; |
| } else if (!is_delim(tagList[i]) && !inTag) { |
| inTag = 1; |
| } |
| } |
| if (!inTag) { |
| /* |
| * Trailing delimiter. |
| */ |
| return 0; |
| } |
| return 1; |
| } |
| |
| int |
| write_snmpTargetAddrTagList(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| struct targetAddrTable_struct *target = NULL; |
| static char *old_tlist; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_OCTET_STR) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTagList not ASN_OCTET_STR\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len > 255) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTagList: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| if (!snmpTagListValid((char *) var_val, var_val_len)) { |
| return SNMP_ERR_WRONGVALUE; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTAGLISTCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTagList: BAD OID!\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrTagList: row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| old_tlist = target->tagList; |
| target->tagList = (char *) malloc(var_val_len + 1); |
| if (target->tagList == NULL) { |
| return SNMP_ERR_RESOURCEUNAVAILABLE; |
| } |
| memcpy(target->tagList, var_val, var_val_len); |
| target->tagList[var_val_len] = '\0'; |
| } |
| } else if (action == COMMIT) { |
| SNMP_FREE(old_tlist); |
| old_tlist = NULL; |
| snmp_store_needed(NULL); |
| } else if (action == FREE || action == UNDO) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRTAGLISTCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) != NULL) { |
| if (target->storageType != SNMP_STORAGE_READONLY) { |
| SNMP_FREE(target->tagList); |
| target->tagList = old_tlist; |
| } |
| } |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrTagList */ |
| |
| |
| int |
| write_snmpTargetAddrParams(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| struct targetAddrTable_struct *target = NULL; |
| static char *old_params = NULL; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_OCTET_STR) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrParams not ASN_OCTET_STR\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } else if (var_val_len < 1 || var_val_len > 32) { |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRPARAMSCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrParams: BAD OID!\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrParams: row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| if (target->rowStatus == SNMP_ROW_ACTIVE) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrParams: not allowed in active row.\n")); |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| |
| old_params = target->params; |
| target->params = malloc(var_val_len + 1); |
| if (target->params == NULL) { |
| return SNMP_ERR_RESOURCEUNAVAILABLE; |
| } |
| memcpy(target->params, var_val, var_val_len); |
| target->params[var_val_len] = '\0'; |
| |
| /* |
| * If row is new, check if its status can be updated. |
| */ |
| if ((target->rowStatus == SNMP_ROW_NOTREADY) && |
| (snmpTargetAddr_rowStatusCheck(target) != 0)) { |
| target->rowStatus = SNMP_ROW_NOTINSERVICE; |
| } |
| } |
| } else if (action == COMMIT) { |
| SNMP_FREE(old_params); |
| old_params = NULL; |
| snmp_store_needed(NULL); |
| } else if (action == FREE || action == UNDO) { |
| /* |
| * Try to undo the SET here (abnormal usage of FREE clause) |
| */ |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRPARAMSCOLUMN; |
| if ((target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1)) != NULL) { |
| if (target->storageType != SNMP_STORAGE_READONLY |
| && target->rowStatus != SNMP_ROW_ACTIVE) { |
| SNMP_FREE(target->params); |
| target->params = old_params; |
| if (target->rowStatus == SNMP_ROW_NOTINSERVICE && |
| snmpTargetAddr_rowStatusCheck(target) == 0) { |
| target->rowStatus = SNMP_ROW_NOTREADY; |
| } |
| } |
| } |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrParams */ |
| |
| int |
| write_snmpTargetAddrStorageType(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, |
| oid * name, size_t name_len) |
| { |
| long long_ret = *((long *) var_val); |
| struct targetAddrTable_struct *target; |
| |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_INTEGER) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrStorageType not ASN_INTEGER\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len != sizeof(long)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrStorageType: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| if (long_ret != SNMP_STORAGE_OTHER && |
| long_ret != SNMP_STORAGE_VOLATILE && |
| long_ret != SNMP_STORAGE_NONVOLATILE) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrStorageType: attempted storage type not a valid")); |
| DEBUGMSG(("snmpTargetAddrEntry", |
| " value of other(%d), volatile(%d), or nonvolatile(%d)\n", |
| SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE, |
| SNMP_STORAGE_NONVOLATILE)); |
| return SNMP_ERR_WRONGVALUE; |
| } |
| } else if (action == RESERVE2) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRSTORAGETYPECOLUMN; |
| if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, |
| name, &name_len, |
| 1)) == NULL) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrStorageType: BAD OID\n")); |
| return SNMP_ERR_INCONSISTENTNAME; |
| } else { |
| if (target->storageType == SNMP_STORAGE_PERMANENT || |
| target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrStorageType: row has unchangeable storage status: %d\n", |
| target->storageType)); |
| return SNMP_ERR_WRONGVALUE; |
| } |
| } |
| } else if (action == COMMIT) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRSTORAGETYPECOLUMN; |
| if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, |
| name, &name_len, |
| 1)) != NULL) { |
| target->storageType = long_ret; |
| } |
| snmp_store_needed(NULL); |
| } |
| |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrStorageType */ |
| |
| |
| /* |
| * snmpTargeAddr_createNewRow is called from write_snmpTargetAddrRowStatus |
| * when a new row is required. It creates a new row with |
| * the index of the passed in 'name' (i.e. full index OID) and |
| * adds it to the linked list. 'name' should be the full OID of the new index. |
| * It passes back 0 if unsuccessfull. |
| */ |
| int |
| snmpTargetAddr_createNewRow(oid * name, size_t name_len) |
| { |
| size_t newNameLen; |
| int i; |
| struct targetAddrTable_struct *temp_struct; |
| |
| /* |
| * setup a new snmpTargetAddrTable structure and add it to the list |
| */ |
| newNameLen = name_len - snmpTargetAddrOIDLen; |
| if (newNameLen > 0) { |
| temp_struct = snmpTargetAddrTable_create(); |
| if (!temp_struct) |
| return SNMP_ERR_GENERR; |
| temp_struct->nameData = (char *) malloc(newNameLen); |
| if (temp_struct->nameData == NULL) { |
| SNMP_FREE(temp_struct->tagList); |
| SNMP_FREE(temp_struct); |
| return 0; |
| } |
| |
| temp_struct->nameLen = newNameLen; |
| for (i = 0; i < (int) newNameLen; i++) { |
| temp_struct->nameData[i] = (char) name[i + snmpTargetAddrOIDLen]; |
| } |
| |
| temp_struct->rowStatus = SNMP_ROW_NOTREADY; |
| |
| snmpTargetAddrTable_addToList(temp_struct, &aAddrTable); |
| |
| return 1; |
| } |
| |
| return 0; |
| } /* snmpTargetAddr_createNewRow */ |
| |
| |
| /* |
| * Assign a value to the Row Status variable |
| */ |
| int |
| write_snmpTargetAddrRowStatus(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| static long value; |
| struct targetAddrTable_struct *target = NULL; |
| |
| if (action == RESERVE1) { |
| value = *((long *) var_val); |
| if (var_val_type != ASN_INTEGER) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrRowStatus not ASN_INTEGER\n")); |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len != sizeof(long)) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "write to snmpTargetAddrRowStatus: bad length\n")); |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| if (value == RS_NOTREADY || value < 1 || value > 6) { |
| return SNMP_ERR_WRONGVALUE; |
| } |
| |
| /* |
| * Check index value is reasonable. |
| */ |
| |
| if (name_len < snmpTargetAddrOIDLen + 1 || |
| name_len > snmpTargetAddrOIDLen + 32) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", "bad index length %d\n", |
| (int)(name_len - snmpTargetAddrOIDLen))); |
| return SNMP_ERR_NOCREATION; |
| } |
| |
| /* |
| * Search for struct in linked list. |
| */ |
| |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRROWSTATUSCOLUMN; |
| target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1); |
| |
| if (target != NULL) { |
| if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) { |
| value = RS_NOTREADY; |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| if (target->storageType == SNMP_STORAGE_READONLY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", "row is read only\n")); |
| return SNMP_ERR_NOTWRITABLE; |
| } |
| if (target->storageType == SNMP_STORAGE_PERMANENT) { |
| if (value == RS_DESTROY) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "unable to destroy permanent row\n")); |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| } |
| } else { |
| if (value == RS_ACTIVE || value == RS_NOTINSERVICE) { |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) { |
| if (snmpTargetAddr_createNewRow(name, name_len) == 0) { |
| DEBUGMSGTL(("snmpTargetAddrEntry", |
| "couldn't malloc() new row\n")); |
| return SNMP_ERR_RESOURCEUNAVAILABLE; |
| } |
| } |
| } |
| } else if (action == ACTION) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRROWSTATUSCOLUMN; |
| target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1); |
| |
| if (target != NULL) { |
| if (value == RS_CREATEANDGO) { |
| /* |
| * Check whether all the required objects have been set. |
| */ |
| if (snmpTargetAddr_rowStatusCheck(target)) { |
| target->rowStatus = RS_ACTIVE; |
| } else { |
| target->rowStatus = RS_NOTREADY; |
| } |
| } else if (value == RS_CREATEANDWAIT) { |
| /* |
| * Check whether all the required objects have been set. |
| */ |
| if (snmpTargetAddr_rowStatusCheck(target)) { |
| target->rowStatus = RS_NOTINSERVICE; |
| } else { |
| target->rowStatus = RS_NOTREADY; |
| } |
| } else if (value == RS_ACTIVE) { |
| if (target->rowStatus == RS_NOTINSERVICE) { |
| target->rowStatus = RS_ACTIVE; |
| } else if (target->rowStatus == RS_NOTREADY) { |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| } else if (value == RS_NOTINSERVICE) { |
| if (target->rowStatus == RS_ACTIVE) { |
| target->rowStatus = RS_NOTINSERVICE; |
| } else if (target->rowStatus == RS_NOTREADY) { |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| } |
| } |
| } else if (action == COMMIT) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRROWSTATUSCOLUMN; |
| target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1); |
| if (target != NULL) { |
| if (value == RS_DESTROY) { |
| snmpTargetAddrTable_remFromList(target, &aAddrTable); |
| } |
| if (value == RS_NOTINSERVICE) { |
| if (target->sess != NULL) { |
| snmp_close(target->sess); |
| target->sess = NULL; |
| } |
| } |
| } |
| snmp_store_needed(NULL); |
| } else if (action == UNDO || action == FREE) { |
| snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] = |
| SNMPTARGETADDRROWSTATUSCOLUMN; |
| target = |
| search_snmpTargetAddrTable(snmpTargetAddrOID, |
| snmpTargetAddrOIDLen, name, |
| &name_len, 1); |
| if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) { |
| if (target != NULL) { |
| snmpTargetAddrTable_remFromList(target, &aAddrTable); |
| } |
| } |
| } |
| return SNMP_ERR_NOERROR; |
| } /* write_snmpTargetAddrRowStatus */ |
| |
| |
| |
| int |
| write_targetSpinLock(int action, |
| u_char * var_val, |
| u_char var_val_type, |
| size_t var_val_len, |
| u_char * statP, oid * name, size_t name_len) |
| { |
| if (action == RESERVE1) { |
| if (var_val_type != ASN_INTEGER) { |
| return SNMP_ERR_WRONGTYPE; |
| } |
| if (var_val_len != sizeof(unsigned long)) { |
| return SNMP_ERR_WRONGLENGTH; |
| } |
| if (*((unsigned long *) var_val) != snmpTargetSpinLock) { |
| return SNMP_ERR_INCONSISTENTVALUE; |
| } |
| } else if (action == COMMIT) { |
| if (snmpTargetSpinLock == 2147483647) { |
| snmpTargetSpinLock = 0; |
| } else { |
| snmpTargetSpinLock++; |
| } |
| } |
| return SNMP_ERR_NOERROR; |
| } |
| |
| #endif /* !NETSNMP_NO_WRITE_SUPPORT */ |
| |
| |
| u_char * |
| var_targetSpinLock(struct variable * vp, |
| oid * name, |
| size_t * length, |
| int exact, |
| size_t * var_len, WriteMethod ** write_method) |
| { |
| if (header_generic(vp, name, length, exact, var_len, write_method) == |
| MATCH_FAILED) { |
| #ifndef NETSNMP_NO_WRITE_SUPPORT |
| *write_method = write_targetSpinLock; |
| #else |
| *write_method = NULL; |
| #endif /* !NETSNMP_NO_WRITE_SUPPORT */ |
| return NULL; |
| } |
| if (vp->magic == SNMPTARGETSPINLOCK) { |
| *var_len = sizeof(unsigned long); |
| #ifndef NETSNMP_NO_WRITE_SUPPORT |
| *write_method = write_targetSpinLock; |
| #else |
| *write_method = NULL; |
| #endif /* !NETSNMP_NO_WRITE_SUPPORT */ |
| return (u_char *) & (snmpTargetSpinLock); |
| } |
| return NULL; |
| } |