From 60b30c036397cb5627fa374bb930794b225daa29 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Fri, 7 Jul 2017 11:55:23 -0400
Subject: Squashed 'lib/lufa/' content from commit 385d40300

git-subtree-dir: lib/lufa
git-subtree-split: 385d4030035dbaf41591309dbde47653bd03841b
---
 .../ClassDriver/RNDISEthernet/Lib/Ethernet.c       | 132 +++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c

(limited to 'Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c')

diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c
new file mode 100644
index 0000000000..c28fa2336b
--- /dev/null
+++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c
@@ -0,0 +1,132 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2017.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2017  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 disclaims 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
+ *
+ *  Ethernet frame packet handling routines. This protocol handles the processing of raw Ethernet
+ *  frames sent and received, deferring the processing of sub-packet protocols to the appropriate
+ *  protocol handlers, such as DHCP or ARP.
+ */
+
+#include "Ethernet.h"
+
+/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */
+const MAC_Address_t ServerMACAddress    = {SERVER_MAC_ADDRESS};
+
+/** Constant for convenience when checking against or setting an IP address to the virtual server IP address. */
+const IP_Address_t  ServerIPAddress     = {SERVER_IP_ADDRESS};
+
+/** Constant for convenience when checking against or setting a MAC address to the broadcast MAC address. */
+const MAC_Address_t BroadcastMACAddress = {BROADCAST_MAC_ADDRESS};
+
+/** Constant for convenience when checking against or setting a IP address to the broadcast IP address. */
+const IP_Address_t  BroadcastIPAddress  = {BROADCAST_IP_ADDRESS};
+
+/** Constant for convenience when checking against or setting an IP address to the client (host) IP address. */
+const IP_Address_t  ClientIPAddress     = {CLIENT_IP_ADDRESS};
+
+
+/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet
+ *  frame buffer if the sub protocol handlers create a valid response.
+ */
+void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* const FrameIN,
+                            Ethernet_Frame_Info_t* const FrameOUT)
+{
+	DecodeEthernetFrameHeader(FrameIN->FrameData);
+
+	/* Cast the incoming Ethernet frame to the Ethernet header type */
+	Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN->FrameData;
+	Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;
+
+	int16_t                  RetSize        = NO_RESPONSE;
+
+	/* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */
+	if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||
+	     MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&
+		 (SwapEndian_16(FrameIN->FrameLength) > ETHERNET_VER2_MINSIZE))
+	{
+		/* Process the packet depending on its protocol */
+		switch (SwapEndian_16(FrameINHeader->EtherType))
+		{
+			case ETHERTYPE_ARP:
+				RetSize = ARP_ProcessARPPacket(&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+				                               &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
+				break;
+			case ETHERTYPE_IPV4:
+				RetSize = IP_ProcessIPPacket(FrameIN,
+				                             &FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+				                             &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
+				break;
+		}
+
+		/* Protocol processing routine has filled a response, complete the ethernet frame header */
+		if (RetSize > 0)
+		{
+			/* Fill out the response Ethernet frame header */
+			FrameOUTHeader->Source          = ServerMACAddress;
+			FrameOUTHeader->Destination     = FrameINHeader->Source;
+			FrameOUTHeader->EtherType       = FrameINHeader->EtherType;
+
+			/* Set the response length in the buffer and indicate that a response is ready to be sent */
+			FrameOUT->FrameLength           = (sizeof(Ethernet_Frame_Header_t) + RetSize);
+		}
+	}
+
+	/* Check if the packet was processed */
+	if (RetSize != NO_PROCESS)
+	{
+		/* Clear the frame buffer */
+		FrameIN->FrameLength = 0;
+	}
+}
+
+/** Calculates the appropriate ethernet checksum, consisting of the addition of the one's
+ *  compliment of each word, complimented.
+ *
+ *  \param[in] Data   Pointer to the packet buffer data whose checksum must be calculated
+ *  \param[in] Bytes  Number of bytes in the data buffer to process
+ *
+ *  \return A 16-bit Ethernet checksum value
+ */
+uint16_t Ethernet_Checksum16(void* Data,
+                             uint16_t Bytes)
+{
+	uint16_t* Words    = (uint16_t*)Data;
+	uint32_t  Checksum = 0;
+
+	for (uint16_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
+	  Checksum += Words[CurrWord];
+
+	while (Checksum & 0xFFFF0000)
+	  Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));
+
+	return ~Checksum;
+}
+
-- 
cgit v1.2.3