You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
5.5 KiB
137 lines
5.5 KiB
16 years ago
|
/*
|
||
|
LUFA Library
|
||
|
Copyright (C) Dean Camera, 2009.
|
||
|
|
||
|
dean [at] fourwalledcubicle [dot] com
|
||
|
www.fourwalledcubicle.com
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||
|
|
||
|
Permission to use, copy, modify, and distribute this software
|
||
|
and its documentation for any purpose and without fee is hereby
|
||
|
granted, 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
|
||
|
*
|
||
|
* Ethernet frame packet handling routines. This protocol handles the processing of raw Ethernet
|
||
16 years ago
|
* frames sent and received, deferring the processing of subpacket protocols to the appropriate
|
||
16 years ago
|
* protocol handlers, such as DHCP or ARP.
|
||
|
*/
|
||
|
|
||
|
#include "Ethernet.h"
|
||
|
|
||
|
/* Global Variables: */
|
||
16 years ago
|
/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */
|
||
|
Ethernet_Frame_Info_t FrameIN;
|
||
|
|
||
|
/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */
|
||
|
Ethernet_Frame_Info_t FrameOUT;
|
||
|
|
||
16 years ago
|
/** 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};
|
||
|
|
||
|
|
||
16 years ago
|
/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet
|
||
16 years ago
|
* frame buffer if the sub protocol handlers create a valid response.
|
||
|
*/
|
||
16 years ago
|
void Ethernet_ProcessPacket(void)
|
||
16 years ago
|
{
|
||
16 years ago
|
DecodeEthernetFrameHeader(FrameIN.FrameData);
|
||
16 years ago
|
|
||
16 years ago
|
/* Cast the incoming Ethernet frame to the Ethernet header type */
|
||
16 years ago
|
Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;
|
||
|
Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
|
||
16 years ago
|
|
||
|
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) ||
|
||
16 years ago
|
MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&
|
||
|
(SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))
|
||
16 years ago
|
{
|
||
|
/* Process the packet depending on its protocol */
|
||
|
switch (SwapEndian_16(FrameINHeader->EtherType))
|
||
|
{
|
||
|
case ETHERTYPE_ARP:
|
||
16 years ago
|
RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||
|
&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||
16 years ago
|
break;
|
||
|
case ETHERTYPE_IPV4:
|
||
16 years ago
|
RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
|
||
|
&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
|
||
16 years ago
|
break;
|
||
|
}
|
||
|
|
||
16 years ago
|
/* Protocol processing routine has filled a response, complete the ethernet frame header */
|
||
16 years ago
|
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 */
|
||
16 years ago
|
FrameOUT.FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);
|
||
|
FrameOUT.FrameInBuffer = true;
|
||
16 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/* Check if the packet was processed */
|
||
|
if (RetSize != NO_PROCESS)
|
||
|
{
|
||
|
/* Clear the frame buffer */
|
||
16 years ago
|
FrameIN.FrameInBuffer = false;
|
||
16 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/** Calculates the appropriate ethernet checksum, consisting of the addition of the one's
|
||
|
* compliment of each word, complimented.
|
||
|
*
|
||
|
* \param Data Pointer to the packet buffer data whose checksum must be calculated
|
||
|
* \param 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 (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
|
||
|
Checksum += Words[CurrWord];
|
||
|
|
||
|
while (Checksum & 0xFFFF0000)
|
||
|
Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));
|
||
|
|
||
|
return ~Checksum;
|
||
|
}
|