in FreeRTOS_IP.c [1959:2140]
static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPPacket,
const NetworkBufferDescriptor_t * const pxNetworkBuffer,
UBaseType_t uxHeaderLength )
{
eFrameProcessingResult_t eReturn = eProcessBuffer;
#if ( ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
#else
/* or else, the parameter won't be used and the function will be optimised
* away */
( void ) pxIPPacket;
#endif
#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
{
/* In systems with a very small amount of RAM, it might be advantageous
* to have incoming messages checked earlier, by the network card driver.
* This method may decrease the usage of sparse network buffers. */
uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
uint32_t ulSourceIPAddress = pxIPHeader->ulSourceIPAddress;
/* Ensure that the incoming packet is not fragmented because the stack
* doesn't not support IP fragmentation. All but the last fragment coming in will have their
* "more fragments" flag set and the last fragment will have a non-zero offset.
* We need to drop the packet in either of those cases. */
if( ( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U ) || ( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_FLAGS_MORE_FRAGMENTS ) != 0U ) )
{
/* Can not handle, fragmented packet. */
eReturn = eReleaseBuffer;
}
/* Test if the length of the IP-header is between 20 and 60 bytes,
* and if the IP-version is 4. */
else if( ( pxIPHeader->ucVersionHeaderLength < ipIPV4_VERSION_HEADER_LENGTH_MIN ) ||
( pxIPHeader->ucVersionHeaderLength > ipIPV4_VERSION_HEADER_LENGTH_MAX ) )
{
/* Can not handle, unknown or invalid header version. */
eReturn = eReleaseBuffer;
}
/* Is the packet for this IP address? */
else if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
/* Is it the global broadcast address 255.255.255.255 ? */
( ulDestinationIPAddress != ipBROADCAST_IP_ADDRESS ) &&
/* Is it a specific broadcast address 192.168.1.255 ? */
( ulDestinationIPAddress != xNetworkAddressing.ulBroadcastAddress ) &&
#if ( ipconfigUSE_LLMNR == 1 )
/* Is it the LLMNR multicast address? */
( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
#endif
/* Or (during DHCP negotiation) we have no IP-address yet? */
( *ipLOCAL_IP_ADDRESS_POINTER != 0U ) )
{
/* Packet is not for this node, release it */
eReturn = eReleaseBuffer;
}
/* Is the source address correct? */
else if( ( FreeRTOS_ntohl( ulSourceIPAddress ) & 0xffU ) == 0xffU )
{
/* The source address cannot be broadcast address. Replying to this
* packet may cause network storms. Drop the packet. */
eReturn = eReleaseBuffer;
}
else if( ( memcmp( ( const void * ) xBroadcastMACAddress.ucBytes,
( const void * ) ( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes ),
sizeof( MACAddress_t ) ) == 0 ) &&
( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xffU ) != 0xffU ) )
{
/* Ethernet address is a broadcast address, but the IP address is not a
* broadcast address. */
eReturn = eReleaseBuffer;
}
else if( memcmp( ( void * ) &xBroadcastMACAddress,
( void * ) &( pxIPPacket->xEthernetHeader.xSourceAddress ),
sizeof( MACAddress_t ) ) == 0 )
{
/* Ethernet source is a broadcast address. Drop the packet. */
eReturn = eReleaseBuffer;
}
else if( xIsIPv4Multicast( ulSourceIPAddress ) == pdTRUE )
{
/* Source is a multicast IP address. Drop the packet in conformity with RFC 1112 section 7.2. */
eReturn = eReleaseBuffer;
}
else
{
/* Packet is not fragmented, destination is this device, source IP and MAC
* addresses are correct. */
}
}
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
#if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 )
{
/* Some drivers of NIC's with checksum-offloading will enable the above
* define, so that the checksum won't be checked again here */
if( eReturn == eProcessBuffer )
{
/* Is the IP header checksum correct?
*
* NOTE: When the checksum of IP header is calculated while not omitting
* the checksum field, the resulting value of the checksum always is 0xffff
* which is denoted by ipCORRECT_CRC. See this wiki for more information:
* https://en.wikipedia.org/wiki/IPv4_header_checksum#Verifying_the_IPv4_header_checksum
* and this RFC: https://tools.ietf.org/html/rfc1624#page-4
*/
if( usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength ) != ipCORRECT_CRC )
{
/* Check sum in IP-header not correct. */
eReturn = eReleaseBuffer;
}
/* Is the upper-layer checksum (TCP/UDP/ICMP) correct? */
else if( usGenerateProtocolChecksum( ( uint8_t * ) ( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE ) != ipCORRECT_CRC )
{
/* Protocol checksum not accepted. */
eReturn = eReleaseBuffer;
}
else
{
/* The checksum of the received packet is OK. */
}
}
}
#else /* if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) */
{
if( eReturn == eProcessBuffer )
{
if( xCheckSizeFields( ( uint8_t * ) ( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength ) != pdPASS )
{
/* Some of the length checks were not successful. */
eReturn = eReleaseBuffer;
}
}
#if ( ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS == 0 )
{
/* Check if this is a UDP packet without a checksum. */
if( eReturn == eProcessBuffer )
{
/* ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS is defined as 0,
* and so UDP packets carrying a protocol checksum of 0, will
* be dropped. */
/* Identify the next protocol. */
if( pxIPPacket->xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
{
ProtocolPacket_t * pxProtPack;
/* pxProtPack will point to the offset were the protocols begin. */
pxProtPack = ipCAST_PTR_TO_TYPE_PTR( ProtocolPacket_t, &( pxNetworkBuffer->pucEthernetBuffer[ uxHeaderLength - ipSIZE_OF_IPv4_HEADER ] ) );
if( pxProtPack->xUDPPacket.xUDPHeader.usChecksum == ( uint16_t ) 0U )
{
#if ( ipconfigHAS_PRINTF != 0 )
{
static BaseType_t xCount = 0;
if( xCount < 5 )
{
FreeRTOS_printf( ( "prvAllowIPPacket: UDP packet from %xip without CRC dropped\n",
FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ) ) );
xCount++;
}
}
#endif /* ( ipconfigHAS_PRINTF != 0 ) */
/* Protocol checksum not accepted. */
eReturn = eReleaseBuffer;
}
}
}
}
#endif /* ( ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS == 0 ) */
/* to avoid warning unused parameters */
( void ) uxHeaderLength;
}
#endif /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 */
return eReturn;
}