/* * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * * U.S. Government Rights - Commercial software. Government users are subject * to the Sun Microsystems, Inc. standard license agreement and applicable * provisions of the FAR and its supplements. * * * This distribution may include materials developed by third parties. Sun, * Sun Microsystems, the Sun logo and Solaris are trademarks or registered * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.5 2002/12/16 22:50:18 hardaker Exp $ */ #include #include #include #include "stdhdr.h" #include "entLogicalTable.h" #include "entAliasMappingTable.h" #include "entLastChangeTime.h" #include "entLPMappingTable.h" static int AddToLogicalTable(entLogicalEntry_t *); static int FreeLogicalEntry(entLogicalEntry_t *); entLogicalEntry_t *gLogicalTableHead, *gLogicalTableTail; int gLogicalTableSize; /** Initialize the entLogicalTable table by defining its contents and how it's structured */ void initialize_table_entLogicalTable(void) { static oid entLogicalTable_oid[] = {1,3,6,1,2,1,47,1,2,1}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /* create the table structure itself */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /* if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ /* Fix for 4910624 - changing HANDLER_CAN_RWRITE to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("entLogicalTable", entLogicalTable_handler, entLogicalTable_oid, OID_LENGTH(entLogicalTable_oid), HANDLER_CAN_RONLY); /* End of Fix for 4910624 */ if (!my_handler || !table_info || !iinfo) return; /* mallocs failed */ /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: entLogicalIndex */ 0); table_info->min_column = 2; table_info->max_column = 8; /* iterator access routines */ iinfo->get_first_data_point = entLogicalTable_get_first_data_point; iinfo->get_next_data_point = entLogicalTable_get_next_data_point; iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_entLogicalTable", "Registering table entLogicalTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); } /** Initializes the entLogicalTable module */ void init_entLogicalTable(void) { /* here we initialize all the tables we're planning on supporting */ initialize_table_entLogicalTable(); gLogicalTableHead = NULL; gLogicalTableSize = 0; gLogicalTableTail = NULL; } /** returns the first data point within the entLogicalTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * entLogicalTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { netsnmp_variable_list *vptr; entLogicalEntry_t *zRunner; zRunner = gLogicalTableHead; while (zRunner) { if (zRunner->entLogicalIndex > 0) break; zRunner = zRunner->pNextEntry; } if (zRunner == NULL) return NULL; *my_loop_context = (void *)zRunner; *my_data_context = (void *)zRunner; vptr = put_index_data; snmp_set_var_value(vptr, (u_char *)&zRunner->entLogicalIndex, sizeof(zRunner->entLogicalIndex)); vptr = vptr->next_variable; return put_index_data; } /** functionally the same as entLogicalTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it and the return my_loop_context->next. The my_data_context pointer should be set to something you need later and the indexes in put_index_data updated again. */ netsnmp_variable_list * entLogicalTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { entLogicalEntry_t *zRunner; netsnmp_variable_list *vptr; zRunner = (entLogicalEntry_t *) *my_loop_context; while (zRunner) { zRunner = zRunner->pNextEntry; if (zRunner && zRunner->entLogicalIndex > 0) break; } if (zRunner == NULL) return NULL; *my_loop_context = (void *)zRunner; *my_data_context = (void *)zRunner; vptr = put_index_data; snmp_set_var_value(vptr, (u_char *)&zRunner->entLogicalIndex, sizeof(zRunner->entLogicalIndex)); vptr = vptr->next_variable; return put_index_data; } /** handles requests for the entLogicalTable table, if anything else needs to be done */ int entLogicalTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; entLogicalEntry_t *zLogicalEntry; for(request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /* perform anything here that you need to do before each request is processed. */ /* the following extracts the my_data_context pointer set in the loop functions above. You can then use the results to help return data for the columns of the entLogicalTable table in question */ zLogicalEntry = (entLogicalEntry_t *) netsnmp_extract_iterator_context(request); if ((zLogicalEntry == NULL) || (zLogicalEntry->entLogicalIndex <= 0) ) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /* XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /* extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /* table_info->colnum contains the column number requested */ /* table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info==NULL) { continue; } switch(reqinfo->mode) { /* the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch(table_info->colnum) { case COLUMN_ENTLOGICALDESCR: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) zLogicalEntry->entLogicalDescr, strlen(zLogicalEntry->entLogicalDescr)); break; case COLUMN_ENTLOGICALTYPE: snmp_set_var_typed_value(var, ASN_OBJECT_ID, (u_char *) zLogicalEntry->entLogicalType, zLogicalEntry->entLogicalTypeSize); break; case COLUMN_ENTLOGICALCOMMUNITY: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) zLogicalEntry->entLogicalCommunity, strlen(zLogicalEntry->entLogicalCommunity)); break; case COLUMN_ENTLOGICALTADDRESS: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) zLogicalEntry->entLogicalTAddress, strlen(zLogicalEntry->entLogicalTAddress)); break; case COLUMN_ENTLOGICALTDOMAIN: snmp_set_var_typed_value(var, ASN_OBJECT_ID, (u_char *) zLogicalEntry->entLogicalTDomain, zLogicalEntry->entLogicalTDomainSize); break; case COLUMN_ENTLOGICALCONTEXTENGINEID: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) zLogicalEntry->entLogicalContextEngineId, strlen(zLogicalEntry->entLogicalContextEngineId)); break; case COLUMN_ENTLOGICALCONTEXTNAME: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) zLogicalEntry->entLogicalContextName, strlen(zLogicalEntry->entLogicalContextName)); break; default: /* We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in entLogicalTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /* set handling... */ default: snmp_log(LOG_ERR, "problem encountered in entLogicalTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } void populate_entLogicalEntry(entLogicalEntry_t *xLogicalStatic, char *entLogicalDescr, oid *entLogicalType, int entLogicalTypeSize, char *entLogicalCommunity, char *entLogicalTAddress, oid *entLogicalTDomain, int entLogicalTDomainSize, char *entLogicalContextEngineId, char *entLogicalContextName) { xLogicalStatic->entLogicalDescr = entLogicalDescr; xLogicalStatic->entLogicalType = entLogicalType; xLogicalStatic->entLogicalTypeSize = entLogicalTypeSize; xLogicalStatic->entLogicalCommunity = entLogicalCommunity; xLogicalStatic->entLogicalTAddress = entLogicalTAddress; xLogicalStatic->entLogicalTDomain = entLogicalTDomain; xLogicalStatic->entLogicalTDomainSize = entLogicalTDomainSize; xLogicalStatic->entLogicalContextEngineId = entLogicalContextEngineId; xLogicalStatic->entLogicalContextName = entLogicalContextName; } /* * Allocates a Logical entry. if logicidx >0 attempts to reuse an * existing entry */ int allocLogicalEntry(int xLogicalIdx, entLogicalEntry_t * xnewLogicalEntry) { entLogicalEntry_t *logicent; int index; /* Fix for 4893101 */ static oid mib2oid[] = { 1,3,6,1,2,1 }; /* End of Fix for 4893101 */ /* Fix for 4927412 */ char emptystring[1] = ""; /* End of Fix for 4927412 */ /* Fix for 4927412: according to RFC 2737, entLogicalDescr has to be */ /* unique - NULL should be rejected. */ /* entLogicalTAddress should not accept NULL or "". */ /* entLogicalTDomain should not accept NULL */ /* entLogicalType will default to mib-2 for */ /* NULL. For the rest, we will force NULL = "" */ /* (zero-length string) */ if (xnewLogicalEntry->entLogicalDescr == NULL) return -1; /* Fix for 4893101: We have to check for NULL so that it does not */ /* crash. Also we need to have mib-2 as the default, */ /* as outlined in the RFC */ if (xnewLogicalEntry->entLogicalType == NULL) { xnewLogicalEntry->entLogicalType = mib2oid; xnewLogicalEntry->entLogicalTypeSize = sizeof(mib2oid); } /* End of Fix for 4893101 */ if (xnewLogicalEntry->entLogicalCommunity == NULL) xnewLogicalEntry->entLogicalCommunity = emptystring; if (xnewLogicalEntry->entLogicalTAddress == NULL) return -1; else if (strcmp((const char *)xnewLogicalEntry->entLogicalTAddress, "") == 0) return -1; if (xnewLogicalEntry->entLogicalTDomain == NULL) return -1; if (xnewLogicalEntry->entLogicalContextEngineId == NULL) xnewLogicalEntry->entLogicalContextEngineId = emptystring; if (xnewLogicalEntry->entLogicalContextName == NULL) xnewLogicalEntry->entLogicalContextName = emptystring; /* End of Fix for 4927412 */ /* Fix for 4921309 */ if (xLogicalIdx < 0 || xLogicalIdx > MAX_ENTITY_INDEX) return NULL; /* End of Fix for 4921309 */ /* Fix for 4911817: Check for size and boundary limits */ /* entLogicalDescr 0..255 */ if (strlen(xnewLogicalEntry->entLogicalDescr) > 255) return -1; /* entLogicalCommunity 0..255 (deprecated) */ if (strlen(xnewLogicalEntry->entLogicalCommunity) > 255) return -1; /* entLogicalTAddress 1..255 */ if (strlen(xnewLogicalEntry->entLogicalTAddress) < 1 || strlen(xnewLogicalEntry->entLogicalTAddress) > 255) return -1; /* entLogicalContextEngineId 0..32 */ if (strlen(xnewLogicalEntry->entLogicalContextEngineId) > 32) return -1; /* entLogicalContextName 0..255 */ if (strlen(xnewLogicalEntry->entLogicalContextName) > 255) return -1; /* End of Fix for 4911817 */ logicent = malloc(sizeof (entLogicalEntry_t)); if (logicent == NULL) { return (-1); } logicent->entLogicalIndex = xLogicalIdx; logicent->entLogicalDescr = strdup(xnewLogicalEntry->entLogicalDescr); /* Fix for 4884526 */ if (logicent->entLogicalDescr == NULL) { free (logicent); return (-1); } /* End of Fix for 4884526 */ logicent->entLogicalType = malloc(xnewLogicalEntry->entLogicalTypeSize); /* Fix for 4884526 */ if (logicent->entLogicalType == NULL) { free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ memcpy(logicent->entLogicalType, xnewLogicalEntry->entLogicalType, xnewLogicalEntry->entLogicalTypeSize); logicent->entLogicalTypeSize = xnewLogicalEntry->entLogicalTypeSize; logicent->entLogicalCommunity = strdup(xnewLogicalEntry->entLogicalCommunity); /* Fix for 4884526 */ if (logicent->entLogicalCommunity == NULL) { free(logicent->entLogicalType); free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ logicent->entLogicalTAddress = strdup(xnewLogicalEntry->entLogicalTAddress); /* Fix for 4884526 */ if (logicent->entLogicalTAddress == NULL) { free(logicent->entLogicalCommunity); free(logicent->entLogicalType); free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ /* Fix for 4926767: We do not want NULL TDomain */ if (xnewLogicalEntry->entLogicalTDomain == NULL) { logicent->entLogicalTDomain = NULL; } else { logicent->entLogicalTDomain = malloc(xnewLogicalEntry->entLogicalTDomainSize); } /* End of Fix for 4926767 */ /* Fix for 4884526 */ if (logicent->entLogicalTDomain == NULL) { free(logicent->entLogicalTAddress); free(logicent->entLogicalCommunity); free(logicent->entLogicalType); free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ memcpy(logicent->entLogicalTDomain, xnewLogicalEntry->entLogicalTDomain, xnewLogicalEntry->entLogicalTDomainSize); logicent->entLogicalTDomainSize = xnewLogicalEntry->entLogicalTDomainSize; logicent->entLogicalContextEngineId = strdup(xnewLogicalEntry->entLogicalContextEngineId); /* Fix for 4884526 */ if (logicent->entLogicalContextEngineId == NULL) { free(logicent->entLogicalTDomain); free(logicent->entLogicalTAddress); free(logicent->entLogicalCommunity); free(logicent->entLogicalType); free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ logicent->entLogicalContextName = strdup(xnewLogicalEntry->entLogicalContextName); /* Fix for 4884526 */ if (logicent->entLogicalContextName == NULL) { free(logicent->entLogicalContextEngineId); free(logicent->entLogicalTDomain); free(logicent->entLogicalTAddress); free(logicent->entLogicalCommunity); free(logicent->entLogicalType); free(logicent->entLogicalDescr); free (logicent); return (-1); } /* End of Fix for 4884526 */ logicent->pNextEntry = NULL; index = AddToLogicalTable(logicent); return (index); } static int AddToLogicalTable(entLogicalEntry_t * xnewLogicalEntry) { entLogicalEntry_t *zRunner, *temp; int placeFound; /* Fix for 4921309 */ int zIndex; zRunner = gLogicalTableHead; if (xnewLogicalEntry == NULL) return (-1); xnewLogicalEntry->pNextEntry = NULL; /* Fix for 4921309 */ /* If index > 0, attempt to insert in appropriate place. */ if (xnewLogicalEntry->entLogicalIndex > 0) { placeFound = 0; temp = zRunner; while (zRunner != NULL) { if (xnewLogicalEntry->entLogicalIndex > abs(zRunner->entLogicalIndex)) { temp = zRunner; zRunner = zRunner->pNextEntry; } else { break; } } /* If the indexes don't match, we can use the specified index */ if (temp == NULL) { /* List is empty, make this the first/last entry */ gLogicalTableHead = xnewLogicalEntry; gLogicalTableTail = xnewLogicalEntry; placeFound = 1; } else if (zRunner == NULL) { /* Index > last value, make this the last entry */ temp->pNextEntry = xnewLogicalEntry; gLogicalTableTail = xnewLogicalEntry; placeFound = 1; } else if (xnewLogicalEntry->entLogicalIndex != abs(zRunner->entLogicalIndex)) { /* Index < zRunner, insert entry before it */ xnewLogicalEntry->pNextEntry = zRunner; if (zRunner == gLogicalTableHead) { /* Index fits before list head, insert entry */ gLogicalTableHead = xnewLogicalEntry; } else { /* Index fits between two entries, insert entry */ temp->pNextEntry = xnewLogicalEntry; } placeFound = 1; } if (placeFound) { gLogicalTableSize++; configChanged(); return (xnewLogicalEntry->entLogicalIndex); } else { /* Re-initialize for code that follows */ zRunner = gLogicalTableHead; } } /* Either index was zero or specified index is already taken */ /* End of Fix for 4921309 */ if (gLogicalTableSize > LARGE_TABLE) { gLogicalTableTail->pNextEntry = xnewLogicalEntry; zIndex = abs(gLogicalTableTail->entLogicalIndex) + 1; xnewLogicalEntry->entLogicalIndex = zIndex; gLogicalTableTail = xnewLogicalEntry; gLogicalTableSize++; configChanged(); return (zIndex); } if (gLogicalTableHead) { /* A slightly slower way to add into the list */ while (zRunner->pNextEntry != NULL) { if ((abs(zRunner->pNextEntry->entLogicalIndex) - abs(zRunner->entLogicalIndex)) > 1) { temp = zRunner->pNextEntry; zRunner->pNextEntry = xnewLogicalEntry; zIndex = abs(zRunner->entLogicalIndex) + 1; xnewLogicalEntry->entLogicalIndex = zIndex; xnewLogicalEntry->pNextEntry = temp; gLogicalTableSize++; configChanged(); return (zIndex); } zRunner = zRunner->pNextEntry; } zIndex = abs(zRunner->entLogicalIndex) + 1; xnewLogicalEntry->entLogicalIndex = zIndex; zRunner->pNextEntry = xnewLogicalEntry; } else { zIndex = xnewLogicalEntry->entLogicalIndex = 1; gLogicalTableHead = xnewLogicalEntry; } gLogicalTableTail = xnewLogicalEntry; gLogicalTableSize++; configChanged(); return (zIndex); } int makeLogicalTableEntryStale(int xLogicalIndex) { entLogicalEntry_t *zRunner; int zLogicalIndex; /* Fix for 4888088 */ if (xLogicalIndex <= 0 || xLogicalIndex > MAX_ENTITY_INDEX) return (-1); /* End of Fix for 4888088 */ zRunner = gLogicalTableHead; while (zRunner) { zLogicalIndex = zRunner->entLogicalIndex; if (zLogicalIndex < 0) { if (zLogicalIndex == -(xLogicalIndex)) return (-2); /* Entry is already stale */ } if (zLogicalIndex == xLogicalIndex) { /* Fix for 4918876: We need to delete the related entries first */ /* Delete all instances of this logical index in all other tables to maintain table integrity. Should we roll-back if a deletion fails, perhaps not */ deleteAliasMappingLogicalIndex( xLogicalIndex); /*Alias mapping*/ deleteLPMappingLogicalIndex( xLogicalIndex); /* LPTable */ /* End of Fix for 4918876 */ zRunner->entLogicalIndex = -zLogicalIndex; configChanged(); return (0); } zRunner = zRunner->pNextEntry; } return (-1); } int makeLogicalTableEntryLive(int xLogicalIndex) { entLogicalEntry_t *zRunner; int zLogicalIndex; /* Fix for 4888088 */ if (xLogicalIndex <= 0 || xLogicalIndex > MAX_ENTITY_INDEX) return (-1); /* End of Fix for 4888088 */ zRunner = gLogicalTableHead; while (zRunner) { zLogicalIndex = zRunner->entLogicalIndex; if (zLogicalIndex > 0) { if (zLogicalIndex == xLogicalIndex) return (-2); /* Entry is already live */ } if (zLogicalIndex == -(xLogicalIndex)) { zRunner->entLogicalIndex = xLogicalIndex; configChanged(); return (0); } zRunner = zRunner->pNextEntry; } return (-1); } entLogicalEntry_t* getLogicalTableEntry(int xLogicalIndex) { entLogicalEntry_t *zRunner; int zLogicalIndex; /* Fix for 4888088 */ if (xLogicalIndex <= 0 || xLogicalIndex > MAX_ENTITY_INDEX) return NULL; /* End of Fix for 4888088 */ zRunner = gLogicalTableHead; while (zRunner) { zLogicalIndex = zRunner->entLogicalIndex; if (zLogicalIndex > 0) { if (zLogicalIndex == xLogicalIndex) return zRunner; } if (zLogicalIndex == -(xLogicalIndex)) { return NULL; /* The stale entry exist, we can stop the search*/ } zRunner = zRunner->pNextEntry; } return NULL; } entLogicalEntry_t* getLogicalTableStaleEntry(int xLogicalIndex) { entLogicalEntry_t *zRunner; int zLogicalIndex; /* Fix for 4888088 */ if (xLogicalIndex <= 0 || xLogicalIndex > MAX_ENTITY_INDEX) return NULL; /* End of Fix for 4888088 */ zRunner = gLogicalTableHead; while (zRunner) { zLogicalIndex = zRunner->entLogicalIndex; if (zLogicalIndex < 0) { if (zLogicalIndex == -(xLogicalIndex)) return zRunner; } if (zLogicalIndex == xLogicalIndex) { return NULL; /* The live entry exist, we can stop the search*/ } zRunner = zRunner->pNextEntry; } return NULL; } int deleteLogicalTableEntry(int xLogicalIndex) { entLogicalEntry_t *zRunner, *temp, *prevEntry; int zLogicalIndex; /* Fix for 4888088 */ if (xLogicalIndex <= 0 || xLogicalIndex > MAX_ENTITY_INDEX) return -1; /* End of Fix for 4888088 */ zRunner = gLogicalTableHead; prevEntry = NULL; while (zRunner) { zLogicalIndex = zRunner->entLogicalIndex; if (zLogicalIndex > 0) { if (zLogicalIndex == xLogicalIndex) { /* Fix for 4918876: We need to delete the related entries */ /* first */ /* Delete all instances of this logical index in all other tables to maintain table integrity. Should we roll-back if a deletion fails, perhaps not */ deleteAliasMappingLogicalIndex( xLogicalIndex); /*Alias mapping*/ deleteLPMappingLogicalIndex( xLogicalIndex); /* LPTable */ /* End of Fix for 4918876 */ temp = zRunner->pNextEntry; zRunner->pNextEntry = NULL; if (prevEntry) prevEntry->pNextEntry = temp; else gLogicalTableHead = temp;; FreeLogicalEntry(zRunner); configChanged(); gLogicalTableSize--; return (0); } } if (zLogicalIndex == -(xLogicalIndex)) { return (-2); /* The stale entry exist, we can stop the search*/ } prevEntry = zRunner; zRunner = zRunner->pNextEntry; } return (-1); } int FreeLogicalEntry(entLogicalEntry_t *xEntry) { if (xEntry == NULL) return (-1); free(xEntry->entLogicalDescr); free(xEntry->entLogicalType); free(xEntry->entLogicalCommunity); free(xEntry->entLogicalTAddress); free(xEntry->entLogicalTDomain); free(xEntry->entLogicalContextEngineId); free(xEntry->entLogicalContextName); free(xEntry); xEntry = NULL; return (1); }