diff options
Diffstat (limited to 'agent/mibgroup/target/snmpTargetAddrEntry.c')
-rw-r--r-- | agent/mibgroup/target/snmpTargetAddrEntry.c | 1704 |
1 files changed, 1704 insertions, 0 deletions
diff --git a/agent/mibgroup/target/snmpTargetAddrEntry.c b/agent/mibgroup/target/snmpTargetAddrEntry.c new file mode 100644 index 0000000..a77b467 --- /dev/null +++ b/agent/mibgroup/target/snmpTargetAddrEntry.c @@ -0,0 +1,1704 @@ +/* + * 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 */ + +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; + + +/* + * Utility routines + */ +struct targetAddrTable_struct * +get_addrTable(void) +{ + return aAddrTable; +} + +struct targetAddrTable_struct * +get_addrForName(char *name) +{ + struct targetAddrTable_struct *ptr; + for (ptr = aAddrTable; ptr != NULL; ptr = ptr->next) { + if (ptr->name && strcmp(ptr->name, name) == 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 = (struct targetAddrTable_struct *) + malloc(sizeof(struct targetAddrTable_struct)); + + if (newEntry) { + newEntry->name = NULL; + + 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 = (netsnmp_session *) 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->name); + 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; + size_t newOIDLen = 0, currOIDLen = 0; + oid newOID[128], currOID[128]; + + /* + * if the list is empty, add the new entry to the top + */ + if ((prev_struct = curr_struct = *listPtr) == NULL) { + *listPtr = newEntry; + return; + } else { + /* + * get the 'OID' value of the new entry + */ + newOIDLen = strlen(newEntry->name); + for (i = 0; i < (int) newOIDLen; i++) { + newOID[i] = newEntry->name[i]; + } + + /* + * search through the list for an equal or greater OID value + */ + while (curr_struct != NULL) { + currOIDLen = strlen(curr_struct->name); + for (i = 0; i < (int) currOIDLen; i++) { + currOID[i] = curr_struct->name[i]; + } + + i = snmp_oid_compare(newOID, newOIDLen, currOID, currOIDLen); + 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 < (int) strlen(temp_struct->name); i++) { + newNum[baseNameLen + i] = temp_struct->name[i]; + } + myOIDLen = baseNameLen + strlen(temp_struct->name); + 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 funciton that checks + * the status of a row's values in order to determine whether + * the row should be notReady or notInService + */ +int +snmpTargetAddr_rowStatusCheck(struct targetAddrTable_struct *entry) +{ + if ((entry->tDomainLen == 0) || (entry->tAddress == NULL) || + (entry->params == NULL)) + return 0; + else + return 1; +} /* snmtpTargetAddrTable_rowStatusCheck */ + + +/* + * Init routines + */ + +/* + * this variable defines function callbacks and type return information + * for the snmpTargetAddrEntry mib + */ + +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}}, + +}; + +struct variable2 snmpTargetSpinLock_var[] = { + {SNMPTARGETSPINLOCK, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, + var_targetSpinLock, 1, {1}} +}; + +static oid snmpTargetSpinLock_oid[] = { 1, 3, 6, 1, 6, 3, 12, 1 }; + +/* + * now load this mib into the agents mib table + */ +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_addName(struct targetAddrTable_struct *entry, char *cptr) +{ + size_t len; + if (cptr == NULL) { + DEBUGMSGTL(("snmpTargetAddrEntry", + "ERROR snmpTargetAddrEntry: no name 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: name out of range in config string\n")); + return (0); + } + entry->name = strdup(cptr); + } + return (1); +} /* addName */ + + +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) +{ + char *cptr = char_ptr, buff[1024]; + struct targetAddrTable_struct *newEntry; + int i; + + newEntry = snmpTargetAddrTable_create(); + + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addName(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addTDomain(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = + read_config_read_octet_string(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(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addTimeout(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addRetryCount(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addTagList(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addParams(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addStorageType(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + cptr = copy_nword(cptr, buff, sizeof(buff)); + if (snmpTargetAddr_addRowStatus(newEntry, buff) == 0) { + snmpTargetAddrTable_dispose(newEntry); + return; + } + snprintf(buff, sizeof(buff), "snmp_parse_config_targetAddr, read: %s\n", + newEntry->name); + buff[ sizeof(buff)-1 ] = 0; + for (i = 0; i < newEntry->tDomainLen; i++) { + snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1, + ".%d", (int) newEntry->tDomain[i]); + buff[ sizeof(buff)-1 ] = 0; + } + snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1, + " %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 + */ +int +store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg, + void *clientarg) +{ + struct targetAddrTable_struct *curr_struct; + char line[1024]; + int i; + + if ((curr_struct = aAddrTable) != NULL) { + 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)) { + snprintf(line, sizeof(line), + "targetAddr %s ", curr_struct->name); + line[ sizeof(line)-1 ] = 0; + for (i = 0; i < curr_struct->tDomainLen; i++) { + snprintf(&line[strlen(line)], + sizeof(line)-strlen(line)-1, ".%i", + (int) curr_struct->tDomain[i]); + line[ sizeof(line)-1 ] = 0; + } + strlcat(line, " ", sizeof(line)); + read_config_save_octet_string(&line[strlen(line)], + curr_struct->tAddress, + curr_struct->tAddressLen); + + snprintf(&line[strlen(line)], sizeof(line)-strlen(line)-1, + " %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 == 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; + } 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); + } 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; + } + } + + 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; + } + } + + 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; + } 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; + } 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; + } + } + + 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->name = (char *) malloc(newNameLen + 1); + if (temp_struct->name == NULL) { + SNMP_FREE(temp_struct->tagList); + SNMP_FREE(temp_struct); + return 0; + } + + for (i = 0; i < (int) newNameLen; i++) { + temp_struct->name[i] = (char) name[i + snmpTargetAddrOIDLen]; + } + + temp_struct->name[newNameLen] = '\0'; + 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; +} |