/* *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches. * *All right reserved * *File Name:traceRouteCtlTable.c *File Description:Rows of traceRouteCtlTable MIB add delete ans read. * Rows of traceRouteResultsTable MIB add and delete. * Rows of traceRouteProbeHistoryTable MIB add and delete. * Rows of traceRouteHopsTable MIB add and delete. * The main function is also here. * *Current Version:1.0 *Author:ChenJing *Date:2004.8.20 */ #include #include #include #include #include #include #ifndef NETSNMP_NO_WRITE_SUPPORT netsnmp_feature_require(header_complex_find_entry); #endif /* NETSNMP_NO_WRITE_SUPPORT */ #include "traceRouteCtlTable.h" #include "traceRouteResultsTable.h" #include "traceRouteProbeHistoryTable.h" #include "traceRouteHopsTable.h" #include "header_complex.h" oid traceRouteCtlTable_variables_oid[] = { 1, 3, 6, 1, 2, 1, 81, 1, 2 }; /* trap */ oid traceRoutePathChange[] = { 1, 3, 6, 1, 2, 1, 81, 0, 1 }; oid traceRouteTestFailed[] = { 1, 3, 6, 1, 2, 1, 81, 0, 2 }; oid traceRouteTestCompleted[] = { 1, 3, 6, 1, 2, 1, 81, 0, 3 }; struct variable2 traceRouteCtlTable_variables[] = { /* * magic number , variable type , ro/rw , callback fn , L, oidsuffix */ {COLUMN_TRACEROUTECTLTARGETADDRESSTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 3}}, {COLUMN_TRACEROUTECTLTARGETADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 4}}, {COLUMN_TRACEROUTECTLBYPASSROUTETABLE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 5}}, {COLUMN_TRACEROUTECTLDATASIZE, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 6}}, {COLUMN_TRACEROUTECTLTIMEOUT, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 7}}, {COLUMN_TRACEROUTECTLPROBESPERHOP, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 8}}, {COLUMN_TRACEROUTECTLPORT, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 9}}, {COLUMN_TRACEROUTECTLMAXTTL, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 10}}, {COLUMN_TRACEROUTECTLDSFIELD, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 11}}, {COLUMN_TRACEROUTECTLSOURCEADDRESSTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 12}}, {COLUMN_TRACEROUTECTLSOURCEADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 13}}, {COLUMN_TRACEROUTECTLIFINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 14}}, {COLUMN_TRACEROUTECTLMISCOPTIONS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 15}}, {COLUMN_TRACEROUTECTLMAXFAILURES, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 16}}, {COLUMN_TRACEROUTECTLDONTFRAGMENT, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 17}}, {COLUMN_TRACEROUTECTLINITIALTTL, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 18}}, {COLUMN_TRACEROUTECTLFREQUENCY, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 19}}, {COLUMN_TRACEROUTECTLSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 20}}, {COLUMN_TRACEROUTECTLADMINSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 21}}, {COLUMN_TRACEROUTECTLDESCR, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 22}}, {COLUMN_TRACEROUTECTLMAXROWS, ASN_UNSIGNED, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 23}}, {COLUMN_TRACEROUTECTLTRAPGENERATION, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 24}}, {COLUMN_TRACEROUTECTLCREATEHOPSENTRIES, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 25}}, {COLUMN_TRACEROUTECTLTYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 26}}, {COLUMN_TRACEROUTECTLROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, var_traceRouteCtlTable, 2, {1, 27}} }; /* * global storage of our data, saved in and configured by header_complex() */ struct header_complex_index *traceRouteCtlTableStorage = NULL; struct header_complex_index *traceRouteResultsTableStorage = NULL; struct header_complex_index *traceRouteProbeHistoryTableStorage = NULL; struct header_complex_index *traceRouteHopsTableStorage = NULL; static char * findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from); int traceRouteResultsTable_add(struct traceRouteCtlTable_data *thedata); int traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata); void init_traceRouteCtlTable(void) { DEBUGMSGTL(("traceRouteCtlTable", "initializing... ")); /* * register ourselves with the agent to handle our mib tree */ REGISTER_MIB("traceRouteCtlTable", traceRouteCtlTable_variables, variable2, traceRouteCtlTable_variables_oid); /* * register our config handler(s) to deal with registrations */ snmpd_register_config_handler("traceRouteCtlTable", parse_traceRouteCtlTable, NULL, NULL); /* * we need to be called back later to store our data */ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, store_traceRouteCtlTable, NULL); DEBUGMSGTL(("traceRouteCtlTable", "done.\n")); } static void init_trResultsTable_ipv4(char *host, struct traceRouteResultsTable_data *StorageTmp) { struct sockaddr whereto; /* Who to try to reach */ struct sockaddr_in *to = (struct sockaddr_in *) &whereto; struct hostinfo *hi; hi = gethostinfo(host); if (hi == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "hi calloc %s\n", strerror(errno))); exit(1); } setsin(to, hi->addrs[0]); if (inet_ntoa(to->sin_addr) == NULL) { StorageTmp->traceRouteResultsIpTgtAddrType = 0; StorageTmp->traceRouteResultsIpTgtAddr = strdup(""); StorageTmp->traceRouteResultsIpTgtAddrLen = 0; } else { StorageTmp->traceRouteResultsIpTgtAddrType = 1; StorageTmp->traceRouteResultsIpTgtAddr = (char *) malloc(sizeof(char) * (strlen(inet_ntoa(to->sin_addr)) + 1)); if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "traceRouteResultsIpTgtAddr malloc %s\n", strerror(errno))); exit(1); } memcpy(StorageTmp->traceRouteResultsIpTgtAddr, inet_ntoa(to->sin_addr), strlen(inet_ntoa(to->sin_addr)) + 1); StorageTmp->traceRouteResultsIpTgtAddr[strlen(inet_ntoa(to->sin_addr))] = '\0'; StorageTmp->traceRouteResultsIpTgtAddrLen = strlen(inet_ntoa(to->sin_addr)); } freehostinfo(hi); } static void init_trResultsTable_ipv6(char *host, struct traceRouteResultsTable_data *StorageTmp) { struct sockaddr_in6 whereto; /* Who to try to reach */ struct sockaddr_in6 *to = (struct sockaddr_in6 *) &whereto; struct hostent *hp = NULL; /* struct hostenv hp; */ char pa[64]; memset(pa, '\0', 64); to->sin6_family = AF_INET6; to->sin6_port = htons(33434); if (inet_pton(AF_INET6, host, &to->sin6_addr) > 0) { StorageTmp->traceRouteResultsIpTgtAddrType = 2; StorageTmp->traceRouteResultsIpTgtAddr = (char *) malloc(sizeof(char) * (strlen(host) + 1)); if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "traceRouteResultsIpTgtAddr malloc %s\n", strerror(errno))); exit(1); } memset(StorageTmp->traceRouteResultsIpTgtAddr, '\0', sizeof(char) * (strlen(host) + 1)); memcpy(StorageTmp->traceRouteResultsIpTgtAddr, host, strlen(host) + 1); StorageTmp->traceRouteResultsIpTgtAddr[strlen(host)] = '\0'; StorageTmp->traceRouteResultsIpTgtAddrLen = strlen(host); } else { hp = gethostbyname2(host, AF_INET6); if (hp != NULL) { const char *hostname; memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16); hostname = inet_ntop(AF_INET6, &to->sin6_addr, pa, 64); StorageTmp->traceRouteResultsIpTgtAddrType = 2; StorageTmp->traceRouteResultsIpTgtAddr = (char *) malloc(sizeof(char) * (strlen(hostname) + 1)); if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "traceRouteResultsIpTgtAddr malloc %s\n", strerror(errno))); exit(1); } memset(StorageTmp->traceRouteResultsIpTgtAddr, '\0', sizeof(char) * (strlen(host) + 1)); memcpy(StorageTmp->traceRouteResultsIpTgtAddr, hostname, strlen(hostname) + 1); StorageTmp->traceRouteResultsIpTgtAddr[strlen(hostname)] = '\0'; StorageTmp->traceRouteResultsIpTgtAddrLen = strlen(hostname); } else { DEBUGMSGTL(("traceRouteCtlTable", "traceroute: unknown host %s\n", host)); StorageTmp->traceRouteResultsIpTgtAddrType = 0; StorageTmp->traceRouteResultsIpTgtAddr = strdup(""); StorageTmp->traceRouteResultsIpTgtAddrLen = 0; } } } void init_trResultsTable(struct traceRouteCtlTable_data *item) { struct traceRouteResultsTable_data *StorageTmp = NULL; netsnmp_variable_list *vars = NULL; char *host = NULL; host = (char *) malloc(sizeof(char) * (item->traceRouteCtlTargetAddressLen + 1)); if (host == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "host calloc %s\n", strerror(errno))); exit(1); } memset(host, '\0', sizeof(char) * (item->traceRouteCtlTargetAddressLen + 1)); strcpy(host, item->traceRouteCtlTargetAddress); host[item->traceRouteCtlTargetAddressLen] = '\0'; StorageTmp = SNMP_MALLOC_STRUCT(traceRouteResultsTable_data); if (StorageTmp == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "StorageTmp malloc %s\n", strerror(errno))); exit(1); } StorageTmp->traceRouteCtlOwnerIndex = (char *) malloc(sizeof(char) * (item->traceRouteCtlOwnerIndexLen + 1)); if (StorageTmp->traceRouteCtlOwnerIndex == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "traceRouteCtlOwnerIndex malloc %s\n", strerror(errno))); exit(1); } memcpy(StorageTmp->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen + 1); StorageTmp->traceRouteCtlOwnerIndex[item->traceRouteCtlOwnerIndexLen] = '\0'; StorageTmp->traceRouteCtlOwnerIndexLen = item->traceRouteCtlOwnerIndexLen; StorageTmp->traceRouteCtlTestName = (char *) malloc(sizeof(char) * (item->traceRouteCtlTestNameLen + 1)); if (StorageTmp->traceRouteCtlTestName == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "traceRouteCtlTestName malloc %s\n", strerror(errno))); exit(1); } memcpy(StorageTmp->traceRouteCtlTestName, item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen + 1); StorageTmp->traceRouteCtlTestName[item->traceRouteCtlTestNameLen] = '\0'; StorageTmp->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen; StorageTmp->traceRouteResultsOperStatus = 1; switch (item->traceRouteCtlTargetAddressType) { case 1: case 16: init_trResultsTable_ipv4(host, StorageTmp); break; case 2: init_trResultsTable_ipv6(host, StorageTmp); break; } StorageTmp->traceRouteResultsCurHopCount = 0; StorageTmp->traceRouteResultsCurProbeCount = 0; StorageTmp->traceRouteResultsTestAttempts = 0; StorageTmp->traceRouteResultsTestSuccesses = 0; StorageTmp->traceRouteResultsLastGoodPathLen = 0; item->traceRouteResults = StorageTmp; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ if ((header_complex_get(traceRouteResultsTableStorage, vars)) != NULL) { traceRouteResultsTable_del(item); } snmp_free_varbind(vars); vars = NULL; if (item->traceRouteResults != NULL) { if (traceRouteResultsTable_add(item) != SNMPERR_SUCCESS) { DEBUGMSGTL(("traceRouteResultsTable", "init an entry error\n")); } } free(host); } int modify_trResultsOper(struct traceRouteCtlTable_data *thedata, long val) { netsnmp_variable_list *vars = NULL; struct traceRouteResultsTable_data *StorageTmp = NULL; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ if ((StorageTmp = header_complex_get(traceRouteResultsTableStorage, vars)) == NULL) { snmp_free_varbind(vars); vars = NULL; return SNMP_ERR_NOSUCHNAME; } else { StorageTmp->traceRouteResultsOperStatus = val; DEBUGMSGTL(("traceRouteResultsOperStatus", "done.\n")); snmp_free_varbind(vars); vars = NULL; return SNMPERR_SUCCESS; } } struct traceRouteCtlTable_data * create_traceRouteCtlTable_data(void) { struct traceRouteCtlTable_data *StorageNew = NULL; StorageNew = SNMP_MALLOC_STRUCT(traceRouteCtlTable_data); if (StorageNew == NULL) { exit(1); } StorageNew->traceRouteCtlTargetAddressType = 1; StorageNew->traceRouteCtlTargetAddress = strdup(""); StorageNew->traceRouteCtlTargetAddressLen = 0; StorageNew->traceRouteCtlByPassRouteTable = 2; StorageNew->traceRouteCtlDataSize = 0; StorageNew->traceRouteCtlTimeOut = 3; StorageNew->traceRouteCtlProbesPerHop = 3; StorageNew->traceRouteCtlPort = 33434; StorageNew->traceRouteCtlMaxTtl = 30; StorageNew->traceRouteCtlDSField = 0; StorageNew->traceRouteCtlSourceAddressType = 0; StorageNew->traceRouteCtlSourceAddress = strdup(""); StorageNew->traceRouteCtlSourceAddressLen = 0; StorageNew->traceRouteCtlIfIndex = 0; StorageNew->traceRouteCtlMiscOptions = strdup(""); StorageNew->traceRouteCtlMiscOptionsLen = 0; StorageNew->traceRouteCtlMaxFailures = 5; StorageNew->traceRouteCtlDontFragment = 2; StorageNew->traceRouteCtlInitialTtl = 1; StorageNew->traceRouteCtlFrequency = 0; StorageNew->traceRouteCtlStorageType = ST_NONVOLATILE; StorageNew->traceRouteCtlAdminStatus = 2; StorageNew->traceRouteCtlDescr = (char *) malloc(strlen("00") + 1); if (StorageNew->traceRouteCtlDescr == NULL) { exit(1); } memcpy(StorageNew->traceRouteCtlDescr, "00", strlen("00") + 1); StorageNew->traceRouteCtlDescr[strlen("00")] = '\0'; StorageNew->traceRouteCtlDescrLen = strlen(StorageNew->traceRouteCtlDescr); StorageNew->traceRouteCtlMaxRows = 50; StorageNew->traceRouteCtlTrapGeneration = strdup(""); StorageNew->traceRouteCtlTrapGenerationLen = 0; StorageNew->traceRouteCtlCreateHopsEntries = 2; StorageNew->traceRouteCtlType = calloc(1, sizeof(oid) * sizeof(2)); /* 0.0 */ StorageNew->traceRouteCtlTypeLen = 2; StorageNew->traceRouteResults = NULL; StorageNew->traceRouteProbeHis = NULL; StorageNew->traceRouteHops = NULL; StorageNew->storageType = ST_NONVOLATILE; /* StorageNew->traceRouteProbeHistoryMaxIndex=0; */ return StorageNew; } /* * traceRouteCtlTable_add(): adds a structure node to our data set */ int traceRouteCtlTable_add(struct traceRouteCtlTable_data *thedata) { netsnmp_variable_list *vars = NULL; DEBUGMSGTL(("traceRouteCtlTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlOperationName */ if (header_complex_add_data(&traceRouteCtlTableStorage, vars, thedata) == NULL) { vars = NULL; return SNMPERR_GENERR; } else { DEBUGMSGTL(("traceRouteCtlTable", "registered an entry\n")); DEBUGMSGTL(("traceRouteCtlTable", "done.\n")); vars = NULL; return SNMPERR_SUCCESS; } } int traceRouteResultsTable_add(struct traceRouteCtlTable_data *thedata) { netsnmp_variable_list *vars_list = NULL; struct traceRouteResultsTable_data *p = NULL; p = thedata->traceRouteResults; if (thedata->traceRouteResults != NULL) { snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ DEBUGMSGTL(("traceRouteResultsTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ header_complex_add_data(&traceRouteResultsTableStorage, vars_list, p); DEBUGMSGTL(("traceRouteResultsTable", "out finished\n")); vars_list = NULL; DEBUGMSGTL(("traceRouteResultsTable", "done.\n")); return SNMPERR_SUCCESS; } else { vars_list = NULL; DEBUGMSGTL(("traceRouteResultsTable", "error.\n")); return SNMP_ERR_INCONSISTENTNAME; } } int traceRouteProbeHistoryTable_add(struct traceRouteProbeHistoryTable_data *thedata) { netsnmp_variable_list *vars_list = NULL; if (thedata != NULL) { snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryIndex, sizeof(thedata->traceRouteProbeHistoryIndex)); /* traceRouteProbeHistoryIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryHopIndex, sizeof(thedata->traceRouteProbeHistoryHopIndex)); /* traceRouteProbeHistoryHopIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteProbeHistoryProbeIndex, sizeof(thedata->traceRouteProbeHistoryProbeIndex)); /* traceRouteProbeHistoryProbeIndex */ DEBUGMSGTL(("traceRouteProbeHistoryTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ if (header_complex_add_data (&traceRouteProbeHistoryTableStorage, vars_list, thedata) == NULL) { vars_list = NULL; return SNMP_ERR_INCONSISTENTNAME; } else { DEBUGMSGTL(("traceRouteProbeHistoryTable", "out finished\n")); vars_list = NULL; DEBUGMSGTL(("traceRouteProbeHistoryTable", "done.\n")); return SNMPERR_SUCCESS; } } else { return SNMP_ERR_INCONSISTENTNAME; } } int traceRouteProbeHistoryTable_addall(struct traceRouteCtlTable_data *thedata) { netsnmp_variable_list *vars_list = NULL; struct traceRouteProbeHistoryTable_data *p = NULL; p = thedata->traceRouteProbeHis; if (thedata->traceRouteProbeHis != NULL) do { snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryIndex, sizeof(p->traceRouteProbeHistoryIndex)); /* traceRouteProbeHistoryIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryHopIndex, sizeof(p->traceRouteProbeHistoryHopIndex)); /* traceRouteProbeHistoryHopIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteProbeHistoryProbeIndex, sizeof(p->traceRouteProbeHistoryProbeIndex)); /* traceRouteProbeHistoryProbeIndex */ DEBUGMSGTL(("traceRouteProbeHistoryTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ if (header_complex_add_data (&traceRouteProbeHistoryTableStorage, vars_list, p) == NULL) { vars_list = NULL; return SNMP_ERR_INCONSISTENTNAME; } else { struct header_complex_index *temp = NULL; temp = traceRouteProbeHistoryTableStorage; if (traceRouteProbeHistoryTableStorage != NULL) do { DEBUGMSGTL(("traceRouteProbeHistoryTable", "adding data,vars_oid=")); DEBUGMSGOID(("traceRouteProbeHistoryTable", temp->name, temp->namelen)); DEBUGMSGTL(("traceRouteProbeHistoryTable", "\n ")); temp = temp->next; } while (temp != NULL); DEBUGMSGTL(("traceRouteProbeHistoryTable", "out finished\n")); DEBUGMSGTL(("traceRouteProbeHistoryTable", "done.\n")); vars_list = NULL; return SNMPERR_SUCCESS; } p = p->next; } while (p != NULL); else { return SNMP_ERR_INCONSISTENTNAME; } } int traceRouteHopsTable_add(struct traceRouteHopsTable_data *thedata) { netsnmp_variable_list *vars_list = NULL; if (thedata != NULL) { snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &thedata->traceRouteHopsHopIndex, sizeof(thedata->traceRouteHopsHopIndex)); /* traceRouteHopsHopIndex */ DEBUGMSGTL(("traceRouteHopsTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ if (header_complex_add_data (&traceRouteHopsTableStorage, vars_list, thedata) == NULL) { vars_list = NULL; return SNMP_ERR_INCONSISTENTNAME; } else { DEBUGMSGTL(("traceRouteHopsTable", "out finished\n")); DEBUGMSGTL(("traceRouteHopsTable", "done.\n")); vars_list = NULL; return SNMPERR_SUCCESS; } } return SNMPERR_GENERR; } int traceRouteHopsTable_addall(struct traceRouteCtlTable_data *thedata) { netsnmp_variable_list *vars_list = NULL; struct traceRouteHopsTable_data *p = NULL; vars_list = NULL; p = thedata->traceRouteHops; if (thedata->traceRouteHops != NULL) { do { snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlOwnerIndex, p->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) p->traceRouteCtlTestName, p->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_UNSIGNED, (char *) &p->traceRouteHopsHopIndex, sizeof(p->traceRouteHopsHopIndex)); /* traceRouteHopsHopIndex */ DEBUGMSGTL(("traceRouteHopsTable", "adding data... ")); /* * add the index variables to the varbind list, which is * used by header_complex to index the data */ if (header_complex_add_data (&traceRouteHopsTableStorage, vars_list, p) == NULL) { vars_list = NULL; return SNMP_ERR_INCONSISTENTNAME; } else { struct header_complex_index *temp = NULL; temp = traceRouteHopsTableStorage; if (traceRouteHopsTableStorage != NULL) do { DEBUGMSGTL(("traceRouteProbeHistoryTable", "adding data,vars_oid=")); DEBUGMSGOID(("traceRouteProbeHistoryTable", temp->name, temp->namelen)); DEBUGMSGTL(("traceRouteProbeHistoryTable", "\n ")); temp = temp->next; } while (temp != NULL); DEBUGMSGTL(("traceRouteHopsTable", "out finished\n")); vars_list = NULL; } p = p->next; } while (p != NULL); DEBUGMSGTL(("traceRouteHopsTable", "done.\n")); return SNMPERR_SUCCESS; } else { return SNMP_ERR_INCONSISTENTNAME; } } unsigned long traceRouteProbeHistoryTable_count(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2 = NULL; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len; unsigned long count = 0; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); vars = NULL; for (hciptr2 = traceRouteProbeHistoryTableStorage; hciptr2 != NULL; hciptr2 = hciptr2->next) { if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { count = count + 1; } } return count; } unsigned long traceRouteHopsTable_count(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2 = NULL; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len; unsigned long count = 0; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlOperationName */ header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); vars = NULL; for (hciptr2 = traceRouteHopsTableStorage; hciptr2 != NULL; hciptr2 = hciptr2->next) { if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { count = count + 1; } } return count; } void traceRouteProbeHistoryTable_delLast(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2 = NULL; struct header_complex_index *hcilast = NULL; struct traceRouteProbeHistoryTable_data *StorageTmp = NULL; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len = 0; time_t last_time = 2147483647; time_t tp; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlOperationName */ memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN); header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); for (hcilast = hciptr2 = traceRouteProbeHistoryTableStorage; hciptr2 != NULL; hciptr2 = hciptr2->next) { if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { StorageTmp = header_complex_get_from_oid (traceRouteProbeHistoryTableStorage, hciptr2->name, hciptr2->namelen); tp = StorageTmp->traceRouteProbeHistoryTime_time; if (last_time > tp) { last_time = tp; hcilast = hciptr2; } } } header_complex_extract_entry(&traceRouteProbeHistoryTableStorage, hcilast); DEBUGMSGTL(("traceRouteProbeHistoryTable", "delete the last one success!\n")); vars = NULL; } void traceRouteCtlTable_cleaner(struct header_complex_index *thestuff) { struct header_complex_index *hciptr, *nhciptr; struct traceRouteCtlTable_data *StorageDel; DEBUGMSGTL(("traceRouteCtlTable", "cleanerout ")); for (hciptr = thestuff; hciptr; hciptr = nhciptr) { nhciptr = hciptr->next; StorageDel = header_complex_extract_entry(&traceRouteCtlTableStorage, hciptr); if (StorageDel != NULL) { free(StorageDel->traceRouteCtlOwnerIndex); free(StorageDel->traceRouteCtlTestName); free(StorageDel->traceRouteCtlTargetAddress); free(StorageDel->traceRouteCtlSourceAddress); free(StorageDel->traceRouteCtlMiscOptions); free(StorageDel->traceRouteCtlDescr); free(StorageDel->traceRouteCtlTrapGeneration); free(StorageDel->traceRouteCtlType); free(StorageDel); } DEBUGMSGTL(("traceRouteCtlTable", "cleaner ")); } } /* * parse_mteObjectsTable(): * parses .conf file entries needed to configure the mib. */ void parse_traceRouteCtlTable(const char *token, char *line) { size_t tmpint; struct traceRouteCtlTable_data *StorageTmp = SNMP_MALLOC_STRUCT(traceRouteCtlTable_data); DEBUGMSGTL(("traceRouteCtlTable", "parsing config... ")); if (StorageTmp == NULL) { config_perror("malloc failure"); return; } line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlOwnerIndex, &StorageTmp->traceRouteCtlOwnerIndexLen); if (StorageTmp->traceRouteCtlOwnerIndex == NULL) { config_perror("invalid specification for traceRouteCtlOwnerIndex"); free(StorageTmp); return; } line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlTestName, &StorageTmp->traceRouteCtlTestNameLen); if (StorageTmp->traceRouteCtlTestName == NULL) { config_perror("invalid specification for traceRouteCtlTestName"); free(StorageTmp); return; } line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlTargetAddressType, &tmpint); line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlTargetAddress, &StorageTmp->traceRouteCtlTargetAddressLen); if (StorageTmp->traceRouteCtlTargetAddress == NULL) { config_perror ("invalid specification for traceRouteCtlTargetAddress"); free(StorageTmp); return; } line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlByPassRouteTable, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlDataSize, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlTimeOut, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlProbesPerHop, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlPort, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlMaxTtl, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlDSField, &tmpint); line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlSourceAddressType, &tmpint); line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlSourceAddress, &StorageTmp->traceRouteCtlSourceAddressLen); if (StorageTmp->traceRouteCtlSourceAddress == NULL) { config_perror ("invalid specification for traceRouteCtlSourceAddress"); free(StorageTmp); return; } line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlIfIndex, &tmpint); line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlMiscOptions, &StorageTmp->traceRouteCtlMiscOptionsLen); if (StorageTmp->traceRouteCtlMiscOptions == NULL) { config_perror ("invalid specification for traceRouteCtlMiscOptions"); free(StorageTmp); return; } line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlMaxFailures, &tmpint); line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlDontFragment, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlInitialTtl, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlFrequency, &tmpint); line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlStorageType, &tmpint); line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlAdminStatus, &tmpint); line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlDescr, &StorageTmp->traceRouteCtlDescrLen); if (StorageTmp->traceRouteCtlDescr == NULL) { config_perror("invalid specification for traceRouteCtlTrapDescr"); free(StorageTmp); return; } line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteCtlMaxRows, &tmpint); line = read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->traceRouteCtlTrapGeneration, &StorageTmp->traceRouteCtlTrapGenerationLen); if (StorageTmp->traceRouteCtlTrapGeneration == NULL) { config_perror ("invalid specification for traceRouteCtlTrapGeneration"); free(StorageTmp); return; } line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlCreateHopsEntries, &tmpint); line = read_config_read_data(ASN_OBJECT_ID, line, &StorageTmp->traceRouteCtlType, &StorageTmp->traceRouteCtlTypeLen); if (StorageTmp->traceRouteCtlType == NULL) { config_perror("invalid specification for traceRouteCtlType"); free(StorageTmp); return; } line = read_config_read_data(ASN_INTEGER, line, &StorageTmp->traceRouteCtlRowStatus, &tmpint); line = read_config_read_data(ASN_UNSIGNED, line, &StorageTmp->traceRouteProbeHistoryMaxIndex, &tmpint); StorageTmp->storageType = ST_NONVOLATILE; traceRouteCtlTable_add(StorageTmp); /* traceRouteCtlTable_cleaner(traceRouteCtlTableStorage); */ DEBUGMSGTL(("traceRouteCtlTable", "done.\n")); } /* * store_traceRouteCtlTable(): * stores .conf file entries needed to configure the mib. */ int store_traceRouteCtlTable(int majorID, int minorID, void *serverarg, void *clientarg) { char line[SNMP_MAXBUF]; char *cptr = NULL; size_t tmpint; struct traceRouteCtlTable_data *StorageTmp = NULL; struct header_complex_index *hcindex = NULL; DEBUGMSGTL(("traceRouteCtlTable", "storing data... ")); for (hcindex = traceRouteCtlTableStorage; hcindex != NULL; hcindex = hcindex->next) { StorageTmp = (struct traceRouteCtlTable_data *) hcindex->data; if (StorageTmp->storageType != ST_READONLY) { memset(line, 0, sizeof(line)); strcat(line, "traceRouteCtlTable "); cptr = line + strlen(line); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp-> traceRouteCtlOwnerIndex, &StorageTmp-> traceRouteCtlOwnerIndexLen); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp->traceRouteCtlTestName, &StorageTmp-> traceRouteCtlTestNameLen); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlTargetAddressType, &tmpint); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp-> traceRouteCtlTargetAddress, &StorageTmp-> traceRouteCtlTargetAddressLen); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlByPassRouteTable, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlDataSize, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlTimeOut, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp-> traceRouteCtlProbesPerHop, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlPort, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlMaxTtl, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlDSField, &tmpint); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlSourceAddressType, &tmpint); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp-> traceRouteCtlSourceAddress, &StorageTmp-> traceRouteCtlSourceAddressLen); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp->traceRouteCtlIfIndex, &tmpint); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp-> traceRouteCtlMiscOptions, &StorageTmp-> traceRouteCtlMiscOptionsLen); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp-> traceRouteCtlMaxFailures, &tmpint); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlDontFragment, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp-> traceRouteCtlInitialTtl, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlFrequency, &tmpint); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlStorageType, &tmpint); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlAdminStatus, &tmpint); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp->traceRouteCtlDescr, &StorageTmp->traceRouteCtlDescrLen); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp->traceRouteCtlMaxRows, &tmpint); cptr = read_config_store_data(ASN_OCTET_STR, cptr, &StorageTmp-> traceRouteCtlTrapGeneration, &StorageTmp-> traceRouteCtlTrapGenerationLen); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp-> traceRouteCtlCreateHopsEntries, &tmpint); cptr = read_config_store_data(ASN_OBJECT_ID, cptr, &StorageTmp->traceRouteCtlType, &StorageTmp->traceRouteCtlTypeLen); cptr = read_config_store_data(ASN_INTEGER, cptr, &StorageTmp->traceRouteCtlRowStatus, &tmpint); cptr = read_config_store_data(ASN_UNSIGNED, cptr, &StorageTmp-> traceRouteProbeHistoryMaxIndex, &tmpint); snmpd_store_config(line); } } DEBUGMSGTL(("traceRouteCtlTable", "done.\n")); return SNMPERR_SUCCESS; } /* * var_traceRouteCtlTable(): * Handle this table separately from the scalar value case. * The workings of this are basically the same as for var_mteObjectsTable above. */ unsigned char * var_traceRouteCtlTable(struct variable *vp, oid * name, size_t *length, int exact, size_t *var_len, WriteMethod ** write_method) { struct traceRouteCtlTable_data *StorageTmp = NULL; /* * this assumes you have registered all your data properly */ if ((StorageTmp = header_complex(traceRouteCtlTableStorage, vp, name, length, exact, var_len, write_method)) == NULL) { if (vp->magic == COLUMN_TRACEROUTECTLROWSTATUS) *write_method = write_traceRouteCtlRowStatus; return NULL; } /* * this is where we do the value assignments for the mib results. */ switch (vp->magic) { case COLUMN_TRACEROUTECTLTARGETADDRESSTYPE: *write_method = write_traceRouteCtlTargetAddressType; *var_len = sizeof(StorageTmp->traceRouteCtlTargetAddressType); return (u_char *) & StorageTmp->traceRouteCtlTargetAddressType; case COLUMN_TRACEROUTECTLTARGETADDRESS: *write_method = write_traceRouteCtlTargetAddress; *var_len = (StorageTmp->traceRouteCtlTargetAddressLen); return (u_char *) StorageTmp->traceRouteCtlTargetAddress; case COLUMN_TRACEROUTECTLBYPASSROUTETABLE: *write_method = write_traceRouteCtlByPassRouteTable; *var_len = sizeof(StorageTmp->traceRouteCtlByPassRouteTable); return (u_char *) & StorageTmp->traceRouteCtlByPassRouteTable; case COLUMN_TRACEROUTECTLDATASIZE: *write_method = write_traceRouteCtlDataSize; *var_len = sizeof(StorageTmp->traceRouteCtlDataSize); return (u_char *) & StorageTmp->traceRouteCtlDataSize; case COLUMN_TRACEROUTECTLTIMEOUT: *write_method = write_traceRouteCtlTimeOut; *var_len = sizeof(StorageTmp->traceRouteCtlTimeOut); return (u_char *) & StorageTmp->traceRouteCtlTimeOut; case COLUMN_TRACEROUTECTLPROBESPERHOP: *write_method = write_traceRouteCtlProbesPerHop; *var_len = sizeof(StorageTmp->traceRouteCtlProbesPerHop); return (u_char *) & StorageTmp->traceRouteCtlProbesPerHop; case COLUMN_TRACEROUTECTLPORT: *write_method = write_traceRouteCtlPort; *var_len = sizeof(StorageTmp->traceRouteCtlPort); return (u_char *) & StorageTmp->traceRouteCtlPort; case COLUMN_TRACEROUTECTLMAXTTL: *write_method = write_traceRouteCtlMaxTtl; *var_len = sizeof(StorageTmp->traceRouteCtlMaxTtl); return (u_char *) & StorageTmp->traceRouteCtlMaxTtl; case COLUMN_TRACEROUTECTLDSFIELD: *write_method = write_traceRouteCtlDSField; *var_len = sizeof(StorageTmp->traceRouteCtlDSField); return (u_char *) & StorageTmp->traceRouteCtlDSField; case COLUMN_TRACEROUTECTLSOURCEADDRESSTYPE: *write_method = write_traceRouteCtlSourceAddressType; *var_len = sizeof(StorageTmp->traceRouteCtlSourceAddressType); return (u_char *) & StorageTmp->traceRouteCtlSourceAddressType; case COLUMN_TRACEROUTECTLSOURCEADDRESS: *write_method = write_traceRouteCtlSourceAddress; *var_len = (StorageTmp->traceRouteCtlSourceAddressLen); return (u_char *) StorageTmp->traceRouteCtlSourceAddress; case COLUMN_TRACEROUTECTLIFINDEX: *write_method = write_traceRouteCtlIfIndex; *var_len = sizeof(StorageTmp->traceRouteCtlIfIndex); return (u_char *) & StorageTmp->traceRouteCtlIfIndex; case COLUMN_TRACEROUTECTLMISCOPTIONS: *write_method = write_traceRouteCtlMiscOptions; *var_len = (StorageTmp->traceRouteCtlMiscOptionsLen); return (u_char *) StorageTmp->traceRouteCtlMiscOptions; case COLUMN_TRACEROUTECTLMAXFAILURES: *write_method = write_traceRouteCtlMaxFailures; *var_len = sizeof(StorageTmp->traceRouteCtlMaxFailures); return (u_char *) & StorageTmp->traceRouteCtlMaxFailures; case COLUMN_TRACEROUTECTLDONTFRAGMENT: *write_method = write_traceRouteCtlDontFragment; *var_len = sizeof(StorageTmp->traceRouteCtlDontFragment); return (u_char *) & StorageTmp->traceRouteCtlDontFragment; case COLUMN_TRACEROUTECTLINITIALTTL: *write_method = write_traceRouteCtlInitialTtl; *var_len = sizeof(StorageTmp->traceRouteCtlInitialTtl); return (u_char *) & StorageTmp->traceRouteCtlInitialTtl; case COLUMN_TRACEROUTECTLFREQUENCY: *write_method = write_traceRouteCtlFrequency; *var_len = sizeof(StorageTmp->traceRouteCtlFrequency); return (u_char *) & StorageTmp->traceRouteCtlFrequency; case COLUMN_TRACEROUTECTLSTORAGETYPE: *write_method = write_traceRouteCtlStorageType; *var_len = sizeof(StorageTmp->traceRouteCtlStorageType); return (u_char *) & StorageTmp->traceRouteCtlStorageType; case COLUMN_TRACEROUTECTLADMINSTATUS: *write_method = write_traceRouteCtlAdminStatus; *var_len = sizeof(StorageTmp->traceRouteCtlAdminStatus); return (u_char *) & StorageTmp->traceRouteCtlAdminStatus; case COLUMN_TRACEROUTECTLDESCR: *write_method = write_traceRouteCtlDescr; *var_len = (StorageTmp->traceRouteCtlDescrLen); return (u_char *) StorageTmp->traceRouteCtlDescr; case COLUMN_TRACEROUTECTLMAXROWS: *write_method = write_traceRouteCtlMaxRows; *var_len = sizeof(StorageTmp->traceRouteCtlMaxRows); return (u_char *) & StorageTmp->traceRouteCtlMaxRows; case COLUMN_TRACEROUTECTLTRAPGENERATION: *write_method = write_traceRouteCtlTrapGeneration; *var_len = (StorageTmp->traceRouteCtlTrapGenerationLen); return (u_char *) StorageTmp->traceRouteCtlTrapGeneration; case COLUMN_TRACEROUTECTLCREATEHOPSENTRIES: *write_method = write_traceRouteCtlCreateHopsEntries; *var_len = sizeof(StorageTmp->traceRouteCtlCreateHopsEntries); return (u_char *) & StorageTmp->traceRouteCtlCreateHopsEntries; case COLUMN_TRACEROUTECTLTYPE: *write_method = write_traceRouteCtlType; *var_len = (StorageTmp->traceRouteCtlTypeLen) * sizeof(oid); return (u_char *) StorageTmp->traceRouteCtlType; case COLUMN_TRACEROUTECTLROWSTATUS: *write_method = write_traceRouteCtlRowStatus; *var_len = sizeof(StorageTmp->traceRouteCtlRowStatus); return (u_char *) & StorageTmp->traceRouteCtlRowStatus; default: ERROR_MSG(""); } return NULL; } int traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2, *nhciptr2; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len = 0; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN); header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); for (hciptr2 = traceRouteResultsTableStorage; hciptr2; hciptr2 = nhciptr2) { nhciptr2 = hciptr2->next; if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { header_complex_extract_entry(&traceRouteResultsTableStorage, hciptr2); DEBUGMSGTL(("traceRouteResultsTable", "delete success!\n")); } } vars = NULL; return SNMPERR_SUCCESS; } int traceRouteProbeHistoryTable_del(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2, *nhciptr2; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len = 0; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlOperationName */ memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN); header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); for (hciptr2 = traceRouteProbeHistoryTableStorage; hciptr2; hciptr2 = nhciptr2) { nhciptr2 = hciptr2->next; if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { header_complex_extract_entry(&traceRouteProbeHistoryTableStorage, hciptr2); DEBUGMSGTL(("traceRouteProbeHistoryTable", "delete success!\n")); } } vars = NULL; return SNMPERR_SUCCESS; } int traceRouteHopsTable_del(struct traceRouteCtlTable_data *thedata) { struct header_complex_index *hciptr2, *nhciptr2; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len = 0; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ memset(newoid, '\0', sizeof(oid) * MAX_OID_LEN); header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); for (hciptr2 = traceRouteHopsTableStorage; hciptr2; hciptr2 = nhciptr2) { nhciptr2 = hciptr2->next; if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len) == 0) { header_complex_extract_entry(&traceRouteHopsTableStorage, hciptr2); DEBUGMSGTL(("traceRouteHopsTable", "delete success!\n")); } } vars = NULL; return SNMPERR_SUCCESS; } /* * send trap */ void send_traceRoute_trap(struct traceRouteCtlTable_data *item, oid * trap_oid, size_t trap_oid_len) { static oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; /* snmpTrapIOD.0 */ struct traceRouteHopsTable_data *StorageHops = NULL; netsnmp_variable_list *var_list = NULL; netsnmp_variable_list *vars = NULL; netsnmp_variable_list *var_hops = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len = 0; oid indexoid[MAX_OID_LEN]; size_t indexoid_len = 0; struct header_complex_index *hciptr; oid tempoid[MAX_OID_LEN]; size_t tempoid_len = 0; oid traceRouteCtlTargetAddress[] = { 1, 3, 6, 1, 2, 1, 81, 1, 2, 1, 4 }; oid traceRouteHopsIpTgAddress[] = { 1, 3, 6, 1, 2, 1, 81, 1, 5, 1, 3 }; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ /* * snmpTrap oid */ snmp_varlist_add_variable(&var_list, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid), ASN_OBJECT_ID, (u_char *) trap_oid, trap_oid_len * sizeof(oid)); /* * traceRouteCtlTargetAddress */ memset(newoid, '\0', MAX_OID_LEN * sizeof(oid)); header_complex_generate_oid(newoid, &newoid_len, traceRouteCtlTargetAddress, sizeof(traceRouteCtlTargetAddress) / sizeof(oid), vars); snmp_varlist_add_variable(&var_list, newoid, newoid_len, ASN_OCTET_STR, (u_char *) item->traceRouteCtlTargetAddress, item->traceRouteCtlTargetAddressLen); for (hciptr = traceRouteHopsTableStorage; hciptr != NULL; hciptr = hciptr->next) { memset(indexoid, '\0', MAX_OID_LEN * sizeof(oid)); header_complex_generate_oid(indexoid, &indexoid_len, NULL, 0, vars); if (snmp_oid_compare (indexoid, indexoid_len, hciptr->name, indexoid_len) == 0) { StorageHops = (struct traceRouteHopsTable_data *) header_complex_get_from_oid(traceRouteHopsTableStorage, hciptr->name, hciptr->namelen); memset(tempoid, '\0', MAX_OID_LEN * sizeof(oid)); header_complex_generate_oid(tempoid, &tempoid_len, traceRouteHopsIpTgAddress, sizeof(traceRouteHopsIpTgAddress) / sizeof(oid), vars); snmp_varlist_add_variable(&var_hops, NULL, 0, ASN_UNSIGNED, (char *) &StorageHops->traceRouteHopsHopIndex, sizeof(StorageHops->traceRouteHopsHopIndex)); /* traceRouteCtlTestName */ memset(newoid, '\0', MAX_OID_LEN * sizeof(oid)); header_complex_generate_oid(newoid, &newoid_len, tempoid, tempoid_len, var_hops); snmp_varlist_add_variable(&var_list, newoid, newoid_len, ASN_OCTET_STR, (u_char *) StorageHops-> traceRouteHopsIpTgtAddress, StorageHops-> traceRouteHopsIpTgtAddressLen); var_hops = NULL; } } /* * XXX: stuff based on event table */ DEBUGMSG(("pingTest:send_traceRoute_trap", "success!\n")); send_v2trap(var_list); snmp_free_varbind(vars); vars = NULL; snmp_free_varbind(var_list); var_list = NULL; } int write_traceRouteCtlTargetAddressType(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddressType not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlTargetAddressType; StorageTmp->traceRouteCtlTargetAddressType = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlTargetAddressType = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlTargetAddress(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 char *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlTargetAddress; tmplen = StorageTmp->traceRouteCtlTargetAddressLen; StorageTmp->traceRouteCtlTargetAddress = (char *) malloc(var_val_len + 1); if (StorageTmp->traceRouteCtlTargetAddress == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlTargetAddress, var_val, var_val_len); StorageTmp->traceRouteCtlTargetAddress[var_val_len] = '\0'; StorageTmp->traceRouteCtlTargetAddressLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlTargetAddress); StorageTmp->traceRouteCtlTargetAddress = tmpvar; StorageTmp->traceRouteCtlTargetAddressLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlByPassRouteTable(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddressType not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlByPassRouteTable; StorageTmp->traceRouteCtlByPassRouteTable = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlByPassRouteTable = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlDataSize(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDataSize not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlDataSize; if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 65507) StorageTmp->traceRouteCtlDataSize = *((long *) var_val); else StorageTmp->traceRouteCtlDataSize = 56; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlDataSize = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlTimeOut(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDataSize not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlTimeOut; if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 60) StorageTmp->traceRouteCtlTimeOut = *((long *) var_val); else StorageTmp->traceRouteCtlTimeOut = 3; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlTimeOut = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlProbesPerHop(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDataSize not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlProbesPerHop; if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 10) StorageTmp->traceRouteCtlProbesPerHop = *((long *) var_val); else StorageTmp->traceRouteCtlProbesPerHop = 3; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlProbesPerHop = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlPort(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddressType not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlPort; StorageTmp->traceRouteCtlPort = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlPort = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlMaxTtl(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDataSize not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlMaxTtl; if ((*((long *) var_val)) >= 1 && (*((long *) var_val)) <= 255) StorageTmp->traceRouteCtlMaxTtl = *((long *) var_val); else StorageTmp->traceRouteCtlMaxTtl = 30; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlMaxTtl = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlDSField(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDataSize not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlDSField; StorageTmp->traceRouteCtlDSField = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlDSField = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlSourceAddressType(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlMaxRows not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlSourceAddressType; StorageTmp->traceRouteCtlSourceAddressType = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlSourceAddressType = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlSourceAddress(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 char *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlSourceAddress; tmplen = StorageTmp->traceRouteCtlSourceAddressLen; StorageTmp->traceRouteCtlSourceAddress = (char *) malloc(var_val_len + 1); if (StorageTmp->traceRouteCtlSourceAddress == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlSourceAddress, var_val, var_val_len + 1); StorageTmp->traceRouteCtlSourceAddress[var_val_len] = '\0'; StorageTmp->traceRouteCtlSourceAddressLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlSourceAddress); StorageTmp->traceRouteCtlSourceAddress = tmpvar; StorageTmp->traceRouteCtlSourceAddressLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlIfIndex(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlMaxRows not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlIfIndex; StorageTmp->traceRouteCtlIfIndex = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlIfIndex = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlMiscOptions(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 char *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlMiscOptions; tmplen = StorageTmp->traceRouteCtlMiscOptionsLen; StorageTmp->traceRouteCtlMiscOptions = (char *) malloc(var_val_len + 1); if (StorageTmp->traceRouteCtlMiscOptions == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlMiscOptions, var_val, var_val_len + 1); StorageTmp->traceRouteCtlMiscOptions[var_val_len] = '\0'; StorageTmp->traceRouteCtlMiscOptionsLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlMiscOptions); StorageTmp->traceRouteCtlMiscOptions = tmpvar; StorageTmp->traceRouteCtlMiscOptionsLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlMaxFailures(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlTrapTestFailureFilter not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlMaxFailures; if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 15) StorageTmp->traceRouteCtlMaxFailures = *((long *) var_val); else StorageTmp->traceRouteCtlMaxFailures = 1; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlMaxFailures = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlDontFragment(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlMaxRows not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlDontFragment; StorageTmp->traceRouteCtlDontFragment = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlDontFragment = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlInitialTtl(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlTrapTestFailureFilter not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlInitialTtl; if ((*((long *) var_val)) >= 0 && (*((long *) var_val)) <= 255) StorageTmp->traceRouteCtlInitialTtl = *((long *) var_val); else StorageTmp->traceRouteCtlInitialTtl = 1; break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlInitialTtl = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlFrequency(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlSourceAddressType not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlFrequency; StorageTmp->traceRouteCtlFrequency = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlFrequency = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlStorageType(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 size_t tmpvar; int set_value; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } set_value = *((long *) var_val); switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlMaxRows not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } if ((StorageTmp->traceRouteCtlStorageType == 2 || StorageTmp->traceRouteCtlStorageType == 3) && (set_value == 4 || set_value == 5)) { return SNMP_ERR_WRONGVALUE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlStorageType; StorageTmp->traceRouteCtlStorageType = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlStorageType = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlAdminStatus(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; netsnmp_variable_list *vars = NULL; struct traceRouteResultsTable_data *StorageNew = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlIfIndex not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlAdminStatus; StorageTmp->traceRouteCtlAdminStatus = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlAdminStatus = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlOwnerIndex, StorageTmp->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlTestName, StorageTmp->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ StorageNew = header_complex_get(traceRouteResultsTableStorage, vars); if (StorageTmp->traceRouteCtlAdminStatus == 1 && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { if (StorageNew == NULL) init_trResultsTable(StorageTmp); else { StorageTmp->traceRouteResults-> traceRouteResultsOperStatus = 1; modify_trResultsOper(StorageTmp, 1); } if (StorageTmp->traceRouteCtlFrequency != 0) StorageTmp->timer_id = snmp_alarm_register(StorageTmp->traceRouteCtlFrequency, SA_REPEAT, run_traceRoute, StorageTmp); else StorageTmp->timer_id = snmp_alarm_register(1, 0, run_traceRoute, StorageTmp); } else if (StorageTmp->traceRouteCtlAdminStatus == 2 && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { snmp_alarm_unregister(StorageTmp->timer_id); if (StorageNew == NULL) init_trResultsTable(StorageTmp); else { StorageTmp->traceRouteResults-> traceRouteResultsOperStatus = 2; modify_trResultsOper(StorageTmp, 2); } } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlDescr(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 char *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlDescr; tmplen = StorageTmp->traceRouteCtlDescrLen; StorageTmp->traceRouteCtlDescr = (char *) malloc(var_val_len + 1); if (StorageTmp->traceRouteCtlDescr == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlDescr, var_val, var_val_len + 1); StorageTmp->traceRouteCtlDescr[var_val_len] = '\0'; StorageTmp->traceRouteCtlDescrLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlDescr); StorageTmp->traceRouteCtlDescr = tmpvar; StorageTmp->traceRouteCtlDescrLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlMaxRows(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_UNSIGNED) { snmp_log(LOG_ERR, "write to traceRouteCtlDSField not ASN_UNSIGNED\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlMaxRows; StorageTmp->traceRouteCtlMaxRows = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlMaxRows = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlTrapGeneration(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 char *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "write to traceRouteCtlTargetAddress not ASN_OCTET_STR\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlTrapGeneration; tmplen = StorageTmp->traceRouteCtlTrapGenerationLen; StorageTmp->traceRouteCtlTrapGeneration = (char *) malloc(var_val_len + 1); if (StorageTmp->traceRouteCtlTrapGeneration == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlTrapGeneration, var_val, var_val_len + 1); StorageTmp->traceRouteCtlTrapGeneration[var_val_len] = '\0'; StorageTmp->traceRouteCtlTrapGenerationLen = var_val_len; break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlTrapGeneration); StorageTmp->traceRouteCtlTrapGeneration = tmpvar; StorageTmp->traceRouteCtlTrapGenerationLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlCreateHopsEntries(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 size_t tmpvar; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "write to traceRouteCtlDSField not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in objid for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlCreateHopsEntries; StorageTmp->traceRouteCtlCreateHopsEntries = *((long *) var_val); break; case UNDO: /* * Back out any changes made in the ACTION case */ StorageTmp->traceRouteCtlCreateHopsEntries = tmpvar; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlType(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 oid *tmpvar; static size_t tmplen; struct traceRouteCtlTable_data *StorageTmp = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); if ((StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL)) == NULL) return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */ if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: if (var_val_type != ASN_OBJECT_ID) { snmp_log(LOG_ERR, "write to traceRouteCtlType not ASN_OBJECT_ID\n"); return SNMP_ERR_WRONGTYPE; } break; case RESERVE2: /* * memory reseveration, final preparation... */ break; case FREE: /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in long_ret for * you to use, and you have just been asked to do something with * it. Note that anything done here must be reversable in the UNDO case */ tmpvar = StorageTmp->traceRouteCtlType; tmplen = StorageTmp->traceRouteCtlTypeLen; StorageTmp->traceRouteCtlType = (oid *) malloc(var_val_len); if (StorageTmp->traceRouteCtlType == NULL) { exit(1); } memcpy(StorageTmp->traceRouteCtlType, var_val, var_val_len); StorageTmp->traceRouteCtlTypeLen = var_val_len / sizeof(oid); break; case UNDO: /* * Back out any changes made in the ACTION case */ SNMP_FREE(StorageTmp->traceRouteCtlType); StorageTmp->traceRouteCtlType = tmpvar; StorageTmp->traceRouteCtlTypeLen = tmplen; break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ SNMP_FREE(tmpvar); snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } int write_traceRouteCtlRowStatus(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 traceRouteCtlTable_data *StorageTmp = NULL; static struct traceRouteCtlTable_data *StorageNew = NULL; static struct traceRouteCtlTable_data *StorageDel = NULL; size_t newlen = name_len - (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1); static int old_value; int set_value; static netsnmp_variable_list *vars = NULL; struct header_complex_index *hciptr = NULL; StorageTmp = header_complex(traceRouteCtlTableStorage, NULL, &name[sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL); if (var_val_type != ASN_INTEGER || var_val == NULL) { snmp_log(LOG_ERR, "write to traceRouteCtlRowStatus not ASN_INTEGER\n"); return SNMP_ERR_WRONGTYPE; } if (StorageTmp && StorageTmp->storageType == ST_READONLY) { return SNMP_ERR_NOTWRITABLE; } set_value = *((long *) var_val); /* * check legal range, and notReady is reserved for us, not a user */ if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) return SNMP_ERR_INCONSISTENTVALUE; switch (action) { case RESERVE1: /* * stage one: test validity */ if (StorageTmp == NULL) { /* * create the row now? */ /* * ditch illegal values now */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } /* * destroying a non-existent row is actually legal */ if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * illegal creation values */ if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) { return SNMP_ERR_INCONSISTENTVALUE; } } else { /* * row exists. Check for a valid state change */ if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) { /* * can't create a row that exists */ return SNMP_ERR_INCONSISTENTVALUE; } /* * XXX: interaction with row storage type needed */ if (StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE && set_value != RS_DESTROY) { /* * "Once made active an entry may not be modified except to * delete it." XXX: doesn't this in fact apply to ALL * columns of the table and not just this one? */ return SNMP_ERR_INCONSISTENTVALUE; } if (StorageTmp->storageType != ST_NONVOLATILE) { return SNMP_ERR_NOTWRITABLE; } } break; case RESERVE2: /* * memory reseveration, final preparation... */ if (StorageTmp == NULL) { if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * creation */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* traceRouteCtlTestName */ if (header_complex_parse_oid (& (name [sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 2]), newlen, vars) != SNMPERR_SUCCESS) { /* * XXX: free, zero vars */ return SNMP_ERR_INCONSISTENTNAME; } StorageNew = create_traceRouteCtlTable_data(); if (vars->val_len <= 32) { StorageNew->traceRouteCtlOwnerIndex = malloc(vars->val_len + 1); memcpy(StorageNew->traceRouteCtlOwnerIndex, vars->val.string, vars->val_len); StorageNew->traceRouteCtlOwnerIndex[vars->val_len] = '\0'; StorageNew->traceRouteCtlOwnerIndexLen = vars->val_len; } else { StorageNew->traceRouteCtlOwnerIndex = malloc(33); memcpy(StorageNew->traceRouteCtlOwnerIndex, vars->val.string, 32); StorageNew->traceRouteCtlOwnerIndex[32] = '\0'; StorageNew->traceRouteCtlOwnerIndexLen = 32; } vars = vars->next_variable; if (vars->val_len <= 32) { StorageNew->traceRouteCtlTestName = malloc(vars->val_len + 1); memcpy(StorageNew->traceRouteCtlTestName, vars->val.string, vars->val_len); StorageNew->traceRouteCtlTestName[vars->val_len] = '\0'; StorageNew->traceRouteCtlTestNameLen = vars->val_len; } else { StorageNew->traceRouteCtlTestName = malloc(33); memcpy(StorageNew->traceRouteCtlTestName, vars->val.string, 32); StorageNew->traceRouteCtlTestName[32] = '\0'; StorageNew->traceRouteCtlTestNameLen = 32; } vars = vars->next_variable; /* * XXX: fill in default row values here into StorageNew */ StorageNew->traceRouteCtlRowStatus = set_value; /* * XXX: free, zero vars, no longer needed? */ } snmp_free_varbind(vars); vars = NULL; break; case FREE: /* * XXX: free, zero vars */ snmp_free_varbind(vars); vars = NULL; /* * Release any resources that have been allocated */ break; case ACTION: /* * The variable has been stored in set_value for you to * use, and you have just been asked to do something with * it. Note that anything done here must be reversable in * the UNDO case */ if (StorageTmp == NULL) { if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * row creation, so add it */ if (StorageNew != NULL) { #if 1 DEBUGMSGTL(("traceRouteCtlTable", "write_traceRouteCtlRowStatus entering new=%d... \n", action)); #endif traceRouteCtlTable_add(StorageNew); } /* * XXX: ack, and if it is NULL? */ } else if (set_value != RS_DESTROY) { /* * set the flag? */ old_value = StorageTmp->traceRouteCtlRowStatus; StorageTmp->traceRouteCtlRowStatus = *((long *) var_val); } else { /* * destroy... extract it for now */ hciptr = header_complex_find_entry(traceRouteCtlTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&traceRouteCtlTableStorage, hciptr); snmp_alarm_unregister(StorageDel->timer_id); traceRouteResultsTable_del(StorageTmp); traceRouteProbeHistoryTable_del(StorageTmp); traceRouteHopsTable_del(StorageTmp); } break; case UNDO: /* * Back out any changes made in the ACTION case */ if (StorageTmp == NULL) { if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } /* * row creation, so remove it again */ hciptr = header_complex_find_entry(traceRouteCtlTableStorage, StorageTmp); StorageDel = header_complex_extract_entry(&traceRouteCtlTableStorage, hciptr); /* * XXX: free it */ } else if (StorageDel != NULL) { /* * row deletion, so add it again */ traceRouteCtlTable_add(StorageDel); traceRouteResultsTable_add(StorageDel); traceRouteProbeHistoryTable_addall(StorageDel); traceRouteHopsTable_addall(StorageDel); } else { StorageTmp->traceRouteCtlRowStatus = old_value; } break; case COMMIT: /* * Things are working well, so it's now safe to make the change * permanently. Make sure that anything done here can't fail! */ if (StorageTmp == NULL) { if (set_value == RS_DESTROY) { return SNMP_ERR_NOERROR; } } if (StorageDel != NULL) { free(StorageDel->traceRouteCtlOwnerIndex); StorageDel->traceRouteCtlOwnerIndex = NULL; free(StorageDel->traceRouteCtlTestName); StorageDel->traceRouteCtlTestName = NULL; free(StorageDel->traceRouteCtlTargetAddress); StorageDel->traceRouteCtlTargetAddress = NULL; free(StorageDel->traceRouteCtlSourceAddress); StorageDel->traceRouteCtlSourceAddress = NULL; free(StorageDel->traceRouteCtlMiscOptions); StorageDel->traceRouteCtlMiscOptions = NULL; free(StorageDel->traceRouteCtlDescr); StorageDel->traceRouteCtlDescr = NULL; free(StorageDel->traceRouteCtlTrapGeneration); StorageDel->traceRouteCtlTrapGeneration = NULL; free(StorageDel->traceRouteCtlType); StorageDel->traceRouteCtlType = NULL; free(StorageDel); StorageDel = NULL; /* * XXX: free it, its dead */ } else { if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_CREATEANDGO) { StorageTmp->traceRouteCtlRowStatus = RS_ACTIVE; } else if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_CREATEANDWAIT) { StorageTmp->traceRouteCtlRowStatus = RS_NOTINSERVICE; } } if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) { #if 1 DEBUGMSGTL(("traceRouteCtlTable", "write_traceRouteCtlRowStatus entering runbefore=%ld... \n", StorageTmp->traceRouteCtlTargetAddressType)); #endif if (StorageTmp->traceRouteCtlAdminStatus == 1) { init_trResultsTable(StorageTmp); if (StorageTmp->traceRouteCtlFrequency != 0) StorageTmp->timer_id = snmp_alarm_register(StorageTmp-> traceRouteCtlFrequency, SA_REPEAT, run_traceRoute, StorageTmp); else StorageTmp->timer_id = snmp_alarm_register(1, 0, run_traceRoute, StorageTmp); } } snmp_store_needed(NULL); break; } return SNMP_ERR_NOERROR; } static void run_traceRoute_ipv4(struct traceRouteCtlTable_data *item) { u_short port = item->traceRouteCtlPort; /* start udp dest port # for probe packets */ int waittime = item->traceRouteCtlTimeOut; /* time to wait for response (in seconds) */ int nprobes = item->traceRouteCtlProbesPerHop; char *old_HopsAddress[255]; int count = 0; int flag = 0; int code, n, k; const char *cp; char *err; u_char *outp; u_int32_t *ap; struct sockaddr whereto; /* Who to try to reach */ struct sockaddr wherefrom; /* Who we are */ struct sockaddr_in *from = (struct sockaddr_in *) &wherefrom; struct sockaddr_in *to = (struct sockaddr_in *) &whereto; struct hostinfo *hi; int on = 1; struct protoent *pe; int ttl, probe, i; int seq = 0; int tos = 0, settos = 0; int lsrr = 0; u_short off = 0; struct ifaddrlist *al; char errbuf[132]; int minpacket = 0; /* min ip packet size */ struct ip *outip = NULL; /* last output (udp) packet */ struct udphdr *outudp; /* last output (udp) packet */ int packlen = 0; /* total length of packet */ int optlen = 0; /* length of ip options */ int options = 0; /* socket options */ int s = -1; /* receive (icmp) socket file descriptor */ int sndsock = -1; /* send (udp/icmp) socket file descriptor */ int fd[3] = { -1, -1, -1 }; u_short ident; /* * loose source route gateway list (including room for final destination) */ u_int32_t gwlist[NGATEWAYS + 1]; static const char devnull[] = "/dev/null"; char *device = NULL; char *source = NULL; char *hostname; u_int pausemsecs = 0; u_char packet[512]; /* last inbound (icmp) packet */ int pmtu = 0; /* Path MTU Discovery (RFC1191) */ struct outdata *outdata; /* last output (udp) packet */ minpacket = sizeof(*outip) + sizeof(*outdata) + optlen; minpacket += sizeof(*outudp); packlen = minpacket; /* minimum sized packet */ hostname = malloc(item->traceRouteCtlTargetAddressLen + 1); if (hostname == NULL) goto out; memcpy(hostname, item->traceRouteCtlTargetAddress, item->traceRouteCtlTargetAddressLen + 1); hostname[item->traceRouteCtlTargetAddressLen] = '\0'; hi = gethostinfo(hostname); setsin(to, hi->addrs[0]); if (hi->n > 1) DEBUGMSGTL(("traceRouteCtlTable", "Warning: %s has multiple addresses; using %s\n", hostname, inet_ntoa(to->sin_addr))); free(hostname); hostname = strdup(hi->name); freehostinfo(hi); netsnmp_set_line_buffering(stdout); outip = (struct ip *) malloc(packlen); if (outip == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "malloc: %s\n", strerror(errno))); exit(1); } memset((char *) outip, 0, packlen); outip->ip_v = IPVERSION; if (settos) outip->ip_tos = tos; #ifdef BYTESWAP_IP_HDR outip->ip_len = htons(packlen); outip->ip_off = htons(off); #else outip->ip_len = packlen; outip->ip_off = off; #endif outp = (u_char *) (outip + 1); #ifdef HAVE_RAW_OPTIONS if (lsrr > 0) { u_char *optlist; optlist = outp; outp += optlen; /* * final hop */ gwlist[lsrr] = to->sin_addr.s_addr; outip->ip_dst.s_addr = gwlist[0]; /* * force 4 byte alignment */ optlist[0] = IPOPT_NOP; /* * loose source route option */ optlist[1] = IPOPT_LSRR; i = lsrr * sizeof(gwlist[0]); optlist[2] = i + 3; /* * Pointer to LSRR addresses */ optlist[3] = IPOPT_MINOFF; memcpy(optlist + 4, gwlist + 1, i); } else #endif outip->ip_dst = to->sin_addr; outip->ip_hl = (outp - (u_char *) outip) >> 2; ident = (getpid() & 0xffff) | 0x8000; outip->ip_p = IPPROTO_UDP; outudp = (struct udphdr *) outp; outudp->source = htons(ident); outudp->len = htons((u_short) (packlen - (sizeof(*outip) + optlen))); outdata = (struct outdata *) (outudp + 1); cp = "icmp"; if ((pe = getprotobyname(cp)) == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "unknown protocol %s\n", cp)); exit(1); } /* * Insure the socket fds won't be 0, 1 or 2 */ if ((fd[0] = open(devnull, O_RDONLY)) < 0 || (fd[1] = open(devnull, O_RDONLY)) < 0 || (fd[2] = open(devnull, O_RDONLY)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "open \"%s\": %s\n", devnull, strerror(errno))); exit(1); } if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "icmp socket: %s\n", strerror(errno))); exit(1); } if (options & SO_DEBUG) (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *) &on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *) &on, sizeof(on)); #ifndef __hpux printf("raw\n"); sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); #else printf("udp\n"); sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); #endif if (sndsock < 0) { DEBUGMSGTL(("traceRouteCtlTable", "raw socket: %s\n", strerror(errno))); exit(1); } #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS) if (lsrr > 0) { u_char optlist[MAX_IPOPTLEN]; cp = "ip"; if ((pe = getprotobyname(cp)) == NULL) { DEBUGMSGTL(("traceRouteCtlTable", "unknown protocol %s\n", cp)); exit(1); } /* * final hop */ gwlist[lsrr] = to->sin_addr.s_addr; ++lsrr; /* * force 4 byte alignment */ optlist[0] = IPOPT_NOP; /* * loose source route option */ optlist[1] = IPOPT_LSRR; i = lsrr * sizeof(gwlist[0]); optlist[2] = i + 3; /* * Pointer to LSRR addresses */ optlist[3] = IPOPT_MINOFF; memcpy(optlist + 4, gwlist, i); if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS, (char *) optlist, i + sizeof(gwlist[0]))) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "IP_OPTIONS: %s\n", strerror(errno))); exit(1); } } #endif #ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &packlen, sizeof(packlen)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "SO_SNDBUF: %s\n", strerror(errno))); exit(1); } #endif #ifdef IP_HDRINCL if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "IP_HDRINCL: %s\n", strerror(errno))); exit(1); } #else #ifdef IP_TOS if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", "setsockopt tos %d: %s\n", strerror(errno))); exit(1); } #endif #endif if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *) &on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *) &on, sizeof(on)); /* * Get the interface address list */ n = ifaddrlist(&al, errbuf); if (n < 0) { DEBUGMSGTL(("traceRouteCtlTable", " ifaddrlist: %s\n", errbuf)); exit(1); } if (n == 0) { DEBUGMSGTL(("traceRouteCtlTable", " Can't find any network interfaces\n")); exit(1); } /* * Look for a specific device */ if (device != NULL) { for (i = n; i > 0; --i, ++al) if (strcmp(device, al->device) == 0) break; if (i <= 0) { DEBUGMSGTL(("traceRouteCtlTable", " Can't find interface %.32s\n", device)); exit(1); } } /* * Determine our source address */ if (source == NULL) { /* * If a device was specified, use the interface address. * Otherwise, try to determine our source address. */ if (device != NULL) setsin(from, al->addr); else if ((err = findsaddr(to, from)) != NULL) { DEBUGMSGTL(("traceRouteCtlTable", " findsaddr: %s\n", err)); free(err); exit(1); } } else { hi = gethostinfo(source); source = hi->name; hi->name = NULL; /* * If the device was specified make sure it * corresponds to the source address specified. * Otherwise, use the first address (and warn if * there are more than one). */ if (device != NULL) { for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) if (*ap == al->addr) break; if (i <= 0) { DEBUGMSGTL(("traceRouteCtlTable", " %s is not on interface %.32s\n", source, device)); exit(1); } setsin(from, *ap); } else { setsin(from, hi->addrs[0]); if (hi->n > 1) DEBUGMSGTL(("traceRouteCtlTable", " Warning: %s has multiple addresses; using %s\n", source, inet_ntoa(from->sin_addr))); } freehostinfo(hi); } /* * Revert to non-privileged user after opening sockets */ NETSNMP_IGNORE_RESULT(setgid(getgid())); NETSNMP_IGNORE_RESULT(setuid(getuid())); outip->ip_src = from->sin_addr; #ifndef IP_HDRINCL if (bind(sndsock, (struct sockaddr *) from, sizeof(*from)) < 0) { DEBUGMSGTL(("traceRouteCtlTable", " bind: %s\n", strerror(errno))); exit(1); } #endif DEBUGMSGTL(("traceRouteCtlTable", " to %s (%s)", hostname, inet_ntoa(to->sin_addr))); if (source) DEBUGMSGTL(("traceRouteCtlTable", " from %s", source)); DEBUGMSGTL(("traceRouteCtlTable", ", %lu hops max, %d byte packets\n", item->traceRouteCtlMaxTtl, packlen)); (void) fflush(stderr); struct traceRouteResultsTable_data *StorageResults = NULL; netsnmp_variable_list *vars_results = NULL; struct traceRouteHopsTable_data *temp = NULL; struct traceRouteHopsTable_data *current_temp = NULL; struct traceRouteHopsTable_data *current = NULL; unsigned long index = 0; struct traceRouteProbeHistoryTable_data *temp_his = NULL; struct traceRouteProbeHistoryTable_data *current_temp_his = NULL; snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ if ((StorageResults = header_complex_get(traceRouteResultsTableStorage, vars_results)) == NULL) { goto out; } snmp_free_varbind(vars_results); vars_results = NULL; for (ttl = item->traceRouteCtlInitialTtl; ttl <= item->traceRouteCtlMaxTtl; ++ttl) { u_int32_t lastaddr = 0; int gotlastaddr = 0; int got_there = 0; int unreachable = 0; int sentfirst = 0; time_t timep = 0; StorageResults->traceRouteResultsCurHopCount = ttl; if (item->traceRouteCtlCreateHopsEntries == 1) { if (ttl == item->traceRouteCtlInitialTtl) { int k = 0; count = traceRouteHopsTable_count(item); struct traceRouteHopsTable_data *StorageTmp = NULL; struct header_complex_index *hciptr2, *nhciptr2; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); for (hciptr2 = traceRouteHopsTableStorage; hciptr2; hciptr2 = nhciptr2) { nhciptr2 = hciptr2->next; if (snmp_oid_compare (newoid, newoid_len, hciptr2->name, newoid_len) == 0) { StorageTmp = header_complex_extract_entry (&traceRouteHopsTableStorage, hciptr2); old_HopsAddress[k] = (char *) malloc(StorageTmp-> traceRouteHopsIpTgtAddressLen + 1); if (old_HopsAddress[k] == NULL) { exit(1); } old_HopsAddress[k] = netsnmp_memdup( StorageTmp->traceRouteHopsIpTgtAddress, StorageTmp-> traceRouteHopsIpTgtAddressLen + 1); old_HopsAddress[k][StorageTmp-> traceRouteHopsIpTgtAddressLen] = '\0'; k++; StorageTmp = NULL; } } traceRouteHopsTable_del(item); index = 0; } temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data); temp->traceRouteCtlOwnerIndex = (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1); memcpy(temp->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen + 1); temp->traceRouteCtlOwnerIndex[item-> traceRouteCtlOwnerIndexLen] = '\0'; temp->traceRouteCtlOwnerIndexLen = item->traceRouteCtlOwnerIndexLen; temp->traceRouteCtlTestName = (char *) malloc(item->traceRouteCtlTestNameLen + 1); memcpy(temp->traceRouteCtlTestName, item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen + 1); temp->traceRouteCtlTestName[item-> traceRouteCtlTestNameLen] = '\0'; temp->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen; /* add lock to protect */ pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&counter_mutex); temp->traceRouteHopsHopIndex = ++index; pthread_mutex_unlock(&counter_mutex); /* endsadsadsad */ temp->traceRouteHopsIpTgtAddressType = 0; temp->traceRouteHopsIpTgtAddress = strdup(""); temp->traceRouteHopsIpTgtAddressLen = 0; temp->traceRouteHopsMinRtt = 0; temp->traceRouteHopsMaxRtt = 0; temp->traceRouteHopsAverageRtt = 0; temp->traceRouteHopsRttSumOfSquares = 0; temp->traceRouteHopsSentProbes = 0; temp->traceRouteHopsProbeResponses = 0; temp->traceRouteHopsLastGoodProbeLen = 0; if (index == 1) item->traceRouteHops = temp; else { (current_temp)->next = temp; } current_temp = temp; if (index + 1 >= item->traceRouteCtlMaxTtl) { current_temp->next = NULL; } if (item->traceRouteHops != NULL) if (traceRouteHopsTable_add(current_temp) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteHopsTable", "registered an entry error\n")); } unsigned long maxRtt = 0; unsigned long minRtt = 0; unsigned long averageRtt = 0; unsigned long sumRtt = 0; unsigned long responseProbe = 0; unsigned long sumOfSquare = 0; for (probe = 0; probe < nprobes; ++probe) { int cc; struct timeval t1, t2; struct timezone tz; struct ip *ip = NULL; unsigned long Rtt = 0; if (sentfirst && pausemsecs > 0) usleep(pausemsecs * 1000); (void) gettimeofday(&t1, &tz); send_probe(to, ++seq, ttl, &t1, outip, outudp, packlen, optlen, hostname, ident, sndsock, port, outdata); ++sentfirst; while ((cc = wait_for_reply(s, from, &t1, packet, waittime)) != 0) { (void) gettimeofday(&t2, &tz); timep = 0; time(&timep); i = packet_ok(packet, cc, from, seq, ident, pmtu, port); /* * Skip short packet */ if (i == 0) continue; if (!gotlastaddr || from->sin_addr.s_addr != lastaddr) { struct ip *ip; int hlen; ip = (struct ip *) packet; hlen = ip->ip_hl << 2; cc -= hlen; DEBUGMSGTL(("traceRouteCtlTable", " %s", inet_ntoa(from->sin_addr))); lastaddr = from->sin_addr.s_addr; ++gotlastaddr; } Rtt = deltaT(&t1, &t2); responseProbe = responseProbe + 1; if (probe == 0) { minRtt = Rtt; maxRtt = Rtt; averageRtt = Rtt; sumRtt = Rtt; sumOfSquare = Rtt * Rtt; } else { if (Rtt < minRtt) minRtt = Rtt; if (Rtt > maxRtt) maxRtt = Rtt; sumRtt = (sumRtt) + Rtt; averageRtt = round((double) (sumRtt) / (double) responseProbe); sumOfSquare = sumOfSquare + Rtt * Rtt; } StorageResults->traceRouteResultsCurProbeCount = probe + 1; if (i == -2) { #ifndef ARCHAIC ip = (struct ip *) packet; if (ip->ip_ttl <= 1) Printf(" !"); #endif ++got_there; break; } /* * time exceeded in transit */ if (i == -1) break; code = i - 1; switch (code) { case ICMP_UNREACH_PORT: #ifndef ARCHAIC ip = (struct ip *) packet; if (ip->ip_ttl <= 1) Printf(" !"); #endif ++got_there; break; case ICMP_UNREACH_NET: ++unreachable; Printf(" !N"); break; case ICMP_UNREACH_HOST: ++unreachable; Printf(" !H"); break; case ICMP_UNREACH_PROTOCOL: ++got_there; Printf(" !P"); break; case ICMP_UNREACH_NEEDFRAG: ++unreachable; Printf(" !F-%d", pmtu); break; case ICMP_UNREACH_SRCFAIL: ++unreachable; Printf(" !S"); break; case ICMP_UNREACH_FILTER_PROHIB: ++unreachable; Printf(" !X"); break; case ICMP_UNREACH_HOST_PRECEDENCE: ++unreachable; Printf(" !V"); break; case ICMP_UNREACH_PRECEDENCE_CUTOFF: ++unreachable; Printf(" !C"); break; default: ++unreachable; Printf(" !<%d>", code); break; } break; } if (cc == 0) { timep = 0; time(&timep); Printf(" *"); Rtt = (item->traceRouteCtlTimeOut) * 1000; } if (item->traceRouteCtlMaxRows != 0) { temp_his = SNMP_MALLOC_STRUCT (traceRouteProbeHistoryTable_data); temp_his->traceRouteCtlOwnerIndex = (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1); memcpy(temp_his->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen + 1); temp_his->traceRouteCtlOwnerIndex[item-> traceRouteCtlOwnerIndexLen] = '\0'; temp_his->traceRouteCtlOwnerIndexLen = item->traceRouteCtlOwnerIndexLen; temp_his->traceRouteCtlTestName = (char *) malloc(item->traceRouteCtlTestNameLen + 1); memcpy(temp_his->traceRouteCtlTestName, item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen + 1); temp_his->traceRouteCtlTestName[item-> traceRouteCtlTestNameLen] = '\0'; temp_his->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen; /* add lock to protect */ pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&counter_mutex); if (item->traceRouteProbeHistoryMaxIndex >= (unsigned long) (2147483647)) item->traceRouteProbeHistoryMaxIndex = 0; temp_his->traceRouteProbeHistoryIndex = ++(item->traceRouteProbeHistoryMaxIndex); pthread_mutex_unlock(&counter_mutex); /* endsadsadsad */ temp_his->traceRouteProbeHistoryHopIndex = ttl; temp_his->traceRouteProbeHistoryProbeIndex = probe + 1; temp_his->traceRouteProbeHistoryHAddrType = 1; temp_his->traceRouteProbeHistoryHAddr = (char *) malloc(strlen(inet_ntoa(from->sin_addr)) + 1); strcpy(temp_his->traceRouteProbeHistoryHAddr, (inet_ntoa(from->sin_addr))); temp_his-> traceRouteProbeHistoryHAddr[strlen (inet_ntoa (from->sin_addr))] = '\0'; temp_his->traceRouteProbeHistoryHAddrLen = strlen(inet_ntoa(from->sin_addr)); temp_his->traceRouteProbeHistoryResponse = Rtt; temp_his->traceRouteProbeHistoryStatus = 1; temp_his->traceRouteProbeHistoryLastRC = 0; temp_his->traceRouteProbeHistoryTime_time = timep; temp_his->traceRouteProbeHistoryTime = netsnmp_memdup(date_n_time(&timep, &temp_his->traceRouteProbeHistoryTimeLen), 11); if (probe == 0) item->traceRouteProbeHis = temp_his; else { (current_temp_his)->next = temp_his; } current_temp_his = temp_his; if (probe + 1 >= nprobes) { current_temp_his->next = NULL; } if (item->traceRouteProbeHis != NULL) { if (traceRouteProbeHistoryTable_count(item) < item->traceRouteCtlMaxRows) { if (traceRouteProbeHistoryTable_add (current_temp_his) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteProbeHistoryTable", "registered an entry error\n")); } else { traceRouteProbeHistoryTable_delLast(item); if (traceRouteProbeHistoryTable_add (current_temp_his) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteProbeHistoryTable", "registered an entry error\n")); } } } if (item->traceRouteCtlCreateHopsEntries == 1) { netsnmp_variable_list *vars_hops = NULL; snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index)); /* traceRouteHopsIndex */ if ((current = header_complex_get(traceRouteHopsTableStorage, vars_hops)) == NULL) { goto out; } snmp_free_varbind(vars_hops); vars_hops = NULL; current->traceRouteHopsIpTgtAddressType = 1; current->traceRouteHopsIpTgtAddress = (char *) malloc(strlen(inet_ntoa(from->sin_addr)) + 1); current->traceRouteHopsIpTgtAddress = strdup(inet_ntoa(from->sin_addr)); current-> traceRouteHopsIpTgtAddress[strlen (inet_ntoa (from->sin_addr))] = '\0'; current->traceRouteHopsIpTgtAddressLen = strlen(inet_ntoa(from->sin_addr)); if (count != 0) { if (strcmp (old_HopsAddress[index - 1], current->traceRouteHopsIpTgtAddress) != 0) flag = 1; } current->traceRouteHopsIpTgtAddressLen = strlen(inet_ntoa(from->sin_addr)); current->traceRouteHopsMinRtt = minRtt; current->traceRouteHopsMaxRtt = maxRtt; current->traceRouteHopsAverageRtt = averageRtt; current->traceRouteHopsRttSumOfSquares = sumOfSquare; current->traceRouteHopsSentProbes = probe + 1; current->traceRouteHopsProbeResponses = responseProbe; current->traceRouteHopsLastGoodProbe_time = timep; current->traceRouteHopsLastGoodProbe = netsnmp_memdup(date_n_time(&timep, ¤t->traceRouteHopsLastGoodProbeLen), 11); } (void) fflush(stdout); } putchar('\n'); if (got_there || (unreachable > 0 && unreachable >= nprobes - 1)) { if (got_there != 0) { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; StorageResults->traceRouteResultsTestSuccesses = StorageResults->traceRouteResultsTestSuccesses + 1; StorageResults->traceRouteResultsLastGoodPath_time = timep; StorageResults->traceRouteResultsLastGoodPath = netsnmp_memdup(date_n_time(&timep, &StorageResults-> traceRouteResultsLastGoodPathLen), 11); if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) { DEBUGMSGTL(("traceRouteProbeHistoryTable", "TEST completed!\n")); send_traceRoute_trap(item, traceRouteTestCompleted, sizeof (traceRouteTestCompleted) / sizeof(oid)); } } else { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTFAILED) != 0) { DEBUGMSGTL(("traceRouteProbeHistoryTable", "test Failed!\n")); send_traceRoute_trap(item, traceRouteTestFailed, sizeof(traceRouteTestFailed) / sizeof(oid)); } } break; } else if (ttl == item->traceRouteCtlMaxTtl && (probe + 1) == nprobes) { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTFAILED) != 0) { DEBUGMSGTL(("traceRouteProbeHistoryTable", "test Failed!\n")); send_traceRoute_trap(item, traceRouteTestFailed, sizeof(traceRouteTestFailed) / sizeof(oid)); } } } if (flag == 1) { DEBUGMSGTL(("traceRouteProbeHistoryTable", "path changed!\n")); send_traceRoute_trap(item, traceRoutePathChange, sizeof(traceRoutePathChange) / sizeof(oid)); } out: for (k = 0; k < count; k++) free(old_HopsAddress[k]); for (k = 0; k < 3; k++) if (fd[k] >= 0) close(fd[k]); if (s >= 0) close(s); if (sndsock >= 0) close(sndsock); free(outip); free(hostname); } static void run_traceRoute_ipv6(struct traceRouteCtlTable_data *item) { int nprobes = item->traceRouteCtlProbesPerHop; char *old_HopsAddress[255]; int count = 0; int flag = 0; int icmp_sock = -1; /* receive (icmp) socket file descriptor */ int sndsock = -1; /* send (udp) socket file descriptor */ struct sockaddr_in6 whereto; /* Who to try to reach */ struct sockaddr_in6 saddr; struct sockaddr_in6 firsthop; char *source = NULL; char *device = NULL; char *hostname; pid_t ident = 0; u_short port = 32768 + 666; /* start udp dest port # for probe packets */ int options = 0; /* socket options */ int waittime = 5; /* time to wait for response (in seconds) */ char *sendbuff = NULL; int datalen = sizeof(struct pkt_format); u_char packet[512]; /* last inbound (icmp) packet */ char pa[64]; struct hostent *hp = NULL; struct sockaddr_in6 from, *to = NULL; int i = 0, k, on = 0, probe = 0, seq = 0, tos = 0, ttl = 0; int socket_errno = 0; icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); socket_errno = errno; NETSNMP_IGNORE_RESULT(setuid(getuid())); on = 1; seq = tos = 0; to = (struct sockaddr_in6 *) &whereto; hostname = malloc(item->traceRouteCtlTargetAddressLen + 1); if (!hostname) goto out; memcpy(hostname, item->traceRouteCtlTargetAddress, item->traceRouteCtlTargetAddressLen + 1); hostname[item->traceRouteCtlTargetAddressLen] = '\0'; setlinebuf(stdout); memset(&whereto, '\0', sizeof(struct sockaddr_in6)); to->sin6_family = AF_INET6; to->sin6_port = htons(port); if (inet_pton(AF_INET6, hostname, &to->sin6_addr) <= 0) { hp = gethostbyname2(hostname, AF_INET6); if (hp != NULL) { memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16); free(hostname); hostname = strdup((char *) hp->h_name); } else { fprintf(stderr, "traceroute: unknown host %s\n", hostname); free(hostname); hostname = NULL; goto out; } } firsthop = *to; datalen = item->traceRouteCtlDataSize; if (datalen < (int) sizeof(struct pkt_format) || datalen >= MAXPACKET) { Fprintf(stderr, "traceroute: packet size must be %d <= s < %d.\n", (int) sizeof(struct pkt_format), MAXPACKET); datalen = 16; } ident = getpid(); sendbuff = malloc(datalen); if (sendbuff == NULL) { fprintf(stderr, "malloc failed\n"); goto out; } if (icmp_sock < 0) { errno = socket_errno; perror("traceroute6: icmp socket"); goto out; } if (options & SO_DEBUG) setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG, (char *) &on, sizeof(on)); if (options & SO_DONTROUTE) setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE, (char *) &on, sizeof(on)); if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("traceroute: UDP socket"); goto out; } #ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &datalen, sizeof(datalen)) < 0) { perror("traceroute: SO_SNDBUF"); goto out; } #endif /* SO_SNDBUF */ if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *) &on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *) &on, sizeof(on)); if (source == NULL) { socklen_t alen; int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0); if (probe_fd < 0) { perror("socket"); close(probe_fd); goto out; } if (device) { if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) perror("WARNING: interface is ignored"); } firsthop.sin6_port = htons(1025); if (connect(probe_fd, (struct sockaddr *) &firsthop, sizeof(firsthop)) == -1) { perror("connect"); close(probe_fd); goto out; } alen = sizeof(saddr); if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { perror("getsockname"); close(probe_fd); goto out; } saddr.sin6_port = 0; close(probe_fd); } else { memset(&saddr, '\0', sizeof(struct sockaddr_in6)); saddr.sin6_family = AF_INET6; if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 0) { Printf("traceroute: unknown addr %s\n", source); goto out; } } if (bind(sndsock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("traceroute: bind sending socket"); goto out; } if (bind(icmp_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("traceroute: bind icmp6 socket"); goto out; } Fprintf(stderr, "traceroute to %s (%s)", hostname, inet_ntop(AF_INET6, &to->sin6_addr, pa, 64)); Fprintf(stderr, " from %s", inet_ntop(AF_INET6, &saddr.sin6_addr, pa, 64)); Fprintf(stderr, ", %lu hops max, %d byte packets\n", item->traceRouteCtlMaxTtl, datalen); (void) fflush(stderr); struct traceRouteResultsTable_data *StorageResults = NULL; netsnmp_variable_list *vars_results = NULL; struct traceRouteHopsTable_data *temp = NULL; struct traceRouteHopsTable_data *current_temp = NULL; struct traceRouteHopsTable_data *current = NULL; unsigned long index = 0; struct traceRouteProbeHistoryTable_data *temp_his = NULL; struct traceRouteProbeHistoryTable_data *current_temp_his = NULL; snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ if ((StorageResults = header_complex_get(traceRouteResultsTableStorage, vars_results)) == NULL) { goto out; } snmp_free_varbind(vars_results); vars_results = NULL; for (ttl = item->traceRouteCtlInitialTtl; ttl <= item->traceRouteCtlMaxTtl; ++ttl) { struct in6_addr lastaddr = { {{0,}} }; int got_there = 0; int unreachable = 0; time_t timep = 0; Printf("%2d ", ttl); StorageResults->traceRouteResultsCurHopCount = ttl; if (item->traceRouteCtlCreateHopsEntries == 1) { if (ttl == item->traceRouteCtlInitialTtl) { int k = 0; count = traceRouteHopsTable_count(item); struct traceRouteHopsTable_data *StorageTmp; struct header_complex_index *hciptr2, *nhciptr2; netsnmp_variable_list *vars = NULL; oid newoid[MAX_OID_LEN]; size_t newoid_len; snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ header_complex_generate_oid(newoid, &newoid_len, NULL, 0, vars); snmp_free_varbind(vars); vars = NULL; for (hciptr2 = traceRouteHopsTableStorage; hciptr2; hciptr2 = nhciptr2) { nhciptr2 = hciptr2->next; if (snmp_oid_compare (newoid, newoid_len, hciptr2->name, newoid_len) == 0) { StorageTmp = header_complex_extract_entry (&traceRouteHopsTableStorage, hciptr2); old_HopsAddress[k] = (char *) malloc(StorageTmp-> traceRouteHopsIpTgtAddressLen + 1); if (old_HopsAddress[k] == NULL) { exit(1); } old_HopsAddress[k] = netsnmp_memdup( StorageTmp->traceRouteHopsIpTgtAddress, StorageTmp-> traceRouteHopsIpTgtAddressLen + 1); old_HopsAddress[k][StorageTmp-> traceRouteHopsIpTgtAddressLen] = '\0'; k++; } } traceRouteHopsTable_del(item); index = 0; } temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data); temp->traceRouteCtlOwnerIndex = (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1); memcpy(temp->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen + 1); temp->traceRouteCtlOwnerIndex[item-> traceRouteCtlOwnerIndexLen] = '\0'; temp->traceRouteCtlOwnerIndexLen = item->traceRouteCtlOwnerIndexLen; temp->traceRouteCtlTestName = (char *) malloc(item->traceRouteCtlTestNameLen + 1); memcpy(temp->traceRouteCtlTestName, item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen + 1); temp->traceRouteCtlTestName[item-> traceRouteCtlTestNameLen] = '\0'; temp->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen; /* add lock to protect */ pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&counter_mutex); temp->traceRouteHopsHopIndex = ++index; pthread_mutex_unlock(&counter_mutex); /* endsadsadsad */ temp->traceRouteHopsIpTgtAddressType = 0; temp->traceRouteHopsIpTgtAddress = strdup(""); temp->traceRouteHopsIpTgtAddressLen = 0; temp->traceRouteHopsMinRtt = 0; temp->traceRouteHopsMaxRtt = 0; temp->traceRouteHopsAverageRtt = 0; temp->traceRouteHopsRttSumOfSquares = 0; temp->traceRouteHopsSentProbes = 0; temp->traceRouteHopsProbeResponses = 0; temp->traceRouteHopsLastGoodProbeLen = 0; if (index == 1) item->traceRouteHops = temp; else { (current_temp)->next = temp; } current_temp = temp; if (index >= item->traceRouteCtlMaxTtl) { current_temp->next = NULL; } if (item->traceRouteHops != NULL) if (traceRouteHopsTable_add(current_temp) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteHopsTable", "registered an entry error\n")); } unsigned long maxRtt = 0; unsigned long minRtt = 0; unsigned long averageRtt = 0; unsigned long sumRtt = 0; unsigned long responseProbe = 0; unsigned long sumOfSquare = 0; for (probe = 0; probe < nprobes; ++probe) { int cc = 0, reset_timer = 0; struct timeval t1, t2; struct timezone tz; unsigned long Rtt = 0; gettimeofday(&t1, &tz); send_probe_v6(++seq, ttl, sendbuff, ident, &tz, sndsock, datalen, &whereto, hostname); reset_timer = 1; while ((cc = wait_for_reply_v6(icmp_sock, &from, reset_timer, waittime, icmp_sock, packet)) != 0) { gettimeofday(&t2, &tz); timep = 0; time(&timep); if ((i = packet_ok_v6(packet, cc, &from, seq, &t1, ident))) { reset_timer = 1; if (memcmp (&from.sin6_addr, &lastaddr, sizeof(struct in6_addr))) { memcpy(&lastaddr, &from.sin6_addr, sizeof(struct in6_addr)); } Rtt = deltaT(&t1, &t2); responseProbe = responseProbe + 1; if (probe == 0) { minRtt = Rtt; maxRtt = Rtt; averageRtt = Rtt; sumRtt = Rtt; sumOfSquare = Rtt * Rtt; } else { if (Rtt < minRtt) minRtt = Rtt; if (Rtt > maxRtt) maxRtt = Rtt; sumRtt = (sumRtt) + Rtt; averageRtt = round((double) (sumRtt) / (double) responseProbe); sumOfSquare = sumOfSquare + Rtt * Rtt; } StorageResults->traceRouteResultsCurProbeCount = probe + 1; switch (i - 1) { case ICMP6_DST_UNREACH_NOPORT: ++got_there; break; case ICMP6_DST_UNREACH_NOROUTE: ++unreachable; Printf(" !N"); break; case ICMP6_DST_UNREACH_ADDR: ++unreachable; Printf(" !H"); break; case ICMP6_DST_UNREACH_ADMIN: ++unreachable; Printf(" !S"); break; } break; } else reset_timer = 0; } if (cc == 0) { timep = 0; time(&timep); Printf(" *"); Rtt = (item->traceRouteCtlTimeOut) * 1000; } if (item->traceRouteCtlMaxRows != 0) { temp_his = SNMP_MALLOC_STRUCT (traceRouteProbeHistoryTable_data); temp_his->traceRouteCtlOwnerIndex = (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1); memcpy(temp_his->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen + 1); temp_his->traceRouteCtlOwnerIndex[item-> traceRouteCtlOwnerIndexLen] = '\0'; temp_his->traceRouteCtlOwnerIndexLen = item->traceRouteCtlOwnerIndexLen; temp_his->traceRouteCtlTestName = (char *) malloc(item->traceRouteCtlTestNameLen + 1); memcpy(temp_his->traceRouteCtlTestName, item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen + 1); temp_his->traceRouteCtlTestName[item-> traceRouteCtlTestNameLen] = '\0'; temp_his->traceRouteCtlTestNameLen = item->traceRouteCtlTestNameLen; /* add lock to protect */ pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&counter_mutex); if (item->traceRouteProbeHistoryMaxIndex >= (unsigned long) (2147483647)) item->traceRouteProbeHistoryMaxIndex = 0; temp_his->traceRouteProbeHistoryIndex = ++(item->traceRouteProbeHistoryMaxIndex); pthread_mutex_unlock(&counter_mutex); /* endsadsadsad */ temp_his->traceRouteProbeHistoryHopIndex = ttl; temp_his->traceRouteProbeHistoryProbeIndex = probe + 1; temp_his->traceRouteProbeHistoryHAddrType = 2; temp_his->traceRouteProbeHistoryHAddr = (char *) malloc(strlen (inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)) + 1); temp_his->traceRouteProbeHistoryHAddr = strdup(inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)); temp_his-> traceRouteProbeHistoryHAddr[strlen (inet_ntop (AF_INET6, &from.sin6_addr, pa, 64))] = '\0'; temp_his->traceRouteProbeHistoryHAddrLen = strlen(inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)); temp_his->traceRouteProbeHistoryResponse = Rtt; temp_his->traceRouteProbeHistoryStatus = 1; temp_his->traceRouteProbeHistoryLastRC = 0; temp_his->traceRouteProbeHistoryTime_time = timep; temp_his->traceRouteProbeHistoryTime = netsnmp_memdup( date_n_time(&timep, &temp_his->traceRouteProbeHistoryTimeLen), 11); if (probe == 0) item->traceRouteProbeHis = temp_his; else { (current_temp_his)->next = temp_his; } current_temp_his = temp_his; if (probe + 1 >= nprobes) { current_temp_his->next = NULL; } if (item->traceRouteProbeHis != NULL) { if (traceRouteProbeHistoryTable_count(item) < item->traceRouteCtlMaxRows) { if (traceRouteProbeHistoryTable_add (current_temp_his) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteProbeHistoryTable", "registered an entry error\n")); } else { traceRouteProbeHistoryTable_delLast(item); if (traceRouteProbeHistoryTable_add (current_temp_his) != SNMPERR_SUCCESS) DEBUGMSGTL(("traceRouteProbeHistoryTable", "registered an entry error\n")); } } } if (item->traceRouteCtlCreateHopsEntries == 1) { netsnmp_variable_list *vars_hops = NULL; snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */ snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */ snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index)); /* traceRouteHopsIndex */ if ((current = header_complex_get(traceRouteHopsTableStorage, vars_hops)) == NULL) goto out; current->traceRouteHopsIpTgtAddressType = 2; current->traceRouteHopsIpTgtAddress = (char *) malloc(strlen (inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)) + 1); current->traceRouteHopsIpTgtAddress = strdup(inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)); current-> traceRouteHopsIpTgtAddress[strlen (inet_ntop (AF_INET6, &from.sin6_addr, pa, 64))] = '\0'; if (count != 0) { if (strcmp (old_HopsAddress[index - 1], current->traceRouteHopsIpTgtAddress) != 0) flag = 1; } current->traceRouteHopsIpTgtAddressLen = strlen(inet_ntop (AF_INET6, &from.sin6_addr, pa, 64)); current->traceRouteHopsMinRtt = minRtt; current->traceRouteHopsMaxRtt = maxRtt; current->traceRouteHopsAverageRtt = averageRtt; current->traceRouteHopsRttSumOfSquares = sumOfSquare; current->traceRouteHopsSentProbes = probe + 1; current->traceRouteHopsProbeResponses = responseProbe; current->traceRouteHopsLastGoodProbe_time = timep; current->traceRouteHopsLastGoodProbe = netsnmp_memdup(date_n_time(&timep, ¤t->traceRouteHopsLastGoodProbeLen), 11); snmp_free_varbind(vars_hops); vars_hops = NULL; } (void) fflush(stdout); } putchar('\n'); if (got_there || unreachable >= nprobes - 1) { if (got_there != 0) { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; StorageResults->traceRouteResultsTestSuccesses = StorageResults->traceRouteResultsTestSuccesses + 1; StorageResults->traceRouteResultsLastGoodPath_time = timep; StorageResults->traceRouteResultsLastGoodPath = netsnmp_memdup(date_n_time(&timep, &StorageResults-> traceRouteResultsLastGoodPathLen), 11); if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) { printf("TEST completed!\n"); send_traceRoute_trap(item, traceRouteTestCompleted, sizeof (traceRouteTestCompleted) / sizeof(oid)); } } else { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTFAILED) != 0) { printf("test Failed!\n"); send_traceRoute_trap(item, traceRouteTestFailed, sizeof(traceRouteTestFailed) / sizeof(oid)); } } break; } else if (ttl == item->traceRouteCtlMaxTtl && (probe + 1) == nprobes) { StorageResults->traceRouteResultsTestAttempts = StorageResults->traceRouteResultsTestAttempts + 1; if ((item-> traceRouteCtlTrapGeneration[0] & TRACEROUTETRAPGENERATION_TESTFAILED) != 0) { printf("test Failed!\n"); send_traceRoute_trap(item, traceRouteTestFailed, sizeof(traceRouteTestFailed) / sizeof(oid)); } } } if (flag == 1) { printf("path changed!\n"); send_traceRoute_trap(item, traceRoutePathChange, sizeof(traceRoutePathChange) / sizeof(oid)); } out: for (k = 0; k < count; k++) free(old_HopsAddress[k]); free(sendbuff); if (sndsock >= 0) close(sndsock); if (icmp_sock >= 0) close(icmp_sock); free(hostname); } void run_traceRoute(unsigned int clientreg, void *clientarg) { struct traceRouteCtlTable_data *item = clientarg; if (item->traceRouteCtlInitialTtl > item->traceRouteCtlMaxTtl) { DEBUGMSGTL(("traceRouteCtlTable", "first ttl (%lu) may not be greater than max ttl (%lu)\n", item->traceRouteCtlInitialTtl, item->traceRouteCtlMaxTtl)); return; } switch (item->traceRouteCtlTargetAddressType) { case 1: case 16: run_traceRoute_ipv4(item); break; case 2: run_traceRoute_ipv6(item); break; } } int wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp, u_char * packet, int waittime) { fd_set fds; struct timeval now, wait; struct timezone tz; int cc = 0; socklen_t fromlen = sizeof(*fromp); FD_ZERO(&fds); FD_SET(sock, &fds); wait.tv_sec = tp->tv_sec + waittime; wait.tv_usec = tp->tv_usec; (void) gettimeofday(&now, &tz); tvsub(&wait, &now); if (select(sock + 1, &fds, NULL, NULL, &wait) > 0) cc = recvfrom(sock, (char *) packet, 512, 0, (struct sockaddr *) fromp, &fromlen); return (cc); } int wait_for_reply_v6(int sock, struct sockaddr_in6 *from, int reset_timer, int waittime, int icmp_sock, u_char * packet) { fd_set fds; static struct timeval wait; int cc = 0; socklen_t fromlen = sizeof(*from); FD_ZERO(&fds); FD_SET(sock, &fds); if (reset_timer) { /* * traceroute could hang if someone else has a ping * running and our ICMP reply gets dropped but we don't * realize it because we keep waking up to handle those * other ICMP packets that keep coming in. To fix this, * "reset_timer" will only be true if the last packet that * came in was for us or if this is the first time we're * waiting for a reply since sending out a probe. Note * that this takes advantage of the select() feature on * Linux where the remaining timeout is written to the * struct timeval area. */ wait.tv_sec = waittime; wait.tv_usec = 0; } if (select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &wait) > 0) { cc = recvfrom(icmp_sock, (char *) packet, 512, 0, (struct sockaddr *) from, &fromlen); } return (cc); } /* * send_probe() uses the BSD-ish udpiphdr. * Define something that looks enough like it to work. */ struct udpiphdr { struct iphdr ui_i; struct udphdr ui_u; }; #define ui_src ui_i.saddr #define ui_dst ui_i.daddr #define ui_pr ui_i.protocol #define ui_len ui_i.tot_len void send_probe(struct sockaddr_in *whereto, int seq, int ttl, struct timeval *tp, struct ip *outip, struct udphdr *outudp, int packlen, int optlen, char *hostname, u_short ident, int sndsock, u_short port, struct outdata *outdata) { int cc = 0; struct udpiphdr *ui = NULL, *oui = NULL; struct ip tip; outip->ip_ttl = ttl; #ifndef __hpux outip->ip_id = htons(ident + seq); #endif /* * In most cases, the kernel will recalculate the ip checksum. * But we must do it anyway so that the udp checksum comes out * right. */ outip->ip_sum = in_checksum((u_short *) outip, sizeof(*outip) + optlen); if (outip->ip_sum == 0) outip->ip_sum = 0xffff; /* * Payload */ outdata->seq = seq; outdata->ttl = ttl; outdata->tv = *tp; outudp->dest = htons(port + seq); /* * Checksum (we must save and restore ip header) */ tip = *outip; ui = (struct udpiphdr *) outip; oui = (struct udpiphdr *) &tip; /* * Easier to zero and put back things that are ok */ memset((char *) ui, 0, sizeof(ui->ui_i)); ui->ui_src = oui->ui_src; ui->ui_dst = oui->ui_dst; ui->ui_pr = oui->ui_pr; ui->ui_len = outudp->len; outudp->check = 0; outudp->check = in_checksum((u_short *) ui, packlen); if (outudp->check == 0) outudp->check = 0xffff; *outip = tip; /* * XXX undocumented debugging hack */ #if !defined(IP_HDRINCL) && defined(IP_TTL) printf("ttl\n"); if (setsockopt(sndsock, IPPROTO_IP, IP_TTL, (char *) &ttl, sizeof(ttl)) < 0) { Fprintf(stderr, "%s: setsockopt ttl %d: %s\n", "traceroute", ttl, strerror(errno)); exit(1); } #endif #ifdef __hpux Printf("whereto=%s\n", inet_ntoa(((struct sockaddr_in *) whereto)->sin_addr)); cc = sendto(sndsock, (char *) outudp, packlen - (sizeof(*outip) + optlen), 0, whereto, sizeof(*whereto)); if (cc > 0) cc += sizeof(*outip) + optlen; #else cc = sendto(sndsock, (char *) outip, packlen, 0, whereto, sizeof(*whereto)); #endif if (cc < 0 || cc != packlen) { if (cc < 0) Fprintf(stderr, "%s: sendto: %s\n", "traceroute", strerror(errno)); Printf("%s: wrote %s %d chars, ret=%d\n", "traceroute", hostname, packlen, cc); (void) fflush(stdout); } } void send_probe_v6(int seq, int ttl, char *sendbuff, pid_t ident, struct timezone *tz, int sndsock, int datalen, struct sockaddr_in6 *whereto, char *hostname) { struct pkt_format *pkt = (struct pkt_format *) sendbuff; int i = 0; pkt->ident = htonl(ident); pkt->seq = htonl(seq); gettimeofday(&pkt->tv, tz); i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(int)); if (i < 0) { perror("setsockopt"); exit(1); } do { i = sendto(sndsock, sendbuff, datalen, 0, (struct sockaddr *) whereto, sizeof(struct sockaddr_in6)); } while (i < 0 && errno == ECONNREFUSED); if (i < 0 || i != datalen) { if (i < 0) perror("sendto"); Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname, datalen, i); (void) fflush(stdout); } } unsigned long deltaT(struct timeval *t1p, struct timeval *t2p) { unsigned long dt; dt = (unsigned long) ((long) (t2p->tv_sec - t1p->tv_sec) * 1000 + (long) (t2p->tv_usec - t1p->tv_usec) / 1000); return (dt); } int packet_ok(u_char * buf, int cc, struct sockaddr_in *from, int seq, u_short ident, int pmtu NETSNMP_ATTRIBUTE_UNUSED, u_short port) { struct icmp *icp = NULL; u_char type, code; int hlen = 0; #ifndef ARCHAIC struct ip *ip = NULL; ip = (struct ip *) buf; hlen = ip->ip_hl << 2; if (cc < hlen + ICMP_MINLEN) { return (0); } cc -= hlen; icp = (struct icmp *) (buf + hlen); #else icp = (struct icmp *) buf; #endif type = icp->icmp_type; code = icp->icmp_code; /* * Path MTU Discovery (RFC1191) */ #if 0 if (code != ICMP_UNREACH_NEEDFRAG) pmtu = 0; else { #ifdef HAVE_ICMP_NEXTMTU pmtu = ntohs(icp->icmp_nextmtu); #else pmtu = ntohs(((struct my_pmtu *) &icp->icmp_void)->ipm_nextmtu); #endif } #endif if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) || type == ICMP_UNREACH || type == ICMP_ECHOREPLY) { struct ip *hip; struct udphdr *up; if(cc < offsetof(struct icmp, icmp_ip) + sizeof(icp->icmp_ip)) { return (0); } hip = &icp->icmp_ip; hlen = hip->ip_hl << 2; up = (struct udphdr *) ((u_char *) hip + hlen); /* * XXX 8 is a magic number */ if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP && up->source == htons(ident) && up->dest == htons(port + seq)) return (type == ICMP_TIMXCEED ? -1 : code + 1); } return (0); } int packet_ok_v6(u_char * buf, int cc, struct sockaddr_in6 *from, int seq, struct timeval *tv, pid_t ident) { struct icmp6_hdr *icp = NULL; u_char type, code; if(cc < sizeof(struct icmp6_hdr)) return 0; icp = (struct icmp6_hdr *) buf; type = icp->icmp6_type; code = icp->icmp6_code; if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) || type == ICMP6_DST_UNREACH) { struct ip6_hdr *hip = NULL; struct udphdr *up = NULL; int nexthdr = 0; hip = (struct ip6_hdr *) (icp + 1); up = (struct udphdr *) (hip + 1); nexthdr = hip->ip6_nxt; if (nexthdr == 44) { nexthdr = *(unsigned char *) up; up++; } if (nexthdr == IPPROTO_UDP) { struct pkt_format *pkt; pkt = (struct pkt_format *) (up + 1); if (ntohl(pkt->ident) == ident && ntohl(pkt->seq) == seq) { *tv = pkt->tv; return (type == ICMP6_TIME_EXCEEDED ? -1 : code + 1); } } } return (0); } /* * Checksum routine for Internet Protocol family headers (C Version) */ u_short in_checksum(u_short * addr, int len) { int nleft = len; u_short *w = addr; u_short answer; int sum = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), * we add sequential 16 bit words to it, and at the end, fold * back all the carry bits from the top 16 bits into the lower * 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* * mop up an odd byte, if necessary */ if (nleft == 1) sum += *(u_char *) w; /* * add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer); } /* * Subtract 2 timeval structs: out = out - in. * Out is assumed to be >= in. */ void tvsub(struct timeval *out, struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; out->tv_usec += 1000000; } out->tv_sec -= in->tv_sec; } struct hostinfo * gethostinfo(char *hostname) { int n; struct hostent *hp = NULL; struct hostinfo *hi = NULL; char **p = NULL; u_int32_t addr, *ap = NULL; if (strlen(hostname) > 64) { Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n", "traceroute", hostname); exit(1); } hi = calloc(1, sizeof(*hi)); if (hi == NULL) { Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno)); exit(1); } addr = inet_addr(hostname); if ((int32_t) addr != -1) { hi->name = strdup(hostname); hi->n = 1; hi->addrs = calloc(1, sizeof(hi->addrs[0])); if (hi->addrs == NULL) { Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno)); exit(1); } hi->addrs[0] = addr; return (hi); } hp = netsnmp_gethostbyname(hostname); if (hp == NULL) { Fprintf(stderr, "%s: unknown host %s\n", "traceroute", hostname); printf("hp=NULL\n"); exit(1); } if (hp->h_addrtype != AF_INET || hp->h_length != 4) { Fprintf(stderr, "%s: bad host %s\n", "traceroute", hostname); exit(1); } hi->name = strdup(hp->h_name); for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p) continue; hi->n = n; hi->addrs = calloc(n, sizeof(hi->addrs[0])); if (hi->addrs == NULL) { Fprintf(stderr, "%s: calloc %s\n", "traceroute", strerror(errno)); exit(1); } for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p) memcpy(ap, *p, sizeof(*ap)); return (hi); } void freehostinfo(struct hostinfo *hi) { if (hi->name != NULL) { free(hi->name); hi->name = NULL; } free((char *) hi->addrs); free((char *) hi); } void setsin(struct sockaddr_in *sin, u_int32_t addr) { memset(sin, 0, sizeof(*sin)); #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(*sin); #endif sin->sin_family = AF_INET; sin->sin_addr.s_addr = addr; } /* * Return the source address for the given destination address */ static char * findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) { int i, n; FILE *f; u_int32_t mask; u_int32_t dest, tmask; struct ifaddrlist *al; char buf[256], tdevice[256], device[256]; char *errbuf = NULL; static const char route[] = "/proc/net/route"; if ((f = fopen(route, "r")) == NULL) { if (asprintf(&errbuf, "open %s: %s", route, strerror(errno)) < 0) snmp_log(LOG_ERR, "error buffer allocation failed\n"); return errbuf; } /* * Find the appropriate interface */ n = 0; mask = 0; device[0] = '\0'; while (fgets(buf, sizeof(buf), f) != NULL) { ++n; if (n == 1 && strncmp(buf, "Iface", 5) == 0) continue; if ((i = sscanf(buf, "%s %x %*s %*s %*s %*s %*s %x", tdevice, &dest, &tmask)) != 3) { fclose(f); return strdup("junk in buffer"); } if ((to->sin_addr.s_addr & tmask) == dest && (tmask > mask || mask == 0)) { mask = tmask; strcpy(device, tdevice); } } fclose(f); if (device[0] == '\0') return strdup("Can't find interface"); /* * Get the interface address list */ if ((n = ifaddrlist(&al, errbuf)) < 0) return (errbuf); if (n == 0) return strdup("Can't find any network interfaces"); /* * Find our appropriate source address */ for (i = n; i > 0; --i, ++al) if (strcmp(device, al->device) == 0) break; if (i <= 0) { sprintf(errbuf, "Can't find interface \"%.32s\"", device); return (errbuf); } setsin(from, al->addr); return (NULL); } int ifaddrlist(struct ifaddrlist **ipaddrp, char *errbuf) { int fd, nipaddr; #ifdef HAVE_SOCKADDR_SA_LEN int n; #endif struct ifreq *ifrp, *ifend, *ifnext; struct sockaddr_in *sin; struct ifaddrlist *al; struct ifconf ifc; struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr; #define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0])) static struct ifaddrlist ifaddrlist[MAX_IPADDR]; char device[sizeof(ifr.ifr_name) + 1]; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { (void) sprintf(errbuf, "socket: %s", strerror(errno)); return (-1); } ifc.ifc_len = sizeof(ibuf); ifc.ifc_buf = (caddr_t) ibuf; if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 || ifc.ifc_len < sizeof(struct ifreq)) { if (errno == EINVAL) (void) sprintf(errbuf, "SIOCGIFCONF: ifreq struct too small (%d bytes)", (int)sizeof(ibuf)); else (void) sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno)); (void) close(fd); return (-1); } ifrp = ibuf; ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len); al = ifaddrlist; nipaddr = 0; for (; ifrp < ifend; ifrp = ifnext) { #ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ifnext = ifrp + 1; else ifnext = (struct ifreq *) ((char *) ifrp + n); if (ifrp->ifr_addr.sa_family != AF_INET) continue; #else ifnext = ifrp + 1; #endif /* * Need a template to preserve address info that is * used below to locate the next entry. (Otherwise, * SIOCGIFFLAGS stomps over it because the requests * are returned in a union.) */ strlcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) { if (errno == ENXIO) continue; (void) sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s", (int) sizeof(ifr.ifr_name), ifr.ifr_name, strerror(errno)); (void) close(fd); return (-1); } /* * Must be up */ if ((ifr.ifr_flags & IFF_UP) == 0) continue; sprintf(device, "%.*s", (int) sizeof(ifr.ifr_name), ifr.ifr_name); #ifdef sun /* * Ignore sun virtual interfaces */ if (strchr(device, ':') != NULL) continue; #endif if (ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) { (void) sprintf(errbuf, "SIOCGIFADDR: %s: %s", device, strerror(errno)); (void) close(fd); return (-1); } if (nipaddr >= MAX_IPADDR) { (void) sprintf(errbuf, "Too many interfaces (%d)", nipaddr); (void) close(fd); return (-1); } sin = (struct sockaddr_in *) &ifr.ifr_addr; al->addr = sin->sin_addr.s_addr; al->device = strdup(device); ++al; ++nipaddr; } (void) close(fd); *ipaddrp = ifaddrlist; return (nipaddr); }