Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * pxIPPacket,
* Turns around an incoming ping request to convert it into a ping reply.
*/
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket );
static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket,
NetworkBufferDescriptor_t * const pxNetworkBuffer );
#endif /* ipconfigREPLY_TO_INCOMING_PINGS */

/*
Expand Down Expand Up @@ -3038,11 +3039,11 @@ static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * pxIPPacket,
*
* @param[in,out] pxICMPPacket: The IP packet that contains the ICMP message.
*/
static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket )
static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket,
NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
ICMPHeader_t * pxICMPHeader;
IPHeader_t * pxIPHeader;
uint16_t usRequest;
uint32_t ulIPAddress;

pxICMPHeader = &( pxICMPPacket->xICMPHeader );
Expand All @@ -3060,22 +3061,32 @@ static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * pxIPPacket,
pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
pxIPHeader->ulSourceIPAddress = ulIPAddress;

/* Update the checksum because the ucTypeOfMessage member in the header
* has been changed to ipICMP_ECHO_REPLY. This is faster than calling
* usGenerateChecksum(). */

/* due to compiler warning "integer operation result is out of range" */
/* The stack doesn't support fragments, so the fragment offset field must always be zero.
* The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
*/
#if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
#else
pxIPHeader->usFragmentOffset = 0U;
#endif

usRequest = ( uint16_t ) ( ( uint16_t ) ipICMP_ECHO_REQUEST << 8 );
#if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
/* calculate the IP header checksum, in case the driver won't do that. */
pxIPHeader->usHeaderChecksum = 0x00U;
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );

if( pxICMPHeader->usChecksum >= FreeRTOS_htons( 0xFFFFU - usRequest ) )
{
pxICMPHeader->usChecksum = pxICMPHeader->usChecksum + FreeRTOS_htons( usRequest + 1U );
}
else
{
pxICMPHeader->usChecksum = pxICMPHeader->usChecksum + FreeRTOS_htons( usRequest );
}
/* calculate the ICMP checksum for an outgoing packet. */
( void ) usGenerateProtocolChecksum( ( uint8_t * ) pxICMPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
}
#else
{
/* Many EMAC peripherals will only calculate the ICMP checksum
* correctly if the field is nulled beforehand. */
pxICMPHeader->usChecksum = 0U;
}
#endif /* if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) */

return eReturnEthernetFrame;
}
Expand Down Expand Up @@ -3111,7 +3122,7 @@ static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * pxIPPacket,
case ipICMP_ECHO_REQUEST:
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
{
eReturn = prvProcessICMPEchoRequest( pxICMPPacket );
eReturn = prvProcessICMPEchoRequest( pxICMPPacket, pxNetworkBuffer );
}
#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) */
break;
Expand Down Expand Up @@ -3394,7 +3405,7 @@ static BaseType_t prvChecksumProtocolChecks( size_t uxBufferLength,
#if ( ipconfigUSE_IPv6 != 0 )
else if( pxSet->ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP_IPv6 )
{
prvChecksumICMPv6Checks( uxBufferLength, pxSet );
xReturn = prvChecksumICMPv6Checks( uxBufferLength, pxSet );
}
#endif /* if ( ipconfigUSE_IPv6 != 0 ) */
else
Expand Down Expand Up @@ -3469,7 +3480,8 @@ static void prvChecksumProtocolCalculate( BaseType_t xOutgoingPacket,
* 36..38 three zero's
* 39 Next Header, i.e. the protocol type. */

pulHeader[ 0 ] = FreeRTOS_htonl( pxSet->usProtocolBytes );
pulHeader[ 0 ] = ( uint32_t ) pxSet->usProtocolBytes;
pulHeader[ 0 ] = FreeRTOS_htonl( pulHeader[ 0 ] );
pulHeader[ 1 ] = ( uint32_t ) pxSet->pxIPPacket_IPv6->ucNextHeader;
pulHeader[ 1 ] = FreeRTOS_htonl( pulHeader[ 1 ] );

Expand Down
15 changes: 12 additions & 3 deletions FreeRTOS_ND.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,18 @@
/* Important: tell NIC driver how many bytes must be sent */
pxNetworkBuffer->xDataLength = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxICMPSize );

pxICMPHeader_IPv6->usChecksum = 0;
/* calculate the UDP checksum for outgoing package */
( void ) usGenerateProtocolChecksum( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, pdTRUE );
#if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
/* calculate the UDP checksum for outgoing package */
( void ) usGenerateProtocolChecksum( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, pdTRUE );
}
#else
{
/* Many EMAC peripherals will only calculate the ICMP checksum
* correctly if the field is nulled beforehand. */
pxICMPHeader_IPv6->usChecksum = 0;
}
#endif

/* This function will fill in the Ethernet addresses and send the packet */
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
Expand Down