From 3cba88e4c05d6a3c25ffa9c7185d41a84b7f72b1 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 22 May 2011 08:28:40 +0000 Subject: Add RNDIS Device support to the Webserver project, so that the files stored on the device can be viewed from a web-browser while the board is plugged into a host machine. --- Projects/Webserver/Lib/DHCPClientApp.c | 87 ++---------- Projects/Webserver/Lib/DHCPClientApp.h | 111 +-------------- Projects/Webserver/Lib/DHCPCommon.c | 102 ++++++++++++++ Projects/Webserver/Lib/DHCPCommon.h | 157 ++++++++++++++++++++++ Projects/Webserver/Lib/DHCPServerApp.c | 237 +++++++++++++++++++++++++++++++++ Projects/Webserver/Lib/DHCPServerApp.h | 62 +++++++++ Projects/Webserver/Lib/HTTPServerApp.c | 6 +- Projects/Webserver/Lib/uIPManagement.c | 96 +++++++++---- Projects/Webserver/Lib/uIPManagement.h | 11 +- Projects/Webserver/Lib/uip/uip-split.c | 15 ++- Projects/Webserver/Lib/uip/uip.c | 10 +- 11 files changed, 676 insertions(+), 218 deletions(-) create mode 100644 Projects/Webserver/Lib/DHCPCommon.c create mode 100644 Projects/Webserver/Lib/DHCPCommon.h create mode 100644 Projects/Webserver/Lib/DHCPServerApp.c create mode 100644 Projects/Webserver/Lib/DHCPServerApp.h (limited to 'Projects/Webserver/Lib') diff --git a/Projects/Webserver/Lib/DHCPClientApp.c b/Projects/Webserver/Lib/DHCPClientApp.c index 4afe6bfe2..6a2f02938 100644 --- a/Projects/Webserver/Lib/DHCPClientApp.c +++ b/Projects/Webserver/Lib/DHCPClientApp.c @@ -43,13 +43,13 @@ 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(DHCPC_SERVER_PORT)); + 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(DHCPC_CLIENT_PORT)); + uip_udp_bind(Connection, HTONS(DHCP_CLIENT_PORT)); /* Set the initial client state */ AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover; @@ -80,8 +80,8 @@ void DHCPClientApp_Callback(void) /* Add the required DHCP options list to the packet */ uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER}; - AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList), - RequiredOptionList); + AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList), + RequiredOptionList); /* Send the DHCP DISCOVER packet */ uip_udp_send(AppDataSize); @@ -103,14 +103,14 @@ void DHCPClientApp_Callback(void) uint8_t OfferResponse_MessageType; if ((AppData->TransactionID == DHCP_TRANSACTION_ID) && - DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) && + 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)); - DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask); - DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPClient.DHCPOffer_Data.GatewayIP); - DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPClient.DHCPOffer_Data.ServerIP); + 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; @@ -122,12 +122,12 @@ void DHCPClientApp_Callback(void) AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState); /* Add the DHCP REQUESTED IP ADDRESS option to the packet */ - AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t), - &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP); + 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 += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t), - &AppState->DHCPClient.DHCPOffer_Data.ServerIP); + 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); @@ -149,7 +149,7 @@ void DHCPClientApp_Callback(void) uint8_t RequestResponse_MessageType; if ((AppData->TransactionID == DHCP_TRANSACTION_ID) && - DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) && + DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) && (RequestResponse_MessageType == DHCP_ACK)) { /* Set the new network parameters from the DHCP server */ @@ -207,66 +207,5 @@ static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader, return (sizeof(DHCP_Header_t) + 4); } -/** Sets the given DHCP option in the DHCP packet's option list. This automatically moves the - * end of options terminator past the new option in the options list. - * - * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list - * \param[in] Option DHCP option to add to the list - * \param[in] DataLen Size in bytes of the option data to add - * \param[in] OptionData Buffer where the option's data is to be sourced from - * - * \return Number of bytes added to the DHCP packet - */ -static uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList, - const uint8_t Option, - const uint8_t DataLen, - void* const OptionData) -{ - /* Skip through the DHCP options list until the terminator option is found */ - while (*DHCPOptionList != DHCP_OPTION_END) - DHCPOptionList += (DHCPOptionList[1] + 2); - - /* Overwrite the existing terminator with the new option, add a new terminator at the end of the list */ - DHCPOptionList[0] = Option; - DHCPOptionList[1] = DataLen; - memcpy(&DHCPOptionList[2], OptionData, DataLen); - DHCPOptionList[2 + DataLen] = DHCP_OPTION_END; - - /* Calculate the total number of bytes added to the outgoing packet */ - return (2 + DataLen); -} - -/** Retrieves the given option's data (if present) from the DHCP packet's options list. - * - * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list - * \param[in] Option DHCP option to retrieve to the list - * \param[out] Destination Buffer where the option's data is to be written to if found - * - * \return Boolean true if the option was found in the DHCP packet's options list, false otherwise - */ -static bool DHCPClientApp_GetOption(const uint8_t* DHCPOptionList, - const uint8_t Option, - void* const Destination) -{ - /* Look through the incoming DHCP packet's options list for the requested option */ - while (*DHCPOptionList != DHCP_OPTION_END) - { - /* Check if the current DHCP option in the packet is the one requested */ - if (DHCPOptionList[0] == Option) - { - /* Copy request option's data to the destination buffer */ - memcpy(Destination, &DHCPOptionList[2], DHCPOptionList[1]); - - /* Indicate that the requested option data was successfully retrieved */ - return true; - } - - /* Skip to next DHCP option in the options list */ - DHCPOptionList += (DHCPOptionList[1] + 2); - } - - /* Requested option not found in the incoming packet's DHCP options list */ - return false; -} #endif diff --git a/Projects/Webserver/Lib/DHCPClientApp.h b/Projects/Webserver/Lib/DHCPClientApp.h index cb4014fbc..1f3104c6f 100644 --- a/Projects/Webserver/Lib/DHCPClientApp.h +++ b/Projects/Webserver/Lib/DHCPClientApp.h @@ -42,111 +42,11 @@ #include #include "../Webserver.h" - - /* Macros: */ - /** UDP listen port for a BOOTP server. */ - #define DHCPC_SERVER_PORT 67 - - /** UDP listen port for a BOOTP client. */ - #define DHCPC_CLIENT_PORT 68 - - /** BOOTP message type for a BOOTP REQUEST message. */ - #define DHCP_OP_BOOTREQUEST 0x01 - - /** BOOTP message type for a BOOTP REPLY message. */ - #define DHCP_OP_BOOTREPLY 0x02 - - /** BOOTP flag for a BOOTP broadcast message. */ - #define BOOTP_BROADCAST 0x8000 - - /** Magic DHCP cookie for a BOOTP message to identify it as a DHCP message. */ - #define DHCP_MAGIC_COOKIE 0x63538263 - - /** Unique transaction ID used to identify DHCP responses to the client. */ - #define DHCP_TRANSACTION_ID 0x13245466 - - /** DHCP message type for a DISCOVER message. */ - #define DHCP_DISCOVER 1 - - /** DHCP message type for an OFFER message. */ - #define DHCP_OFFER 2 - - /** DHCP message type for a REQUEST message. */ - #define DHCP_REQUEST 3 - - /** DHCP message type for a DECLINE message. */ - #define DHCP_DECLINE 4 - - /** DHCP message type for an ACK message. */ - #define DHCP_ACK 5 - - /** DHCP message type for a NAK message. */ - #define DHCP_NAK 6 - - /** DHCP message type for a RELEASE message. */ - #define DHCP_RELEASE 7 - - /** DHCP medium type for standard Ethernet. */ - #define DHCP_HTYPE_ETHERNET 1 - - /** DHCP message option for the network subnet mask. */ - #define DHCP_OPTION_SUBNET_MASK 1 - - /** DHCP message option for the network gateway IP. */ - #define DHCP_OPTION_ROUTER 3 - - /** DHCP message option for the network DNS server. */ - #define DHCP_OPTION_DNS_SERVER 6 - - /** DHCP message option for the requested client IP address. */ - #define DHCP_OPTION_REQ_IPADDR 50 - - /** DHCP message option for the IP address lease time. */ - #define DHCP_OPTION_LEASE_TIME 51 - - /** DHCP message option for the DHCP message type. */ - #define DHCP_OPTION_MSG_TYPE 53 - - /** DHCP message option for the DHCP server IP. */ - #define DHCP_OPTION_SERVER_ID 54 - - /** DHCP message option for the list of required options from the server. */ - #define DHCP_OPTION_REQ_LIST 55 - - /** DHCP message option for the options list terminator. */ - #define DHCP_OPTION_END 255 - - /* Type Defines: */ - /** Type define for a DHCP packet inside an Ethernet frame. */ - typedef struct - { - uint8_t Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */ - uint8_t HardwareType; /**< Hardware carrier type constant */ - uint8_t HardwareAddressLength; /**< Length in bytes of a hardware (MAC) address on the network */ - uint8_t Hops; /**< Number of hops required to reach the server, unused */ - - uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */ - - uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */ - uint16_t Flags; /**< BOOTP packet flags */ - - uip_ipaddr_t ClientIP; /**< Client IP address, if already leased an IP */ - uip_ipaddr_t YourIP; /**< Client IP address */ - uip_ipaddr_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */ - uip_ipaddr_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */ - - uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */ - uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */ - uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */ - - uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */ - - uint8_t Options[]; /**< DHCP message options */ - } DHCP_Header_t; + #include "DHCPCommon.h" /* Enums: */ /** States for each DHCP connection to a DHCP client. */ - enum DHCP_States_t + enum DHCP_Client_States_t { DHCP_STATE_SendDiscover, /**< Send DISCOVER packet to retrieve DHCP lease offers */ DHCP_STATE_WaitForOffer, /**< Waiting for OFFER packet giving available DHCP leases */ @@ -163,13 +63,6 @@ static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader, const uint8_t DHCPMessageType, uip_udp_appstate_t* const AppState); - static uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList, - const uint8_t Option, - const uint8_t DataLen, - void* const OptionData); - static bool DHCPClientApp_GetOption(const uint8_t* DHCPOptionList, - const uint8_t Option, - void* const Destination); #endif #endif diff --git a/Projects/Webserver/Lib/DHCPCommon.c b/Projects/Webserver/Lib/DHCPCommon.c new file mode 100644 index 000000000..dac5fa797 --- /dev/null +++ b/Projects/Webserver/Lib/DHCPCommon.c @@ -0,0 +1,102 @@ +/* + 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(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__) + +/** \file + * + * Common DHCP routines to manage DHCP packet data. + */ + +#include "DHCPCommon.h" + +/** Sets the given DHCP option in the DHCP packet's option list. This automatically moves the + * end of options terminator past the new option in the options list. + * + * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list + * \param[in] Option DHCP option to add to the list + * \param[in] DataLen Size in bytes of the option data to add + * \param[in] OptionData Buffer where the option's data is to be sourced from + * + * \return Number of bytes added to the DHCP packet + */ +uint8_t DHCPCommon_SetOption(uint8_t* DHCPOptionList, + const uint8_t Option, + const uint8_t DataLen, + void* const OptionData) +{ + /* Skip through the DHCP options list until the terminator option is found */ + while (*DHCPOptionList != DHCP_OPTION_END) + DHCPOptionList += (DHCPOptionList[1] + 2); + + /* Overwrite the existing terminator with the new option, add a new terminator at the end of the list */ + DHCPOptionList[0] = Option; + DHCPOptionList[1] = DataLen; + memcpy(&DHCPOptionList[2], OptionData, DataLen); + DHCPOptionList[2 + DataLen] = DHCP_OPTION_END; + + /* Calculate the total number of bytes added to the outgoing packet */ + return (2 + DataLen); +} + +/** Retrieves the given option's data (if present) from the DHCP packet's options list. + * + * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list + * \param[in] Option DHCP option to retrieve to the list + * \param[out] Destination Buffer where the option's data is to be written to if found + * + * \return Boolean true if the option was found in the DHCP packet's options list, false otherwise + */ +bool DHCPCommon_GetOption(const uint8_t* DHCPOptionList, + const uint8_t Option, + void* const Destination) +{ + /* Look through the incoming DHCP packet's options list for the requested option */ + while (*DHCPOptionList != DHCP_OPTION_END) + { + /* Check if the current DHCP option in the packet is the one requested */ + if (DHCPOptionList[0] == Option) + { + /* Copy request option's data to the destination buffer */ + memcpy(Destination, &DHCPOptionList[2], DHCPOptionList[1]); + + /* Indicate that the requested option data was successfully retrieved */ + return true; + } + + /* Skip to next DHCP option in the options list */ + DHCPOptionList += (DHCPOptionList[1] + 2); + } + + /* Requested option not found in the incoming packet's DHCP options list */ + return false; +} + +#endif diff --git a/Projects/Webserver/Lib/DHCPCommon.h b/Projects/Webserver/Lib/DHCPCommon.h new file mode 100644 index 000000000..652db683c --- /dev/null +++ b/Projects/Webserver/Lib/DHCPCommon.h @@ -0,0 +1,157 @@ +/* + 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. +*/ + +/** \file + * + * Header file for common DHCP defines. + */ + +#ifndef _DHCP_COMMON_H_ +#define _DHCP_COMMON_H_ + + /* Includes: */ + #include + #include + #include + + #include + + /* Macros: */ + /** UDP listen port for a BOOTP server. */ + #define DHCP_SERVER_PORT 67 + + /** UDP listen port for a BOOTP client. */ + #define DHCP_CLIENT_PORT 68 + + /** BOOTP message type for a BOOTP REQUEST message. */ + #define DHCP_OP_BOOTREQUEST 0x01 + + /** BOOTP message type for a BOOTP REPLY message. */ + #define DHCP_OP_BOOTREPLY 0x02 + + /** BOOTP flag for a BOOTP broadcast message. */ + #define BOOTP_BROADCAST 0x8000 + + /** Magic DHCP cookie for a BOOTP message to identify it as a DHCP message. */ + #define DHCP_MAGIC_COOKIE 0x63538263 + + /** Unique transaction ID used to identify DHCP responses to the client. */ + #define DHCP_TRANSACTION_ID 0x13245466 + + /** DHCP message type for a DISCOVER message. */ + #define DHCP_DISCOVER 1 + + /** DHCP message type for an OFFER message. */ + #define DHCP_OFFER 2 + + /** DHCP message type for a REQUEST message. */ + #define DHCP_REQUEST 3 + + /** DHCP message type for a DECLINE message. */ + #define DHCP_DECLINE 4 + + /** DHCP message type for an ACK message. */ + #define DHCP_ACK 5 + + /** DHCP message type for a NAK message. */ + #define DHCP_NAK 6 + + /** DHCP message type for a RELEASE message. */ + #define DHCP_RELEASE 7 + + /** DHCP medium type for standard Ethernet. */ + #define DHCP_HTYPE_ETHERNET 1 + + /** DHCP message option for the network subnet mask. */ + #define DHCP_OPTION_SUBNET_MASK 1 + + /** DHCP message option for the network gateway IP. */ + #define DHCP_OPTION_ROUTER 3 + + /** DHCP message option for the network DNS server. */ + #define DHCP_OPTION_DNS_SERVER 6 + + /** DHCP message option for the requested client IP address. */ + #define DHCP_OPTION_REQ_IPADDR 50 + + /** DHCP message option for the IP address lease time. */ + #define DHCP_OPTION_LEASE_TIME 51 + + /** DHCP message option for the DHCP message type. */ + #define DHCP_OPTION_MSG_TYPE 53 + + /** DHCP message option for the DHCP server IP. */ + #define DHCP_OPTION_SERVER_ID 54 + + /** DHCP message option for the list of required options from the server. */ + #define DHCP_OPTION_REQ_LIST 55 + + /** DHCP message option for the options list terminator. */ + #define DHCP_OPTION_END 255 + + /* Type Defines: */ + /** Type define for a DHCP packet inside an Ethernet frame. */ + typedef struct + { + uint8_t Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */ + uint8_t HardwareType; /**< Hardware carrier type constant */ + uint8_t HardwareAddressLength; /**< Length in bytes of a hardware (MAC) address on the network */ + uint8_t Hops; /**< Number of hops required to reach the server, unused */ + + uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */ + + uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */ + uint16_t Flags; /**< BOOTP packet flags */ + + uip_ipaddr_t ClientIP; /**< Client IP address, if already leased an IP */ + uip_ipaddr_t YourIP; /**< Client IP address */ + uip_ipaddr_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */ + uip_ipaddr_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */ + + uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */ + uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */ + uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */ + + uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */ + + uint8_t Options[]; /**< DHCP message options */ + } DHCP_Header_t; + + /* Function Prototypes: */ + uint8_t DHCPCommon_SetOption(uint8_t* DHCPOptionList, + const uint8_t Option, + const uint8_t DataLen, + void* const OptionData); + bool DHCPCommon_GetOption(const uint8_t* DHCPOptionList, + const uint8_t Option, + void* const Destination); + +#endif + diff --git a/Projects/Webserver/Lib/DHCPServerApp.c b/Projects/Webserver/Lib/DHCPServerApp.c new file mode 100644 index 000000000..84c57d0a2 --- /dev/null +++ b/Projects/Webserver/Lib/DHCPServerApp.c @@ -0,0 +1,237 @@ +/* + 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_SERVER) || defined(__DOXYGEN__) + +/** \file + * + * DHCP Server Application. When connected to the uIP stack, this will send IP configuration settings to a + * DHCP client on the network. + */ + +#define INCLUDE_FROM_DHCPSERVERAPP_C +#include "DHCPServerApp.h" + +struct uip_conn* BroadcastConnection; + +uint8_t LeasedIPs[255 / 8]; + +/** Initialization function for the DHCP server. */ +void DHCPServerApp_Init(void) +{ + /* Listen on port 67 for DHCP server connections from hosts */ + uip_listen(HTONS(DHCP_SERVER_PORT)); + + /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */ + struct uip_udp_conn* BroadcastConnection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_CLIENT_PORT)); + + /* If the connection was successfully created, bind it to the local DHCP client port */ + if (BroadcastConnection != NULL) + uip_udp_bind(BroadcastConnection, HTONS(DHCP_SERVER_PORT)); + + /* Set all IP addresses as unleased */ + memset(LeasedIPs, 0x00, sizeof(LeasedIPs)); +} + +/** uIP stack application callback for the DHCP server. This function must be called each time the TCP/IP stack + * needs a UDP packet to be processed. + */ +void DHCPServerApp_Callback(void) +{ + DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata; + uint16_t AppDataSize = 0; + + uint8_t DHCPMessageType; + if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &DHCPMessageType))) + return; + + uip_ipaddr_t Netmask, GatewayIPAddress; + struct uip_eth_addr RemoteMACAddress; + uint32_t TransactionID; + + memcpy(&RemoteMACAddress, &AppData->ClientHardwareAddress, sizeof(struct uip_eth_addr)); + uip_getnetmask(&Netmask); + uip_getdraddr(&GatewayIPAddress); + TransactionID = AppData->TransactionID; + + switch (DHCPMessageType) + { + case DHCP_DISCOVER: + AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_OFFER, &RemoteMACAddress, TransactionID); + + AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, + sizeof(uip_ipaddr_t), &Netmask); + AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER, + sizeof(uip_ipaddr_t), &GatewayIPAddress); + + /* Send the DHCP OFFER packet */ + uip_poll_conn(BroadcastConnection); + memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t)); + uip_udp_send(AppDataSize); + + break; + case DHCP_REQUEST: + if (!(DHCPServerApp_CheckIfIPLeased(&AppData->YourIP))) + { + AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_ACK, &RemoteMACAddress, TransactionID); + + AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, + sizeof(uip_ipaddr_t), &Netmask); + AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER, + sizeof(uip_ipaddr_t), &GatewayIPAddress); + + DHCPServerApp_LeaseIP(&AppData->YourIP); + } + else + { + AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_NAK, &RemoteMACAddress, TransactionID); + } + + /* Send the DHCP ACK or NAK packet */ + uip_poll_conn(BroadcastConnection); + memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t)); + uip_udp_send(AppDataSize); + + break; + case DHCP_RELEASE: + /* Mark the IP address as released in the allocation table */ + DHCPServerApp_UnleaseIP(&uip_udp_conn->ripaddr); + 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 client. + * + * \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] ClientHardwareAddress Client MAC address the created transaction should be directed to + * \param[in] TransactionID Transaction ID the created transaction should be associated with + * + * \return Size in bytes of the created DHCP packet + */ +static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader, + const uint8_t DHCPMessageType, + struct uip_eth_addr* ClientHardwareAddress, + uint32_t TransactionID) +{ + /* Erase existing packet data so that we start will all 0x00 DHCP header data */ + memset(DHCPHeader, 0, sizeof(DHCP_Header_t)); + + DHCPHeader->Operation = DHCPMessageType; + DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET; + DHCPHeader->HardwareAddressLength = sizeof(MACAddress); + DHCPHeader->Hops = 0; + DHCPHeader->TransactionID = TransactionID; + DHCPHeader->ElapsedSeconds = 0; + DHCPHeader->Flags = 0; + memcpy(&DHCPHeader->NextServerIP, &uip_hostaddr, sizeof(uip_ipaddr_t)); + if (uip_ipaddr_cmp(&DHCPHeader->YourIP, &uip_all_zeroes_addr)) + DHCPServerApp_GetUnleasedIP(&DHCPHeader->YourIP); + memcpy(&DHCPHeader->ClientHardwareAddress, ClientHardwareAddress, 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); +} + +/** Checks to see if the nominated IP address has already been allocated to a client. + * + * \param[in] IPAddress IP Address whose lease status should be checked + * + * \pre The IP address must be within the same /24 subnet as the virtual webserver. + * + * \return Boolean true if the IP has already been leased to a client, false otherwise. + */ +static bool DHCPServerApp_CheckIfIPLeased(uip_ipaddr_t* IPAddress) +{ + uint8_t Byte = (IPAddress->u8[3] / 8); + uint8_t Mask = (1 << (IPAddress->u8[3] % 8)); + + if (!(IPAddress->u8[3] == uip_hostaddr.u8[3]) && !(LeasedIPs[Byte] & Mask)) + return false; + else + return true; +} + +/** Retrieves the next unleased IP in the IP address pool. + * + * \param[out] NewIPAddress Location where the generated IP Address should be stored + */ +static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* NewIPAddress) +{ + uip_ipaddr_copy(NewIPAddress, &uip_hostaddr); + + for (uint8_t IP = 1; IP < 254; IP++) + { + NewIPAddress->u8[3] = IP; + + if (!(DHCPServerApp_CheckIfIPLeased(NewIPAddress))) + return; + } +} + +/** Marks the given IP Address as leased in the address pool, so that it will not be + * allocated to another client unless it is first released. + * + * \param[in] IPAddress IP Address to mark as leased + * + * \pre The IP address must be within the same /24 subnet as the virtual webserver. + */ +static void DHCPServerApp_LeaseIP(uip_ipaddr_t* IPAddress) +{ + uint8_t Byte = (IPAddress->u8[3] / 8); + uint8_t Mask = (1 << (IPAddress->u8[3] % 8)); + + LeasedIPs[Byte] |= Mask; +} + +/** Marks the given IP Address as not leased in the address pool, so that it can be + * allocated to another client upon request. + * + * \param[in] IPAddress IP Address to mark as not leased + * + * \pre The IP address must be within the same /24 subnet as the virtual webserver. + */ +static void DHCPServerApp_UnleaseIP(uip_ipaddr_t* IPAddress) +{ + uint8_t Byte = (IPAddress->u8[3] / 8); + uint8_t Mask = (1 << (IPAddress->u8[3] % 8)); + + LeasedIPs[Byte] &= ~Mask; +} +#endif + diff --git a/Projects/Webserver/Lib/DHCPServerApp.h b/Projects/Webserver/Lib/DHCPServerApp.h new file mode 100644 index 000000000..e70869588 --- /dev/null +++ b/Projects/Webserver/Lib/DHCPServerApp.h @@ -0,0 +1,62 @@ +/* + 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. +*/ + +/** \file + * + * Header file for DHCPServerApp.c. + */ + +#ifndef _DHCPSERVER_APP_H_ +#define _DHCPSERVER_APP_H_ + + /* Includes: */ + #include + + #include + + #include "../Webserver.h" + #include "DHCPCommon.h" + + /* Function Prototypes: */ + void DHCPServerApp_Init(void); + void DHCPServerApp_Callback(void); + + #if defined(INCLUDE_FROM_DHCPSERVERAPP_C) + static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader, + const uint8_t DHCPMessageType, + struct uip_eth_addr* ClientHardwareAddress, + uint32_t TransactionID); + static bool DHCPServerApp_CheckIfIPLeased(uip_ipaddr_t* IPAddress); + static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* NewIPAddress); + static void DHCPServerApp_LeaseIP(uip_ipaddr_t* IPAddress); + static void DHCPServerApp_UnleaseIP(uip_ipaddr_t* IPAddress); + #endif +#endif + diff --git a/Projects/Webserver/Lib/HTTPServerApp.c b/Projects/Webserver/Lib/HTTPServerApp.c index 8548045df..6822b270d 100644 --- a/Projects/Webserver/Lib/HTTPServerApp.c +++ b/Projects/Webserver/Lib/HTTPServerApp.c @@ -181,7 +181,7 @@ static void HTTPServerApp_OpenRequestedFile(void) } /* Copy over the requested filename */ - strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], (sizeof(AppState->HTTPServer.FileName) - 1)); + strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], sizeof(AppState->HTTPServer.FileName)); /* Ensure filename is null-terminated */ AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00; @@ -190,11 +190,11 @@ static void HTTPServerApp_OpenRequestedFile(void) uint8_t FileNameLen = strlen(AppState->HTTPServer.FileName); /* If the URI is a directory, append the default filename */ - if (AppState->HTTPServer.FileName[FileNameLen - 1] == '/') + if ((AppState->HTTPServer.FileName[FileNameLen - 1] == '/') || !(FileNameLen)) { strncpy_P(&AppState->HTTPServer.FileName[FileNameLen], DefaultDirFileName, (sizeof(AppState->HTTPServer.FileName) - FileNameLen)); - + /* Ensure altered filename is still null-terminated */ AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00; } diff --git a/Projects/Webserver/Lib/uIPManagement.c b/Projects/Webserver/Lib/uIPManagement.c index a99e8be93..59045c06a 100644 --- a/Projects/Webserver/Lib/uIPManagement.c +++ b/Projects/Webserver/Lib/uIPManagement.c @@ -61,22 +61,49 @@ void uIPManagement_Init(void) /* uIP Stack Initialization */ uip_init(); uip_arp_init(); - uip_setethaddr(MACAddress); /* DHCP/Server IP Settings Initialization */ - #if defined(ENABLE_DHCP_CLIENT) - HaveIPConfiguration = false; - DHCPClientApp_Init(); - #else - HaveIPConfiguration = true; - uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress; - uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]); - uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]); - uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]); - uip_sethostaddr(&IPAddress); - uip_setnetmask(&Netmask); - uip_setdraddr(&GatewayIPAddress); - #endif + if (USB_CurrentMode == USB_MODE_Device) + { + MACAddress.addr[0] = SERVER_MAC_ADDRESS[0]; + MACAddress.addr[1] = SERVER_MAC_ADDRESS[1]; + MACAddress.addr[2] = SERVER_MAC_ADDRESS[2]; + MACAddress.addr[3] = SERVER_MAC_ADDRESS[3]; + MACAddress.addr[4] = SERVER_MAC_ADDRESS[4]; + MACAddress.addr[5] = SERVER_MAC_ADDRESS[5]; + + #if defined(ENABLE_DHCP_SERVER) + DHCPServerApp_Init(); + #endif + + HaveIPConfiguration = true; + uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress; + uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]); + uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]); + uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]); + uip_sethostaddr(&IPAddress); + uip_setnetmask(&Netmask); + uip_setdraddr(&GatewayIPAddress); + } + else + { + #if defined(ENABLE_DHCP_CLIENT) + HaveIPConfiguration = false; + DHCPClientApp_Init(); + #else + HaveIPConfiguration = true; + uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress; + uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]); + uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]); + uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]); + uip_sethostaddr(&IPAddress); + uip_setnetmask(&Netmask); + uip_setdraddr(&GatewayIPAddress); + #endif + } + + /* Virtual Webserver Ethernet Address Configuration */ + uip_setethaddr(MACAddress); /* HTTP Webserver Initialization */ HTTPServerApp_Init(); @@ -92,7 +119,8 @@ void uIPManagement_Init(void) */ void uIPManagement_ManageNetwork(void) { - if ((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) + if (((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) || + ((USB_CurrentMode == USB_MODE_Device) && (USB_DeviceState == DEVICE_STATE_Configured))) { uIPManagement_ProcessIncomingPacket(); uIPManagement_ManageConnections(); @@ -126,24 +154,46 @@ void uIPManagement_UDPCallback(void) /* Call the correct UDP application based on the port number the connection is listening on */ switch (uip_udp_conn->lport) { - case HTONS(DHCPC_CLIENT_PORT): + #if defined(ENABLE_DHCP_CLIENT) + case HTONS(DHCP_CLIENT_PORT): DHCPClientApp_Callback(); break; + #endif + #if defined(ENABLE_DHCP_SERVER) + case HTONS(DHCP_SERVER_PORT): + DHCPServerApp_Callback(); + break; + #endif } } /** Processes Incoming packets to the server from the connected RNDIS device, creating responses as needed. */ static void uIPManagement_ProcessIncomingPacket(void) { - /* If no packet received, exit processing routine */ - if (!(RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface))) - return; - - LEDs_SetAllLEDs(LEDMASK_USB_BUSY); + /* Determine which USB mode the system is currently initialised in */ + if (USB_CurrentMode == USB_MODE_Device) + { + /* If no packet received, exit processing routine */ + if (!(RNDIS_Device_IsPacketReceived(&Ethernet_RNDIS_Interface_Device))) + return; + + LEDs_SetAllLEDs(LEDMASK_USB_BUSY); - /* Read the Incoming packet straight into the UIP packet buffer */ - RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, uip_buf, &uip_len); + /* Read the Incoming packet straight into the UIP packet buffer */ + RNDIS_Device_ReadPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, &uip_len); + } + else + { + /* If no packet received, exit processing routine */ + if (!(RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface_Host))) + return; + + LEDs_SetAllLEDs(LEDMASK_USB_BUSY); + /* Read the Incoming packet straight into the UIP packet buffer */ + RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, &uip_len); + } + /* If the packet contains an Ethernet frame, process it */ if (uip_len > 0) { diff --git a/Projects/Webserver/Lib/uIPManagement.h b/Projects/Webserver/Lib/uIPManagement.h index 7409eab90..c42e13225 100644 --- a/Projects/Webserver/Lib/uIPManagement.h +++ b/Projects/Webserver/Lib/uIPManagement.h @@ -45,12 +45,13 @@ #include #include "Lib/DHCPClientApp.h" + #include "Lib/DHCPServerApp.h" #include "Lib/HTTPServerApp.h" #include "Lib/TELNETServerApp.h" /* Macros: */ /** IP address that the webserver should use once connected to a RNDIS device (when DHCP is disabled). */ - #define DEVICE_IP_ADDRESS (uint8_t[]){192, 168, 1, 10} + #define DEVICE_IP_ADDRESS (uint8_t[]){10, 0, 0, 2} /** Netmask that the webserver should once connected to a RNDIS device (when DHCP is disabled). */ #define DEVICE_NETMASK (uint8_t[]){255, 255, 255, 0} @@ -58,7 +59,13 @@ /** IP address of the default gateway the webserver should use when routing outside the local subnet * (when DHCP is disabled). */ - #define DEVICE_GATEWAY (uint8_t[]){192, 168, 1, 1} + #define DEVICE_GATEWAY (uint8_t[]){10, 0, 0, 1} + + /** Ethernet MAC address of the virtual webserver. When in device RNDIS mode, the virtual webserver requires + * a unique MAC address that it can use when sending packets to the RNDIS adapter, which contains a seperate + * MAC address as set in the RNDIS class driver configuration structure. + */ + #define SERVER_MAC_ADDRESS (uint8_t[]){1, 0, 1, 0, 1, 0} /* External Variables: */ extern struct uip_eth_addr MACAddress; diff --git a/Projects/Webserver/Lib/uip/uip-split.c b/Projects/Webserver/Lib/uip/uip-split.c index 87dbd7e1f..5222a05b6 100644 --- a/Projects/Webserver/Lib/uip/uip-split.c +++ b/Projects/Webserver/Lib/uip/uip-split.c @@ -83,7 +83,10 @@ uip_split_output(void) #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else - RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len); + if (USB_CurrentMode == USB_MODE_Device) + RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len); + else + RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len); #endif /* UIP_CONF_IPV6 */ /* Now, create the second packet. To do this, it is not enough to @@ -124,7 +127,10 @@ uip_split_output(void) #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else - RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len); + if (USB_CurrentMode == USB_MODE_Device) + RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len); + else + RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len); #endif /* UIP_CONF_IPV6 */ return; } @@ -134,7 +140,10 @@ uip_split_output(void) #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else - RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len); + if (USB_CurrentMode == USB_MODE_Device) + RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len); + else + RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len); #endif /* UIP_CONF_IPV6 */ } diff --git a/Projects/Webserver/Lib/uip/uip.c b/Projects/Webserver/Lib/uip/uip.c index afa19f750..94171adad 100644 --- a/Projects/Webserver/Lib/uip/uip.c +++ b/Projects/Webserver/Lib/uip/uip.c @@ -904,10 +904,12 @@ uip_process(u8_t flag) #if UIP_BROADCAST DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); if(BUF->proto == UIP_PROTO_UDP && - uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) - /*&& - uip_ipchksum() == 0xffff*/) { - goto udp_input; + uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) + { + if (uip_ipaddr_cmp(&BUF->srcipaddr, &uip_all_zeroes_addr)) + uip_ipaddr_copy(&BUF->srcipaddr, &uip_broadcast_addr); + + goto udp_input; } #endif /* UIP_BROADCAST */ -- cgit v1.2.3