]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
Sync FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP with the version in GitHub at (23665258ca...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / FreeRTOS_DHCP.c
index 6e35068912aa8cefb1ce3d600e46635dd362ac40..9180426dfa8d94f6cd21e064ded1711d9817dbbd 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * FreeRTOS+TCP V2.0.0\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
@@ -10,8 +10,7 @@
  * subject to the following conditions:\r
  *\r
  * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software. If you wish to use our Amazon\r
- * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
+ * copies or substantial portions of the Software.\r
  *\r
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\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
@@ -87,9 +84,9 @@
 \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
@@ -111,14 +108,7 @@ are located. */
 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
@@ -364,11 +354,17 @@ BaseType_t xGivingUp = pdFALSE;
 \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
@@ -520,7 +516,7 @@ BaseType_t xGivingUp = pdFALSE;
        {\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
@@ -588,25 +584,27 @@ TickType_t xTimeoutTime = ( TickType_t ) 0;
 \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
@@ -630,11 +628,14 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                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
@@ -642,33 +643,60 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                /* 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
@@ -676,22 +704,21 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                                                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
@@ -699,9 +726,9 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                                        }\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
@@ -709,7 +736,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                                        }\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
@@ -717,7 +744,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                                        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
@@ -738,7 +765,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                                                        }\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
@@ -789,7 +816,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
                }\r
 \r
                FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );\r
-       } /* if( lBytes > 0 ) */\r
+       }\r
 \r
        return xReturn;\r
 }\r
@@ -825,9 +852,6 @@ uint8_t *pucUDPPayloadBuffer;
        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
@@ -851,7 +875,7 @@ uint8_t *pucUDPPayloadBuffer;
 \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
@@ -880,15 +904,15 @@ static const uint8_t ucDHCPRequestOptions[] =
        /* 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
@@ -901,7 +925,8 @@ size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
        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
@@ -917,19 +942,20 @@ struct freertos_sockaddr xAddress;
 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
@@ -943,13 +969,16 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
        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
@@ -970,9 +999,15 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
                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