/*\r
- * FreeRTOS+TCP V2.0.1\r
+ * FreeRTOS+TCP V2.2.0\r
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy of\r
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
*\r
- * http://www.FreeRTOS.org\r
* http://aws.amazon.com/freertos\r
- *\r
- * 1 tab == 4 spaces!\r
+ * http://www.FreeRTOS.org\r
*/\r
\r
/* Standard includes. */\r
#endif\r
\r
/* Codes of interest found in the DHCP options field. */\r
-#define dhcpIPv4_ZERO_PAD_OPTION_CODE ( 0u )\r
-#define dhcpIPv4_SUBNET_MASK_OPTION_CODE ( 1u )\r
-#define dhcpIPv4_GATEWAY_OPTION_CODE ( 3u )\r
-#define dhcpIPv4_DNS_SERVER_OPTIONS_CODE ( 6u )\r
-#define dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE ( 12u )\r
-#define dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE ( 50u )\r
-#define dhcpIPv4_LEASE_TIME_OPTION_CODE ( 51u )\r
-#define dhcpIPv4_MESSAGE_TYPE_OPTION_CODE ( 53u )\r
-#define dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE ( 54u )\r
-#define dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE ( 55u )\r
-#define dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE ( 61u )\r
+#define dhcpZERO_PAD_OPTION_CODE ( 0u )\r
+#define dhcpSUBNET_MASK_OPTION_CODE ( 1u )\r
+#define dhcpGATEWAY_OPTION_CODE ( 3u )\r
+#define dhcpDNS_SERVER_OPTIONS_CODE ( 6u )\r
+#define dhcpDNS_HOSTNAME_OPTIONS_CODE ( 12u )\r
+#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE ( 50u )\r
+#define dhcpLEASE_TIME_OPTION_CODE ( 51u )\r
+#define dhcpMESSAGE_TYPE_OPTION_CODE ( 53u )\r
+#define dhcpSERVER_IP_ADDRESS_OPTION_CODE ( 54u )\r
+#define dhcpPARAMETER_REQUEST_OPTION_CODE ( 55u )\r
+#define dhcpCLIENT_IDENTIFIER_OPTION_CODE ( 61u )\r
\r
/* The four DHCP message types of interest. */\r
#define dhcpMESSAGE_TYPE_DISCOVER ( 1 )\r
\r
/* Offsets into the transmitted DHCP options fields at which various parameters\r
are located. */\r
-#define dhcpCLIENT_IDENTIFIER_OFFSET ( 5 )\r
-#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 13 )\r
-#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 19 )\r
+#define dhcpCLIENT_IDENTIFIER_OFFSET ( 6 )\r
+#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 14 )\r
+#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 20 )\r
\r
/* Values used in the DHCP packets. */\r
#define dhcpREQUEST_OPCODE ( 1 )\r
located. */\r
#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )\r
\r
-/* When walking the variable length options field, the following value is used\r
-to ensure the walk has not gone past the end of the valid options. 2 bytes is\r
-made up of the length byte, and minimum one byte value. */\r
-#define dhcpMAX_OPTION_LENGTH_OF_INTEREST ( 2L )\r
-\r
-/* Standard DHCP port numbers and magic cookie value.\r
-DHCPv4 uses UDP port number 68 for clients and port number 67 for servers.\r
-*/\r
+/* Standard DHCP port numbers and magic cookie value. */\r
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )\r
#define dhcpCLIENT_PORT 0x4400u\r
#define dhcpSERVER_PORT 0x4300u\r
\r
if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )\r
{\r
- xDHCPData.ulTransactionId++;\r
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();\r
- xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;\r
- prvSendDHCPDiscover( );\r
- FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );\r
+ if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )\r
+ {\r
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount( );\r
+ xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;\r
+ prvSendDHCPDiscover( );\r
+ FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );\r
+ }\r
+ else\r
+ {\r
+ FreeRTOS_debug_printf( ( "vDHCPProcess: failed to generate a random Transaction ID\n" ) );\r
+ }\r
}\r
else\r
{\r
{\r
/* xGivingUp became true either because of a time-out, or because\r
xApplicationDHCPHook() returned another value than 'eDHCPContinue',\r
- meaning that the conversion is cancelled from here. */\r
+ meaning that the conversion is canceled from here. */\r
\r
/* Revert to static IP address. */\r
taskENTER_CRITICAL();\r
\r
static void prvInitialiseDHCP( void )\r
{\r
- /* Initialise the parameters that will be set by the DHCP process. */\r
- if( xDHCPData.ulTransactionId == 0ul )\r
+ /* Initialise the parameters that will be set by the DHCP process. Per\r
+ https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random\r
+ value chosen by the client. */\r
+\r
+ /* Check for random number generator API failure. */\r
+ if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )\r
{\r
- xDHCPData.ulTransactionId = ipconfigRAND32();\r
+ xDHCPData.xUseBroadcast = 0;\r
+ xDHCPData.ulOfferedIPAddress = 0UL;\r
+ xDHCPData.ulDHCPServerAddress = 0UL;\r
+ xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;\r
+\r
+ /* Create the DHCP socket if it has not already been created. */\r
+ prvCreateDHCPSocket();\r
+ FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );\r
+ vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );\r
}\r
else\r
{\r
- xDHCPData.ulTransactionId++;\r
+ /* There was a problem with the randomiser. */\r
}\r
-\r
- xDHCPData.xUseBroadcast = 0;\r
- xDHCPData.ulOfferedIPAddress = 0UL;\r
- xDHCPData.ulDHCPServerAddress = 0UL;\r
- xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;\r
-\r
- /* Create the DHCP socket if it has not already been created. */\r
- prvCreateDHCPSocket();\r
- FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );\r
- vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );\r
}\r
/*-----------------------------------------------------------*/\r
\r
pxDHCPMessage = ( DHCPMessage_t * ) ( pucUDPPayload );\r
\r
/* Sanity check. */\r
- if( ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&\r
+ if( ( lBytes >= sizeof( DHCPMessage_t ) ) &&\r
+ ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&\r
( pxDHCPMessage->ucOpcode == ( uint8_t ) dhcpREPLY_OPCODE ) &&\r
( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( xDHCPData.ulTransactionId ) ) )\r
{\r
- if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ), ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ) == 0 )\r
+ if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ),\r
+ ( void * ) ipLOCAL_MAC_ADDRESS,\r
+ sizeof( MACAddress_t ) ) == 0 )\r
{\r
/* None of the essential options have been processed yet. */\r
ulProcessed = 0ul;\r
/* Walk through the options until the dhcpOPTION_END_BYTE byte\r
is found, taking care not to walk off the end of the options. */\r
pucByte = &( pxDHCPMessage->ucFirstOptionByte );\r
- pucLastByte = &( pucUDPPayload[ lBytes - dhcpMAX_OPTION_LENGTH_OF_INTEREST ] );\r
+ /* Maintain a pointer to the last valid byte (i.e. not the first\r
+ invalid byte). */\r
+ pucLastByte = pucUDPPayload + lBytes - 1;\r
\r
- while( pucByte < pucLastByte )\r
+ while( pucByte <= pucLastByte )\r
{\r
ucOptionCode = pucByte[ 0 ];\r
- if( ucOptionCode == ( uint8_t ) dhcpOPTION_END_BYTE )\r
+ if( ucOptionCode == dhcpOPTION_END_BYTE )\r
{\r
/* Ready, the last byte has been seen. */\r
break;\r
}\r
- if( ucOptionCode == ( uint8_t ) dhcpIPv4_ZERO_PAD_OPTION_CODE )\r
+ if( ucOptionCode == dhcpZERO_PAD_OPTION_CODE )\r
{\r
/* The value zero is used as a pad byte,\r
it is not followed by a length byte. */\r
pucByte += 1;\r
continue;\r
}\r
- ucLength = pucByte[ 1 ];\r
- pucByte += 2;\r
+\r
+ /* Stop if the response is malformed. */\r
+ if( pucByte < pucLastByte )\r
+ {\r
+ /* There are at least two bytes left. */\r
+ ucLength = pucByte[ 1 ];\r
+ pucByte += 2;\r
+\r
+ if( pucByte + ucLength > pucLastByte )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
\r
/* In most cases, a 4-byte network-endian parameter follows,\r
- just get it once here and use later */\r
- memcpy( ( void * ) &( ulParameter ), ( void * ) pucByte, ( size_t ) sizeof( ulParameter ) );\r
+ just get it once here and use later. */\r
+ if( ucLength >= sizeof( ulParameter ) )\r
+ {\r
+ memcpy( ( void * ) &( ulParameter ),\r
+ ( void * ) pucByte,\r
+ ( size_t ) sizeof( ulParameter ) );\r
+ }\r
+ else\r
+ {\r
+ ulParameter = 0;\r
+ }\r
\r
+ /* Option-specific handling. */\r
switch( ucOptionCode )\r
{\r
- case dhcpIPv4_MESSAGE_TYPE_OPTION_CODE :\r
+ case dhcpMESSAGE_TYPE_OPTION_CODE :\r
\r
if( *pucByte == ( uint8_t ) xExpectedMessageType )\r
{\r
state machine is expecting. */\r
ulProcessed++;\r
}\r
- else\r
+ else if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )\r
{\r
- if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )\r
+ if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )\r
{\r
- if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )\r
- {\r
- /* Start again. */\r
- xDHCPData.eDHCPState = eWaitingSendFirstDiscover;\r
- }\r
+ /* Start again. */\r
+ xDHCPData.eDHCPState = eWaitingSendFirstDiscover;\r
}\r
- /* Stop processing further options. */\r
- ucLength = 0;\r
+ }\r
+ else\r
+ {\r
+ /* Don't process other message types. */\r
}\r
break;\r
\r
- case dhcpIPv4_SUBNET_MASK_OPTION_CODE :\r
+ case dhcpSUBNET_MASK_OPTION_CODE :\r
\r
if( ucLength == sizeof( uint32_t ) )\r
{\r
}\r
break;\r
\r
- case dhcpIPv4_GATEWAY_OPTION_CODE :\r
- /* The DHCP server may send more than 1 gateway addresses. */\r
- if( ucLength >= sizeof( uint32_t ) )\r
+ case dhcpGATEWAY_OPTION_CODE :\r
+\r
+ if( ucLength == sizeof( uint32_t ) )\r
{\r
/* ulProcessed is not incremented in this case\r
because the gateway is not essential. */\r
}\r
break;\r
\r
- case dhcpIPv4_DNS_SERVER_OPTIONS_CODE :\r
+ case dhcpDNS_SERVER_OPTIONS_CODE :\r
\r
/* ulProcessed is not incremented in this case\r
because the DNS server is not essential. Only the\r
xNetworkAddressing.ulDNSServerAddress = ulParameter;\r
break;\r
\r
- case dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE :\r
+ case dhcpSERVER_IP_ADDRESS_OPTION_CODE :\r
\r
if( ucLength == sizeof( uint32_t ) )\r
{\r
}\r
break;\r
\r
- case dhcpIPv4_LEASE_TIME_OPTION_CODE :\r
+ case dhcpLEASE_TIME_OPTION_CODE :\r
\r
if( ucLength == sizeof( xDHCPData.ulLeaseTime ) )\r
{\r
}\r
\r
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );\r
- } /* if( lBytes > 0 ) */\r
+ }\r
\r
return xReturn;\r
}\r
pxDHCPMessage->ucOpcode = ( uint8_t ) xOpcode;\r
pxDHCPMessage->ucAddressType = ( uint8_t ) dhcpADDRESS_TYPE_ETHERNET;\r
pxDHCPMessage->ucAddressLength = ( uint8_t ) dhcpETHERNET_ADDRESS_LENGTH;\r
-\r
- /* ulTransactionID doesn't really need a htonl() translation, but when DHCP\r
- times out, it is nicer to see an increasing number in this ID field */\r
pxDHCPMessage->ulTransactionID = FreeRTOS_htonl( xDHCPData.ulTransactionId );\r
pxDHCPMessage->ulDHCPCookie = ( uint32_t ) dhcpCOOKIE;\r
if( xDHCPData.xUseBroadcast != pdFALSE )\r
\r
/* Point to where the OPTION_END was stored to add data. */\r
pucPtr = &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + ( *pxOptionsArraySize - 1 ) ] );\r
- pucPtr[ 0 ] = dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE;\r
+ pucPtr[ 0 ] = dhcpDNS_HOSTNAME_OPTIONS_CODE;\r
pucPtr[ 1 ] = ( uint8_t ) xNameLength;\r
memcpy( ( void *) ( pucPtr + 2 ), pucHostName, xNameLength );\r
pucPtr[ 2 + xNameLength ] = dhcpOPTION_END_BYTE;\r
/* Do not change the ordering without also changing\r
dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and\r
dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */\r
- dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */\r
- dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */\r
- dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */\r
- dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */\r
+ dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */\r
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */\r
+ dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */\r
+ dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */\r
dhcpOPTION_END_BYTE\r
};\r
size_t xOptionsLength = sizeof( ucDHCPRequestOptions );\r
\r
- pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );\r
+ pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );\r
\r
/* Copy in the IP address being requested. */\r
memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ),\r
FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );\r
iptraceSENDING_DHCP_REQUEST();\r
\r
- if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
+ /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */\r
+ if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
{\r
/* The packet was not successfully queued for sending and must be\r
returned to the stack. */\r
static const uint8_t ucDHCPDiscoverOptions[] =\r
{\r
/* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */\r
- dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */\r
- dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */\r
- dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE, 3, dhcpIPv4_SUBNET_MASK_OPTION_CODE, dhcpIPv4_GATEWAY_OPTION_CODE, dhcpIPv4_DNS_SERVER_OPTIONS_CODE, /* Parameter request option. */\r
+ dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */\r
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */\r
+ dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */\r
dhcpOPTION_END_BYTE\r
};\r
size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );\r
\r
- pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );\r
+ pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );\r
\r
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );\r
iptraceSENDING_DHCP_DISCOVER();\r
\r
- if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
+ /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */\r
+ if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
{\r
/* The packet was not successfully queued for sending and must be\r
returned to the stack. */\r
static void prvPrepareLinkLayerIPLookUp( void )\r
{\r
uint8_t ucLinkLayerIPAddress[ 2 ];\r
+ uint32_t ulNumbers[ 2 ];\r
\r
/* After DHCP has failed to answer, prepare everything to start\r
trying-out LinkLayer IP-addresses, using the random method. */\r
xDHCPData.xDHCPTxTime = xTaskGetTickCount();\r
\r
- ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ipconfigRAND32() % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */\r
- ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ipconfigRAND32() % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */\r
+ xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );\r
+ xApplicationGetRandomNumber( &( ulNumbers[ 1 ] ) );\r
+ ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 0 ] % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */\r
+ ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 1 ] % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */\r
\r
xNetworkAddressing.ulGatewayAddress = FreeRTOS_htonl( 0xA9FE0203 );\r
\r
xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;\r
\r
/* Close socket to ensure packets don't queue on it. not needed anymore as DHCP failed. but still need timer for ARP testing. */\r
- vSocketClose( xDHCPData.xDHCPSocket );\r
- xDHCPData.xDHCPSocket = NULL;\r
- xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ipconfigRAND32() & 0x3fful ) ); /* do ARP test every (3 + 0-1024mS) seconds. */\r
+ if( xDHCPData.xDHCPSocket != NULL )\r
+ {\r
+ /* Close socket to ensure packets don't queue on it. */\r
+ vSocketClose( xDHCPData.xDHCPSocket );\r
+ xDHCPData.xDHCPSocket = NULL;\r
+ }\r
+\r
+ xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );\r
+ xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ulNumbers[ 0 ] & 0x3ffuL ) ); /* do ARP test every (3 + 0-1024mS) seconds. */\r
\r
xARPHadIPClash = pdFALSE; /* reset flag that shows if have ARP clash. */\r
vARPSendGratuitous();\r