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