diff options
| author | Jack Humbert <[email protected]> | 2017-07-07 11:55:23 -0400 | 
|---|---|---|
| committer | Jack Humbert <[email protected]> | 2017-07-07 11:55:23 -0400 | 
| commit | 60b30c036397cb5627fa374bb930794b225daa29 (patch) | |
| tree | e156c2d6b27f01db6985f2cc560c9c345d48fdac /Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c | |
| download | qmk_firmware-60b30c036397cb5627fa374bb930794b225daa29.tar.gz qmk_firmware-60b30c036397cb5627fa374bb930794b225daa29.zip | |
Squashed 'lib/lufa/' content from commit 385d40300
git-subtree-dir: lib/lufa
git-subtree-split: 385d4030035dbaf41591309dbde47653bd03841b
Diffstat (limited to 'Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c')
| -rw-r--r-- | Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c | 132 | 
1 files changed, 132 insertions, 0 deletions
| 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; +} + | 
