Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.11.1.2
intf_stats_example.c
/*********************************************************************
*
* Copyright 2016-2018 Broadcom.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************
*
* @filename intf_stats_example.c
*
* @purpose Interface and Statistics APIs example.
*
* @component OPEN
*
* @note
*
* @create 08/29/2012
*
* @end
*
**********************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
#include "openapi_if.h"
#include "openapi_stats.h"
typedef struct
{
uint32_t ctrId;
char ctrName[40];
} ctrIdToStrMap_t;
char *exampleName;
static ctrIdToStrMap_t ctrIdToStr[] =
{
{OPEN_CTR_RESERVED, "OPEN_CTR_RESERVED"},
{OPEN_CTR_RX_TOTAL_BYTES, "OPEN_CTR_RX_TOTAL_BYTES"},
{OPEN_CTR_RX_64,"OPEN_CTR_RX_64"},
{OPEN_CTR_RX_65_127, "OPEN_CTR_RX_65_127"},
{OPEN_CTR_RX_128_255, "OPEN_CTR_RX_128_255"},
{OPEN_CTR_RX_256_511, "OPEN_CTR_RX_256_511"},
{OPEN_CTR_RX_512_1023, "OPEN_CTR_RX_512_1023"},
{OPEN_CTR_RX_1024_1518, "OPEN_CTR_RX_1024_1518"},
{OPEN_CTR_RX_1519_1530, "OPEN_CTR_RX_1519_1530"},
{OPEN_CTR_RX_GOOD_OVERSIZE, "OPEN_CTR_RX_GOOD_OVERSIZE"},
{OPEN_CTR_RX_ERROR_OVERSIZE, "OPEN_CTR_RX_ERROR_OVERSIZE"},
{OPEN_CTR_RX_GOOD_UNDERSIZE, "OPEN_CTR_RX_GOOD_UNDERSIZE"},
{OPEN_CTR_RX_ERROR_UNDERSIZE, "OPEN_CTR_RX_ERROR_UNDERSIZE"},
{OPEN_CTR_RX_UCAST_FRAMES, "OPEN_CTR_RX_UCAST_FRAMES"},
{OPEN_CTR_RX_MCAST_FRAMES, "OPEN_CTR_RX_MCAST_FRAMES"},
{OPEN_CTR_RX_BCAST_FRAMES, "OPEN_CTR_RX_BCAST_FRAMES"},
{OPEN_CTR_RX_ALIGN_ERRORS, "OPEN_CTR_RX_ALIGN_ERRORS"},
{OPEN_CTR_RX_FCS_ERRORS, "OPEN_CTR_RX_FCS_ERRORS"},
{OPEN_CTR_RX_OVERRUNS, "OPEN_CTR_RX_OVERRUNS"},
{OPEN_CTR_RX_FRAME_TOO_LONG, "OPEN_CTR_RX_FRAME_TOO_LONG"},
{OPEN_CTR_TX_TOTAL_BYTES, "OPEN_CTR_TX_TOTAL_BYTES"},
{OPEN_CTR_TX_64, "OPEN_CTR_TX_64"},
{OPEN_CTR_TX_65_127, "OPEN_CTR_TX_65_127"},
{OPEN_CTR_TX_128_255, "OPEN_CTR_TX_128_255"},
{OPEN_CTR_TX_256_511, "OPEN_CTR_TX_256_511"},
{OPEN_CTR_TX_512_1023, "OPEN_CTR_TX_512_1023"},
{OPEN_CTR_TX_1024_1518, "OPEN_CTR_TX_1024_1518"},
{OPEN_CTR_TX_1519_1530, "OPEN_CTR_TX_1519_1530"},
{OPEN_CTR_TX_UCAST_FRAMES, "OPEN_CTR_TX_UCAST_FRAMES"},
{OPEN_CTR_TX_MCAST_FRAMES, "OPEN_CTR_TX_MCAST_FRAMES"},
{OPEN_CTR_TX_BCAST_FRAMES, "OPEN_CTR_TX_BCAST_FRAMES"},
{OPEN_CTR_TX_FCS_ERRORS, "OPEN_CTR_TX_FCS_ERRORS"},
{OPEN_CTR_TX_OVERSIZED, "OPEN_CTR_TX_OVERSIZED"},
{OPEN_CTR_TX_UNDERRUN_ERRORS, "OPEN_CTR_TX_UNDERRUN_ERRORS"},
{OPEN_CTR_TX_ONE_COLLISION, "OPEN_CTR_TX_ONE_COLLISION"},
{OPEN_CTR_TX_MULTIPLE_COLLISION, "OPEN_CTR_TX_MULTIPLE_COLLISION"},
{OPEN_CTR_TX_EXCESSIVE_COLLISION, "OPEN_CTR_TX_EXCESSIVE_COLLISION"},
{OPEN_CTR_TX_LATE_COLLISION, "OPEN_CTR_TX_LATE_COLLISION"},
{OPEN_CTR_TX_RX_64, "OPEN_CTR_TX_RX_64"},
{OPEN_CTR_TX_RX_65_127, "OPEN_CTR_TX_RX_65_127"},
{OPEN_CTR_TX_RX_128_255, "OPEN_CTR_TX_RX_128_255"},
{OPEN_CTR_TX_RX_256_511, "OPEN_CTR_TX_RX_256_511"},
{OPEN_CTR_TX_RX_512_1023, "OPEN_CTR_TX_RX_512_1023"},
{OPEN_CTR_TX_RX_1024_1518, "OPEN_CTR_TX_RX_1024_1518"},
{OPEN_CTR_TX_RX_1519_1522, "OPEN_CTR_TX_RX_1519_1522"},
{OPEN_CTR_TX_RX_1523_2047, "OPEN_CTR_TX_RX_1523_2047"},
{OPEN_CTR_TX_RX_2048_4095, "OPEN_CTR_TX_RX_2048_4095"},
{OPEN_CTR_TX_RX_4096_9216, "OPEN_CTR_TX_RX_4096_9216"},
{OPEN_CTR_ETHER_STATS_DROP_EVENTS, "OPEN_CTR_ETHER_STATS_DROP_EVENTS"},
{OPEN_CTR_SNMPIFOUTDISCARD_FRAMES, "OPEN_CTR_SNMPIFOUTDISCARD_FRAMES"},
{OPEN_CTR_SNMPIFINDISCARD_FRAMES, "OPEN_CTR_SNMPIFINDISCARD_FRAMES"},
{OPEN_CTR_RX_TOTAL_FRAMES, "OPEN_CTR_RX_TOTAL_FRAMES"},
{OPEN_CTR_RX_TOTAL_ERROR_FRAMES, "OPEN_CTR_RX_TOTAL_ERROR_FRAMES"},
{OPEN_CTR_TX_TOTAL_FRAMES, "OPEN_CTR_TX_TOTAL_FRAMES"},
{OPEN_CTR_TX_TOTAL_ERROR_FRAMES, "OPEN_CTR_TX_TOTAL_ERROR_FRAMES"},
{OPEN_CTR_TX_TOTAL_COLLISION_FRAMES, "OPEN_CTR_TX_TOTAL_COLLISION_FRAMES"},
{OPEN_CTR_RX_CRC_ERRORS, "OPEN_CTR_RX_CRC_ERRORS"},
{OPEN_CTR_RX_TOTAL_MAC_ERROR_FRAMES, "OPEN_CTR_RX_TOTAL_MAC_ERROR_FRAMES"},
{OPEN_CTR_RX_RATE_BITS, "OPEN_CTR_RX_RATE_BITS"},
{OPEN_CTR_TX_RATE_BITS, "OPEN_CTR_TX_RATE_BITS"},
{OPEN_CTR_RX_RATE_FRAMES, "OPEN_CTR_RX_RATE_FRAMES"},
{OPEN_CTR_TX_RATE_FRAMES, "OPEN_CTR_TX_RATE_FRAMES"},
{OPEN_CTR_ETHER_STATS_HOLD, "OPEN_CTR_ETHER_STATS_HOLD"},
{OPEN_CTR_RX_JABBER_FRAMES, "OPEN_CTR_RX_JABBER_FRAMES"},
{OPEN_CTR_PORT_LINK_DOWN_COUNTER, "OPEN_CTR_PORT_LINK_DOWN_COUNTER"}
};
#define NUM_COUNTERS (sizeof(ctrIdToStr)/sizeof(ctrIdToStrMap_t))
/***************************************************************/
void printInterfaceStatsAppMenu()
{
printf("\nUsage: %s <test#> <arg1> <arg2> ... \n\n", exampleName);
printf("Test 0: Display interface Name to Interface Number: %s 0 \n", exampleName);
printf("Test 1: Display interface counter through iterative individual counter fetch: %s 1 <ifNum> \n", exampleName);
printf("Test 2: Display interface counter through bulk fetch: %s 2 <ifNum>\n", exampleName);
printf("Test 3: Reset interface counter: %s 3 <ifNum> <counter>\n", exampleName);
printf("Test 4: Reset all counters on interface: %s 4 <ifNum>\n", exampleName);
printf("Test 5: Display time elapsed after interface counter reset: %s 5 <ifNum>\n", exampleName);
}
/*****************************************************************/
void intfStatsBulkDisplay(openapiClientHandle_t *clientHandle, uint32_t ifNum)
{
char *ctrArray = NULL;
char linkName[256];
open_error_t result;
uint32_t i;
uint32_t bufSize;
uint64_t *pCtr;
uint32_t maxCtrIdx;
uint64_t ctrValue;
printf("\n");
/* get the size and allocate a counter array buffer */
result = openapiInterfaceStatsBufSizeGet(clientHandle, &bufSize);
if (OPEN_E_NONE != result)
{
printf("Error obtaining counter buffer size (rc = %d)\n\n", result);
return;
}
ctrArray = (char *)malloc(bufSize);
if (NULL == ctrArray)
{
printf("Cannot allocate memory for counter collection buffer\n\n");
return;
}
/* get all interface counters in a single OpEN API call */
memset(ctrArray, 0, bufSize);
bufd.pstart = ctrArray;
bufd.size = bufSize;
result = openapiInterfaceStatsGet(clientHandle, ifNum, &bufd);
if (OPEN_E_NONE != result)
{
printf("Error obtaining counters using bulk get method (rc = %d)\n", result);
free(ctrArray);
return;
}
memset(linkName, 0, sizeof(linkName));
bufd.pstart = linkName;
bufd.size = sizeof(linkName);
if (OPEN_E_NONE == openapiIfNameGet(clientHandle, ifNum, &bufd))
{
printf("Bulk statistics for interface %s:\n", linkName);
}
else
{
printf("Interface name retrieval error for ifNum %d\n\n", ifNum);
printf("Bulk statistics for ifNum %u\n", ifNum);
}
printf("\n");
/* Display all the counters for the interface */
pCtr = (uint64_t *)ctrArray;
maxCtrIdx = (uint32_t)*pCtr++; /* index 0 contains total number of counters provided */
for (i = 1; i < NUM_COUNTERS; i++)
{
if (i < maxCtrIdx)
{
ctrValue = *pCtr++;
}
else
{
ctrValue = 0;
}
printf("%-40s - 0x%016llx\n", ctrIdToStr[i].ctrName, ctrValue);
}
printf("\n");
free(ctrArray);
}
/*****************************************************************/
void intfStatsNameToNumMapDisplay(openapiClientHandle_t *clientHandle)
{
uint32_t i;
uint32_t ifNum;
char linkName[256];
open_buffdesc linkNameBuff = {.pstart = linkName, .size = sizeof(linkName)};
OPEN_LINK_STATE_t linkState;
printf(" Intf \n");
printf("ifNum Interface Name State \n");
printf("----- -------------------------------- ----- \n");
for (i = 0; i < OPEN_INTF_TYPE_ANY; i++)
{
switch (i)
{
break;
break;
break;
break;
default:
continue;
}
if (OPEN_E_NONE == openapiIfFirstGet(clientHandle, ifType, &ifNum))
{
do
{
printf("%5u ", ifNum);
memset(linkName, 0, sizeof(linkName));
linkNameBuff.size = sizeof(linkName);
if (openapiIfNameGet(clientHandle, ifNum, &linkNameBuff) == OPEN_E_NONE)
printf("%-32s ", (char *)linkNameBuff.pstart);
else
printf("%-32s ", "link name retrieve error");
if (openapiIfLinkStateGet(clientHandle, ifNum, &linkState) == OPEN_E_NONE)
printf("%-5s ", (linkState == OPEN_LINK_UP) ? "UP":"DOWN");
else
printf("%-5s ", "???");
printf("\n");
} while (OPEN_E_NONE == openapiIfNextGet(clientHandle, ifType, ifNum, &ifNum));
printf("\n");
}
}
}
/***************************************************************************/
void intfStatsIterativeDisplay(openapiClientHandle_t *clientHandle, uint32_t ifNum)
{
char linkName[256] = {0};
open_buffdesc linkNameBuff = {.pstart = linkName, .size = sizeof(linkName)};
char statValStr[OPEN_MIN_U64_STR_BUFFER_SIZE] = {0};
open_buffdesc statValStrBuff = {.pstart = statValStr, .size = sizeof(statValStr)};
uint64_t ctrValue;
uint32_t i;
printf("\n");
memset(linkName, 0, sizeof(linkName));
linkNameBuff.pstart = linkName;
linkNameBuff.size = sizeof(linkName);
if (OPEN_E_NONE == openapiIfNameGet(clientHandle, ifNum, &linkNameBuff))
printf("Displaying statistics of %s\n", (char *)linkNameBuff.pstart);
else
printf("link name retrieval error\n");
printf("\n");
/* Display all the counters on an interface using single get method */
for (i = 1; i < NUM_COUNTERS; i++)
{
ctrValue = -1;
rc = openapiStatGet(clientHandle, ctrIdToStr[i].ctrId, ifNum, &ctrValue);
switch (rc)
{
printf("%-40s - 0x%016llx\n", ctrIdToStr[i].ctrName, ctrValue);
break;
printf("%-40s - Counter unavailable\n", ctrIdToStr[i].ctrName);
break;
default:
printf("%-40s - Counter get failed (rc = %d)\n", ctrIdToStr[i].ctrName, rc);
break;
}
memset(statValStr, 0, sizeof(statValStr));
statValStrBuff.size = sizeof(statValStr);
rc = openapiStatStringGet(clientHandle, ctrIdToStr[i].ctrId, ifNum, &statValStrBuff);
switch (rc)
{
printf("%-40s - %s\n", ctrIdToStr[i].ctrName, (char *)statValStrBuff.pstart);
break;
printf("%-40s - Counter unavailable\n", ctrIdToStr[i].ctrName);
break;
default:
printf("%-40s - Counter get failed (rc = %d)\n", ctrIdToStr[i].ctrName, rc);
break;
}
}
}
/***************************************************************************/
void intfStatsReset(openapiClientHandle_t *clientHandle, uint32_t ifNum, OPEN_COUNTER_ID_t counter)
{
printf("Resetting %s on an interface.\n", ctrIdToStr[counter].ctrName);
rc = openapiStatReset(clientHandle, counter, ifNum);
if (OPEN_E_NONE == rc)
{
printf("%s Statistics reset successfully on interface %d.\n",
ctrIdToStr[counter].ctrName, ifNum);
}
else if (OPEN_E_NONE == rc)
{
printf("Failed to reset %s statistics on interface %d.\n",
ctrIdToStr[counter].ctrName, ifNum);
}
else if (OPEN_E_NONE == rc)
{
printf("Error resetting stats.\n");
}
else
{
printf("Internal error.\n");
}
printf("\n");
}
/***************************************************************************/
void intfInterfaceStatsReset(openapiClientHandle_t *clientHandle, uint32_t ifNum)
{
printf("Resetting all counters on an interface %d.\n", ifNum);
rc = openapiInterfaceStatsReset(clientHandle, ifNum);
if (OPEN_E_NONE == rc)
{
printf("Statistics reset successfully on interface %d.\n", ifNum);
}
else if (OPEN_E_NONE == rc)
{
printf("Failed to reset statistics on interface %d.\n", ifNum);
}
else if (OPEN_E_NONE == rc)
{
printf("Error resetting stats.\n");
}
else
{
printf("Internal error.\n");
}
printf("\n");
}
/***************************************************************************/
void intfStatsResetTimeGet(openapiClientHandle_t *clientHandle, uint32_t ifNum)
{
uint32_t lastResetSecs;
rc = openapiInterfaceStatsResetTimeGet(clientHandle, ifNum, &lastResetSecs);
if (OPEN_E_NONE == rc)
{
printf("Seconds since stats last reset on interface %d: %8u (after)\n", ifNum, lastResetSecs);
}
else
{
printf("Failed to get last reset time on interface %d.\n", ifNum);
}
printf("\n");
}
/***************************************************************/
int main(int argc, char **argv)
{
openapiClientHandle_t clientHandle;
uint32_t ifNum;
open_buffdesc linkNameBuff;
char linkName[256];
uint32_t testNum;
exampleName = argv[0];
if (argc < 2)
{
printInterfaceStatsAppMenu();
exit(1);
}
testNum = atoi(argv[1]);
l7proc_crashlog_register();
/* Register with OpEN */
if (OPEN_E_NONE != (rc = openapiClientRegister("intf_stats_example", &clientHandle)))
{
printf("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", rc);
exit(1);
}
/* RPC call can fail until server starts. Keep trying */
while (OPEN_E_NONE != openapiConnectivityCheck(&clientHandle))
{
sleep(1);
}
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Starting interface statistics example application");
linkNameBuff.pstart = linkName;
linkNameBuff.size = sizeof(linkName);
printf("\n");
if (OPEN_E_NONE == openapiNetworkOSVersionGet(&clientHandle, &linkNameBuff))
printf("Network OS version = %s\n", (char *) linkNameBuff.pstart);
else
printf("Network OS Version retrieve error\n");
printf("\n");
switch (testNum)
{
case 0:
if (2 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
intfStatsNameToNumMapDisplay(&clientHandle);
break;
case 1:
if (3 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
ifNum = atoi(argv[2]);
intfStatsIterativeDisplay(&clientHandle, ifNum);
break;
case 2:
if (3 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
ifNum = atoi(argv[2]);
intfStatsBulkDisplay(&clientHandle, ifNum);
break;
case 3:
if (4 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
ifNum = atoi(argv[2]);
counter = atoi(argv[3]);
intfStatsReset(&clientHandle, ifNum, counter);
break;
case 4:
if (3 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
ifNum = atoi(argv[2]);
intfInterfaceStatsReset(&clientHandle, ifNum);
break;
case 5:
if (3 != argc)
{
printInterfaceStatsAppMenu();
exit(1);
}
ifNum = atoi(argv[2]);
intfStatsResetTimeGet(&clientHandle, ifNum);
break;
}
/* Log goodbye message with OPEN */
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Stopping interface statistics example application");
(void) openapiClientTearDown(&clientHandle);
return 0;
}