--- /dev/null
+/*\r
+ LUFA Library\r
+ Copyright (C) Dean Camera, 2009.\r
+ \r
+ dean [at] fourwalledcubicle [dot] com\r
+ www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+ Permission to use, copy, modify, and distribute this software\r
+ and its documentation for any purpose and without fee is hereby\r
+ granted, provided that the above copyright notice appear in all\r
+ 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
+ * Ethernet frame packet handling routines. This protocol handles the processing of raw Ethernet\r
+ * frames sent and received, deferring the processing of subpacket protocols to the appropriate\r
+ * protocol handlers, such as DHCP or ARP.\r
+ */\r
+ \r
+#include "Ethernet.h"\r
+\r
+/* Global Variables: */\r
+/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */\r
+Ethernet_Frame_Info_t FrameIN;\r
+\r
+/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */\r
+Ethernet_Frame_Info_t FrameOUT;\r
+\r
+/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */\r
+const MAC_Address_t ServerMACAddress = {SERVER_MAC_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting an IP address to the virtual server IP address. */\r
+const IP_Address_t ServerIPAddress = {SERVER_IP_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting a MAC address to the broadcast MAC address. */\r
+const MAC_Address_t BroadcastMACAddress = {BROADCAST_MAC_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting a IP address to the broadcast IP address. */\r
+const IP_Address_t BroadcastIPAddress = {BROADCAST_IP_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting an IP address to the client (host) IP address. */\r
+const IP_Address_t ClientIPAddress = {CLIENT_IP_ADDRESS};\r
+\r
+\r
+/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet\r
+ * frame buffer if the sub protocol handlers create a valid response.\r
+ */\r
+void Ethernet_ProcessPacket(void)\r
+{\r
+ DecodeEthernetFrameHeader(FrameIN.FrameData);\r
+\r
+ /* Cast the incoming Ethernet frame to the Ethernet header type */\r
+ Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;\r
+ Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
+ \r
+ int16_t RetSize = NO_RESPONSE;\r
+ \r
+ /* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */\r
+ if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||\r
+ MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&\r
+ (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))\r
+ {\r
+ /* Process the packet depending on its protocol */\r
+ switch (SwapEndian_16(FrameINHeader->EtherType))\r
+ {\r
+ case ETHERTYPE_ARP:\r
+ RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+ &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+ break; \r
+ case ETHERTYPE_IPV4:\r
+ RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+ &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+ break;\r
+ }\r
+ \r
+ /* Protocol processing routine has filled a response, complete the ethernet frame header */\r
+ if (RetSize > 0)\r
+ {\r
+ /* Fill out the response Ethernet frame header */\r
+ FrameOUTHeader->Source = ServerMACAddress;\r
+ FrameOUTHeader->Destination = FrameINHeader->Source;\r
+ FrameOUTHeader->EtherType = FrameINHeader->EtherType;\r
+ \r
+ /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
+ FrameOUT.FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);\r
+ FrameOUT.FrameInBuffer = true;\r
+ }\r
+ }\r
+\r
+ /* Check if the packet was processed */\r
+ if (RetSize != NO_PROCESS)\r
+ {\r
+ /* Clear the frame buffer */\r
+ FrameIN.FrameInBuffer = false;\r
+ }\r
+}\r
+\r
+/** Calculates the appropriate ethernet checksum, consisting of the addition of the one's\r
+ * compliment of each word, complimented.\r
+ *\r
+ * \param Data Pointer to the packet buffer data whose checksum must be calculated\r
+ * \param Bytes Number of bytes in the data buffer to process\r
+ *\r
+ * \return A 16-bit Ethernet checksum value\r
+ */\r
+uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes)\r
+{\r
+ uint16_t* Words = (uint16_t*)Data;\r
+ uint32_t Checksum = 0;\r
+\r
+ for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)\r
+ Checksum += Words[CurrWord];\r
+ \r
+ while (Checksum & 0xFFFF0000)\r
+ Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));\r
+ \r
+ return ~Checksum;\r
+}\r