@ -36,6 +36,9 @@
/* Demo config. */
# include "demo_config.h"
/* Device Defender Client Library. */
# include "defender.h"
/* Interface include. */
# include "report_builder.h"
@ -50,53 +53,68 @@
/* Formats used to generate the JSON report. */
# define reportbuilderJSON_PORT_OBJECT_FORMAT \
" { " \
" \" port\" : %u " \
" \" %s\" : %u " \
" }, "
# define reportbuilderJSON_CONNECTION_OBJECT_FORMAT \
" { " \
" \" local_port\" : %u, " \
" \" remote_addr \" : \" %u.%u.%u.%u:%u \" " \
" \" %s\" : %u, " \
" \" %s \" : \" %u.%u.%u.%u:%u \" " \
" }, "
# define reportbuilderJSON_REPORT_FORMAT_PART1 \
" { " \
" \" header\" : { " \
" \" report_id\" : %u, " \
" \" version \" : \" %u.%u \" " \
" \" %s\" : { " \
" \" %s\" : %u, " \
" \" %s \" : \" %u.%u \" " \
" }, " \
" \" metrics\" : { " \
" \" listening_tcp_ports\" : { " \
" \" port s\" : "
" \" %s\" : { " \
" \" %s\" : { " \
" \" % s\" : "
# define reportbuilderJSON_REPORT_FORMAT_PART2 \
" , " \
" \" total\" : %u " \
" \" %s\" : %u " \
" }, " \
" \" listening_udp_ports\" : { " \
" \" port s\" : "
" \" %s\" : { " \
" \" % s\" : "
# define reportbuilderJSON_REPORT_FORMAT_PART3 \
" , " \
" \" total\" : %u " \
" \" %s\" : %u " \
" }, " \
" \" network_stats\" : { " \
" \" bytes_in\" : %u, " \
" \" bytes_out\" : %u, " \
" \" packets_in\" : %u, " \
" \" packets_out\" : %u " \
" \" %s\" : { " \
" \" %s\" : %u, " \
" \" %s\" : %u, " \
" \" %s\" : %u, " \
" \" %s\" : %u " \
" }, " \
" \" tcp_connections\" : { " \
" \" established_connections\" : { " \
" \" connection s\" : "
" \" %s\" : { " \
" \" %s\" : { " \
" \" % s\" : "
# define reportbuilderJSON_REPORT_FORMAT_PART4 \
" , " \
" \" total \" : %u " \
" \" %s \" : %u " \
" } " \
" } " \
" }, " \
" \" %s \" : { " \
" \" stack_high_water_mark \" : [ " \
" { " \
" \" %s \" : %u " \
" } " \
" ], " \
" \" task_numbers \" : [ " \
" { " \
" \" %s \" : "
# define reportbuilderJSON_REPORT_FORMAT_PART5 \
" } " \
" ] " \
" } " \
" } "
/*-----------------------------------------------------------*/
/**
@ -158,6 +176,24 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer,
const Connection_t * pxConnectionsArray ,
uint32_t ulConnectionsArrayLength ,
uint32_t * pulOutCharsWritten ) ;
/**
* @ brief Write task ID array to the given buffer as a JSON array .
*
* @ param [ in ] pcBuffer The buffer to write the array of task IDs .
* @ param [ in ] ulBufferLength The length of the buffer .
* @ param [ in ] pulTaskIdArray The array containing the task IDs .
* @ param [ in ] pulTaskIdArrayLength Length of the pulTaskIdsArray array .
* @ param [ out ] pulOutCharsWritten Number of characters written to the buffer .
*
* @ return # ReportBuilderSuccess if the array is successfully written ;
* # ReportBuilderBufferTooSmall if the buffer cannot hold the full array .
*/
static eReportBuilderStatus prvWriteTaskIdArray ( char * pcBuffer ,
uint32_t ulBufferLength ,
const uint32_t * pulTaskIdArray ,
uint32_t pulTaskIdArrayLength ,
uint32_t * pulOutCharsWritten ) ;
/*-----------------------------------------------------------*/
static eReportBuilderStatus prvWritePortsArray ( char * pcBuffer ,
@ -168,7 +204,7 @@ static eReportBuilderStatus prvWritePortsArray( char * pcBuffer,
{
char * pcCurrentWritePos = pcBuffer ;
uint32_t i , ulRemainingBufferLength = ulBufferLength ;
int32_t u lCharactersWritten;
int32_t lCharactersWritten;
eReportBuilderStatus eStatus = eReportBuilderSuccess ;
configASSERT ( pcBuffer ! = NULL ) ;
@ -190,20 +226,20 @@ static eReportBuilderStatus prvWritePortsArray( char * pcBuffer,
/* Write the array elements. */
for ( i = 0 ; ( ( i < ulOpenPortsArrayLength ) & & ( eStatus = = eReportBuilderSuccess ) ) ; i + + )
{
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_PORT_OBJECT_FORMAT ,
pusOpenPortsArray [ i ] ) ;
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_PORT_OBJECT_FORMAT ,
DEFENDER_REPORT_PORT_KEY ,
pusOpenPortsArray [ i ] ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( u lCharactersWritten, ulRemainingBufferLength ) )
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten, ulRemainingBufferLength ) )
{
eStatus = eReportBuilderBufferTooSmall ;
break ;
}
else
{
ulRemainingBufferLength - = ( uint32_t ) u lCharactersWritten;
pcCurrentWritePos + = u lCharactersWritten;
ulRemainingBufferLength - = ( uint32_t ) lCharactersWritten;
pcCurrentWritePos + = lCharactersWritten;
}
}
@ -222,6 +258,7 @@ static eReportBuilderStatus prvWritePortsArray( char * pcBuffer,
* pcCurrentWritePos = reportbuilderJSON_ARRAY_CLOSE_MARKER ;
ulRemainingBufferLength - = 1 ;
pcCurrentWritePos + = 1 ;
* pulOutCharsWritten = ulBufferLength - ulRemainingBufferLength ;
}
else
{
@ -229,11 +266,6 @@ static eReportBuilderStatus prvWritePortsArray( char * pcBuffer,
}
}
if ( eStatus = = eReportBuilderSuccess )
{
* pulOutCharsWritten = ulBufferLength - ulRemainingBufferLength ;
}
return eStatus ;
}
/*-----------------------------------------------------------*/
@ -246,7 +278,7 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer,
{
char * pcCurrentWritePos = pcBuffer ;
uint32_t i , ulRemainingBufferLength = ulBufferLength ;
int32_t u lCharactersWritten;
int32_t lCharactersWritten;
eReportBuilderStatus eStatus = eReportBuilderSuccess ;
const Connection_t * pxConn ;
@ -270,25 +302,26 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer,
for ( i = 0 ; ( ( i < ulConnectionsArrayLength ) & & ( eStatus = = eReportBuilderSuccess ) ) ; i + + )
{
pxConn = & ( pxConnectionsArray [ i ] ) ;
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_CONNECTION_OBJECT_FORMAT ,
pxConn - > usLocalPort ,
( pxConn - > ulRemoteIp > > 24 ) & 0xFF ,
( pxConn - > ulRemoteIp > > 16 ) & 0xFF ,
( pxConn - > ulRemoteIp > > 8 ) & 0xFF ,
( pxConn - > ulRemoteIp ) & 0xFF ,
pxConn - > usRemotePort ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( ulCharactersWritten , ulRemainingBufferLength ) )
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_CONNECTION_OBJECT_FORMAT ,
DEFENDER_REPORT_LOCAL_PORT_KEY ,
pxConn - > usLocalPort ,
DEFENDER_REPORT_REMOTE_ADDR_KEY ,
( pxConn - > ulRemoteIp > > 24 ) & 0xFF ,
( pxConn - > ulRemoteIp > > 16 ) & 0xFF ,
( pxConn - > ulRemoteIp > > 8 ) & 0xFF ,
( pxConn - > ulRemoteIp ) & 0xFF ,
pxConn - > usRemotePort ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
eStatus = eReportBuilderBufferTooSmall ;
break ;
}
else
{
ulRemainingBufferLength - = u lCharactersWritten;
pcCurrentWritePos + = u lCharactersWritten;
ulRemainingBufferLength - = lCharactersWritten;
pcCurrentWritePos + = lCharactersWritten;
}
}
@ -307,6 +340,7 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer,
* pcCurrentWritePos = reportbuilderJSON_ARRAY_CLOSE_MARKER ;
ulRemainingBufferLength - = 1 ;
pcCurrentWritePos + = 1 ;
* pulOutCharsWritten = ulBufferLength - ulRemainingBufferLength ;
}
else
{
@ -314,9 +348,77 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer,
}
}
return eStatus ;
}
/*-----------------------------------------------------------*/
static eReportBuilderStatus prvWriteTaskIdArray ( char * pcBuffer ,
uint32_t ulBufferLength ,
const uint32_t * pulTaskIdArray ,
uint32_t pulTaskIdArrayLength ,
uint32_t * pulOutCharsWritten )
{
char * pcCurrentWritePos = pcBuffer ;
uint32_t i , ulRemainingBufferLength = ulBufferLength ;
int32_t lCharactersWritten ;
eReportBuilderStatus eStatus = eReportBuilderSuccess ;
configASSERT ( pcBuffer ! = NULL ) ;
configASSERT ( pulTaskIdArray ! = NULL ) ;
configASSERT ( pulOutCharsWritten ! = NULL ) ;
/* Write the JSON array open marker. */
if ( ulRemainingBufferLength > 1 )
{
* pcCurrentWritePos = reportbuilderJSON_ARRAY_OPEN_MARKER ;
ulRemainingBufferLength - = 1 ;
pcCurrentWritePos + = 1 ;
}
else
{
eStatus = eReportBuilderBufferTooSmall ;
}
/* Write the array elements. */
for ( i = 0 ; ( ( i < pulTaskIdArrayLength ) & & ( eStatus = = eReportBuilderSuccess ) ) ; i + + )
{
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
" %u, " ,
pulTaskIdArray [ i ] ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = ( uint32_t ) lCharactersWritten ;
pcCurrentWritePos + = lCharactersWritten ;
}
}
if ( eStatus = = eReportBuilderSuccess )
{
* pulOutCharsWritten = ulBufferLength - ulRemainingBufferLength ;
/* Discard the last comma. */
if ( pulTaskIdArrayLength > 0 )
{
pcCurrentWritePos - = 1 ;
ulRemainingBufferLength + = 1 ;
}
/* Write the JSON array close marker. */
if ( ulRemainingBufferLength > 1 )
{
* pcCurrentWritePos = reportbuilderJSON_ARRAY_CLOSE_MARKER ;
ulRemainingBufferLength - = 1 ;
pcCurrentWritePos + = 1 ;
* pulOutCharsWritten = ulBufferLength - ulRemainingBufferLength ;
}
else
{
eStatus = eReportBuilderBufferTooSmall ;
}
}
return eStatus ;
@ -332,9 +434,10 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer,
uint32_t * pulOutReportLength )
{
char * pcCurrentWritePos = pcBuffer ;
uint32_t ulRemainingBufferLength = ulBufferLength , bufferWritten ;
uint32_t ulRemainingBufferLength = ulBufferLength ;
uint32_t bufferWritten ;
eReportBuilderStatus eStatus = eReportBuilderSuccess ;
int32_t u lCharactersWritten;
int32_t lCharactersWritten;
configASSERT ( pcBuffer ! = NULL ) ;
configASSERT ( pxMetrics ! = NULL ) ;
@ -358,22 +461,29 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer,
/* Write part1. */
if ( eStatus = = eReportBuilderSuccess )
{
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART1 ,
ulReportId ,
ulMajorReportVersion ,
ulMinorReportVersion ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( ulCharactersWritten , ulRemainingBufferLength ) )
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART1 ,
DEFENDER_REPORT_HEADER_KEY ,
DEFENDER_REPORT_ID_KEY ,
ulReportId ,
DEFENDER_REPORT_VERSION_KEY ,
ulMajorReportVersion ,
ulMinorReportVersion ,
DEFENDER_REPORT_METRICS_KEY ,
DEFENDER_REPORT_TCP_LISTENING_PORTS_KEY ,
DEFENDER_REPORT_PORTS_KEY
) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
LogError ( ( " Failed to write part 1. " ) ) ;
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = ulCharactersWritten ;
pcCurrentWritePos + = u lCharactersWritten;
ulRemainingBufferLength - = lCharactersWritten;
pcCurrentWritePos + = lCharactersWritten;
}
}
@ -400,20 +510,24 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer,
/* Write part2. */
if ( eStatus = = eReportBuilderSuccess )
{
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART2 ,
pxMetrics - > ulOpenTcpPortsArrayLength ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( ulCharactersWritten , ulRemainingBufferLength ) )
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART2 ,
DEFENDER_REPORT_TOTAL_KEY ,
pxMetrics - > ulOpenTcpPortsArrayLength ,
DEFENDER_REPORT_UDP_LISTENING_PORTS_KEY ,
DEFENDER_REPORT_PORTS_KEY
) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
LogError ( ( " Failed to write part 2. " ) ) ;
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = u lCharactersWritten;
pcCurrentWritePos + = u lCharactersWritten;
ulRemainingBufferLength - = lCharactersWritten;
pcCurrentWritePos + = lCharactersWritten;
}
}
@ -440,24 +554,34 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer,
/* Write part3. */
if ( eStatus = = eReportBuilderSuccess )
{
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART3 ,
pxMetrics - > ulOpenUdpPortsArrayLength ,
pxMetrics - > pxNetworkStats - > ulBytesReceived ,
pxMetrics - > pxNetworkStats - > ulBytesSent ,
pxMetrics - > pxNetworkStats - > ulPacketsReceived ,
pxMetrics - > pxNetworkStats - > ulPacketsSent ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( ulCharactersWritten , ulRemainingBufferLength ) )
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART3 ,
DEFENDER_REPORT_TOTAL_KEY ,
pxMetrics - > ulOpenUdpPortsArrayLength ,
DEFENDER_REPORT_NETWORK_STATS_KEY ,
DEFENDER_REPORT_BYTES_IN_KEY ,
pxMetrics - > pxNetworkStats - > ulBytesReceived ,
DEFENDER_REPORT_BYTES_OUT_KEY ,
pxMetrics - > pxNetworkStats - > ulBytesSent ,
DEFENDER_REPORT_PKTS_IN_KEY ,
pxMetrics - > pxNetworkStats - > ulPacketsReceived ,
DEFENDER_REPORT_PKTS_OUT_KEY ,
pxMetrics - > pxNetworkStats - > ulPacketsSent ,
DEFENDER_REPORT_TCP_CONNECTIONS_KEY ,
DEFENDER_REPORT_ESTABLISHED_CONNECTIONS_KEY ,
DEFENDER_REPORT_CONNECTIONS_KEY
) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
LogError ( ( " Failed to write part 3. " ) ) ;
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = ulCharactersWritten ;
pcCurrentWritePos + = ulCharactersWritten ;
ulRemainingBufferLength - = lCharactersWritten;
pcCurrentWritePos + = lCharactersWritten;
}
}
@ -484,26 +608,67 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer,
/* Write part4. */
if ( eStatus = = eReportBuilderSuccess )
{
ulCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART4 ,
pxMetrics - > ulEstablishedConnectionsArrayLength ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( ulCharactersWritten , ulRemainingBufferLength ) )
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART4 ,
DEFENDER_REPORT_TOTAL_KEY ,
pxMetrics - > ulEstablishedConnectionsArrayLength ,
DEFENDER_REPORT_CUSTOM_METRICS_KEY ,
DEFENDER_REPORT_NUMBER_KEY ,
pxMetrics - > ulStackHighWaterMark ,
DEFENDER_REPORT_NUMBER_LIST_KEY
) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
LogError ( ( " Failed to write part 4. " ) ) ;
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = ulCharactersWritten ;
pcCurrentWritePos + = ulCharactersWritten ;
ulRemainingBufferLength - = lCharactersWritten ;
pcCurrentWritePos + = lCharactersWritten ;
}
}
/* Write task ids array. */
if ( eStatus = = eReportBuilderSuccess )
{
eStatus = prvWriteTaskIdArray ( pcCurrentWritePos ,
ulRemainingBufferLength ,
pxMetrics - > pulTaskIdArray ,
pxMetrics - > ulTaskIdArrayLength ,
& ( bufferWritten ) ) ;
if ( eStatus = = eReportBuilderSuccess )
{
pcCurrentWritePos + = bufferWritten ;
ulRemainingBufferLength - = bufferWritten ;
}
else
{
LogError ( ( " Failed to write task ID array. " ) ) ;
}
}
/* Write part5. */
if ( eStatus = = eReportBuilderSuccess )
{
* pulOutReportLength = ulBufferLength - ulRemainingBufferLength ;
lCharactersWritten = snprintf ( pcCurrentWritePos ,
ulRemainingBufferLength ,
reportbuilderJSON_REPORT_FORMAT_PART5 ) ;
if ( ! reportbuilderSNPRINTF_SUCCESS ( lCharactersWritten , ulRemainingBufferLength ) )
{
LogError ( ( " Failed to write part 5. " ) ) ;
eStatus = eReportBuilderBufferTooSmall ;
}
else
{
ulRemainingBufferLength - = lCharactersWritten ;
pcCurrentWritePos + = lCharactersWritten ;
* pulOutReportLength = ulBufferLength - ulRemainingBufferLength ;
}
}
return eStatus ;