Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Projects / Webserver / Lib / DHCPClientApp.c
index 0e51d57..599def0 100644 (file)
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2010.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, distribute, and sell this \r
-  software and its documentation for any purpose is hereby granted\r
-  without fee, provided that the above copyright notice appear in \r
-  all copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting \r
-  documentation, and that the name of the author not be used in \r
-  advertising or publicity pertaining to distribution of the \r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  DHCP Client Application. When connected to the uIP stack, this will retrieve IP configuration settings from the\r
- *  DHCP server on the network.\r
- */\r
\r
-#include "DHCPClientApp.h"\r
-\r
-#if defined(ENABLE_DHCP_CLIENT) || defined(__DOXYGEN__)\r
-/** Timer for managing the timeout period for a DHCP server to respond */\r
-struct timer DHCPTimer;\r
-\r
-/** Initialization function for the DHCP client. */\r
-void DHCPClientApp_Init(void)\r
-{\r
-       /* Create an IP address to the broadcast network address */\r
-       uip_ipaddr_t DHCPServerIPAddress;\r
-       uip_ipaddr(&DHCPServerIPAddress, 255, 255, 255, 255);\r
-\r
-       /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */\r
-       struct uip_udp_conn* Connection = uip_udp_new(&DHCPServerIPAddress, HTONS(DHCPC_SERVER_PORT));\r
-       \r
-       /* If the connection was successfully created, bind it to the local DHCP client port */\r
-       if (Connection != NULL)\r
-       {\r
-               uip_udp_appstate_t* const AppState = &Connection->appstate;\r
-\r
-               uip_udp_bind(Connection, HTONS(DHCPC_CLIENT_PORT));\r
-               AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;\r
-       }\r
-\r
-       /* Set timeout period to half a second for a DHCP server to respond */\r
-       timer_set(&DHCPTimer, CLOCK_SECOND / 2);\r
-}\r
\r
-/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack \r
- *  needs a UDP packet to be processed.\r
- */\r
-void DHCPClientApp_Callback(void)\r
-{\r
-       uip_udp_appstate_t* const AppState    = &uip_udp_conn->appstate;\r
-       DHCP_Header_t*      const AppData     = (DHCP_Header_t*)uip_appdata;\r
-       uint16_t                  AppDataSize = 0;\r
-       \r
-       switch (AppState->DHCPClient.CurrentState)\r
-       {\r
-               case DHCP_STATE_SendDiscover:\r
-                       /* Clear all DHCP settings, reset client IP address */\r
-                       memset(&AppState->DHCPClient.DHCPOffer_Data, 0x00, sizeof(AppState->DHCPClient.DHCPOffer_Data));\r
-                       uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);\r
-\r
-                       /* Fill out the DHCP response header */\r
-                       AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);\r
-                       \r
-                       /* Add the required DHCP options list to the packet */\r
-                       uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};\r
-                       AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),\r
-                                                              RequiredOptionList);                     \r
-                       \r
-                       /* Send the DHCP DISCOVER packet */\r
-                       uip_udp_send(AppDataSize);\r
-\r
-                       /* Reset the timeout timer, progress to next state */\r
-                       timer_reset(&DHCPTimer);\r
-                       AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;                    \r
-                       \r
-                       break;\r
-               case DHCP_STATE_WaitForOffer:\r
-                       if (!(uip_newdata()))\r
-                       {\r
-                               /* Check if the DHCP timeout period has expired while waiting for a response */\r
-                               if (timer_expired(&DHCPTimer))\r
-                                 AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;\r
-                               \r
-                               break;\r
-                       }\r
-                         \r
-                       uint8_t OfferResponse_MessageType;\r
-                       if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&\r
-                           DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&\r
-                           (OfferResponse_MessageType == DHCP_OFFER))\r
-                       {\r
-                               /* Received a DHCP offer for an IP address, copy over values for later request */\r
-                               memcpy(&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));\r
-                               DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);\r
-                               DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER,      &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);\r
-                               DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID,   &AppState->DHCPClient.DHCPOffer_Data.ServerIP);\r
-                               \r
-                               timer_reset(&DHCPTimer);\r
-                               AppState->DHCPClient.CurrentState = DHCP_STATE_SendRequest;\r
-                       }\r
-\r
-                       break;\r
-               case DHCP_STATE_SendRequest:\r
-                       /* Fill out the DHCP response header */\r
-                       AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);\r
-\r
-                       /* Add the DHCP REQUESTED IP ADDRESS option to the packet */\r
-                       AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),\r
-                                                              &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);\r
-\r
-                       /* Add the DHCP SERVER IP ADDRESS option to the packet */\r
-                       AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),\r
-                                                              &AppState->DHCPClient.DHCPOffer_Data.ServerIP);\r
-\r
-                       /* Send the DHCP REQUEST packet */\r
-                       uip_udp_send(AppDataSize);\r
-                       \r
-                       /* Reset the timeout timer, progress to next state */\r
-                       timer_reset(&DHCPTimer);\r
-                       AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForACK;\r
-\r
-                       break;\r
-               case DHCP_STATE_WaitForACK:\r
-                       if (!(uip_newdata()))\r
-                       {\r
-                               /* Check if the DHCP timeout period has expired while waiting for a response */\r
-                               if (timer_expired(&DHCPTimer))\r
-                                 AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;\r
-                               \r
-                               break;\r
-                       }\r
-                       \r
-                       uint8_t RequestResponse_MessageType;\r
-                       if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&\r
-                           DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&\r
-                           (RequestResponse_MessageType == DHCP_ACK))\r
-                       {\r
-                               /* Set the new network parameters from the DHCP server */\r
-                               uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);\r
-                               uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.Netmask);\r
-                               uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.GatewayIP);\r
-                       \r
-                               AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;\r
-                       }\r
-                       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required\r
- *  fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP server.\r
- *\r
- *  \param[out] DHCPHeader  Location in the packet buffer where the BOOTP header should be written to\r
- *  \param[in]  DHCPMessageType  DHCP Message type, such as DHCP_DISCOVER\r
- *  \param[in]  AppState    Application state of the current UDP connection\r
- *\r
- *  \return Size in bytes of the created DHCP packet\r
- */\r
-uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState)\r
-{\r
-       /* Erase existing packet data so that we start will all 0x00 DHCP header data */\r
-       memset(DHCPHeader, 0, sizeof(DHCP_Header_t));\r
-\r
-       /* Fill out the DHCP packet header */\r
-       DHCPHeader->Operation             = DHCP_OP_BOOTREQUEST;\r
-       DHCPHeader->HardwareType          = DHCP_HTYPE_ETHERNET;\r
-       DHCPHeader->HardwareAddressLength = sizeof(MACAddress);\r
-       DHCPHeader->Hops                  = 0;\r
-       DHCPHeader->TransactionID         = DHCP_TRANSACTION_ID;\r
-       DHCPHeader->ElapsedSeconds        = 0;\r
-       DHCPHeader->Flags                 = HTONS(BOOTP_BROADCAST);\r
-       memcpy(&DHCPHeader->ClientIP,     &uip_hostaddr,        sizeof(uip_ipaddr_t));\r
-       memcpy(&DHCPHeader->YourIP,       &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));\r
-       memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPClient.DHCPOffer_Data.ServerIP,    sizeof(uip_ipaddr_t));\r
-       memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));\r
-       DHCPHeader->Cookie                = DHCP_MAGIC_COOKIE;\r
-       \r
-       /* Add a DHCP message type and terminator options to the start of the DHCP options field */\r
-       DHCPHeader->Options[0]            = DHCP_OPTION_MSG_TYPE;\r
-       DHCPHeader->Options[1]            = 1;\r
-       DHCPHeader->Options[2]            = DHCPMessageType;\r
-       DHCPHeader->Options[3]            = DHCP_OPTION_END;\r
-       \r
-       /* Calculate the total number of bytes added to the outgoing packet */\r
-       return (sizeof(DHCP_Header_t) + 4);\r
-}\r
-\r
-/** Sets the given DHCP option in the DHCP packet's option list. This automatically moves the\r
- *  end of options terminator past the new option in the options list.\r
- *\r
- *  \param[in,out] DHCPOptionList  Pointer to the start of the DHCP packet's options list\r
- *  \param[in]     Option          DHCP option to add to the list\r
- *  \param[in]     DataLen         Size in bytes of the option data to add\r
- *  \param[in]     OptionData      Buffer where the option's data is to be sourced from\r
- *\r
- *  \return Number of bytes added to the DHCP packet\r
- */\r
-uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* OptionData)\r
-{\r
-       /* Skip through the DHCP options list until the terminator option is found */\r
-       while (*DHCPOptionList != DHCP_OPTION_END)\r
-         DHCPOptionList += (DHCPOptionList[1] + 2);\r
-\r
-       /* Overwrite the existing terminator with the new option, add a new terminator at the end of the list */\r
-       DHCPOptionList[0] = Option;\r
-       DHCPOptionList[1] = DataLen;\r
-       memcpy(&DHCPOptionList[2], OptionData, DataLen);\r
-       DHCPOptionList[2 + DataLen] = DHCP_OPTION_END;\r
-       \r
-       /* Calculate the total number of bytes added to the outgoing packet */\r
-       return (2 + DataLen);\r
-}\r
-\r
-/** Retrieves the given option's data (if present) from the DHCP packet's options list.\r
- *\r
- *  \param[in,out] DHCPOptionList  Pointer to the start of the DHCP packet's options list\r
- *  \param[in]     Option          DHCP option to retrieve to the list\r
- *  \param[out]    Destination     Buffer where the option's data is to be written to if found\r
- *\r
- *  \return Boolean true if the option was found in the DHCP packet's options list, false otherwise\r
- */\r
-bool DHCPClientApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination)\r
-{\r
-       /* Look through the incoming DHCP packet's options list for the requested option */\r
-       while (*DHCPOptionList != DHCP_OPTION_END)\r
-       {\r
-               /* Check if the current DHCP option in the packet is the one requested */\r
-               if (DHCPOptionList[0] == Option)\r
-               {\r
-                       /* Copy request option's data to the destination buffer */\r
-                       memcpy(Destination, &DHCPOptionList[2], DHCPOptionList[1]);\r
-                       \r
-                       /* Indicate that the requested option data was successfully retrieved */\r
-                       return true;\r
-               }\r
-               \r
-               /* Skip to next DHCP option in the options list */\r
-               DHCPOptionList += (DHCPOptionList[1] + 2);\r
-       }\r
-       \r
-       /* Requested option not found in the incoming packet's DHCP options list */\r
-       return false;\r
-}\r
-#endif\r
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2011.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#if defined(ENABLE_DHCP_CLIENT) || defined(__DOXYGEN__)
+
+/** \file
+ *
+ *  DHCP Client Application. When connected to the uIP stack, this will retrieve IP configuration settings from the
+ *  DHCP server on the network.
+ */
+
+#define  INCLUDE_FROM_DHCPCLIENTAPP_C
+#include "DHCPClientApp.h"
+
+/** Initialization function for the DHCP client. */
+void DHCPClientApp_Init(void)
+{
+       /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
+       struct uip_udp_conn* Connection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_SERVER_PORT));
+
+       /* If the connection was successfully created, bind it to the local DHCP client port */
+       if (Connection != NULL)
+       {
+               uip_udp_appstate_t* const AppState = &Connection->appstate;
+               uip_udp_bind(Connection, HTONS(DHCP_CLIENT_PORT));
+
+               /* Set the initial client state */
+               AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
+
+               /* Set timeout period to half a second for a DHCP server to respond */
+               timer_set(&AppState->DHCPClient.Timeout, CLOCK_SECOND / 2);
+       }
+}
+
+/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
+ *  needs a UDP packet to be processed.
+ */
+void DHCPClientApp_Callback(void)
+{
+       uip_udp_appstate_t* const AppState    = &uip_udp_conn->appstate;
+       DHCP_Header_t*      const AppData     = (DHCP_Header_t*)uip_appdata;
+       uint16_t                  AppDataSize = 0;
+
+       switch (AppState->DHCPClient.CurrentState)
+       {
+               case DHCP_STATE_SendDiscover:
+                       /* Clear all DHCP settings, reset client IP address */
+                       memset(&AppState->DHCPClient.DHCPOffer_Data, 0x00, sizeof(AppState->DHCPClient.DHCPOffer_Data));
+                       uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
+
+                       /* Fill out the DHCP response header */
+                       AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
+
+                       /* Add the required DHCP options list to the packet */
+                       uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
+                       AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
+                                                           RequiredOptionList);
+
+                       /* Send the DHCP DISCOVER packet */
+                       uip_udp_send(AppDataSize);
+
+                       /* Reset the timeout timer, progress to next state */
+                       timer_reset(&AppState->DHCPClient.Timeout);
+                       AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;
+
+                       break;
+               case DHCP_STATE_WaitForOffer:
+                       if (!(uip_newdata()))
+                       {
+                               /* Check if the DHCP timeout period has expired while waiting for a response */
+                               if (timer_expired(&AppState->DHCPClient.Timeout))
+                                 AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
+
+                               break;
+                       }
+
+                       uint8_t OfferResponse_MessageType;
+                       if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
+                           DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
+                           (OfferResponse_MessageType == DHCP_OFFER))
+                       {
+                               /* Received a DHCP offer for an IP address, copy over values for later request */
+                               memcpy(&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));
+                               DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);
+                               DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_ROUTER,      &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
+                               DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID,   &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
+
+                               timer_reset(&AppState->DHCPClient.Timeout);
+                               AppState->DHCPClient.CurrentState = DHCP_STATE_SendRequest;
+                       }
+
+                       break;
+               case DHCP_STATE_SendRequest:
+                       /* Fill out the DHCP response header */
+                       AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
+
+                       /* Add the DHCP REQUESTED IP ADDRESS option to the packet */
+                       AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
+                                                           &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
+
+                       /* Add the DHCP SERVER IP ADDRESS option to the packet */
+                       AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
+                                                           &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
+
+                       /* Send the DHCP REQUEST packet */
+                       uip_udp_send(AppDataSize);
+
+                       /* Reset the timeout timer, progress to next state */
+                       timer_reset(&AppState->DHCPClient.Timeout);
+                       AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForACK;
+
+                       break;
+               case DHCP_STATE_WaitForACK:
+                       if (!(uip_newdata()))
+                       {
+                               /* Check if the DHCP timeout period has expired while waiting for a response */
+                               if (timer_expired(&AppState->DHCPClient.Timeout))
+                                 AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
+
+                               break;
+                       }
+
+                       uint8_t RequestResponse_MessageType;
+                       if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
+                           DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
+                           (RequestResponse_MessageType == DHCP_ACK))
+                       {
+                               /* Set the new network parameters from the DHCP server */
+                               uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
+                               uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.Netmask);
+                               uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
+
+                               AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;
+                       }
+
+                       break;
+       }
+}
+
+/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required
+ *  fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP server.
+ *
+ *  \param[out] DHCPHeader       Location in the packet buffer where the BOOTP header should be written to
+ *  \param[in]  DHCPMessageType  DHCP Message type, such as DHCP_DISCOVER
+ *  \param[in]  AppState         Application state of the current UDP connection
+ *
+ *  \return Size in bytes of the created DHCP packet
+ */
+static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
+                                             const uint8_t DHCPMessageType,
+                                             uip_udp_appstate_t* const AppState)
+{
+       /* Erase existing packet data so that we start will all 0x00 DHCP header data */
+       memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
+
+       /* Fill out the DHCP packet header */
+       DHCPHeader->Operation             = DHCP_OP_BOOTREQUEST;
+       DHCPHeader->HardwareType          = DHCP_HTYPE_ETHERNET;
+       DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
+       DHCPHeader->Hops                  = 0;
+       DHCPHeader->TransactionID         = DHCP_TRANSACTION_ID;
+       DHCPHeader->ElapsedSeconds        = 0;
+       DHCPHeader->Flags                 = HTONS(BOOTP_BROADCAST);
+       memcpy(&DHCPHeader->ClientIP,     &uip_hostaddr,        sizeof(uip_ipaddr_t));
+       memcpy(&DHCPHeader->YourIP,       &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));
+       memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPClient.DHCPOffer_Data.ServerIP,    sizeof(uip_ipaddr_t));
+       memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));
+       DHCPHeader->Cookie                = DHCP_MAGIC_COOKIE;
+
+       /* Add a DHCP message type and terminator options to the start of the DHCP options field */
+       DHCPHeader->Options[0]            = DHCP_OPTION_MSG_TYPE;
+       DHCPHeader->Options[1]            = 1;
+       DHCPHeader->Options[2]            = DHCPMessageType;
+       DHCPHeader->Options[3]            = DHCP_OPTION_END;
+
+       /* Calculate the total number of bytes added to the outgoing packet */
+       return (sizeof(DHCP_Header_t) + 4);
+}
+
+#endif
+