xref: /FreeRTOS-Plus-TCP-v4.0.0/source/FreeRTOS_UDP_IPv4.c (revision 62f5d3a1fd65a52b480e9495cbe0ffcef2168754)
1 /*
2  * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * http://aws.amazon.com/freertos
25  * http://www.FreeRTOS.org
26  */
27 
28 /**
29  * @file FreeRTOS_UDP_IPv4.c
30  * @brief This file has the source code for the UDP-IP functionality of the FreeRTOS+TCP
31  *        network stack.
32  */
33 
34 /* Standard includes. */
35 #include <stdint.h>
36 #include <stdio.h>
37 
38 /* FreeRTOS includes. */
39 #include "FreeRTOS.h"
40 #include "task.h"
41 #include "queue.h"
42 #include "semphr.h"
43 #include "event_groups.h"
44 #include "list.h"
45 
46 /* FreeRTOS+TCP includes. */
47 #include "FreeRTOS_IP.h"
48 #include "FreeRTOS_Sockets.h"
49 #include "FreeRTOS_IP_Private.h"
50 #include "FreeRTOS_UDP_IP.h"
51 #include "FreeRTOS_ARP.h"
52 #include "FreeRTOS_DNS.h"
53 #include "FreeRTOS_DHCP.h"
54 #include "FreeRTOS_IP_Utils.h"
55 #include "NetworkInterface.h"
56 #include "NetworkBufferManagement.h"
57 
58 #if ( ipconfigUSE_DNS == 1 )
59     #include "FreeRTOS_DNS.h"
60 #endif
61 
62 /* Just make sure the contents doesn't get compiled if IPv4 is not enabled. */
63 /* *INDENT-OFF* */
64     #if( ipconfigUSE_IPv4 != 0 )
65 /* *INDENT-ON* */
66 
67 /** @brief The expected IP version and header length coded into the IP header itself. */
68 #define ipIP_VERSION_AND_HEADER_LENGTH_BYTE    ( ( uint8_t ) 0x45 )
69 
70 /*-----------------------------------------------------------*/
71 
72 /**
73  * @brief Process the generated UDP packet and do other checks before sending the
74  *        packet such as ARP cache check and address resolution.
75  *
76  * @param[in] pxNetworkBuffer The network buffer carrying the packet.
77  */
vProcessGeneratedUDPPacket_IPv4(NetworkBufferDescriptor_t * const pxNetworkBuffer)78 void vProcessGeneratedUDPPacket_IPv4( NetworkBufferDescriptor_t * const pxNetworkBuffer )
79 {
80     UDPPacket_t * pxUDPPacket;
81     IPHeader_t * pxIPHeader;
82     eARPLookupResult_t eReturned;
83     uint32_t ulIPAddress = pxNetworkBuffer->xIPAddress.ulIP_IPv4;
84     NetworkEndPoint_t * pxEndPoint = pxNetworkBuffer->pxEndPoint;
85     size_t uxPayloadSize;
86     /* memcpy() helper variables for MISRA Rule 21.15 compliance*/
87     const void * pvCopySource;
88     void * pvCopyDest;
89 
90     /* Map the UDP packet onto the start of the frame. */
91 
92     /* MISRA Ref 11.3.1 [Misaligned access] */
93     /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
94     /* coverity[misra_c_2012_rule_11_3_violation] */
95     pxUDPPacket = ( ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
96 
97     #if ipconfigSUPPORT_OUTGOING_PINGS == 1
98         if( pxNetworkBuffer->usPort == ( uint16_t ) ipPACKET_CONTAINS_ICMP_DATA )
99         {
100             uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( ICMPPacket_t );
101         }
102         else
103     #endif
104     {
105         uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
106     }
107 
108     /* Determine the ARP cache status for the requested IP address. */
109     eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ), &( pxEndPoint ) );
110 
111     if( pxNetworkBuffer->pxEndPoint == NULL )
112     {
113         pxNetworkBuffer->pxEndPoint = pxEndPoint;
114     }
115 
116     if( eReturned != eCantSendPacket )
117     {
118         if( eReturned == eARPCacheHit )
119         {
120             #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
121                 uint8_t ucSocketOptions;
122             #endif
123             iptraceSENDING_UDP_PACKET( pxNetworkBuffer->xIPAddress.ulIP_IPv4 );
124 
125             /* Create short cuts to the data within the packet. */
126             pxIPHeader = &( pxUDPPacket->xIPHeader );
127 
128             #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
129 
130                 /* Is it possible that the packet is not actually a UDP packet
131                  * after all, but an ICMP packet. */
132                 if( pxNetworkBuffer->usPort != ( uint16_t ) ipPACKET_CONTAINS_ICMP_DATA )
133             #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
134             {
135                 UDPHeader_t * pxUDPHeader;
136 
137                 pxUDPHeader = &( pxUDPPacket->xUDPHeader );
138 
139                 pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;
140                 pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;
141                 pxUDPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( UDPHeader_t ) );
142                 pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );
143                 pxUDPHeader->usChecksum = 0U;
144             }
145 
146             /* memcpy() the constant parts of the header information into
147              * the correct location within the packet.  This fills in:
148              *  xEthernetHeader.xSourceAddress
149              *  xEthernetHeader.usFrameType
150              *  xIPHeader.ucVersionHeaderLength
151              *  xIPHeader.ucDifferentiatedServicesCode
152              *  xIPHeader.usLength
153              *  xIPHeader.usIdentification
154              *  xIPHeader.usFragmentOffset
155              *  xIPHeader.ucTimeToLive
156              *  xIPHeader.ucProtocol
157              * and
158              *  xIPHeader.usHeaderChecksum
159              */
160 
161             /* Save options now, as they will be overwritten by memcpy */
162             #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
163                 {
164                     ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
165                 }
166             #endif
167 
168             /*
169              * Offset the memcpy by the size of a MAC address to start at the packet's
170              * Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
171              */
172 
173             /*
174              * Use helper variables for memcpy() to remain
175              * compliant with MISRA Rule 21.15.  These should be
176              * optimized away.
177              */
178             pvCopySource = xDefaultPartUDPPacketHeader.ucBytes;
179             /* The Ethernet source address is at offset 6. */
180             pvCopyDest = &pxNetworkBuffer->pucEthernetBuffer[ sizeof( MACAddress_t ) ];
181             ( void ) memcpy( pvCopyDest, pvCopySource, sizeof( xDefaultPartUDPPacketHeader ) );
182 
183             #if ipconfigSUPPORT_OUTGOING_PINGS == 1
184                 if( pxNetworkBuffer->usPort == ( uint16_t ) ipPACKET_CONTAINS_ICMP_DATA )
185                 {
186                     pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;
187                     pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( ICMPHeader_t ) );
188                 }
189                 else
190             #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
191             {
192                 pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
193             }
194 
195             pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
196             pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->xIPAddress.ulIP_IPv4;
197 
198             if( pxNetworkBuffer->pxEndPoint != NULL )
199             {
200                 pxIPHeader->ulSourceIPAddress = pxNetworkBuffer->pxEndPoint->ipv4_settings.ulIPAddress;
201             }
202 
203             /* The stack doesn't support fragments, so the fragment offset field must always be zero.
204              * The header was never memset to zero, so set both the fragment offset and fragmentation flags in one go.
205              */
206             #if ( ipconfigFORCE_IP_DONT_FRAGMENT != 0 )
207                 pxIPHeader->usFragmentOffset = ipFRAGMENT_FLAGS_DONT_FRAGMENT;
208             #else
209                 pxIPHeader->usFragmentOffset = 0U;
210             #endif
211 
212             #if ( ipconfigUSE_LLMNR == 1 )
213                 {
214                     /* LLMNR messages are typically used on a LAN and they're
215                      * not supposed to cross routers */
216                     if( pxNetworkBuffer->xIPAddress.ulIP_IPv4 == ipLLMNR_IP_ADDR )
217                     {
218                         pxIPHeader->ucTimeToLive = 0x01;
219                     }
220                 }
221             #endif
222             #if ( ipconfigUSE_MDNS == 1 )
223                 {
224                     /* mDNS messages have a hop-count of 255, see RFC 6762, section 11. */
225                     if( pxNetworkBuffer->xIPAddress.ulIP_IPv4 == ipMDNS_IP_ADDRESS )
226                     {
227                         pxIPHeader->ucTimeToLive = 0xffU;
228                     }
229                 }
230             #endif
231 
232             #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
233                 {
234                     pxIPHeader->usHeaderChecksum = 0U;
235                     pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), uxIPHeaderSizePacket( pxNetworkBuffer ) );
236                     pxIPHeader->usHeaderChecksum = ( uint16_t ) ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
237 
238                     if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0U )
239                     {
240                         ( void ) usGenerateProtocolChecksum( ( uint8_t * ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
241                     }
242                     else
243                     {
244                         pxUDPPacket->xUDPHeader.usChecksum = 0U;
245                     }
246                 }
247             #endif /* if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) */
248         }
249         else if( eReturned == eARPCacheMiss )
250         {
251             /* Add an entry to the ARP table with a null hardware address.
252              * This allows the ARP timer to know that an ARP reply is
253              * outstanding, and perform retransmissions if necessary. */
254             vARPRefreshCacheEntry( NULL, ulIPAddress, NULL );
255 
256             /* Generate an ARP for the required IP address. */
257             iptracePACKET_DROPPED_TO_GENERATE_ARP( pxNetworkBuffer->xIPAddress.ulIP_IPv4 );
258 
259             /* 'ulIPAddress' might have become the address of the Gateway.
260              * Find the route again. */
261 
262             pxNetworkBuffer->pxEndPoint = FreeRTOS_FindEndPointOnNetMask( pxNetworkBuffer->xIPAddress.ulIP_IPv4, 11 );
263 
264             if( pxNetworkBuffer->pxEndPoint == NULL )
265             {
266                 eReturned = eCantSendPacket;
267             }
268             else
269             {
270                 pxNetworkBuffer->xIPAddress.ulIP_IPv4 = ulIPAddress;
271                 vARPGenerateRequestPacket( pxNetworkBuffer );
272             }
273         }
274         else
275         {
276             /* The lookup indicated that an ARP request has already been
277              * sent out for the queried IP address. */
278             eReturned = eCantSendPacket;
279         }
280     }
281 
282     if( eReturned != eCantSendPacket )
283     {
284         /* The network driver is responsible for freeing the network buffer
285          * after the packet has been sent. */
286 
287         if( pxNetworkBuffer->pxEndPoint != NULL )
288         {
289             NetworkInterface_t * pxInterface = pxNetworkBuffer->pxEndPoint->pxNetworkInterface;
290             /* MISRA Ref 11.3.1 [Misaligned access] */
291             /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
292             /* coverity[misra_c_2012_rule_11_3_violation] */
293             EthernetHeader_t * pxEthernetHeader = ( ( EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer );
294             ( void ) memcpy( pxEthernetHeader->xSourceAddress.ucBytes, pxNetworkBuffer->pxEndPoint->xMACAddress.ucBytes, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
295 
296             #if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 )
297                 {
298                     if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
299                     {
300                         BaseType_t xIndex;
301 
302                         for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
303                         {
304                             pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0U;
305                         }
306 
307                         pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
308                     }
309                 }
310             #endif /* if( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 ) */
311             iptraceNETWORK_INTERFACE_OUTPUT( pxNetworkBuffer->xDataLength, pxNetworkBuffer->pucEthernetBuffer );
312 
313             if( ( pxInterface != NULL ) && ( pxInterface->pfOutput != NULL ) )
314             {
315                 ( void ) pxInterface->pfOutput( pxInterface, pxNetworkBuffer, pdTRUE );
316             }
317         }
318         else
319         {
320             /* The packet can't be sent (no route found).  Drop the packet. */
321             vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
322         }
323     }
324     else
325     {
326         /* The packet can't be sent (DHCP not completed?).  Just drop the
327          * packet. */
328         vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
329     }
330 }
331 /*-----------------------------------------------------------*/
332 
333 /**
334  * @brief Process the received UDP packet.
335  *
336  * @param[in] pxNetworkBuffer The network buffer carrying the UDP packet.
337  * @param[in] usPort The port number on which this packet was received.
338  * @param[out] pxIsWaitingForARPResolution If the packet is awaiting ARP resolution,
339  *             this pointer will be set to pdTRUE. pdFALSE otherwise.
340  *
341  * @return pdPASS in case the UDP packet could be processed. Else pdFAIL is returned.
342  */
xProcessReceivedUDPPacket_IPv4(NetworkBufferDescriptor_t * pxNetworkBuffer,uint16_t usPort,BaseType_t * pxIsWaitingForARPResolution)343 BaseType_t xProcessReceivedUDPPacket_IPv4( NetworkBufferDescriptor_t * pxNetworkBuffer,
344                                            uint16_t usPort,
345                                            BaseType_t * pxIsWaitingForARPResolution )
346 {
347     BaseType_t xReturn = pdPASS;
348     FreeRTOS_Socket_t * pxSocket;
349     const UDPPacket_t * pxUDPPacket;
350 
351     configASSERT( pxNetworkBuffer != NULL );
352     configASSERT( pxNetworkBuffer->pucEthernetBuffer != NULL );
353 
354     /* Map the ethernet buffer to the UDPPacket_t struct for easy access to the fields. */
355 
356     /* MISRA Ref 11.3.1 [Misaligned access] */
357     /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */
358     /* coverity[misra_c_2012_rule_11_3_violation] */
359     pxUDPPacket = ( ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
360     const NetworkEndPoint_t * pxEndpoint = pxNetworkBuffer->pxEndPoint;
361 
362     /* Caller must check for minimum packet size. */
363     pxSocket = pxUDPSocketLookup( usPort );
364 
365     *pxIsWaitingForARPResolution = pdFALSE;
366 
367     do
368     {
369         if( pxSocket != NULL )
370         {
371             if( ( pxEndpoint != NULL ) && ( pxEndpoint->ipv4_settings.ulIPAddress != 0U ) )
372             {
373                 if( xCheckRequiresARPResolution( pxNetworkBuffer ) == pdTRUE )
374                 {
375                     /* Mark this packet as waiting for ARP resolution. */
376                     *pxIsWaitingForARPResolution = pdTRUE;
377 
378                     /* Return a fail to show that the frame will not be processed right now. */
379                     xReturn = pdFAIL;
380                     break;
381                 }
382                 else
383                 {
384                     /* Update the age of this cache entry since a packet was received. */
385                     vARPRefreshCacheEntryAge( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
386                 }
387             }
388             else
389             {
390                 /* During DHCP, IP address is not assigned and therefore ARP verification
391                  * is not possible. */
392             }
393 
394             #if ( ipconfigUSE_CALLBACKS == 1 )
395                 {
396                     /* Did the owner of this socket register a reception handler ? */
397                     if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleReceive ) )
398                     {
399                         struct freertos_sockaddr xSourceAddress, destinationAddress;
400                         void * pcData = &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
401                         FOnUDPReceive_t xHandler = ( FOnUDPReceive_t ) pxSocket->u.xUDP.pxHandleReceive;
402 
403                         xSourceAddress.sin_port = pxNetworkBuffer->usPort;
404                         xSourceAddress.sin_address.ulIP_IPv4 = pxNetworkBuffer->xIPAddress.ulIP_IPv4;
405                         xSourceAddress.sin_family = ( uint8_t ) FREERTOS_AF_INET4;
406                         xSourceAddress.sin_len = ( uint8_t ) sizeof( xSourceAddress );
407                         destinationAddress.sin_port = usPort;
408                         destinationAddress.sin_address.ulIP_IPv4 = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
409                         destinationAddress.sin_family = ( uint8_t ) FREERTOS_AF_INET4;
410                         destinationAddress.sin_len = ( uint8_t ) sizeof( destinationAddress );
411 
412                         /* The value of 'xDataLength' was proven to be at least the size of a UDP packet in prvProcessIPPacket(). */
413                         if( xHandler( ( Socket_t ) pxSocket,
414                                       ( void * ) pcData,
415                                       ( size_t ) ( pxNetworkBuffer->xDataLength - ipUDP_PAYLOAD_OFFSET_IPv4 ),
416                                       &( xSourceAddress ),
417                                       &( destinationAddress ) ) != 0 )
418                         {
419                             xReturn = pdFAIL; /* xHandler has consumed the data, do not add it to .xWaitingPacketsList'. */
420                         }
421                     }
422                 }
423             #endif /* ipconfigUSE_CALLBACKS */
424 
425             #if ( ipconfigUDP_MAX_RX_PACKETS > 0U )
426                 {
427                     if( xReturn == pdPASS )
428                     {
429                         if( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) >= pxSocket->u.xUDP.uxMaxPackets )
430                         {
431                             FreeRTOS_debug_printf( ( "xProcessReceivedUDPPacket: buffer full %ld >= %ld port %u\n",
432                                                      listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ),
433                                                      pxSocket->u.xUDP.uxMaxPackets, pxSocket->usLocalPort ) );
434                             xReturn = pdFAIL; /* we did not consume or release the buffer */
435                         }
436                     }
437                 }
438             #endif /* if ( ipconfigUDP_MAX_RX_PACKETS > 0U ) */
439 
440             #if ( ipconfigUSE_CALLBACKS == 1 ) || ( ipconfigUDP_MAX_RX_PACKETS > 0U )
441                 if( xReturn == pdPASS ) /*lint !e774: Boolean within 'if' always evaluates to True, depending on configuration. [MISRA 2012 Rule 14.3, required. */
442             #else
443                 /* xReturn is still pdPASS. */
444             #endif
445             {
446                 vTaskSuspendAll();
447                 {
448                     taskENTER_CRITICAL();
449                     {
450                         /* Add the network packet to the list of packets to be
451                          * processed by the socket. */
452                         vListInsertEnd( &( pxSocket->u.xUDP.xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
453                     }
454                     taskEXIT_CRITICAL();
455                 }
456                 ( void ) xTaskResumeAll();
457 
458                 /* Set the socket's receive event */
459                 if( pxSocket->xEventGroup != NULL )
460                 {
461                     ( void ) xEventGroupSetBits( pxSocket->xEventGroup, ( EventBits_t ) eSOCKET_RECEIVE );
462                 }
463 
464                 #if ( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
465                     {
466                         if( ( pxSocket->pxSocketSet != NULL ) && ( ( pxSocket->xSelectBits & ( ( EventBits_t ) eSELECT_READ ) ) != 0U ) )
467                         {
468                             ( void ) xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, ( EventBits_t ) eSELECT_READ );
469                         }
470                     }
471                 #endif
472 
473                 #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
474                     {
475                         if( pxSocket->pxUserSemaphore != NULL )
476                         {
477                             ( void ) xSemaphoreGive( pxSocket->pxUserSemaphore );
478                         }
479                     }
480                 #endif
481 
482                 #if ( ipconfigUSE_DHCP == 1 )
483                     {
484                         if( xIsDHCPSocket( pxSocket ) != 0 )
485                         {
486                             ( void ) xSendDHCPEvent( pxNetworkBuffer->pxEndPoint );
487                         }
488                     }
489                 #endif
490             }
491         }
492         else
493         {
494             /* There is no socket listening to the target port, but still it might
495              * be for this node. */
496 
497             #if ( ipconfigUSE_DNS == 1 ) && ( ipconfigDNS_USE_CALLBACKS == 1 )
498 
499                 /* A DNS reply, check for the source port.  Although the DNS client
500                  * does open a UDP socket to send a messages, this socket will be
501                  * closed after a short timeout.  Messages that come late (after the
502                  * socket is closed) will be treated here. */
503                 if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ( uint16_t ) ipDNS_PORT )
504                 {
505                     vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress,
506                                            pxNetworkBuffer->pxEndPoint );
507                     xReturn = ( BaseType_t ) ulDNSHandlePacket( pxNetworkBuffer );
508                 }
509                 else
510             #endif
511 
512             #if ( ipconfigUSE_DNS == 1 ) && ( ipconfigUSE_LLMNR == 1 )
513                 /* A LLMNR request, check for the destination port. */
514                 if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
515                     ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
516                 {
517                     vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress,
518                                            pxNetworkBuffer->pxEndPoint );
519                     xReturn = ( BaseType_t ) ulDNSHandlePacket( pxNetworkBuffer );
520                 }
521                 else
522             #endif /* ipconfigUSE_LLMNR */
523 
524             #if ( ipconfigUSE_DNS == 1 ) && ( ipconfigUSE_MDNS == 1 )
525                 /* A MDNS request, check for the destination port. */
526                 if( ( usPort == FreeRTOS_ntohs( ipMDNS_PORT ) ) ||
527                     ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipMDNS_PORT ) ) )
528                 {
529                     #if ( ipconfigUSE_IPv6 != 0 )
530                         if( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE )
531                         {
532                         }
533                         else
534                     #endif
535                     {
536                         vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress,
537                                                pxNetworkBuffer->pxEndPoint );
538                     }
539 
540                     xReturn = ( BaseType_t ) ulDNSHandlePacket( pxNetworkBuffer );
541                 }
542                 else
543             #endif /* ipconfigUSE_MDNS */
544 
545             #if ( ipconfigUSE_NBNS == 1 )
546                 /* a NetBIOS request, check for the destination port */
547                 if( ( usPort == FreeRTOS_ntohs( ipNBNS_PORT ) ) ||
548                     ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipNBNS_PORT ) ) )
549                 {
550                     vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress,
551                                            pxNetworkBuffer->pxEndPoint );
552                     xReturn = ( BaseType_t ) ulNBNSHandlePacket( pxNetworkBuffer );
553                 }
554                 else
555             #endif /* ipconfigUSE_NBNS */
556             {
557                 xReturn = pdFAIL;
558             }
559         }
560     } while( ipFALSE_BOOL );
561 
562     return xReturn;
563 }
564 /*-----------------------------------------------------------*/
565 
566 /* *INDENT-OFF* */
567     #endif /* ipconfigUSE_IPv4 != 0 ) */
568 /* *INDENT-ON* */
569