From 7c8f3392b237fbe00b84134f3b793f139b3330e7 Mon Sep 17 00:00:00 2001 From: cruxic Date: Mon, 30 Sep 2024 22:34:29 -0700 Subject: [PATCH] Bugfix in ATSAME5x network interface. Incorrect detection of ICMP (#1194) Bugfix in ATSAME5x network interface. Incorrect detection of ICMP packets when CRC offloading is enabled. Co-authored-by: Adam B. --- .../ATSAME5x/NetworkInterface.c | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/source/portable/NetworkInterface/ATSAME5x/NetworkInterface.c b/source/portable/NetworkInterface/ATSAME5x/NetworkInterface.c index 72fbd8c55..dabedde09 100644 --- a/source/portable/NetworkInterface/ATSAME5x/NetworkInterface.c +++ b/source/portable/NetworkInterface/ATSAME5x/NetworkInterface.c @@ -90,6 +90,9 @@ static uint8_t ucLLMNR_MAC_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC }; #endif +/* Check if the raw Ethernet frame is ICMP */ +static BaseType_t isICMP( const NetworkBufferDescriptor_t * pxDescriptor ); + /* Receive task refresh time */ #define RECEIVE_BLOCK_TIME_MS 100 @@ -272,6 +275,34 @@ BaseType_t xATSAM5x_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface return xATSAM5x_PHYGetLinkStatus( NULL ); } +/* Check if the raw Ethernet frame is ICMP */ +static BaseType_t isICMP( const NetworkBufferDescriptor_t * pxDescriptor ) +{ + BaseType_t xReturn = pdFALSE; + + const IPPacket_t * pkt = ( const IPPacket_t * ) pxDescriptor->pucEthernetBuffer; + + if( pkt->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) + { + if( pkt->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) + { + xReturn = pdTRUE; + } + } + + #if ipconfigUSE_IPv6 != 0 + else if( pkt->xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE ) + { + ICMPPacket_IPv6_t * icmp6 = ( ICMPPacket_IPv6_t * ) pxDescriptor->pucEthernetBuffer; + + if( icmp6->xIPHeader.ucNextHeader == ipPROTOCOL_ICMP_IPv6 ) + { + xReturn = pdTRUE; + } + } + #endif + return xReturn; +} static void prvEMACDeferredInterruptHandlerTask( void * pvParameters ) { @@ -279,7 +310,6 @@ static void prvEMACDeferredInterruptHandlerTask( void * pvParameters ) size_t xBytesReceived = 0, xBytesRead = 0; uint16_t xICMPChecksumResult = ipCORRECT_CRC; - const IPPacket_t * pxIPPacket; /* Used to indicate that xSendEventStructToIPTask() is being called because @@ -336,15 +366,13 @@ static void prvEMACDeferredInterruptHandlerTask( void * pvParameters ) { /* the Atmel SAM GMAC peripheral does not support hardware CRC offloading for ICMP packets. * It must therefore be implemented in software. */ - pxIPPacket = ( IPPacket_t const * ) pxBufferDescriptor->pucEthernetBuffer; - - if( pxIPPacket->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) + if( isICMP( pxBufferDescriptor ) == pdTRUE ) { xICMPChecksumResult = usGenerateProtocolChecksum( pxBufferDescriptor->pucEthernetBuffer, pxBufferDescriptor->xDataLength, pdFALSE ); } else { - xICMPChecksumResult = ipCORRECT_CRC; /* Reset the result value in case this is not an ICMP packet. */ + xICMPChecksumResult = ipCORRECT_CRC; /* Checksum already verified by GMAC */ } } #endif /* if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 ) */ @@ -440,9 +468,7 @@ BaseType_t xATSAM5x_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, { /* the Atmel SAM GMAC peripheral does not support hardware CRC offloading for ICMP packets. * It must therefore be implemented in software. */ - const IPPacket_t * pxIPPacket = ( IPPacket_t const * ) pxDescriptor->pucEthernetBuffer; - - if( pxIPPacket->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) + if( isICMP( pxDescriptor ) == pdTRUE ) { ( void ) usGenerateProtocolChecksum( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, pdTRUE ); }