示例#1
0
void vReleaseNetworkBufferAndDescriptor( xNetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;

#if( ipconfigIP_TASK_KEEPS_MESSAGE_BUFFER != 0 )
	if( pxNetworkBuffer == pxIpTaskMessageBuffer )
		return;
#endif

	if( !bIsValidNetworkDescriptor ( pxNetworkBuffer ) )
	{
		FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
		return ;
	}
	/* Ensure the buffer is returned to the list of free buffers before the
	counting semaphore is 'given' to say a buffer is available. */
/*	taskENTER_CRITICAL(); */
	ipconfigBUFFER_ALLOC_LOCK();
	{
		{
			xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );

			if( xListItemAlreadyInFreeList == pdFALSE )
			{
				vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
			}
		}

/*		configASSERT( xListItemAlreadyInFreeList == pdFALSE ); */
	}
	ipconfigBUFFER_ALLOC_UNLOCK();
/*	taskEXIT_CRITICAL(); */
	if( xListItemAlreadyInFreeList )
	{
		FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
			pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) );
	}
	if( !xListItemAlreadyInFreeList )
	{
		xSemaphoreGive( xNetworkBufferSemaphore );
		showWarnings();
		if( xTCPWindowLoggingLevel > 3 )
			FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n",
				bIsValidNetworkDescriptor( pxNetworkBuffer ),
				pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer,
				uxGetNumberOfFreeNetworkBuffers( ) ) );
	}
	iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
示例#2
0
	static void prvShowWarnings( void )
	{
		UBaseType_t uxCount = uxGetNumberOfFreeNetworkBuffers( );
		if( ( ( cIsLow == 0 ) && ( uxCount <= WARN_LOW ) ) || ( ( cIsLow != 0 ) && ( uxCount >= WARN_HIGH ) ) )
		{
			cIsLow = !cIsLow;
			FreeRTOS_debug_printf( ( "*** Warning *** %s %lu buffers left\n", cIsLow ? "only" : "now", uxCount ) );
		}
	}
示例#3
0
	static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, BaseType_t xLookUp )
	{
	BaseType_t x;
	BaseType_t xFound = pdFALSE;
	static BaseType_t xFreeEntry = 0;

		/* For each entry in the DNS cache table. */
		for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
		{
			if( xDNSCache[ x ].pcName[ 0 ] == 0 )
			{
				break;
			}

			if( strncmp( xDNSCache[ x ].pcName, pcName, sizeof( xDNSCache[ x ].pcName ) ) == 0 )
			{
				/* Is this function called for a lookup or to add/update an IP address? */
				if( xLookUp != pdFALSE )
				{
					*pulIP = xDNSCache[ x ].ulIPAddress;
				}
				else
				{
					xDNSCache[ x ].ulIPAddress = *pulIP;
				}

				xFound = pdTRUE;
				break;
			}
		}

		if( xFound == pdFALSE )
		{
			if( xLookUp != pdFALSE )
			{
				*pulIP = 0;
			}
			else
			{
				/* Called to add or update an item */
				strncpy( xDNSCache[ xFreeEntry ].pcName, pcName, sizeof( xDNSCache[ xFreeEntry ].pcName ) );
				xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;

				xFreeEntry++;
				if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
				{
					xFreeEntry = 0;
				}
			}
		}

		if( ( xLookUp == 0 ) || ( *pulIP != 0 ) )
		{
			FreeRTOS_debug_printf( ( "prvProcessDNSCache: %s: '%s' @ %lxip\n", xLookUp ? "look-up" : "add", pcName, FreeRTOS_ntohl( *pulIP ) ) );
		}
	}
示例#4
0
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;

	if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED )
	{
		FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
		return ;
	}
	/* Ensure the buffer is returned to the list of free buffers before the
	counting semaphore is 'given' to say a buffer is available. */
	ipconfigBUFFER_ALLOC_LOCK();
	{
		{
			xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );

			if( xListItemAlreadyInFreeList == pdFALSE )
			{
				vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
			}
		}
	}
	ipconfigBUFFER_ALLOC_UNLOCK();

	if( xListItemAlreadyInFreeList )
	{
		FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
			pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) );
	}
	if( xListItemAlreadyInFreeList == pdFALSE )
	{
		xSemaphoreGive( xNetworkBufferSemaphore );
		prvShowWarnings();
		if( xTCPWindowLoggingLevel > 3 )
			FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n",
				bIsValidNetworkDescriptor( pxNetworkBuffer ),
				pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer,
				uxGetNumberOfFreeNetworkBuffers( ) ) );
	}
	iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
示例#5
0
uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback, void *pvSearchID, TickType_t xTimeout )
#endif
{
uint32_t ulIPAddress = 0UL;
static uint16_t usIdentifier = 0u;
TickType_t xReadTimeOut_ms = 1200U;
/* Generate a unique identifier for this query. Keep it in a local variable
 as gethostbyname() may be called from different threads */
TickType_t xIdentifier = ( TickType_t )usIdentifier++;

	/* If a DNS cache is used then check the cache before issuing another DNS
	request. */
	#if( ipconfigUSE_DNS_CACHE == 1 )
	{
		ulIPAddress = FreeRTOS_dnslookup( pcHostName );
		if( ulIPAddress != 0 )
		{
			FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
		}
		else
		{
			/* prvGetHostByName will be called to start a DNS lookup. */
		}
	}
	#endif /* ipconfigUSE_DNS_CACHE == 1 */

	#if( ipconfigDNS_USE_CALLBACKS != 0 )
	{
		if( pCallback != NULL )
		{
			if( ulIPAddress == 0UL )
			{
				/* The user has provided a callback function, so do not block on recvfrom() */
				xReadTimeOut_ms  = 0;
				vDNSSetCallBack( pcHostName, pvSearchID, pCallback, xTimeout, ( TickType_t ) xIdentifier );
			}
			else
			{
				/* The IP address is known, do the call-back now. */
				pCallback( pcHostName, pvSearchID, ulIPAddress );
			}
		}
	}
	#endif

	if( ulIPAddress == 0UL)
	{
		ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms );
	}

	return ulIPAddress;
}
示例#6
0
static void prvTcpInit( xTcpServer_t *pxTcpServer )
{
struct freertos_sockaddr addr;
BaseType_t xReceiveTimeOut = 0;
BaseType_t xSendTimeOut = 0;

	pxTcpServer->pxSendData = ( SSimpleBuf * )pvPortMalloc( sizeof( *pxTcpServer->pxSendData ) - sizeof( pxTcpServer->pxSendData->array ) + SEND_BUFFER_SIZE + 1 );

	configASSERT( pxTcpServer->pxSendData != NULL );
	memset( pxTcpServer->pxSendData, '\0', sizeof( *pxTcpServer->pxSendData ) );
	pxTcpServer->pxSendData->LENGTH = SEND_BUFFER_SIZE + 1;

	FreeRTOS_GetRemoteAddress( pxTcpServer->xSocket, &addr );
	FreeRTOS_debug_printf( ( "prvTcpInit: serving %xip:%u\n",
		FreeRTOS_ntohl( addr.sin_addr ), addr.sin_port) );

	FreeRTOS_setsockopt( pxTcpServer->xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
	FreeRTOS_setsockopt( pxTcpServer->xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) );
}
示例#7
0
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
{
size_t xSpace;

	iptraceNETWORK_INTERFACE_TRANSMIT();
	configASSERT( xIsCallingFromIPTask() == pdTRUE );

	/* Both the length of the data being sent and the actual data being sent
	are placed in the thread safe buffer used to pass data between the FreeRTOS
	tasks and the Win32 thread that sends data via the WinPCAP library.  Drop
	the packet if there is insufficient space in the buffer to hold both. */
	xSpace = uxStreamBufferGetSpace( xSendBuffer );

	if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
		( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
	{
		/* First write in the length of the data, then write in the data
		itself. */
		uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
		uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
	}
	else
	{
		FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
	}

	/* Kick the Tx task in either case in case it doesn't know the buffer is
	full. */
	SetEvent( pvSendEvent );

	/* The buffer has been sent so can be released. */
	if( bReleaseAfterSend != pdFALSE )
	{
		vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
	}

	return pdPASS;
}
示例#8
0
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
{
NetworkBufferDescriptor_t *pxReturn = NULL;
BaseType_t xInvalid = pdFALSE;
size_t uxCount;

	/* The current implementation only has a single size memory block, so
	the requested size parameter is not used (yet). */
	( void ) xRequestedSizeBytes;
	if( xNetworkBufferSemaphore != NULL )
	{
		/* If there is a semaphore available, there is a network buffer available. */
		if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
		{
			/* Protect the structure as it is accessed from tasks and interrupts. */
			ipconfigBUFFER_ALLOC_LOCK();
			{
				pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
				if( bIsValidNetworkDescriptor(pxReturn) &&
					listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) )
				{
					uxListRemove( &( pxReturn->xBufferListItem ) );
				}
				else
				{
					xInvalid = pdTRUE;
				}
			}
			ipconfigBUFFER_ALLOC_UNLOCK();

			if( xInvalid )
			{
				FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n",
					pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) );
				pxReturn = NULL;
			}
			else
			{
				{
					/* Reading UBaseType_t, no critical section needed. */
					uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
		
					if( uxMinimumFreeNetworkBuffers > uxCount )
					{
						uxMinimumFreeNetworkBuffers = uxCount;
					}		
				}
				pxReturn->xDataLength = xRequestedSizeBytes;

				#if( ipconfigTCP_IP_SANITY != 0 )
				{
					showWarnings();
				}
				#endif /* ipconfigTCP_IP_SANITY */

				#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
				{
					/* make sure the buffer is not linked */
					pxReturn->pxNextBuffer = NULL;
				}
				#endif /* ipconfigUSE_LINKED_RX_MESSAGES */

				if( xTCPWindowLoggingLevel > 3 )
				{
					FreeRTOS_debug_printf( ( "BUF_GET[%ld]: %p (%p)\n",
						bIsValidNetworkDescriptor( pxReturn ),
						pxReturn, pxReturn->pucEthernetBuffer ) );
				}
			}
			iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
		}
		else
		{
			iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
		}
	}

	return pxReturn;
}
示例#9
0
static void prvConnectionListeningTask( void *pvParameters )
{
struct freertos_sockaddr xClient, xBindAddress;
xSocket_t xListeningSocket;

socklen_t xSize = sizeof( xClient );
static const TickType_t xReceiveTimeOut = 0; //portMAX_DELAY;
const BaseType_t xBacklog = 10;
xSocketSet_t xSocketSet;
struct xTCP_SERVER *pxServerList = NULL;
struct xTCP_SERVER *pxIterator;

xWinProperties_t winProps;

	/* Just to prevent compiler warnings. */
	( void ) pvParameters;

	/* Attempt to open the socket. */
	xListeningSocket = FreeRTOS_socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
	configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );

	/* Set a time out so accept() will just wait for a connection. */
	FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );

	memset(&winProps, '\0', sizeof( winProps ) );
	// Size in units of MSS
	winProps.lTxBufSize   = 1 * 1460;//1000;
	winProps.lTxWinSize   = 2;

	winProps.lRxBufSize   = 2 * 1460;
	winProps.lRxWinSize   =  2;

	FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &winProps, sizeof( winProps ) );

	/* The strange casting is to remove compiler errors. */
	xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
	xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );

	/* Bind the socket to the port that the client task will send to, then
	listen for incoming connections. */
	while( FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ) != 0 );
	FreeRTOS_listen( xListeningSocket, xBacklog );
	lastTickTime = xTaskGetTickCount ();

	pxServerList = NULL;

	xSocketSet = FreeRTOS_createsocketset( );
	configASSERT( xSocketSet != NULL );
	FreeRTOS_FD_SET( xListeningSocket, xSocketSet, eSELECT_READ );

	for( ;; )
	{
		TickType_t xMask = FreeRTOS_select( xSocketSet, 3000 );

		if( FreeRTOS_FD_ISSET( xListeningSocket, xSocketSet ) )
		{
			xSocket_t xNewSocket;

			xNewSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
			if ( xNewSocket && xNewSocket != FREERTOS_INVALID_SOCKET )
			{
				xTcpServer_t *pxServer;

				FreeRTOS_debug_printf( ( "prvConnectionListeningTask: new connection %xip:%u\n",
					FreeRTOS_ntohl( xClient.sin_addr ), FreeRTOS_ntohs( xClient.sin_port ) ) );

				pxServer = (xTcpServer_t *)pvPortMalloc( sizeof( *pxServer ) );
				memset( pxServer, '\0', sizeof( *pxServer ));

				pxServer->xSocket = xNewSocket;
				FreeRTOS_FD_SET( xNewSocket, xSocketSet, eSELECT_READ | eSELECT_EXCEPT );
				if( pxServerList == NULL )
				{
					/* This is the first server */
					pxServerList = pxServer;
				}
				else
				{
					/* Attach it to the end of the list */
					for( pxIterator = pxServerList; pxIterator->pxNext != NULL; pxIterator = pxIterator->pxNext )
					{
					}
					pxIterator->pxNext = pxServer;
				}
				prvTcpInit( pxServer );
			}
		}
		{
			xTcpServer_t *pxThisServer = NULL;

			for( pxIterator = pxServerList; pxIterator != NULL;  )
			{
				BaseType_t rc;
				pxThisServer = pxIterator;
				/* Move to the next one before the current gets deleted */
				pxIterator = pxIterator->pxNext;

				if( FreeRTOS_FD_ISSET( pxThisServer->xSocket, xSocketSet )  == 0 )
				{
					continue;
				}

				rc = prvTcpWork( pxThisServer );

				if( rc < 0)
				{
					FreeRTOS_FD_CLR( pxThisServer->xSocket, xSocketSet, eSELECT_ALL );

					if( pxServerList = pxThisServer )
					{
						pxServerList = pxThisServer->pxNext;
					}
					else
					{
						struct xTCP_SERVER *pxOther;
						for( pxOther = pxServerList; pxOther->pxNext != NULL; pxOther = pxOther->pxNext )
						{
							if( pxOther->pxNext == pxThisServer )
							{
								pxOther->pxNext == pxThisServer->pxNext;
								break;
							}
						}
					}
					/* Close the socket and free the space */
					prvTcpClose( pxThisServer );
				} else
				{
					pxThisServer->bHasSendRequest = prvTcpHasSendData( pxThisServer );
					if( pxThisServer->bHasSendRequest )
						FreeRTOS_FD_SET( pxThisServer->xSocket, xSocketSet, eSELECT_WRITE );
					else
						FreeRTOS_FD_CLR( pxThisServer->xSocket, xSocketSet, eSELECT_WRITE );
					//FreeRTOS_debug_printf( ( "SET_FD WRITE %d\n", pxServerFound->bHasSendRequest != 0 ) );
				}
			}
		}
		if( ( xTaskGetTickCount () - lastTickTime ) > 30000 )
		{
			lastTickTime = xTaskGetTickCount ();
			//plusPrintf( "ListeningTask %ld,%ld tasks\n", xTaskCount, xConfirmedCount );
		}
	}
}
示例#10
0
BaseType_t xProcessReceivedUDPPacket( xNetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
{
BaseType_t xReturn = pdPASS;
xFreeRTOS_Socket_t *pxSocket;

xUDPPacket_t *pxUDPPacket = (xUDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;

	pxSocket = pxUDPSocketLookup( usPort );

	if( pxSocket )
	{

		/* When refreshing the ARP cache with received UDP packets we must be
		careful;  hundreds of broadcast messages may pass and if we're not
		handling them, no use to fill the ARP cache with those IP addresses. */
		vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );

		#if( ipconfigUSE_CALLBACKS == 1 )
		{
			/* Did the owner of this socket register a reception handler ? */
			if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUdp.pHndReceive ) )
			{
				struct freertos_sockaddr xSourceAddress, destinationAddress;
				void *pcData = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET ] );
				FOnUdpReceive xHandler = ( FOnUdpReceive ) pxSocket->u.xUdp.pHndReceive;
				xSourceAddress.sin_port = pxNetworkBuffer->usPort;
				xSourceAddress.sin_addr = pxNetworkBuffer->ulIPAddress;
				destinationAddress.sin_port = usPort;
				destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;

				if( xHandler( (xSocket_t *)pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
					&xSourceAddress, &destinationAddress ) )
				{
					xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
				}
			}
		}
		#endif /* ipconfigUSE_CALLBACKS */

		#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
		{
			if( xReturn == pdPASS )
			{
				if ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUdp.xWaitingPacketsList ) ) >= pxSocket->u.xUdp.xMaxPackets )
				{
					FreeRTOS_debug_printf( ( "xProcessReceivedUDPPacket: buffer full %ld >= %ld port %u\n",
						listCURRENT_LIST_LENGTH( &( pxSocket->u.xUdp.xWaitingPacketsList ) ),
						pxSocket->u.xUdp.xMaxPackets, pxSocket->usLocPort ) );
					xReturn = pdFAIL; /* we did not consume or release the buffer */
				}
			}
		}
		#endif

		if( xReturn == pdPASS )
		{
			vTaskSuspendAll();
			{
				if( xReturn == pdPASS )
				{
					taskENTER_CRITICAL();
					{
						/* Add the network packet to the list of packets to be
						processed by the socket. */
						vListInsertEnd( &( pxSocket->u.xUdp.xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
					}
					taskEXIT_CRITICAL();
				}
			}
			xTaskResumeAll();

			/* Set the socket's receive event */
			if( pxSocket->xEventGroup != NULL )
			{
				xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
			}

			#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
			{
				if( ( pxSocket->pxSocketSet != NULL ) && ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) )
				{
					xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_READ );
				}
			}
			#endif

			#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
			{
				if( pxSocket->pxUserSemaphore != NULL )
				{
					xSemaphoreGive( pxSocket->pxUserSemaphore );
				}
			}
			#endif

			#if( ipconfigUSE_DHCP == 1 )
			{
				if( xIsDHCPSocket( pxSocket ) )
				{
					xSendEventToIPTask( eDHCPEvent );
				}
			}
			#endif
		}
	}
	else
	{
		/* There is no socket listening to the target port, but still it might
		be for this node. */

		#if( ipconfigUSE_DNS == 1 )
			/* a DNS reply, check for the source port.  Although the DNS client
			does open a UDP socket to send a messages, this socket will be
			closed after a short timeout.  Messages that come late (after the
			socket is closed) will be treated here. */
			if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
			{
				vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
				xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
			}
			else
		#endif

		#if( ipconfigUSE_LLMNR == 1 )
			/* a LLMNR request, check for the destination port. */
			if( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) )
			{
				vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
				xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
			}
			else
		#endif /* ipconfigUSE_LLMNR */

		#if( ipconfigUSE_NBNS == 1 )
			/* a NetBIOS request, check for the destination port */
			if( usPort == FreeRTOS_ntohs( ipNBNS_PORT ) )
			{
				vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
				xReturn = ( BaseType_t )ulNBNSHandlePacket( pxNetworkBuffer );
			}
			else
		#endif /* ipconfigUSE_NBNS */
		{
			xReturn = pdFAIL;
		}
	}

	return xReturn;
}