Skip to content

Commit 280ec68

Browse files
committed
Bugfix in ATSAME5x network interface. Incorrect detection of ICMP packets when CRC offloading is enabled.
1 parent 875bfd2 commit 280ec68

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

source/portable/NetworkInterface/ATSAME5x/NetworkInterface.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,27 @@ BaseType_t xATSAM5x_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface
272272
return xATSAM5x_PHYGetLinkStatus( NULL );
273273
}
274274

275+
/* Check if the raw ethernet frame is ICMP */
276+
static inline BaseType_t isICMP(const NetworkBufferDescriptor_t * pxDescriptor) {
277+
const IPPacket_t * pkt = (const IPPacket_t *) pxDescriptor->pucEthernetBuffer;
278+
if (pkt->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE) {
279+
return pkt->xIPHeader.ucProtocol == (uint8_t) ipPROTOCOL_ICMP;
280+
}
281+
#if ipconfigUSE_IPv6 != 0
282+
else if (pkt->xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE) {
283+
ICMPPacket_IPv6_t * icmp6 = (ICMPPacket_IPv6_t *) pxDescriptor->pucEthernetBuffer;
284+
return icmp6->xIPHeader.ucNextHeader == ipPROTOCOL_ICMP_IPv6;
285+
}
286+
#endif
287+
return pdFALSE;
288+
}
275289

276290
static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
277291
{
278292
NetworkBufferDescriptor_t * pxBufferDescriptor;
279293
size_t xBytesReceived = 0, xBytesRead = 0;
280294

281295
uint16_t xICMPChecksumResult = ipCORRECT_CRC;
282-
const IPPacket_t * pxIPPacket;
283296

284297

285298
/* Used to indicate that xSendEventStructToIPTask() is being called because
@@ -335,16 +348,12 @@ static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
335348
#if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 )
336349
{
337350
/* the Atmel SAM GMAC peripheral does not support hardware CRC offloading for ICMP packets.
338-
* It must therefore be implemented in software. */
339-
pxIPPacket = ( IPPacket_t const * ) pxBufferDescriptor->pucEthernetBuffer;
340-
341-
if( pxIPPacket->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
342-
{
351+
* It must therefore be implemented in software. */
352+
if ( isICMP(pxBufferDescriptor) ) {
343353
xICMPChecksumResult = usGenerateProtocolChecksum( pxBufferDescriptor->pucEthernetBuffer, pxBufferDescriptor->xDataLength, pdFALSE );
344354
}
345-
else
346-
{
347-
xICMPChecksumResult = ipCORRECT_CRC; /* Reset the result value in case this is not an ICMP packet. */
355+
else {
356+
xICMPChecksumResult = ipCORRECT_CRC; /* Checksum already verified by GMAC */
348357
}
349358
}
350359
#endif /* if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 ) */
@@ -440,12 +449,9 @@ BaseType_t xATSAM5x_NetworkInterfaceOutput( NetworkInterface_t * pxInterface,
440449
{
441450
/* the Atmel SAM GMAC peripheral does not support hardware CRC offloading for ICMP packets.
442451
* It must therefore be implemented in software. */
443-
const IPPacket_t * pxIPPacket = ( IPPacket_t const * ) pxDescriptor->pucEthernetBuffer;
444-
445-
if( pxIPPacket->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
446-
{
447-
( void ) usGenerateProtocolChecksum( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, pdTRUE );
448-
}
452+
if ( isICMP(pxDescriptor) ) {
453+
usGenerateProtocolChecksum( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, pdTRUE );
454+
}
449455
}
450456
#endif /* if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) */
451457

0 commit comments

Comments
 (0)