Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.
This commit is contained in:
parent
e331b531c6
commit
071e02c6b6
839 changed files with 274562 additions and 274562 deletions
|
@ -1,85 +1,85 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Address Resolution Protocol (ARP) packet handling routines. This protocol handles the
|
||||
* conversion of physical MAC addresses to protocol IP addresses between the host and the
|
||||
* device.
|
||||
*/
|
||||
|
||||
#include "ARP.h"
|
||||
|
||||
/** Processes an ARP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is requesting the IP or MAC address of the
|
||||
* virtual server device on the network.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's ARP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's ARP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
DecodeARPHeader(InDataStart);
|
||||
|
||||
ARP_Header_t* ARPHeaderIN = (ARP_Header_t*)InDataStart;
|
||||
ARP_Header_t* ARPHeaderOUT = (ARP_Header_t*)OutDataStart;
|
||||
|
||||
/* Ensure that the ARP request is a IPv4 request packet */
|
||||
if ((SwapEndian_16(ARPHeaderIN->ProtocolType) == ETHERTYPE_IPV4) &&
|
||||
(SwapEndian_16(ARPHeaderIN->Operation) == ARP_OPERATION_REQUEST))
|
||||
{
|
||||
/* If the ARP packet is requesting the MAC or IP of the virtual webserver, return the response */
|
||||
if (IP_COMPARE(&ARPHeaderIN->TPA, &ServerIPAddress) ||
|
||||
MAC_COMPARE(&ARPHeaderIN->THA, &ServerMACAddress))
|
||||
{
|
||||
/* Fill out the ARP response header */
|
||||
ARPHeaderOUT->HardwareType = ARPHeaderIN->HardwareType;
|
||||
ARPHeaderOUT->ProtocolType = ARPHeaderIN->ProtocolType;
|
||||
ARPHeaderOUT->HLEN = ARPHeaderIN->HLEN;
|
||||
ARPHeaderOUT->PLEN = ARPHeaderIN->PLEN;
|
||||
ARPHeaderOUT->Operation = SwapEndian_16(ARP_OPERATION_REPLY);
|
||||
|
||||
/* Copy over the sender MAC/IP to the target fields for the response */
|
||||
ARPHeaderOUT->THA = ARPHeaderIN->SHA;
|
||||
ARPHeaderOUT->TPA = ARPHeaderIN->SPA;
|
||||
|
||||
/* Copy over the new sender MAC/IP - MAC and IP addresses of the virtual webserver */
|
||||
ARPHeaderOUT->SHA = ServerMACAddress;
|
||||
ARPHeaderOUT->SPA = ServerIPAddress;
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return sizeof(ARP_Header_t);
|
||||
}
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Address Resolution Protocol (ARP) packet handling routines. This protocol handles the
|
||||
* conversion of physical MAC addresses to protocol IP addresses between the host and the
|
||||
* device.
|
||||
*/
|
||||
|
||||
#include "ARP.h"
|
||||
|
||||
/** Processes an ARP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is requesting the IP or MAC address of the
|
||||
* virtual server device on the network.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's ARP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's ARP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
DecodeARPHeader(InDataStart);
|
||||
|
||||
ARP_Header_t* ARPHeaderIN = (ARP_Header_t*)InDataStart;
|
||||
ARP_Header_t* ARPHeaderOUT = (ARP_Header_t*)OutDataStart;
|
||||
|
||||
/* Ensure that the ARP request is a IPv4 request packet */
|
||||
if ((SwapEndian_16(ARPHeaderIN->ProtocolType) == ETHERTYPE_IPV4) &&
|
||||
(SwapEndian_16(ARPHeaderIN->Operation) == ARP_OPERATION_REQUEST))
|
||||
{
|
||||
/* If the ARP packet is requesting the MAC or IP of the virtual webserver, return the response */
|
||||
if (IP_COMPARE(&ARPHeaderIN->TPA, &ServerIPAddress) ||
|
||||
MAC_COMPARE(&ARPHeaderIN->THA, &ServerMACAddress))
|
||||
{
|
||||
/* Fill out the ARP response header */
|
||||
ARPHeaderOUT->HardwareType = ARPHeaderIN->HardwareType;
|
||||
ARPHeaderOUT->ProtocolType = ARPHeaderIN->ProtocolType;
|
||||
ARPHeaderOUT->HLEN = ARPHeaderIN->HLEN;
|
||||
ARPHeaderOUT->PLEN = ARPHeaderIN->PLEN;
|
||||
ARPHeaderOUT->Operation = SwapEndian_16(ARP_OPERATION_REPLY);
|
||||
|
||||
/* Copy over the sender MAC/IP to the target fields for the response */
|
||||
ARPHeaderOUT->THA = ARPHeaderIN->SHA;
|
||||
ARPHeaderOUT->TPA = ARPHeaderIN->SPA;
|
||||
|
||||
/* Copy over the new sender MAC/IP - MAC and IP addresses of the virtual webserver */
|
||||
ARPHeaderOUT->SHA = ServerMACAddress;
|
||||
ARPHeaderOUT->SPA = ServerIPAddress;
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return sizeof(ARP_Header_t);
|
||||
}
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ARP.c.
|
||||
*/
|
||||
|
||||
#ifndef _ARP_H_
|
||||
#define _ARP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ARP header operation constant, indicating a request from a host for an address translation */
|
||||
#define ARP_OPERATION_REQUEST 1
|
||||
|
||||
/** ARP header operation constant, indicating a reply from a host giving an address translation */
|
||||
#define ARP_OPERATION_REPLY 2
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an ARP packet inside an Ethernet frame. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t HardwareType; /**< Hardware type constant, indicating the hardware used */
|
||||
uint16_t ProtocolType; /**< Protocol being resolved, usually ETHERTYPE_IPV4 */
|
||||
|
||||
uint8_t HLEN; /**< Length in bytes of the source/destination hardware addresses */
|
||||
uint8_t PLEN; /**< Length in bytes of the source/destination protocol addresses */
|
||||
uint16_t Operation; /**< Type of operation, either ARP_OPERATION_REQUEST or ARP_OPERATION_REPLY */
|
||||
|
||||
MAC_Address_t SHA; /**< Sender's hardware address */
|
||||
IP_Address_t SPA; /**< Sender's protocol address */
|
||||
MAC_Address_t THA; /**< Target's hardware address */
|
||||
IP_Address_t TPA; /**< Target's protocol address */
|
||||
} ARP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ARP.c.
|
||||
*/
|
||||
|
||||
#ifndef _ARP_H_
|
||||
#define _ARP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ARP header operation constant, indicating a request from a host for an address translation */
|
||||
#define ARP_OPERATION_REQUEST 1
|
||||
|
||||
/** ARP header operation constant, indicating a reply from a host giving an address translation */
|
||||
#define ARP_OPERATION_REPLY 2
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an ARP packet inside an Ethernet frame. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t HardwareType; /**< Hardware type constant, indicating the hardware used */
|
||||
uint16_t ProtocolType; /**< Protocol being resolved, usually ETHERTYPE_IPV4 */
|
||||
|
||||
uint8_t HLEN; /**< Length in bytes of the source/destination hardware addresses */
|
||||
uint8_t PLEN; /**< Length in bytes of the source/destination protocol addresses */
|
||||
uint16_t Operation; /**< Type of operation, either ARP_OPERATION_REQUEST or ARP_OPERATION_REPLY */
|
||||
|
||||
MAC_Address_t SHA; /**< Sender's hardware address */
|
||||
IP_Address_t SPA; /**< Sender's protocol address */
|
||||
MAC_Address_t THA; /**< Target's hardware address */
|
||||
IP_Address_t TPA; /**< Target's protocol address */
|
||||
} ARP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,118 +1,118 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Dynamic Host Configuration Protocol (DHCP) packet handling routines. This protocol
|
||||
* handles the automatic IP negotiation to the host, so that the host will use the provided
|
||||
* IP address given to it by the device.
|
||||
*/
|
||||
|
||||
#include "DHCP.h"
|
||||
|
||||
/** Processes a DHCP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is requesting or accepting an IP address.
|
||||
*
|
||||
* \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[in] DHCPHeaderInStart Pointer to the start of the incoming packet's DHCP header
|
||||
* \param[out] DHCPHeaderOutStart Pointer to the start of the outgoing packet's DHCP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart)
|
||||
{
|
||||
IP_Header_t* IPHeaderIN = (IP_Header_t*)IPHeaderInStart;
|
||||
DHCP_Header_t* DHCPHeaderIN = (DHCP_Header_t*)DHCPHeaderInStart;
|
||||
DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart;
|
||||
|
||||
uint8_t* DHCPOptionsINStart = (uint8_t*)(DHCPHeaderInStart + sizeof(DHCP_Header_t));
|
||||
uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t));
|
||||
|
||||
DecodeDHCPHeader(DHCPHeaderInStart);
|
||||
|
||||
/* Zero out the response DHCP packet, as much of it legacy and left at 0 */
|
||||
memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t));
|
||||
|
||||
/* Fill out the response DHCP packet */
|
||||
DHCPHeaderOUT->HardwareType = DHCPHeaderIN->HardwareType;
|
||||
DHCPHeaderOUT->Operation = DHCP_OP_BOOTREPLY;
|
||||
DHCPHeaderOUT->HardwareAddressLength = DHCPHeaderIN->HardwareAddressLength;
|
||||
DHCPHeaderOUT->Hops = 0;
|
||||
DHCPHeaderOUT->TransactionID = DHCPHeaderIN->TransactionID;
|
||||
DHCPHeaderOUT->ElapsedSeconds = 0;
|
||||
DHCPHeaderOUT->Flags = DHCPHeaderIN->Flags;
|
||||
DHCPHeaderOUT->YourIP = ClientIPAddress;
|
||||
memcpy(&DHCPHeaderOUT->ClientHardwareAddress, &DHCPHeaderIN->ClientHardwareAddress, sizeof(MAC_Address_t));
|
||||
DHCPHeaderOUT->Cookie = SwapEndian_32(DHCP_MAGIC_COOKIE);
|
||||
|
||||
/* Alter the incoming IP packet header so that the corrected IP source and destinations are used - this means that
|
||||
when the response IP header is generated, it will use the corrected addresses and not the null/broatcast addresses */
|
||||
IPHeaderIN->SourceAddress = ClientIPAddress;
|
||||
IPHeaderIN->DestinationAddress = ServerIPAddress;
|
||||
|
||||
/* Process the incoming DHCP packet options */
|
||||
while (DHCPOptionsINStart[0] != DHCP_OPTION_END)
|
||||
{
|
||||
/* Find the Message Type DHCP option, to determine the type of DHCP packet */
|
||||
if (DHCPOptionsINStart[0] == DHCP_OPTION_MESSAGETYPE)
|
||||
{
|
||||
if ((DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) || (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_REQUEST))
|
||||
{
|
||||
/* Fill out the response DHCP packet options for a DHCP OFFER or ACK response */
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_MESSAGETYPE;
|
||||
*(DHCPOptionsOUTStart++) = 1;
|
||||
*(DHCPOptionsOUTStart++) = (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) ? DHCP_MESSAGETYPE_OFFER
|
||||
: DHCP_MESSAGETYPE_ACK;
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_SUBNETMASK;
|
||||
*(DHCPOptionsOUTStart++) = 4;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0x00;
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_DHCPSERVER;
|
||||
*(DHCPOptionsOUTStart++) = sizeof(IP_Address_t);
|
||||
memcpy(DHCPOptionsOUTStart, &ServerIPAddress, sizeof(IP_Address_t));
|
||||
DHCPOptionsOUTStart += sizeof(IP_Address_t);
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_END;
|
||||
|
||||
return (sizeof(DHCP_Header_t) + 12 + sizeof(IP_Address_t));
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next DHCP option - skip one byte if option is a padding byte, else skip the complete option's size */
|
||||
DHCPOptionsINStart += ((DHCPOptionsINStart[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptionsINStart[1] + 2));
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Dynamic Host Configuration Protocol (DHCP) packet handling routines. This protocol
|
||||
* handles the automatic IP negotiation to the host, so that the host will use the provided
|
||||
* IP address given to it by the device.
|
||||
*/
|
||||
|
||||
#include "DHCP.h"
|
||||
|
||||
/** Processes a DHCP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is requesting or accepting an IP address.
|
||||
*
|
||||
* \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[in] DHCPHeaderInStart Pointer to the start of the incoming packet's DHCP header
|
||||
* \param[out] DHCPHeaderOutStart Pointer to the start of the outgoing packet's DHCP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart)
|
||||
{
|
||||
IP_Header_t* IPHeaderIN = (IP_Header_t*)IPHeaderInStart;
|
||||
DHCP_Header_t* DHCPHeaderIN = (DHCP_Header_t*)DHCPHeaderInStart;
|
||||
DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart;
|
||||
|
||||
uint8_t* DHCPOptionsINStart = (uint8_t*)(DHCPHeaderInStart + sizeof(DHCP_Header_t));
|
||||
uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t));
|
||||
|
||||
DecodeDHCPHeader(DHCPHeaderInStart);
|
||||
|
||||
/* Zero out the response DHCP packet, as much of it legacy and left at 0 */
|
||||
memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t));
|
||||
|
||||
/* Fill out the response DHCP packet */
|
||||
DHCPHeaderOUT->HardwareType = DHCPHeaderIN->HardwareType;
|
||||
DHCPHeaderOUT->Operation = DHCP_OP_BOOTREPLY;
|
||||
DHCPHeaderOUT->HardwareAddressLength = DHCPHeaderIN->HardwareAddressLength;
|
||||
DHCPHeaderOUT->Hops = 0;
|
||||
DHCPHeaderOUT->TransactionID = DHCPHeaderIN->TransactionID;
|
||||
DHCPHeaderOUT->ElapsedSeconds = 0;
|
||||
DHCPHeaderOUT->Flags = DHCPHeaderIN->Flags;
|
||||
DHCPHeaderOUT->YourIP = ClientIPAddress;
|
||||
memcpy(&DHCPHeaderOUT->ClientHardwareAddress, &DHCPHeaderIN->ClientHardwareAddress, sizeof(MAC_Address_t));
|
||||
DHCPHeaderOUT->Cookie = SwapEndian_32(DHCP_MAGIC_COOKIE);
|
||||
|
||||
/* Alter the incoming IP packet header so that the corrected IP source and destinations are used - this means that
|
||||
when the response IP header is generated, it will use the corrected addresses and not the null/broatcast addresses */
|
||||
IPHeaderIN->SourceAddress = ClientIPAddress;
|
||||
IPHeaderIN->DestinationAddress = ServerIPAddress;
|
||||
|
||||
/* Process the incoming DHCP packet options */
|
||||
while (DHCPOptionsINStart[0] != DHCP_OPTION_END)
|
||||
{
|
||||
/* Find the Message Type DHCP option, to determine the type of DHCP packet */
|
||||
if (DHCPOptionsINStart[0] == DHCP_OPTION_MESSAGETYPE)
|
||||
{
|
||||
if ((DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) || (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_REQUEST))
|
||||
{
|
||||
/* Fill out the response DHCP packet options for a DHCP OFFER or ACK response */
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_MESSAGETYPE;
|
||||
*(DHCPOptionsOUTStart++) = 1;
|
||||
*(DHCPOptionsOUTStart++) = (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) ? DHCP_MESSAGETYPE_OFFER
|
||||
: DHCP_MESSAGETYPE_ACK;
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_SUBNETMASK;
|
||||
*(DHCPOptionsOUTStart++) = 4;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0xFF;
|
||||
*(DHCPOptionsOUTStart++) = 0x00;
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_DHCPSERVER;
|
||||
*(DHCPOptionsOUTStart++) = sizeof(IP_Address_t);
|
||||
memcpy(DHCPOptionsOUTStart, &ServerIPAddress, sizeof(IP_Address_t));
|
||||
DHCPOptionsOUTStart += sizeof(IP_Address_t);
|
||||
|
||||
*(DHCPOptionsOUTStart++) = DHCP_OPTION_END;
|
||||
|
||||
return (sizeof(DHCP_Header_t) + 12 + sizeof(IP_Address_t));
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next DHCP option - skip one byte if option is a padding byte, else skip the complete option's size */
|
||||
DHCPOptionsINStart += ((DHCPOptionsINStart[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptionsINStart[1] + 2));
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 DHCP.c.
|
||||
*/
|
||||
|
||||
#ifndef _DHCP_H_
|
||||
#define _DHCP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** DHCP operation constant, indicating a request from a host to a DHCP server */
|
||||
#define DHCP_OP_BOOTREQUEST 0x01
|
||||
|
||||
/** DHCP operation constant, indicating a reply from a DHCP server to a host */
|
||||
#define DHCP_OP_BOOTREPLY 0x02
|
||||
|
||||
/** Hardware type constant, indicating Ethernet as a carrier */
|
||||
#define DHCP_HTYPE_ETHERNET 0x01
|
||||
|
||||
/** Magic boot protocol "cookie", inserted into all BOOTP packets (BOOTP is the carrier of DHCP) */
|
||||
#define DHCP_MAGIC_COOKIE 0x63825363
|
||||
|
||||
/** DHCP option list entry header, indicating that a subnet mask will follow */
|
||||
#define DHCP_OPTION_SUBNETMASK 1
|
||||
|
||||
/** DHCP option list entry header, indicating that the DHCP message type constant will follow */
|
||||
#define DHCP_OPTION_MESSAGETYPE 53
|
||||
|
||||
/** DHCP option list entry header, indicating that the IP address of the DHCP server will follow */
|
||||
#define DHCP_OPTION_DHCPSERVER 54
|
||||
|
||||
/** DHCP option list entry header, used to pad out option data */
|
||||
#define DHCP_OPTION_PAD 0
|
||||
|
||||
/** DHCP option list entry header, indicating the end of option data */
|
||||
#define DHCP_OPTION_END 255
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, requesting that a DHCP server offer an IP address */
|
||||
#define DHCP_MESSAGETYPE_DISCOVER 1
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, indicating that a DHCP server is offering an IP address */
|
||||
#define DHCP_MESSAGETYPE_OFFER 2
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, requesting that a DHCP server lease a given IP address */
|
||||
#define DHCP_MESSAGETYPE_REQUEST 3
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, declining an offered DHCP server IP address lease */
|
||||
#define DHCP_MESSAGETYPE_DECLINE 4
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, ACKing a host IP lease request */
|
||||
#define DHCP_MESSAGETYPE_ACK 5
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, NACKing a host IP lease request */
|
||||
#define DHCP_MESSAGETYPE_NACK 6
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, indicating that a host is releasing a leased IP address */
|
||||
#define DHCP_MESSAGETYPE_RELEASE 7
|
||||
|
||||
/* 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 */
|
||||
|
||||
IP_Address_t ClientIP; /**< Client IP address, if already leased an IP */
|
||||
IP_Address_t YourIP; /**< Client IP address */
|
||||
IP_Address_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */
|
||||
IP_Address_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 */
|
||||
} DHCP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 DHCP.c.
|
||||
*/
|
||||
|
||||
#ifndef _DHCP_H_
|
||||
#define _DHCP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** DHCP operation constant, indicating a request from a host to a DHCP server */
|
||||
#define DHCP_OP_BOOTREQUEST 0x01
|
||||
|
||||
/** DHCP operation constant, indicating a reply from a DHCP server to a host */
|
||||
#define DHCP_OP_BOOTREPLY 0x02
|
||||
|
||||
/** Hardware type constant, indicating Ethernet as a carrier */
|
||||
#define DHCP_HTYPE_ETHERNET 0x01
|
||||
|
||||
/** Magic boot protocol "cookie", inserted into all BOOTP packets (BOOTP is the carrier of DHCP) */
|
||||
#define DHCP_MAGIC_COOKIE 0x63825363
|
||||
|
||||
/** DHCP option list entry header, indicating that a subnet mask will follow */
|
||||
#define DHCP_OPTION_SUBNETMASK 1
|
||||
|
||||
/** DHCP option list entry header, indicating that the DHCP message type constant will follow */
|
||||
#define DHCP_OPTION_MESSAGETYPE 53
|
||||
|
||||
/** DHCP option list entry header, indicating that the IP address of the DHCP server will follow */
|
||||
#define DHCP_OPTION_DHCPSERVER 54
|
||||
|
||||
/** DHCP option list entry header, used to pad out option data */
|
||||
#define DHCP_OPTION_PAD 0
|
||||
|
||||
/** DHCP option list entry header, indicating the end of option data */
|
||||
#define DHCP_OPTION_END 255
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, requesting that a DHCP server offer an IP address */
|
||||
#define DHCP_MESSAGETYPE_DISCOVER 1
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, indicating that a DHCP server is offering an IP address */
|
||||
#define DHCP_MESSAGETYPE_OFFER 2
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, requesting that a DHCP server lease a given IP address */
|
||||
#define DHCP_MESSAGETYPE_REQUEST 3
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, declining an offered DHCP server IP address lease */
|
||||
#define DHCP_MESSAGETYPE_DECLINE 4
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, ACKing a host IP lease request */
|
||||
#define DHCP_MESSAGETYPE_ACK 5
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, NACKing a host IP lease request */
|
||||
#define DHCP_MESSAGETYPE_NACK 6
|
||||
|
||||
/** Message type constant, used in the DHCP option data field, indicating that a host is releasing a leased IP address */
|
||||
#define DHCP_MESSAGETYPE_RELEASE 7
|
||||
|
||||
/* 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 */
|
||||
|
||||
IP_Address_t ClientIP; /**< Client IP address, if already leased an IP */
|
||||
IP_Address_t YourIP; /**< Client IP address */
|
||||
IP_Address_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */
|
||||
IP_Address_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 */
|
||||
} DHCP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,135 +1,135 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* 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"
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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(void)
|
||||
{
|
||||
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.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);
|
||||
FrameOUT.FrameInBuffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the packet was processed */
|
||||
if (RetSize != NO_PROCESS)
|
||||
{
|
||||
/* Clear the frame buffer */
|
||||
FrameIN.FrameInBuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
|
||||
Checksum += Words[CurrWord];
|
||||
|
||||
while (Checksum & 0xFFFF0000)
|
||||
Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));
|
||||
|
||||
return ~Checksum;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* 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"
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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(void)
|
||||
{
|
||||
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.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);
|
||||
FrameOUT.FrameInBuffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the packet was processed */
|
||||
if (RetSize != NO_PROCESS)
|
||||
{
|
||||
/* Clear the frame buffer */
|
||||
FrameIN.FrameInBuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
|
||||
Checksum += Words[CurrWord];
|
||||
|
||||
while (Checksum & 0xFFFF0000)
|
||||
Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));
|
||||
|
||||
return ~Checksum;
|
||||
}
|
||||
|
|
|
@ -1,119 +1,119 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 Ethernet.c.
|
||||
*/
|
||||
|
||||
#ifndef _ETHERNET_H_
|
||||
#define _ETHERNET_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
#include "ICMP.h"
|
||||
#include "TCP.h"
|
||||
#include "UDP.h"
|
||||
#include "DHCP.h"
|
||||
#include "ARP.h"
|
||||
#include "IP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Physical MAC address of the USB RNDIS network adapter */
|
||||
#define ADAPTER_MAC_ADDRESS {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}
|
||||
|
||||
/** Physical MAC address of the virtual server on the network */
|
||||
#define SERVER_MAC_ADDRESS {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}
|
||||
|
||||
/** Physical MAC address of the network broadcast address */
|
||||
#define BROADCAST_MAC_ADDRESS {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
|
||||
/** Performs a comparison between two MAC addresses, indicating if they are identical.
|
||||
*
|
||||
* \param[in] MAC1 First MAC address
|
||||
* \param[in] MAC2 Second MAC address
|
||||
*
|
||||
* \return True if the addresses match, false otherwise
|
||||
*/
|
||||
#define MAC_COMPARE(MAC1, MAC2) (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)
|
||||
|
||||
/** Maximum size of an incoming or outgoing Ethernet frame in bytes */
|
||||
#define ETHERNET_FRAME_SIZE_MAX 1500
|
||||
|
||||
/** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */
|
||||
#define ETHERNET_VER2_MINSIZE 0x0600
|
||||
|
||||
/** Return value for all sub protocol handling routines, indicating that no response packet has been generated */
|
||||
#define NO_RESPONSE 0
|
||||
|
||||
/** Return value for all sub protocol handling routines, indicating that the packet has not yet been handled */
|
||||
#define NO_PROCESS -1
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an Ethernet frame buffer. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
|
||||
uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
|
||||
bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
|
||||
} Ethernet_Frame_Info_t;
|
||||
|
||||
/** Type define for an Ethernet frame header */
|
||||
typedef struct
|
||||
{
|
||||
MAC_Address_t Destination; /**< Physical MAC address of the packet recipient */
|
||||
MAC_Address_t Source; /**< Physics MAC address of the packet source */
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t EtherType; /**< Ethernet packet sub-protocol type, for Ethernet V2 packets */
|
||||
uint16_t Length; /**< Ethernet frame length, for Ethernet V1 packets */
|
||||
};
|
||||
} Ethernet_Frame_Header_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern Ethernet_Frame_Info_t FrameIN;
|
||||
extern Ethernet_Frame_Info_t FrameOUT;
|
||||
|
||||
extern const MAC_Address_t ServerMACAddress;
|
||||
extern const IP_Address_t ServerIPAddress;
|
||||
extern const MAC_Address_t BroadcastMACAddress;
|
||||
extern const IP_Address_t BroadcastIPAddress;
|
||||
extern const IP_Address_t ClientIPAddress;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Ethernet_ProcessPacket(void);
|
||||
uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 Ethernet.c.
|
||||
*/
|
||||
|
||||
#ifndef _ETHERNET_H_
|
||||
#define _ETHERNET_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
#include "ICMP.h"
|
||||
#include "TCP.h"
|
||||
#include "UDP.h"
|
||||
#include "DHCP.h"
|
||||
#include "ARP.h"
|
||||
#include "IP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Physical MAC address of the USB RNDIS network adapter */
|
||||
#define ADAPTER_MAC_ADDRESS {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}
|
||||
|
||||
/** Physical MAC address of the virtual server on the network */
|
||||
#define SERVER_MAC_ADDRESS {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}
|
||||
|
||||
/** Physical MAC address of the network broadcast address */
|
||||
#define BROADCAST_MAC_ADDRESS {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
|
||||
/** Performs a comparison between two MAC addresses, indicating if they are identical.
|
||||
*
|
||||
* \param[in] MAC1 First MAC address
|
||||
* \param[in] MAC2 Second MAC address
|
||||
*
|
||||
* \return True if the addresses match, false otherwise
|
||||
*/
|
||||
#define MAC_COMPARE(MAC1, MAC2) (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)
|
||||
|
||||
/** Maximum size of an incoming or outgoing Ethernet frame in bytes */
|
||||
#define ETHERNET_FRAME_SIZE_MAX 1500
|
||||
|
||||
/** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */
|
||||
#define ETHERNET_VER2_MINSIZE 0x0600
|
||||
|
||||
/** Return value for all sub protocol handling routines, indicating that no response packet has been generated */
|
||||
#define NO_RESPONSE 0
|
||||
|
||||
/** Return value for all sub protocol handling routines, indicating that the packet has not yet been handled */
|
||||
#define NO_PROCESS -1
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an Ethernet frame buffer. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
|
||||
uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
|
||||
bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
|
||||
} Ethernet_Frame_Info_t;
|
||||
|
||||
/** Type define for an Ethernet frame header */
|
||||
typedef struct
|
||||
{
|
||||
MAC_Address_t Destination; /**< Physical MAC address of the packet recipient */
|
||||
MAC_Address_t Source; /**< Physics MAC address of the packet source */
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t EtherType; /**< Ethernet packet sub-protocol type, for Ethernet V2 packets */
|
||||
uint16_t Length; /**< Ethernet frame length, for Ethernet V1 packets */
|
||||
};
|
||||
} Ethernet_Frame_Header_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern Ethernet_Frame_Info_t FrameIN;
|
||||
extern Ethernet_Frame_Info_t FrameOUT;
|
||||
|
||||
extern const MAC_Address_t ServerMACAddress;
|
||||
extern const IP_Address_t ServerIPAddress;
|
||||
extern const MAC_Address_t BroadcastMACAddress;
|
||||
extern const IP_Address_t BroadcastIPAddress;
|
||||
extern const IP_Address_t ClientIPAddress;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Ethernet_ProcessPacket(void);
|
||||
uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* General Ethernet protocol constants and type defines, for use by
|
||||
* all network protocol portions of the TCP/IP stack.
|
||||
*/
|
||||
|
||||
#ifndef _ETHERNET_PROTOCOLS_H_
|
||||
#define _ETHERNET_PROTOCOLS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define ETHERTYPE_IPV4 0x0800
|
||||
#define ETHERTYPE_ARP 0x0806
|
||||
#define ETHERTYPE_RARP 0x8035
|
||||
#define ETHERTYPE_APPLETALK 0x809b
|
||||
#define ETHERTYPE_APPLETALKARP 0x80f3
|
||||
#define ETHERTYPE_IEEE8021Q 0x8100
|
||||
#define ETHERTYPE_NOVELLIPX 0x8137
|
||||
#define ETHERTYPE_NOVELL 0x8138
|
||||
#define ETHERTYPE_IPV6 0x86DD
|
||||
#define ETHERTYPE_COBRANET 0x8819
|
||||
#define ETHERTYPE_PROVIDERBRIDGING 0x88a8
|
||||
#define ETHERTYPE_MPLSUNICAST 0x8847
|
||||
#define ETHERTYPE_MPLSMULTICAST 0x8848
|
||||
#define ETHERTYPE_PPPoEDISCOVERY 0x8863
|
||||
#define ETHERTYPE_PPPoESESSION 0x8864
|
||||
#define ETHERTYPE_EAPOVERLAN 0x888E
|
||||
#define ETHERTYPE_HYPERSCSI 0x889A
|
||||
#define ETHERTYPE_ATAOVERETHERNET 0x88A2
|
||||
#define ETHERTYPE_ETHERCAT 0x88A4
|
||||
#define ETHERTYPE_SERCOSIII 0x88CD
|
||||
#define ETHERTYPE_CESoE 0x88D8
|
||||
#define ETHERTYPE_MACSECURITY 0x88E5
|
||||
#define ETHERTYPE_FIBRECHANNEL 0x8906
|
||||
#define ETHERTYPE_QINQ 0x9100
|
||||
#define ETHERTYPE_VLLT 0xCAFE
|
||||
|
||||
#define PROTOCOL_ICMP 1
|
||||
#define PROTOCOL_IGMP 2
|
||||
#define PROTOCOL_TCP 6
|
||||
#define PROTOCOL_UDP 17
|
||||
#define PROTOCOL_OSPF 89
|
||||
#define PROTOCOL_SCTP 132
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a physical MAC address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
|
||||
} MAC_Address_t;
|
||||
|
||||
/** Type define for a protocol IP address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[4]; /**< Individual bytes of an IP address */
|
||||
} IP_Address_t;
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* General Ethernet protocol constants and type defines, for use by
|
||||
* all network protocol portions of the TCP/IP stack.
|
||||
*/
|
||||
|
||||
#ifndef _ETHERNET_PROTOCOLS_H_
|
||||
#define _ETHERNET_PROTOCOLS_H_
|
||||
|
||||
/* Macros: */
|
||||
#define ETHERTYPE_IPV4 0x0800
|
||||
#define ETHERTYPE_ARP 0x0806
|
||||
#define ETHERTYPE_RARP 0x8035
|
||||
#define ETHERTYPE_APPLETALK 0x809b
|
||||
#define ETHERTYPE_APPLETALKARP 0x80f3
|
||||
#define ETHERTYPE_IEEE8021Q 0x8100
|
||||
#define ETHERTYPE_NOVELLIPX 0x8137
|
||||
#define ETHERTYPE_NOVELL 0x8138
|
||||
#define ETHERTYPE_IPV6 0x86DD
|
||||
#define ETHERTYPE_COBRANET 0x8819
|
||||
#define ETHERTYPE_PROVIDERBRIDGING 0x88a8
|
||||
#define ETHERTYPE_MPLSUNICAST 0x8847
|
||||
#define ETHERTYPE_MPLSMULTICAST 0x8848
|
||||
#define ETHERTYPE_PPPoEDISCOVERY 0x8863
|
||||
#define ETHERTYPE_PPPoESESSION 0x8864
|
||||
#define ETHERTYPE_EAPOVERLAN 0x888E
|
||||
#define ETHERTYPE_HYPERSCSI 0x889A
|
||||
#define ETHERTYPE_ATAOVERETHERNET 0x88A2
|
||||
#define ETHERTYPE_ETHERCAT 0x88A4
|
||||
#define ETHERTYPE_SERCOSIII 0x88CD
|
||||
#define ETHERTYPE_CESoE 0x88D8
|
||||
#define ETHERTYPE_MACSECURITY 0x88E5
|
||||
#define ETHERTYPE_FIBRECHANNEL 0x8906
|
||||
#define ETHERTYPE_QINQ 0x9100
|
||||
#define ETHERTYPE_VLLT 0xCAFE
|
||||
|
||||
#define PROTOCOL_ICMP 1
|
||||
#define PROTOCOL_IGMP 2
|
||||
#define PROTOCOL_TCP 6
|
||||
#define PROTOCOL_UDP 17
|
||||
#define PROTOCOL_OSPF 89
|
||||
#define PROTOCOL_SCTP 132
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a physical MAC address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[6]; /**< Individual bytes of a MAC address */
|
||||
} MAC_Address_t;
|
||||
|
||||
/** Type define for a protocol IP address of a device on a network */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Octets[4]; /**< Individual bytes of an IP address */
|
||||
} IP_Address_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,79 +1,79 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Internet Control Message Protocol (ICMP) packet handling routines. This protocol handles
|
||||
* Echo requests from the host, to indicate a successful network connection between the host
|
||||
* and the virtual server.
|
||||
*/
|
||||
|
||||
#include "ICMP.h"
|
||||
|
||||
/** Processes an ICMP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is issuing a ICMP ECHO request.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's ICMP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's ICMP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
ICMP_Header_t* ICMPHeaderIN = (ICMP_Header_t*)InDataStart;
|
||||
ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;
|
||||
|
||||
DecodeICMPHeader(InDataStart);
|
||||
|
||||
/* Determine if the ICMP packet is an echo request (ping) */
|
||||
if (ICMPHeaderIN->Type == ICMP_TYPE_ECHOREQUEST)
|
||||
{
|
||||
/* Fill out the ICMP response packet */
|
||||
ICMPHeaderOUT->Type = ICMP_TYPE_ECHOREPLY;
|
||||
ICMPHeaderOUT->Code = 0;
|
||||
ICMPHeaderOUT->Checksum = 0;
|
||||
ICMPHeaderOUT->Id = ICMPHeaderIN->Id;
|
||||
ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;
|
||||
|
||||
uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));
|
||||
|
||||
/* Copy the remaining payload to the response - echo requests should echo back any sent data */
|
||||
memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],
|
||||
&((uint8_t*)InDataStart)[sizeof(ICMP_Header_t)],
|
||||
DataSize);
|
||||
|
||||
ICMPHeaderOUT->Checksum = Ethernet_Checksum16(ICMPHeaderOUT, (DataSize + sizeof(ICMP_Header_t)));
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (DataSize + sizeof(ICMP_Header_t));
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Internet Control Message Protocol (ICMP) packet handling routines. This protocol handles
|
||||
* Echo requests from the host, to indicate a successful network connection between the host
|
||||
* and the virtual server.
|
||||
*/
|
||||
|
||||
#include "ICMP.h"
|
||||
|
||||
/** Processes an ICMP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if the host is issuing a ICMP ECHO request.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's ICMP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's ICMP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
ICMP_Header_t* ICMPHeaderIN = (ICMP_Header_t*)InDataStart;
|
||||
ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;
|
||||
|
||||
DecodeICMPHeader(InDataStart);
|
||||
|
||||
/* Determine if the ICMP packet is an echo request (ping) */
|
||||
if (ICMPHeaderIN->Type == ICMP_TYPE_ECHOREQUEST)
|
||||
{
|
||||
/* Fill out the ICMP response packet */
|
||||
ICMPHeaderOUT->Type = ICMP_TYPE_ECHOREPLY;
|
||||
ICMPHeaderOUT->Code = 0;
|
||||
ICMPHeaderOUT->Checksum = 0;
|
||||
ICMPHeaderOUT->Id = ICMPHeaderIN->Id;
|
||||
ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;
|
||||
|
||||
uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));
|
||||
|
||||
/* Copy the remaining payload to the response - echo requests should echo back any sent data */
|
||||
memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],
|
||||
&((uint8_t*)InDataStart)[sizeof(ICMP_Header_t)],
|
||||
DataSize);
|
||||
|
||||
ICMPHeaderOUT->Checksum = Ethernet_Checksum16(ICMPHeaderOUT, (DataSize + sizeof(ICMP_Header_t)));
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (DataSize + sizeof(ICMP_Header_t));
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
|
|
@ -1,80 +1,80 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ICMP.c.
|
||||
*/
|
||||
|
||||
#ifndef _ICMP_H_
|
||||
#define _ICMP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ICMP message type constant, indicating an ICMP ECHO Reply message */
|
||||
#define ICMP_TYPE_ECHOREPLY 0
|
||||
|
||||
/** ICMP message type constant, indicating a packet destination is unreachable */
|
||||
#define ICMP_TYPE_DESTINATIONUNREACHABLE 3
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Source Quench message */
|
||||
#define ICMP_TYPE_SOURCEQUENCH 4
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Redirect message */
|
||||
#define ICMP_TYPE_REDIRECTMESSAGE 5
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP ECHO Request message */
|
||||
#define ICMP_TYPE_ECHOREQUEST 8
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Time Exceeded message */
|
||||
#define ICMP_TYPE_TIMEEXCEEDED 11
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an ICMP message header. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Type; /**< ICMP message type, a ICMP_TYPE_* constant */
|
||||
uint8_t Code; /**< ICMP message code, indicating the message value */
|
||||
uint16_t Checksum; /**< Ethernet checksum of the ICMP message */
|
||||
uint16_t Id; /**< Id of the ICMP message */
|
||||
uint16_t Sequence; /**< Sequence number of the ICMP message, to link together message responses */
|
||||
} ICMP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ICMP.c.
|
||||
*/
|
||||
|
||||
#ifndef _ICMP_H_
|
||||
#define _ICMP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ICMP message type constant, indicating an ICMP ECHO Reply message */
|
||||
#define ICMP_TYPE_ECHOREPLY 0
|
||||
|
||||
/** ICMP message type constant, indicating a packet destination is unreachable */
|
||||
#define ICMP_TYPE_DESTINATIONUNREACHABLE 3
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Source Quench message */
|
||||
#define ICMP_TYPE_SOURCEQUENCH 4
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Redirect message */
|
||||
#define ICMP_TYPE_REDIRECTMESSAGE 5
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP ECHO Request message */
|
||||
#define ICMP_TYPE_ECHOREQUEST 8
|
||||
|
||||
/** ICMP message type constant, indicating an ICMP Time Exceeded message */
|
||||
#define ICMP_TYPE_TIMEEXCEEDED 11
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for an ICMP message header. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Type; /**< ICMP message type, a ICMP_TYPE_* constant */
|
||||
uint8_t Code; /**< ICMP message code, indicating the message value */
|
||||
uint16_t Checksum; /**< Ethernet checksum of the ICMP message */
|
||||
uint16_t Id; /**< Id of the ICMP message */
|
||||
uint16_t Sequence; /**< Sequence number of the ICMP message, to link together message responses */
|
||||
} ICMP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,111 +1,111 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Internet Protocol (IP) packet handling routines. This protocol handles IP packets from the
|
||||
* host which typically encapsulate other protocols such as ICMP, UDP and TCP.
|
||||
*/
|
||||
|
||||
#include "IP.h"
|
||||
|
||||
/** Processes an IP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if one is created by a sub-protocol handler.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's IP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no
|
||||
* response was generated, NO_PROCESS if the packet processing was deferred until the
|
||||
* next Ethernet packet handler iteration
|
||||
*/
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
DecodeIPHeader(InDataStart);
|
||||
|
||||
IP_Header_t* IPHeaderIN = (IP_Header_t*)InDataStart;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)OutDataStart;
|
||||
|
||||
/* Header length is specified in number of longs in the packet header, convert to bytes */
|
||||
uint16_t HeaderLengthBytes = (IPHeaderIN->HeaderLength * sizeof(uint32_t));
|
||||
|
||||
int16_t RetSize = NO_RESPONSE;
|
||||
|
||||
/* Check to ensure the IP packet is addressed to the virtual webserver's IP or the broadcast IP address */
|
||||
if (!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &ServerIPAddress)) &&
|
||||
!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &BroadcastIPAddress)))
|
||||
{
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
||||
/* Pass off the IP payload to the appropriate protocol processing routine */
|
||||
switch (IPHeaderIN->Protocol)
|
||||
{
|
||||
case PROTOCOL_ICMP:
|
||||
RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
case PROTOCOL_TCP:
|
||||
RetSize = TCP_ProcessTCPPacket(InDataStart,
|
||||
&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
case PROTOCOL_UDP:
|
||||
RetSize = UDP_ProcessUDPPacket(InDataStart,
|
||||
&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to see if the protocol processing routine has filled out a response */
|
||||
if (RetSize > 0)
|
||||
{
|
||||
/* Fill out the response IP packet header */
|
||||
IPHeaderOUT->TotalLength = SwapEndian_16(sizeof(IP_Header_t) + RetSize);
|
||||
IPHeaderOUT->TypeOfService = 0;
|
||||
IPHeaderOUT->HeaderLength = (sizeof(IP_Header_t) / sizeof(uint32_t));
|
||||
IPHeaderOUT->Version = 4;
|
||||
IPHeaderOUT->Flags = 0;
|
||||
IPHeaderOUT->FragmentOffset = 0;
|
||||
IPHeaderOUT->Identification = 0;
|
||||
IPHeaderOUT->HeaderChecksum = 0;
|
||||
IPHeaderOUT->Protocol = IPHeaderIN->Protocol;
|
||||
IPHeaderOUT->TTL = DEFAULT_TTL;
|
||||
IPHeaderOUT->SourceAddress = IPHeaderIN->DestinationAddress;
|
||||
IPHeaderOUT->DestinationAddress = IPHeaderIN->SourceAddress;
|
||||
|
||||
IPHeaderOUT->HeaderChecksum = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (sizeof(IP_Header_t) + RetSize);
|
||||
}
|
||||
|
||||
return RetSize;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Internet Protocol (IP) packet handling routines. This protocol handles IP packets from the
|
||||
* host which typically encapsulate other protocols such as ICMP, UDP and TCP.
|
||||
*/
|
||||
|
||||
#include "IP.h"
|
||||
|
||||
/** Processes an IP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if one is created by a sub-protocol handler.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[out] OutDataStart Pointer to the start of the outgoing packet's IP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no
|
||||
* response was generated, NO_PROCESS if the packet processing was deferred until the
|
||||
* next Ethernet packet handler iteration
|
||||
*/
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
|
||||
{
|
||||
DecodeIPHeader(InDataStart);
|
||||
|
||||
IP_Header_t* IPHeaderIN = (IP_Header_t*)InDataStart;
|
||||
IP_Header_t* IPHeaderOUT = (IP_Header_t*)OutDataStart;
|
||||
|
||||
/* Header length is specified in number of longs in the packet header, convert to bytes */
|
||||
uint16_t HeaderLengthBytes = (IPHeaderIN->HeaderLength * sizeof(uint32_t));
|
||||
|
||||
int16_t RetSize = NO_RESPONSE;
|
||||
|
||||
/* Check to ensure the IP packet is addressed to the virtual webserver's IP or the broadcast IP address */
|
||||
if (!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &ServerIPAddress)) &&
|
||||
!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &BroadcastIPAddress)))
|
||||
{
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
||||
/* Pass off the IP payload to the appropriate protocol processing routine */
|
||||
switch (IPHeaderIN->Protocol)
|
||||
{
|
||||
case PROTOCOL_ICMP:
|
||||
RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
case PROTOCOL_TCP:
|
||||
RetSize = TCP_ProcessTCPPacket(InDataStart,
|
||||
&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
case PROTOCOL_UDP:
|
||||
RetSize = UDP_ProcessUDPPacket(InDataStart,
|
||||
&((uint8_t*)InDataStart)[HeaderLengthBytes],
|
||||
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to see if the protocol processing routine has filled out a response */
|
||||
if (RetSize > 0)
|
||||
{
|
||||
/* Fill out the response IP packet header */
|
||||
IPHeaderOUT->TotalLength = SwapEndian_16(sizeof(IP_Header_t) + RetSize);
|
||||
IPHeaderOUT->TypeOfService = 0;
|
||||
IPHeaderOUT->HeaderLength = (sizeof(IP_Header_t) / sizeof(uint32_t));
|
||||
IPHeaderOUT->Version = 4;
|
||||
IPHeaderOUT->Flags = 0;
|
||||
IPHeaderOUT->FragmentOffset = 0;
|
||||
IPHeaderOUT->Identification = 0;
|
||||
IPHeaderOUT->HeaderChecksum = 0;
|
||||
IPHeaderOUT->Protocol = IPHeaderIN->Protocol;
|
||||
IPHeaderOUT->TTL = DEFAULT_TTL;
|
||||
IPHeaderOUT->SourceAddress = IPHeaderIN->DestinationAddress;
|
||||
IPHeaderOUT->DestinationAddress = IPHeaderIN->SourceAddress;
|
||||
|
||||
IPHeaderOUT->HeaderChecksum = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (sizeof(IP_Header_t) + RetSize);
|
||||
}
|
||||
|
||||
return RetSize;
|
||||
}
|
||||
|
|
|
@ -1,93 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 IP.c.
|
||||
*/
|
||||
|
||||
#ifndef _IP_H_
|
||||
#define _IP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Protocol IP address of the host (client) machine, once assigned by DHCP */
|
||||
#define CLIENT_IP_ADDRESS { 10, 0, 0, 1}
|
||||
|
||||
/** Protocol IP address of the virtual server machine */
|
||||
#define SERVER_IP_ADDRESS { 10, 0, 0, 2}
|
||||
|
||||
/** Protocol IP address of the broadcast address */
|
||||
#define BROADCAST_IP_ADDRESS {0xFF, 0xFF, 0xFF, 0xFF}
|
||||
|
||||
/** Default Time To Live (TTL) value for sent packets, indicating the maximum allowable hops until their destination is reached */
|
||||
#define DEFAULT_TTL 128
|
||||
|
||||
/** Performs a comparison between two IP addresses, indicating if they are identical.
|
||||
*
|
||||
* \param[in] IP1 First IP address
|
||||
* \param[in] IP2 Second IP address
|
||||
*
|
||||
* \return True if the addresses match, false otherwise
|
||||
*/
|
||||
#define IP_COMPARE(IP1, IP2) (memcmp(IP1, IP2, sizeof(IP_Address_t)) == 0)
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define of an IP packet header. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned char HeaderLength : 4; /**< Total length of the packet header, in 4-byte blocks */
|
||||
unsigned char Version : 4; /**< IP protocol version */
|
||||
uint8_t TypeOfService; /**< Special service type identifier, indicating delay/throughput/reliability levels */
|
||||
uint16_t TotalLength; /**< Total length of the IP packet, in bytes */
|
||||
|
||||
uint16_t Identification; /**< Identification value for identifying fragmented packets */
|
||||
unsigned int FragmentOffset : 13; /**< Offset of this IP fragment */
|
||||
unsigned int Flags : 3; /**< Fragment flags, to indicate if a packet is fragmented */
|
||||
|
||||
uint8_t TTL; /**< Maximum allowable number of hops to reach the packet destination */
|
||||
uint8_t Protocol; /**< Encapsulated protocol type */
|
||||
uint16_t HeaderChecksum; /**< Ethernet checksum of the IP header */
|
||||
|
||||
IP_Address_t SourceAddress; /**< Source protocol IP address of the packet */
|
||||
IP_Address_t DestinationAddress; /**< Destination protocol IP address of the packet */
|
||||
} IP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 IP.c.
|
||||
*/
|
||||
|
||||
#ifndef _IP_H_
|
||||
#define _IP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Protocol IP address of the host (client) machine, once assigned by DHCP */
|
||||
#define CLIENT_IP_ADDRESS { 10, 0, 0, 1}
|
||||
|
||||
/** Protocol IP address of the virtual server machine */
|
||||
#define SERVER_IP_ADDRESS { 10, 0, 0, 2}
|
||||
|
||||
/** Protocol IP address of the broadcast address */
|
||||
#define BROADCAST_IP_ADDRESS {0xFF, 0xFF, 0xFF, 0xFF}
|
||||
|
||||
/** Default Time To Live (TTL) value for sent packets, indicating the maximum allowable hops until their destination is reached */
|
||||
#define DEFAULT_TTL 128
|
||||
|
||||
/** Performs a comparison between two IP addresses, indicating if they are identical.
|
||||
*
|
||||
* \param[in] IP1 First IP address
|
||||
* \param[in] IP2 Second IP address
|
||||
*
|
||||
* \return True if the addresses match, false otherwise
|
||||
*/
|
||||
#define IP_COMPARE(IP1, IP2) (memcmp(IP1, IP2, sizeof(IP_Address_t)) == 0)
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define of an IP packet header. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned char HeaderLength : 4; /**< Total length of the packet header, in 4-byte blocks */
|
||||
unsigned char Version : 4; /**< IP protocol version */
|
||||
uint8_t TypeOfService; /**< Special service type identifier, indicating delay/throughput/reliability levels */
|
||||
uint16_t TotalLength; /**< Total length of the IP packet, in bytes */
|
||||
|
||||
uint16_t Identification; /**< Identification value for identifying fragmented packets */
|
||||
unsigned int FragmentOffset : 13; /**< Offset of this IP fragment */
|
||||
unsigned int Flags : 3; /**< Fragment flags, to indicate if a packet is fragmented */
|
||||
|
||||
uint8_t TTL; /**< Maximum allowable number of hops to reach the packet destination */
|
||||
uint8_t Protocol; /**< Encapsulated protocol type */
|
||||
uint16_t HeaderChecksum; /**< Ethernet checksum of the IP header */
|
||||
|
||||
IP_Address_t SourceAddress; /**< Source protocol IP address of the packet */
|
||||
IP_Address_t DestinationAddress; /**< Destination protocol IP address of the packet */
|
||||
} IP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,279 +1,279 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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.
|
||||
*/
|
||||
|
||||
/* Protocol decoders for Ethernet, TCP, IP, ICMP and ARP. Each of these routines
|
||||
accepts a header to the appropriate protocol and prints out pertinent information
|
||||
on the packet through the serial port.
|
||||
|
||||
To disable printing of a specific protocol, define the token NO_DECODE_{Protocol}
|
||||
in the project makefile, and pass it to the compiler using the -D switch.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Protocol decoding routines, for the plain-text decoding of Ethernet frames for debugging purposes.
|
||||
* Enabled protocol decoders will print incoming Ethernet frame contents through the USART in a human
|
||||
* readable format.
|
||||
*
|
||||
* Note that the USART is a slow transmission medium, and will slow down packet processing considerably.
|
||||
* Packet decoding routines can be disabled by defining NO_DECODE_{Protocol Name} in the project makefile
|
||||
* and passing it to the compiler via the -D switch.
|
||||
*/
|
||||
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/** Decodes an Ethernet frame header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an Ethernet frame header
|
||||
*/
|
||||
void DecodeEthernetFrameHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ETHERNET)
|
||||
Ethernet_Frame_Header_t* FrameHeader = (Ethernet_Frame_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR("\r\n"));
|
||||
|
||||
printf_P(PSTR(" ETHERNET\r\n"));
|
||||
printf_P(PSTR(" + Frame Size: %u\r\n"), FrameIN.FrameLength);
|
||||
|
||||
if (!(MAC_COMPARE(&FrameHeader->Destination, &ServerMACAddress)) &&
|
||||
!(MAC_COMPARE(&FrameHeader->Destination, &BroadcastMACAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + MAC Source : %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Source.Octets[0],
|
||||
FrameHeader->Source.Octets[1],
|
||||
FrameHeader->Source.Octets[2],
|
||||
FrameHeader->Source.Octets[3],
|
||||
FrameHeader->Source.Octets[4],
|
||||
FrameHeader->Source.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + MAC Dest: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Destination.Octets[0],
|
||||
FrameHeader->Destination.Octets[1],
|
||||
FrameHeader->Destination.Octets[2],
|
||||
FrameHeader->Destination.Octets[3],
|
||||
FrameHeader->Destination.Octets[4],
|
||||
FrameHeader->Destination.Octets[5]);
|
||||
|
||||
if (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE)
|
||||
printf_P(PSTR(" + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));
|
||||
else
|
||||
printf_P(PSTR(" + Protocol: UNKNOWN E1\r\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an ARP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an ARP packet header
|
||||
*/
|
||||
void DecodeARPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ARP)
|
||||
ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n ARP\r\n"));
|
||||
|
||||
if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&
|
||||
!(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));
|
||||
printf_P(PSTR(" + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));
|
||||
|
||||
if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)
|
||||
{
|
||||
printf_P(PSTR(" + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],
|
||||
ARPHeader->SHA.Octets[1],
|
||||
ARPHeader->SHA.Octets[2],
|
||||
ARPHeader->SHA.Octets[3],
|
||||
ARPHeader->SHA.Octets[4],
|
||||
ARPHeader->SHA.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],
|
||||
ARPHeader->SPA.Octets[1],
|
||||
ARPHeader->SPA.Octets[2],
|
||||
ARPHeader->SPA.Octets[3]);
|
||||
|
||||
printf_P(PSTR(" + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],
|
||||
ARPHeader->THA.Octets[1],
|
||||
ARPHeader->THA.Octets[2],
|
||||
ARPHeader->THA.Octets[3],
|
||||
ARPHeader->THA.Octets[4],
|
||||
ARPHeader->THA.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],
|
||||
ARPHeader->TPA.Octets[1],
|
||||
ARPHeader->TPA.Octets[2],
|
||||
ARPHeader->TPA.Octets[3]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an IP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an IP packet header
|
||||
*/
|
||||
void DecodeIPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_IP)
|
||||
IP_Header_t* IPHeader = (IP_Header_t*)InDataStart;
|
||||
|
||||
uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n IP\r\n"));
|
||||
|
||||
if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
|
||||
printf_P(PSTR(" + Packet Version: %u\r\n"), IPHeader->Version);
|
||||
printf_P(PSTR(" + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));
|
||||
|
||||
printf_P(PSTR(" + Protocol: %u\r\n"), IPHeader->Protocol);
|
||||
printf_P(PSTR(" + TTL: %u\r\n"), IPHeader->TTL);
|
||||
|
||||
printf_P(PSTR(" + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],
|
||||
IPHeader->SourceAddress.Octets[1],
|
||||
IPHeader->SourceAddress.Octets[2],
|
||||
IPHeader->SourceAddress.Octets[3]);
|
||||
|
||||
printf_P(PSTR(" + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],
|
||||
IPHeader->DestinationAddress.Octets[1],
|
||||
IPHeader->DestinationAddress.Octets[2],
|
||||
IPHeader->DestinationAddress.Octets[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an ICMP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an ICMP packet header
|
||||
*/
|
||||
void DecodeICMPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ICMP)
|
||||
ICMP_Header_t* ICMPHeader = (ICMP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n ICMP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Type: %u\r\n"), ICMPHeader->Type);
|
||||
printf_P(PSTR(" + Code: %u\r\n"), ICMPHeader->Code);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes a TCP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a TCP packet header
|
||||
*/
|
||||
void DecodeTCPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_TCP)
|
||||
TCP_Header_t* TCPHeader = (TCP_Header_t*)InDataStart;
|
||||
|
||||
uint16_t HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n TCP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
|
||||
|
||||
printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));
|
||||
printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));
|
||||
|
||||
printf_P(PSTR(" + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));
|
||||
printf_P(PSTR(" + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));
|
||||
|
||||
printf_P(PSTR(" + Flags: 0x%02X\r\n"), TCPHeader->Flags);
|
||||
|
||||
if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)
|
||||
printf_P(PSTR(" + NOT LISTENING ON DESTINATION PORT\r\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an UDP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a UDP packet header
|
||||
*/
|
||||
void DecodeUDPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_UDP)
|
||||
UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n UDP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));
|
||||
printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));
|
||||
|
||||
printf_P(PSTR(" + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an DHCP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a DHCP packet header
|
||||
*/
|
||||
void DecodeDHCPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_DHCP)
|
||||
uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n DHCP\r\n"));
|
||||
|
||||
while (DHCPOptions[0] != DHCP_OPTION_END)
|
||||
{
|
||||
if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)
|
||||
{
|
||||
switch (DHCPOptions[2])
|
||||
{
|
||||
case DHCP_MESSAGETYPE_DISCOVER:
|
||||
printf_P(PSTR(" + DISCOVER\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_REQUEST:
|
||||
printf_P(PSTR(" + REQUEST\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_RELEASE:
|
||||
printf_P(PSTR(" + RELEASE\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_DECLINE:
|
||||
printf_P(PSTR(" + DECLINE\r\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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.
|
||||
*/
|
||||
|
||||
/* Protocol decoders for Ethernet, TCP, IP, ICMP and ARP. Each of these routines
|
||||
accepts a header to the appropriate protocol and prints out pertinent information
|
||||
on the packet through the serial port.
|
||||
|
||||
To disable printing of a specific protocol, define the token NO_DECODE_{Protocol}
|
||||
in the project makefile, and pass it to the compiler using the -D switch.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Protocol decoding routines, for the plain-text decoding of Ethernet frames for debugging purposes.
|
||||
* Enabled protocol decoders will print incoming Ethernet frame contents through the USART in a human
|
||||
* readable format.
|
||||
*
|
||||
* Note that the USART is a slow transmission medium, and will slow down packet processing considerably.
|
||||
* Packet decoding routines can be disabled by defining NO_DECODE_{Protocol Name} in the project makefile
|
||||
* and passing it to the compiler via the -D switch.
|
||||
*/
|
||||
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/** Decodes an Ethernet frame header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an Ethernet frame header
|
||||
*/
|
||||
void DecodeEthernetFrameHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ETHERNET)
|
||||
Ethernet_Frame_Header_t* FrameHeader = (Ethernet_Frame_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR("\r\n"));
|
||||
|
||||
printf_P(PSTR(" ETHERNET\r\n"));
|
||||
printf_P(PSTR(" + Frame Size: %u\r\n"), FrameIN.FrameLength);
|
||||
|
||||
if (!(MAC_COMPARE(&FrameHeader->Destination, &ServerMACAddress)) &&
|
||||
!(MAC_COMPARE(&FrameHeader->Destination, &BroadcastMACAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + MAC Source : %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Source.Octets[0],
|
||||
FrameHeader->Source.Octets[1],
|
||||
FrameHeader->Source.Octets[2],
|
||||
FrameHeader->Source.Octets[3],
|
||||
FrameHeader->Source.Octets[4],
|
||||
FrameHeader->Source.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + MAC Dest: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Destination.Octets[0],
|
||||
FrameHeader->Destination.Octets[1],
|
||||
FrameHeader->Destination.Octets[2],
|
||||
FrameHeader->Destination.Octets[3],
|
||||
FrameHeader->Destination.Octets[4],
|
||||
FrameHeader->Destination.Octets[5]);
|
||||
|
||||
if (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE)
|
||||
printf_P(PSTR(" + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));
|
||||
else
|
||||
printf_P(PSTR(" + Protocol: UNKNOWN E1\r\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an ARP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an ARP packet header
|
||||
*/
|
||||
void DecodeARPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ARP)
|
||||
ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n ARP\r\n"));
|
||||
|
||||
if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&
|
||||
!(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));
|
||||
printf_P(PSTR(" + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));
|
||||
|
||||
if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)
|
||||
{
|
||||
printf_P(PSTR(" + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],
|
||||
ARPHeader->SHA.Octets[1],
|
||||
ARPHeader->SHA.Octets[2],
|
||||
ARPHeader->SHA.Octets[3],
|
||||
ARPHeader->SHA.Octets[4],
|
||||
ARPHeader->SHA.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],
|
||||
ARPHeader->SPA.Octets[1],
|
||||
ARPHeader->SPA.Octets[2],
|
||||
ARPHeader->SPA.Octets[3]);
|
||||
|
||||
printf_P(PSTR(" + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],
|
||||
ARPHeader->THA.Octets[1],
|
||||
ARPHeader->THA.Octets[2],
|
||||
ARPHeader->THA.Octets[3],
|
||||
ARPHeader->THA.Octets[4],
|
||||
ARPHeader->THA.Octets[5]);
|
||||
|
||||
printf_P(PSTR(" + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],
|
||||
ARPHeader->TPA.Octets[1],
|
||||
ARPHeader->TPA.Octets[2],
|
||||
ARPHeader->TPA.Octets[3]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an IP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an IP packet header
|
||||
*/
|
||||
void DecodeIPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_IP)
|
||||
IP_Header_t* IPHeader = (IP_Header_t*)InDataStart;
|
||||
|
||||
uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n IP\r\n"));
|
||||
|
||||
if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))
|
||||
{
|
||||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
|
||||
printf_P(PSTR(" + Packet Version: %u\r\n"), IPHeader->Version);
|
||||
printf_P(PSTR(" + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));
|
||||
|
||||
printf_P(PSTR(" + Protocol: %u\r\n"), IPHeader->Protocol);
|
||||
printf_P(PSTR(" + TTL: %u\r\n"), IPHeader->TTL);
|
||||
|
||||
printf_P(PSTR(" + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],
|
||||
IPHeader->SourceAddress.Octets[1],
|
||||
IPHeader->SourceAddress.Octets[2],
|
||||
IPHeader->SourceAddress.Octets[3]);
|
||||
|
||||
printf_P(PSTR(" + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],
|
||||
IPHeader->DestinationAddress.Octets[1],
|
||||
IPHeader->DestinationAddress.Octets[2],
|
||||
IPHeader->DestinationAddress.Octets[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an ICMP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of an ICMP packet header
|
||||
*/
|
||||
void DecodeICMPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_ICMP)
|
||||
ICMP_Header_t* ICMPHeader = (ICMP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n ICMP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Type: %u\r\n"), ICMPHeader->Type);
|
||||
printf_P(PSTR(" + Code: %u\r\n"), ICMPHeader->Code);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes a TCP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a TCP packet header
|
||||
*/
|
||||
void DecodeTCPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_TCP)
|
||||
TCP_Header_t* TCPHeader = (TCP_Header_t*)InDataStart;
|
||||
|
||||
uint16_t HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n TCP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Header Length: %u Bytes\r\n"), HeaderLengthBytes);
|
||||
|
||||
printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));
|
||||
printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));
|
||||
|
||||
printf_P(PSTR(" + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));
|
||||
printf_P(PSTR(" + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));
|
||||
|
||||
printf_P(PSTR(" + Flags: 0x%02X\r\n"), TCPHeader->Flags);
|
||||
|
||||
if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)
|
||||
printf_P(PSTR(" + NOT LISTENING ON DESTINATION PORT\r\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an UDP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a UDP packet header
|
||||
*/
|
||||
void DecodeUDPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_UDP)
|
||||
UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;
|
||||
|
||||
printf_P(PSTR(" \\\r\n UDP\r\n"));
|
||||
|
||||
printf_P(PSTR(" + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));
|
||||
printf_P(PSTR(" + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));
|
||||
|
||||
printf_P(PSTR(" + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Decodes an DHCP header and prints its contents to through the USART in a human readable format.
|
||||
*
|
||||
* \param[in] InDataStart Pointer to the start of a DHCP packet header
|
||||
*/
|
||||
void DecodeDHCPHeader(void* InDataStart)
|
||||
{
|
||||
#if !defined(NO_DECODE_DHCP)
|
||||
uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));
|
||||
|
||||
printf_P(PSTR(" \\\r\n DHCP\r\n"));
|
||||
|
||||
while (DHCPOptions[0] != DHCP_OPTION_END)
|
||||
{
|
||||
if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)
|
||||
{
|
||||
switch (DHCPOptions[2])
|
||||
{
|
||||
case DHCP_MESSAGETYPE_DISCOVER:
|
||||
printf_P(PSTR(" + DISCOVER\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_REQUEST:
|
||||
printf_P(PSTR(" + REQUEST\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_RELEASE:
|
||||
printf_P(PSTR(" + RELEASE\r\n"));
|
||||
break;
|
||||
case DHCP_MESSAGETYPE_DECLINE:
|
||||
printf_P(PSTR(" + DECLINE\r\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ProtocolDecoders.c.
|
||||
*/
|
||||
|
||||
#ifndef _PROTOCOL_DECODERS_H_
|
||||
#define _PROTOCOL_DECODERS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <LUFA/Drivers/Peripheral/SerialStream.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DecodeEthernetFrameHeader(void* InDataStart);
|
||||
void DecodeARPHeader(void* InDataStart);
|
||||
void DecodeIPHeader(void* InDataStart);
|
||||
void DecodeICMPHeader(void* InDataStart);
|
||||
void DecodeTCPHeader(void* InDataStart);
|
||||
void DecodeUDPHeader(void* InDataStart);
|
||||
void DecodeDHCPHeader(void* InDataStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 ProtocolDecoders.c.
|
||||
*/
|
||||
|
||||
#ifndef _PROTOCOL_DECODERS_H_
|
||||
#define _PROTOCOL_DECODERS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <LUFA/Drivers/Peripheral/SerialStream.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DecodeEthernetFrameHeader(void* InDataStart);
|
||||
void DecodeARPHeader(void* InDataStart);
|
||||
void DecodeIPHeader(void* InDataStart);
|
||||
void DecodeICMPHeader(void* InDataStart);
|
||||
void DecodeTCPHeader(void* InDataStart);
|
||||
void DecodeUDPHeader(void* InDataStart);
|
||||
void DecodeDHCPHeader(void* InDataStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,393 +1,393 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* RNDIS command handler functions. This handles RNDIS commands according to
|
||||
* the Microsoft RNDIS specification, creating a USB Ethernet network adapter.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_RNDIS_C
|
||||
#include "RNDIS.h"
|
||||
|
||||
/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */
|
||||
static MAC_Address_t PROGMEM AdapterMACAddress = {ADAPTER_MAC_ADDRESS};
|
||||
|
||||
/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for
|
||||
* the device, but may still be used by the OS in some circumstances.
|
||||
*/
|
||||
static char PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";
|
||||
|
||||
/** List of RNDIS OID commands supported by this adapter. */
|
||||
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_PHYSICAL_MEDIUM,
|
||||
OID_GEN_HARDWARE_STATUS,
|
||||
OID_GEN_MEDIA_SUPPORTED,
|
||||
OID_GEN_MEDIA_IN_USE,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_LINK_SPEED,
|
||||
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
||||
OID_GEN_RECEIVE_BLOCK_SIZE,
|
||||
OID_GEN_VENDOR_ID,
|
||||
OID_GEN_VENDOR_DESCRIPTION,
|
||||
OID_GEN_CURRENT_PACKET_FILTER,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
OID_GEN_XMIT_OK,
|
||||
OID_GEN_RCV_OK,
|
||||
OID_GEN_XMIT_ERROR,
|
||||
OID_GEN_RCV_ERROR,
|
||||
OID_GEN_RCV_NO_BUFFER,
|
||||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MULTICAST_LIST,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
OID_802_3_RCV_ERROR_ALIGNMENT,
|
||||
OID_802_3_XMIT_ONE_COLLISION,
|
||||
OID_802_3_XMIT_MORE_COLLISIONS,
|
||||
};
|
||||
|
||||
/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire
|
||||
* Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this
|
||||
* reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.
|
||||
*/
|
||||
uint8_t RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t)];
|
||||
|
||||
/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;
|
||||
|
||||
/** Indicates if a RNDIS message response is ready to be sent back to the host. */
|
||||
bool ResponseReady = false;
|
||||
|
||||
/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */
|
||||
uint8_t CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */
|
||||
uint32_t CurrPacketFilter = 0;
|
||||
|
||||
|
||||
/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is
|
||||
* created, the ResponseReady global is updated so that the response is written back to the host upon request.
|
||||
*/
|
||||
void ProcessRNDISControlMessage(void)
|
||||
{
|
||||
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
|
||||
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
|
||||
|
||||
switch (MessageHeader->MessageType)
|
||||
{
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
/* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Initialize_Message_t* INITIALIZE_Message = (RNDIS_Initialize_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Initialize_Complete_t* INITIALIZE_Response = (RNDIS_Initialize_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
INITIALIZE_Response->MessageLength = sizeof(RNDIS_Initialize_Complete_t);
|
||||
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
|
||||
INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
|
||||
INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
|
||||
INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
|
||||
INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
|
||||
INITIALIZE_Response->MaxPacketsPerTransfer = 1;
|
||||
INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
|
||||
INITIALIZE_Response->PacketAlignmentFactor = 0;
|
||||
INITIALIZE_Response->AFListOffset = 0;
|
||||
INITIALIZE_Response->AFListSize = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Initialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
/* Halt the adapter, reset the adapter state - note that no response should be returned when completed */
|
||||
|
||||
ResponseReady = false;
|
||||
MessageHeader->MessageLength = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
/* Request for information about a parameter about the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISMessageBuffer;
|
||||
uint32_t Query_Oid = QUERY_Message->Oid;
|
||||
|
||||
void* QueryData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
QUERY_Message->InformationBufferOffset];
|
||||
void* ResponseData = &RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
|
||||
uint16_t ResponseSize;
|
||||
|
||||
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
QUERY_Response->MessageLength = sizeof(RNDIS_Query_Complete_t);
|
||||
|
||||
if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
|
||||
ResponseData, &ResponseSize))
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
QUERY_Response->MessageLength += ResponseSize;
|
||||
|
||||
QUERY_Response->InformationBufferLength = ResponseSize;
|
||||
QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
QUERY_Response->InformationBufferLength = 0;
|
||||
QUERY_Response->InformationBufferOffset = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
/* Request to set a parameter of the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISMessageBuffer;
|
||||
uint32_t SET_Oid = SET_Message->Oid;
|
||||
|
||||
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
SET_Response->MessageLength = sizeof(RNDIS_Set_Complete_t);
|
||||
SET_Response->RequestId = SET_Message->RequestId;
|
||||
|
||||
void* SetData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
SET_Message->InformationBufferOffset];
|
||||
|
||||
if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
else
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
/* Soft reset the adapter */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
RESET_Response->MessageLength = sizeof(RNDIS_Reset_Complete_t);
|
||||
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
RESET_Response->AddressingReset = 0;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
/* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message = (RNDIS_KeepAlive_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response = (RNDIS_KeepAlive_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KeepAlive_Complete_t);
|
||||
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
|
||||
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
|
||||
* parameter is given as an OID value.
|
||||
*
|
||||
* \param[in] OId OId value of the parameter being queried
|
||||
* \param[in] QueryData Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
|
||||
* \param[in] QuerySize Size in bytes of the extra query data being sent by the host
|
||||
* \param[out] ResponseData Pointer to the start of the query response inside the RNDIS message buffer
|
||||
* \param[out] ResponseSize Pointer to the size in bytes of the response data being sent to the host
|
||||
*
|
||||
* \return Boolean true if the query was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_QUERY_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
*ResponseSize = sizeof(AdapterSupportedOIDList);
|
||||
|
||||
/* Copy the list of supported NDIS OID tokens to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
|
||||
|
||||
return true;
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the device is a true ethernet link */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate hardware ready */
|
||||
*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 802.3 (Ethernet) supported by the adapter */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
|
||||
*((uint32_t*)ResponseData) = 0x00FFFFFF;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the maximum frame size is the size of the ethernet frame buffer */
|
||||
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
*ResponseSize = sizeof(AdapterVendorDescription);
|
||||
|
||||
/* Copy vendor description string to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate that the adapter is connected to a network */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
|
||||
|
||||
return true;
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 10Mb/s link speed */
|
||||
*((uint32_t*)ResponseData) = 100000;
|
||||
|
||||
return true;
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
*ResponseSize = sizeof(MAC_Address_t);
|
||||
|
||||
/* Copy over the fixed adapter MAC to the response buffer */
|
||||
memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
|
||||
return true;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate only one multicast address supported */
|
||||
*((uint32_t*)ResponseData) = 1;
|
||||
|
||||
return true;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate the current packet filter mask */
|
||||
*((uint32_t*)ResponseData) = CurrPacketFilter;
|
||||
|
||||
return true;
|
||||
case OID_GEN_XMIT_OK:
|
||||
case OID_GEN_RCV_OK:
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
case OID_GEN_RCV_ERROR:
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Unused statistic OIDs - always return 0 for each */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
|
||||
*((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given
|
||||
* as an OID value.
|
||||
*
|
||||
* \param[in] OId OId value of the parameter being set
|
||||
* \param[in] SetData Pointer to the parameter value in the RNDIS message buffer
|
||||
* \param[in] SetSize Size in bytes of the parameter value being sent by the host
|
||||
*
|
||||
* \return Boolean true if the set was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_SET_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
/* Save the packet filter mask in case the host queries it again later */
|
||||
CurrPacketFilter = *((uint32_t*)SetData);
|
||||
|
||||
/* Set the RNDIS state to initialized if the packet filter is non-zero */
|
||||
CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
|
||||
|
||||
return true;
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
/* Do nothing - throw away the value from the host as it is unused */
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* RNDIS command handler functions. This handles RNDIS commands according to
|
||||
* the Microsoft RNDIS specification, creating a USB Ethernet network adapter.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_RNDIS_C
|
||||
#include "RNDIS.h"
|
||||
|
||||
/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */
|
||||
static MAC_Address_t PROGMEM AdapterMACAddress = {ADAPTER_MAC_ADDRESS};
|
||||
|
||||
/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for
|
||||
* the device, but may still be used by the OS in some circumstances.
|
||||
*/
|
||||
static char PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";
|
||||
|
||||
/** List of RNDIS OID commands supported by this adapter. */
|
||||
static const uint32_t PROGMEM AdapterSupportedOIDList[] =
|
||||
{
|
||||
OID_GEN_SUPPORTED_LIST,
|
||||
OID_GEN_PHYSICAL_MEDIUM,
|
||||
OID_GEN_HARDWARE_STATUS,
|
||||
OID_GEN_MEDIA_SUPPORTED,
|
||||
OID_GEN_MEDIA_IN_USE,
|
||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_LINK_SPEED,
|
||||
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
||||
OID_GEN_RECEIVE_BLOCK_SIZE,
|
||||
OID_GEN_VENDOR_ID,
|
||||
OID_GEN_VENDOR_DESCRIPTION,
|
||||
OID_GEN_CURRENT_PACKET_FILTER,
|
||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||
OID_GEN_XMIT_OK,
|
||||
OID_GEN_RCV_OK,
|
||||
OID_GEN_XMIT_ERROR,
|
||||
OID_GEN_RCV_ERROR,
|
||||
OID_GEN_RCV_NO_BUFFER,
|
||||
OID_802_3_PERMANENT_ADDRESS,
|
||||
OID_802_3_CURRENT_ADDRESS,
|
||||
OID_802_3_MULTICAST_LIST,
|
||||
OID_802_3_MAXIMUM_LIST_SIZE,
|
||||
OID_802_3_RCV_ERROR_ALIGNMENT,
|
||||
OID_802_3_XMIT_ONE_COLLISION,
|
||||
OID_802_3_XMIT_MORE_COLLISIONS,
|
||||
};
|
||||
|
||||
/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire
|
||||
* Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this
|
||||
* reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.
|
||||
*/
|
||||
uint8_t RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t)];
|
||||
|
||||
/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */
|
||||
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;
|
||||
|
||||
/** Indicates if a RNDIS message response is ready to be sent back to the host. */
|
||||
bool ResponseReady = false;
|
||||
|
||||
/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */
|
||||
uint8_t CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */
|
||||
uint32_t CurrPacketFilter = 0;
|
||||
|
||||
|
||||
/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is
|
||||
* created, the ResponseReady global is updated so that the response is written back to the host upon request.
|
||||
*/
|
||||
void ProcessRNDISControlMessage(void)
|
||||
{
|
||||
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
|
||||
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
|
||||
|
||||
switch (MessageHeader->MessageType)
|
||||
{
|
||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||
/* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Initialize_Message_t* INITIALIZE_Message = (RNDIS_Initialize_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Initialize_Complete_t* INITIALIZE_Response = (RNDIS_Initialize_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
|
||||
INITIALIZE_Response->MessageLength = sizeof(RNDIS_Initialize_Complete_t);
|
||||
INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
|
||||
INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
|
||||
INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
|
||||
INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
|
||||
INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
|
||||
INITIALIZE_Response->MaxPacketsPerTransfer = 1;
|
||||
INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
|
||||
INITIALIZE_Response->PacketAlignmentFactor = 0;
|
||||
INITIALIZE_Response->AFListOffset = 0;
|
||||
INITIALIZE_Response->AFListSize = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Initialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_HALT_MSG:
|
||||
/* Halt the adapter, reset the adapter state - note that no response should be returned when completed */
|
||||
|
||||
ResponseReady = false;
|
||||
MessageHeader->MessageLength = 0;
|
||||
|
||||
CurrRNDISState = RNDIS_Uninitialized;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_QUERY_MSG:
|
||||
/* Request for information about a parameter about the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISMessageBuffer;
|
||||
uint32_t Query_Oid = QUERY_Message->Oid;
|
||||
|
||||
void* QueryData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
QUERY_Message->InformationBufferOffset];
|
||||
void* ResponseData = &RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
|
||||
uint16_t ResponseSize;
|
||||
|
||||
QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
|
||||
QUERY_Response->MessageLength = sizeof(RNDIS_Query_Complete_t);
|
||||
|
||||
if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
|
||||
ResponseData, &ResponseSize))
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
QUERY_Response->MessageLength += ResponseSize;
|
||||
|
||||
QUERY_Response->InformationBufferLength = ResponseSize;
|
||||
QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
QUERY_Response->InformationBufferLength = 0;
|
||||
QUERY_Response->InformationBufferOffset = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_SET_MSG:
|
||||
/* Request to set a parameter of the adapter, specified as an OID token */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISMessageBuffer;
|
||||
uint32_t SET_Oid = SET_Message->Oid;
|
||||
|
||||
SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
|
||||
SET_Response->MessageLength = sizeof(RNDIS_Set_Complete_t);
|
||||
SET_Response->RequestId = SET_Message->RequestId;
|
||||
|
||||
void* SetData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
|
||||
SET_Message->InformationBufferOffset];
|
||||
|
||||
if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
else
|
||||
SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_RESET_MSG:
|
||||
/* Soft reset the adapter */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
|
||||
RESET_Response->MessageLength = sizeof(RNDIS_Reset_Complete_t);
|
||||
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
RESET_Response->AddressingReset = 0;
|
||||
|
||||
break;
|
||||
case REMOTE_NDIS_KEEPALIVE_MSG:
|
||||
/* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
|
||||
|
||||
ResponseReady = true;
|
||||
|
||||
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message = (RNDIS_KeepAlive_Message_t*)&RNDISMessageBuffer;
|
||||
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response = (RNDIS_KeepAlive_Complete_t*)&RNDISMessageBuffer;
|
||||
|
||||
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
|
||||
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KeepAlive_Complete_t);
|
||||
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
|
||||
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
|
||||
* parameter is given as an OID value.
|
||||
*
|
||||
* \param[in] OId OId value of the parameter being queried
|
||||
* \param[in] QueryData Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
|
||||
* \param[in] QuerySize Size in bytes of the extra query data being sent by the host
|
||||
* \param[out] ResponseData Pointer to the start of the query response inside the RNDIS message buffer
|
||||
* \param[out] ResponseSize Pointer to the size in bytes of the response data being sent to the host
|
||||
*
|
||||
* \return Boolean true if the query was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_QUERY_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_SUPPORTED_LIST:
|
||||
*ResponseSize = sizeof(AdapterSupportedOIDList);
|
||||
|
||||
/* Copy the list of supported NDIS OID tokens to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
|
||||
|
||||
return true;
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the device is a true ethernet link */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_HARDWARE_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate hardware ready */
|
||||
*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 802.3 (Ethernet) supported by the adapter */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_ID:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
|
||||
*((uint32_t*)ResponseData) = 0x00FFFFFF;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate that the maximum frame size is the size of the ethernet frame buffer */
|
||||
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
|
||||
|
||||
return true;
|
||||
case OID_GEN_VENDOR_DESCRIPTION:
|
||||
*ResponseSize = sizeof(AdapterVendorDescription);
|
||||
|
||||
/* Copy vendor description string to the response buffer */
|
||||
memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
|
||||
|
||||
return true;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Always indicate that the adapter is connected to a network */
|
||||
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
|
||||
|
||||
return true;
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate 10Mb/s link speed */
|
||||
*((uint32_t*)ResponseData) = 100000;
|
||||
|
||||
return true;
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
*ResponseSize = sizeof(MAC_Address_t);
|
||||
|
||||
/* Copy over the fixed adapter MAC to the response buffer */
|
||||
memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
|
||||
|
||||
return true;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate only one multicast address supported */
|
||||
*((uint32_t*)ResponseData) = 1;
|
||||
|
||||
return true;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate the current packet filter mask */
|
||||
*((uint32_t*)ResponseData) = CurrPacketFilter;
|
||||
|
||||
return true;
|
||||
case OID_GEN_XMIT_OK:
|
||||
case OID_GEN_RCV_OK:
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
case OID_GEN_RCV_ERROR:
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Unused statistic OIDs - always return 0 for each */
|
||||
*((uint32_t*)ResponseData) = 0;
|
||||
|
||||
return true;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*ResponseSize = sizeof(uint32_t);
|
||||
|
||||
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
|
||||
*((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given
|
||||
* as an OID value.
|
||||
*
|
||||
* \param[in] OId OId value of the parameter being set
|
||||
* \param[in] SetData Pointer to the parameter value in the RNDIS message buffer
|
||||
* \param[in] SetSize Size in bytes of the parameter value being sent by the host
|
||||
*
|
||||
* \return Boolean true if the set was handled, false otherwise
|
||||
*/
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
|
||||
{
|
||||
/* Handler for REMOTE_NDIS_SET_MSG messages */
|
||||
|
||||
switch (OId)
|
||||
{
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
/* Save the packet filter mask in case the host queries it again later */
|
||||
CurrPacketFilter = *((uint32_t*)SetData);
|
||||
|
||||
/* Set the RNDIS state to initialized if the packet filter is non-zero */
|
||||
CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
|
||||
|
||||
return true;
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
/* Do nothing - throw away the value from the host as it is unused */
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,223 +1,223 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 RNDIS.c.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_H_
|
||||
#define _RNDIS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "RNDISEthernet.h"
|
||||
#include "RNDISConstants.h"
|
||||
#include "Ethernet.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Implemented RNDIS Version Major */
|
||||
#define REMOTE_NDIS_VERSION_MAJOR 0x01
|
||||
|
||||
/** Implemented RNDIS Version Minor */
|
||||
#define REMOTE_NDIS_VERSION_MINOR 0x00
|
||||
|
||||
/** RNDIS request to issue a host-to-device NDIS command */
|
||||
#define REQ_SendEncapsulatedCommand 0x00
|
||||
|
||||
/** RNDIS request to issue a device-to-host NDIS response */
|
||||
#define REQ_GetEncapsulatedResponse 0x01
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible NDIS adapter states. */
|
||||
enum RNDIS_States_t
|
||||
{
|
||||
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized */
|
||||
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers */
|
||||
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */
|
||||
};
|
||||
|
||||
/** Enum for the NDIS hardware states */
|
||||
enum NDIS_Hardware_Status_t
|
||||
{
|
||||
NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */
|
||||
NdisHardwareStatusInitializing, /**< Hardware busy initializing */
|
||||
NdisHardwareStatusReset, /**< Hardware reset */
|
||||
NdisHardwareStatusClosing, /**< Hardware currently closing */
|
||||
NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a RNDIS message header, sent before RNDIS messages */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
|
||||
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
|
||||
} RNDIS_Message_Header_t;
|
||||
|
||||
/** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataLength;
|
||||
uint32_t OOBDataOffset;
|
||||
uint32_t OOBDataLength;
|
||||
uint32_t NumOOBDataElements;
|
||||
uint32_t PerPacketInfoOffset;
|
||||
uint32_t PerPacketInfoLength;
|
||||
uint32_t VcHandle;
|
||||
uint32_t Reserved;
|
||||
} RNDIS_Packet_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t MaxTransferSize;
|
||||
} RNDIS_Initialize_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t DeviceFlags;
|
||||
uint32_t Medium;
|
||||
uint32_t MaxPacketsPerTransfer;
|
||||
uint32_t MaxTransferSize;
|
||||
uint32_t PacketAlignmentFactor;
|
||||
uint32_t AFListOffset;
|
||||
uint32_t AFListSize;
|
||||
} RNDIS_Initialize_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
} RNDIS_KeepAlive_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_KeepAlive_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Reset complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t AddressingReset;
|
||||
} RNDIS_Reset_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Set command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_Set_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Set complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_Set_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Query command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_Query_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Query complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
} RNDIS_Query_Complete_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern uint8_t RNDISMessageBuffer[];
|
||||
extern RNDIS_Message_Header_t* MessageHeader;
|
||||
extern bool ResponseReady;
|
||||
extern uint8_t CurrRNDISState;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void ProcessRNDISControlMessage(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_RNDIS_C)
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize);
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 RNDIS.c.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_H_
|
||||
#define _RNDIS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "RNDISEthernet.h"
|
||||
#include "RNDISConstants.h"
|
||||
#include "Ethernet.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Implemented RNDIS Version Major */
|
||||
#define REMOTE_NDIS_VERSION_MAJOR 0x01
|
||||
|
||||
/** Implemented RNDIS Version Minor */
|
||||
#define REMOTE_NDIS_VERSION_MINOR 0x00
|
||||
|
||||
/** RNDIS request to issue a host-to-device NDIS command */
|
||||
#define REQ_SendEncapsulatedCommand 0x00
|
||||
|
||||
/** RNDIS request to issue a device-to-host NDIS response */
|
||||
#define REQ_GetEncapsulatedResponse 0x01
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible NDIS adapter states. */
|
||||
enum RNDIS_States_t
|
||||
{
|
||||
RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized */
|
||||
RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers */
|
||||
RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */
|
||||
};
|
||||
|
||||
/** Enum for the NDIS hardware states */
|
||||
enum NDIS_Hardware_Status_t
|
||||
{
|
||||
NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */
|
||||
NdisHardwareStatusInitializing, /**< Hardware busy initializing */
|
||||
NdisHardwareStatusReset, /**< Hardware reset */
|
||||
NdisHardwareStatusClosing, /**< Hardware currently closing */
|
||||
NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a RNDIS message header, sent before RNDIS messages */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
|
||||
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
|
||||
} RNDIS_Message_Header_t;
|
||||
|
||||
/** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataLength;
|
||||
uint32_t OOBDataOffset;
|
||||
uint32_t OOBDataLength;
|
||||
uint32_t NumOOBDataElements;
|
||||
uint32_t PerPacketInfoOffset;
|
||||
uint32_t PerPacketInfoLength;
|
||||
uint32_t VcHandle;
|
||||
uint32_t Reserved;
|
||||
} RNDIS_Packet_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t MaxTransferSize;
|
||||
} RNDIS_Initialize_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Initialize complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t DeviceFlags;
|
||||
uint32_t Medium;
|
||||
uint32_t MaxPacketsPerTransfer;
|
||||
uint32_t MaxTransferSize;
|
||||
uint32_t PacketAlignmentFactor;
|
||||
uint32_t AFListOffset;
|
||||
uint32_t AFListSize;
|
||||
} RNDIS_Initialize_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
} RNDIS_KeepAlive_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Keepalive complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_KeepAlive_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Reset complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t AddressingReset;
|
||||
} RNDIS_Reset_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Set command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_Set_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Set complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
} RNDIS_Set_Complete_t;
|
||||
|
||||
/** Type define for a RNDIS Query command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
|
||||
uint32_t Oid;
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
} RNDIS_Query_Message_t;
|
||||
|
||||
/** Type define for a RNDIS Query complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MessageType;
|
||||
uint32_t MessageLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Status;
|
||||
|
||||
uint32_t InformationBufferLength;
|
||||
uint32_t InformationBufferOffset;
|
||||
} RNDIS_Query_Complete_t;
|
||||
|
||||
/* External Variables: */
|
||||
extern uint8_t RNDISMessageBuffer[];
|
||||
extern RNDIS_Message_Header_t* MessageHeader;
|
||||
extern bool ResponseReady;
|
||||
extern uint8_t CurrRNDISState;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void ProcessRNDISControlMessage(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_RNDIS_C)
|
||||
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
|
||||
void* ResponseData, uint16_t* ResponseSize);
|
||||
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,112 +1,112 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* RNDIS specification related constants. For more information on these
|
||||
* constants, please refer to the Microsoft RNDIS specification.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CONSTANTS_DEVICE_H_
|
||||
#define _RNDIS_CONSTANTS_DEVICE_H_
|
||||
|
||||
/* Macros: */
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
|
||||
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
|
||||
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
|
||||
#define REMOTE_NDIS_SET_MSG 0x00000005UL
|
||||
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
|
||||
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
|
||||
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
|
||||
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
|
||||
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
|
||||
|
||||
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
|
||||
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
|
||||
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
|
||||
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
|
||||
|
||||
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
|
||||
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
|
||||
|
||||
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
|
||||
|
||||
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
|
||||
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
|
||||
|
||||
#define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
|
||||
#define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
|
||||
#define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
|
||||
#define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
|
||||
#define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
|
||||
#define REMOTE_NDIS_PACKET_SMT 0x00000040UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
|
||||
#define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
|
||||
#define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
|
||||
#define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
|
||||
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_LINK_SPEED 0x00010107UL
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
|
||||
#define OID_GEN_VENDOR_ID 0x0001010CUL
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
|
||||
#define OID_GEN_XMIT_OK 0x00020101UL
|
||||
#define OID_GEN_RCV_OK 0x00020102UL
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103UL
|
||||
#define OID_GEN_RCV_ERROR 0x00020104UL
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103UL
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* RNDIS specification related constants. For more information on these
|
||||
* constants, please refer to the Microsoft RNDIS specification.
|
||||
*/
|
||||
|
||||
#ifndef _RNDIS_CONSTANTS_DEVICE_H_
|
||||
#define _RNDIS_CONSTANTS_DEVICE_H_
|
||||
|
||||
/* Macros: */
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001UL
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
|
||||
#define REMOTE_NDIS_HALT_MSG 0x00000003UL
|
||||
#define REMOTE_NDIS_QUERY_MSG 0x00000004UL
|
||||
#define REMOTE_NDIS_SET_MSG 0x00000005UL
|
||||
#define REMOTE_NDIS_RESET_MSG 0x00000006UL
|
||||
#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
|
||||
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
|
||||
#define REMOTE_NDIS_SET_CMPLT 0x80000005UL
|
||||
#define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
|
||||
#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
|
||||
|
||||
#define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
|
||||
#define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
|
||||
#define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
|
||||
#define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
|
||||
#define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
|
||||
|
||||
#define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
|
||||
#define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
|
||||
|
||||
#define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
|
||||
|
||||
#define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
|
||||
#define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
|
||||
|
||||
#define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
|
||||
#define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
|
||||
#define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
|
||||
#define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
|
||||
#define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
|
||||
#define REMOTE_NDIS_PACKET_SMT 0x00000040UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
|
||||
#define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
|
||||
#define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
|
||||
#define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
|
||||
#define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
|
||||
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_LINK_SPEED 0x00010107UL
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
|
||||
#define OID_GEN_VENDOR_ID 0x0001010CUL
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
|
||||
#define OID_GEN_XMIT_OK 0x00020101UL
|
||||
#define OID_GEN_RCV_OK 0x00020102UL
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103UL
|
||||
#define OID_GEN_RCV_ERROR 0x00020104UL
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103UL
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,249 +1,249 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 TCP.c.
|
||||
*/
|
||||
|
||||
#ifndef _TCP_H_
|
||||
#define _TCP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Maximum number of TCP ports which can be open at the one time */
|
||||
#define MAX_OPEN_TCP_PORTS 1
|
||||
|
||||
/** Maximum number of TCP connections which can be sustained at the one time */
|
||||
#define MAX_TCP_CONNECTIONS 3
|
||||
|
||||
/** TCP window size, giving the maximum number of bytes which can be buffered at the one time */
|
||||
#define TCP_WINDOW_SIZE 512
|
||||
|
||||
/** Port number for HTTP transmissions */
|
||||
#define TCP_PORT_HTTP SwapEndian_16(80)
|
||||
|
||||
/** Data direction indicator for a TCP application buffer, indicating data from host-to-device */
|
||||
#define TCP_PACKETDIR_IN false
|
||||
|
||||
/** Data direction indicator for a TCP application buffer, indicating data from device-to-host */
|
||||
#define TCP_PACKETDIR_OUT true
|
||||
|
||||
/** Congestion Window Reduced TCP flag mask */
|
||||
#define TCP_FLAG_CWR (1 << 7)
|
||||
|
||||
/** Explicit Congestion Notification TCP flag mask */
|
||||
#define TCP_FLAG_ECE (1 << 6)
|
||||
|
||||
/** Urgent TCP flag mask */
|
||||
#define TCP_FLAG_URG (1 << 5)
|
||||
|
||||
/** Data Acknowledge TCP flag mask */
|
||||
#define TCP_FLAG_ACK (1 << 4)
|
||||
|
||||
/** Data Push TCP flag mask */
|
||||
#define TCP_FLAG_PSH (1 << 3)
|
||||
|
||||
/** Reset TCP flag mask */
|
||||
#define TCP_FLAG_RST (1 << 2)
|
||||
|
||||
/** Synchronize TCP flag mask */
|
||||
#define TCP_FLAG_SYN (1 << 1)
|
||||
|
||||
/** Connection Finalize TCP flag mask */
|
||||
#define TCP_FLAG_FIN (1 << 0)
|
||||
|
||||
/** Application macro: Determines if the given application buffer contains a packet received from the host
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer contains a packet from the host, false otherwise
|
||||
*/
|
||||
#define TCP_APP_HAS_RECEIVED_PACKET(Buffer) (Buffer->Ready && (Buffer->Direction == TCP_PACKETDIR_IN))
|
||||
|
||||
/** Application macro: Indicates if the application buffer is currently locked by the application for device-to-host transfers.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer has been captured by the application for device-to-host transmissions, false otherwise
|
||||
*/
|
||||
#define TCP_APP_HAVE_CAPTURED_BUFFER(Buffer) (!(Buffer->Ready) && Buffer->InUse && \
|
||||
(Buffer->Direction == TCP_PACKETDIR_OUT))
|
||||
|
||||
/** Application macro: Indicates if the application can lock the buffer for multiple continued device-to-host transmissions.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer may be captured by the application for device-to-host transmissions, false otherwise
|
||||
*/
|
||||
#define TCP_APP_CAN_CAPTURE_BUFFER(Buffer) Buffer->InUse
|
||||
|
||||
/** Application macro: Captures the application buffer, locking it for device-to-host transmissions only. This should be
|
||||
* performed when the application needs to transmit several packets worth of data in succession with no interruptions from the host.
|
||||
*
|
||||
* \note The application must check that the buffer can be locked first using TCP_APP_CAN_CAPTURE_BUFFER().
|
||||
*
|
||||
* \param[in] Buffer Application buffer to lock
|
||||
*/
|
||||
#define TCP_APP_CAPTURE_BUFFER(Buffer) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->InUse = true; }MACROE
|
||||
|
||||
/** Application macro: Releases a captured application buffer, allowing for host-to-device packets to be received.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to release
|
||||
*/
|
||||
#define TCP_APP_RELEASE_BUFFER(Buffer) MACROS{ Buffer->InUse = false; }MACROE
|
||||
|
||||
/** Application macro: Sends the contents of the given application buffer to the host.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to send
|
||||
* \param[in] Len Length of data contained in the buffer
|
||||
*/
|
||||
#define TCP_APP_SEND_BUFFER(Buffer, Len) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->Length = Len; Buffer->Ready = true; }MACROE
|
||||
|
||||
/** Application macro: Clears the application buffer, ready for a packet to be written to it.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to clear
|
||||
*/
|
||||
#define TCP_APP_CLEAR_BUFFER(Buffer) MACROS{ Buffer->Ready = false; Buffer->Length = 0; }MACROE
|
||||
|
||||
/** Application macro: Closes an open connection to a host.
|
||||
*
|
||||
* \param[in] Connection Open TCP connection to close
|
||||
*/
|
||||
#define TCP_APP_CLOSECONNECTION(Connection) MACROS{ Connection->State = TCP_Connection_Closing; }MACROE
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible TCP port states */
|
||||
enum TCP_PortStates_t
|
||||
{
|
||||
TCP_Port_Closed = 0, /**< TCP port closed, no connections to a host may be made on this port. */
|
||||
TCP_Port_Open = 1, /**< TCP port open, connections to a host may be made on this port. */
|
||||
};
|
||||
|
||||
/** Enum for possible TCP connection states */
|
||||
enum TCP_ConnectionStates_t
|
||||
{
|
||||
TCP_Connection_Listen = 0, /**< Listening for a connection from a host */
|
||||
TCP_Connection_SYNSent = 1, /**< Unused */
|
||||
TCP_Connection_SYNReceived = 2, /**< SYN received, waiting for ACK */
|
||||
TCP_Connection_Established = 3, /**< Connection established in both directions */
|
||||
TCP_Connection_FINWait1 = 4, /**< Closing, waiting for ACK */
|
||||
TCP_Connection_FINWait2 = 5, /**< Closing, waiting for FIN ACK */
|
||||
TCP_Connection_CloseWait = 6, /**< Closing, waiting for ACK */
|
||||
TCP_Connection_Closing = 7, /**< Unused */
|
||||
TCP_Connection_LastACK = 8, /**< Unused */
|
||||
TCP_Connection_TimeWait = 9, /**< Unused */
|
||||
TCP_Connection_Closed = 10, /**< Connection closed in both directions */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a TCP connection buffer structure, including size, data and direction */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Length; /**< Length of data in the TCP application buffer */
|
||||
uint8_t Data[TCP_WINDOW_SIZE]; /**< TCP application data buffer */
|
||||
bool Direction; /**< Buffer transmission direction, either TCP_PACKETDIR_IN or TCP_PACKETDIR_OUT */
|
||||
bool Ready; /**< If data from host, indicates buffer ready to be read, otherwise indicates
|
||||
* buffer ready to be sent to the host
|
||||
*/
|
||||
bool InUse; /** Indicates if the buffer is locked to to the current direction, and cannot be changed */
|
||||
} TCP_ConnectionBuffer_t;
|
||||
|
||||
/** Type define for a TCP connection information structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t SequenceNumberIn; /**< Current TCP sequence number for host-to-device */
|
||||
uint32_t SequenceNumberOut; /**< Current TCP sequence number for device-to-host */
|
||||
TCP_ConnectionBuffer_t Buffer; /**< Connection application data buffer */
|
||||
} TCP_ConnectionInfo_t;
|
||||
|
||||
/** Type define for a complete TCP connection state */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Port; /**< Connection port number on the device */
|
||||
uint16_t RemotePort; /**< Connection port number on the host */
|
||||
IP_Address_t RemoteAddress; /**< Connection protocol IP address of the host */
|
||||
TCP_ConnectionInfo_t Info; /**< Connection information, including application buffer */
|
||||
uint8_t State; /**< Current connection state, a value from the TCP_ConnectionStates_t enum */
|
||||
} TCP_ConnectionState_t;
|
||||
|
||||
/** Type define for a TCP port state */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Port; /**< TCP port number on the device */
|
||||
uint8_t State; /**< Current port state, a value from the TCP_PortStates_t enum */
|
||||
void (*ApplicationHandler) (TCP_ConnectionState_t* ConnectionState,
|
||||
TCP_ConnectionBuffer_t* Buffer); /**< Port application handler */
|
||||
} TCP_PortState_t;
|
||||
|
||||
/** Type define for a TCP packet header */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t SourcePort; /**< Source port of the TCP packet */
|
||||
uint16_t DestinationPort; /**< Destination port of the TCP packet */
|
||||
|
||||
uint32_t SequenceNumber; /**< Data sequence number of the packet */
|
||||
uint32_t AcknowledgmentNumber; /**< Data acknowledgment number of the packet */
|
||||
|
||||
unsigned char Reserved : 4; /**< Reserved, must be all 0 */
|
||||
unsigned char DataOffset : 4; /**< Offset of the data from the start of the header, in 4 byte chunks */
|
||||
uint8_t Flags; /**< TCP packet flags */
|
||||
uint16_t WindowSize; /**< Current data window size (bytes remaining in reception buffer) */
|
||||
|
||||
uint16_t Checksum; /**< TCP checksum */
|
||||
uint16_t UrgentPointer; /**< Urgent data pointer */
|
||||
} TCP_Header_t;
|
||||
|
||||
/* External Variables: */
|
||||
TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
|
||||
|
||||
/* Function Prototypes: */
|
||||
void TCP_Init(void);
|
||||
void TCP_Task(void);
|
||||
bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
|
||||
uint8_t TCP_GetPortState(uint16_t Port);
|
||||
bool TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State);
|
||||
uint8_t TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);
|
||||
TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);
|
||||
int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart);
|
||||
|
||||
#if defined(INCLUDE_FROM_TCP_C)
|
||||
static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,
|
||||
IP_Address_t DestinationAddress, uint16_t TCPOutSize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 TCP.c.
|
||||
*/
|
||||
|
||||
#ifndef _TCP_H_
|
||||
#define _TCP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Maximum number of TCP ports which can be open at the one time */
|
||||
#define MAX_OPEN_TCP_PORTS 1
|
||||
|
||||
/** Maximum number of TCP connections which can be sustained at the one time */
|
||||
#define MAX_TCP_CONNECTIONS 3
|
||||
|
||||
/** TCP window size, giving the maximum number of bytes which can be buffered at the one time */
|
||||
#define TCP_WINDOW_SIZE 512
|
||||
|
||||
/** Port number for HTTP transmissions */
|
||||
#define TCP_PORT_HTTP SwapEndian_16(80)
|
||||
|
||||
/** Data direction indicator for a TCP application buffer, indicating data from host-to-device */
|
||||
#define TCP_PACKETDIR_IN false
|
||||
|
||||
/** Data direction indicator for a TCP application buffer, indicating data from device-to-host */
|
||||
#define TCP_PACKETDIR_OUT true
|
||||
|
||||
/** Congestion Window Reduced TCP flag mask */
|
||||
#define TCP_FLAG_CWR (1 << 7)
|
||||
|
||||
/** Explicit Congestion Notification TCP flag mask */
|
||||
#define TCP_FLAG_ECE (1 << 6)
|
||||
|
||||
/** Urgent TCP flag mask */
|
||||
#define TCP_FLAG_URG (1 << 5)
|
||||
|
||||
/** Data Acknowledge TCP flag mask */
|
||||
#define TCP_FLAG_ACK (1 << 4)
|
||||
|
||||
/** Data Push TCP flag mask */
|
||||
#define TCP_FLAG_PSH (1 << 3)
|
||||
|
||||
/** Reset TCP flag mask */
|
||||
#define TCP_FLAG_RST (1 << 2)
|
||||
|
||||
/** Synchronize TCP flag mask */
|
||||
#define TCP_FLAG_SYN (1 << 1)
|
||||
|
||||
/** Connection Finalize TCP flag mask */
|
||||
#define TCP_FLAG_FIN (1 << 0)
|
||||
|
||||
/** Application macro: Determines if the given application buffer contains a packet received from the host
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer contains a packet from the host, false otherwise
|
||||
*/
|
||||
#define TCP_APP_HAS_RECEIVED_PACKET(Buffer) (Buffer->Ready && (Buffer->Direction == TCP_PACKETDIR_IN))
|
||||
|
||||
/** Application macro: Indicates if the application buffer is currently locked by the application for device-to-host transfers.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer has been captured by the application for device-to-host transmissions, false otherwise
|
||||
*/
|
||||
#define TCP_APP_HAVE_CAPTURED_BUFFER(Buffer) (!(Buffer->Ready) && Buffer->InUse && \
|
||||
(Buffer->Direction == TCP_PACKETDIR_OUT))
|
||||
|
||||
/** Application macro: Indicates if the application can lock the buffer for multiple continued device-to-host transmissions.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to check
|
||||
*
|
||||
* \return Boolean true if the buffer may be captured by the application for device-to-host transmissions, false otherwise
|
||||
*/
|
||||
#define TCP_APP_CAN_CAPTURE_BUFFER(Buffer) Buffer->InUse
|
||||
|
||||
/** Application macro: Captures the application buffer, locking it for device-to-host transmissions only. This should be
|
||||
* performed when the application needs to transmit several packets worth of data in succession with no interruptions from the host.
|
||||
*
|
||||
* \note The application must check that the buffer can be locked first using TCP_APP_CAN_CAPTURE_BUFFER().
|
||||
*
|
||||
* \param[in] Buffer Application buffer to lock
|
||||
*/
|
||||
#define TCP_APP_CAPTURE_BUFFER(Buffer) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->InUse = true; }MACROE
|
||||
|
||||
/** Application macro: Releases a captured application buffer, allowing for host-to-device packets to be received.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to release
|
||||
*/
|
||||
#define TCP_APP_RELEASE_BUFFER(Buffer) MACROS{ Buffer->InUse = false; }MACROE
|
||||
|
||||
/** Application macro: Sends the contents of the given application buffer to the host.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to send
|
||||
* \param[in] Len Length of data contained in the buffer
|
||||
*/
|
||||
#define TCP_APP_SEND_BUFFER(Buffer, Len) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->Length = Len; Buffer->Ready = true; }MACROE
|
||||
|
||||
/** Application macro: Clears the application buffer, ready for a packet to be written to it.
|
||||
*
|
||||
* \param[in] Buffer Application buffer to clear
|
||||
*/
|
||||
#define TCP_APP_CLEAR_BUFFER(Buffer) MACROS{ Buffer->Ready = false; Buffer->Length = 0; }MACROE
|
||||
|
||||
/** Application macro: Closes an open connection to a host.
|
||||
*
|
||||
* \param[in] Connection Open TCP connection to close
|
||||
*/
|
||||
#define TCP_APP_CLOSECONNECTION(Connection) MACROS{ Connection->State = TCP_Connection_Closing; }MACROE
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for possible TCP port states */
|
||||
enum TCP_PortStates_t
|
||||
{
|
||||
TCP_Port_Closed = 0, /**< TCP port closed, no connections to a host may be made on this port. */
|
||||
TCP_Port_Open = 1, /**< TCP port open, connections to a host may be made on this port. */
|
||||
};
|
||||
|
||||
/** Enum for possible TCP connection states */
|
||||
enum TCP_ConnectionStates_t
|
||||
{
|
||||
TCP_Connection_Listen = 0, /**< Listening for a connection from a host */
|
||||
TCP_Connection_SYNSent = 1, /**< Unused */
|
||||
TCP_Connection_SYNReceived = 2, /**< SYN received, waiting for ACK */
|
||||
TCP_Connection_Established = 3, /**< Connection established in both directions */
|
||||
TCP_Connection_FINWait1 = 4, /**< Closing, waiting for ACK */
|
||||
TCP_Connection_FINWait2 = 5, /**< Closing, waiting for FIN ACK */
|
||||
TCP_Connection_CloseWait = 6, /**< Closing, waiting for ACK */
|
||||
TCP_Connection_Closing = 7, /**< Unused */
|
||||
TCP_Connection_LastACK = 8, /**< Unused */
|
||||
TCP_Connection_TimeWait = 9, /**< Unused */
|
||||
TCP_Connection_Closed = 10, /**< Connection closed in both directions */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a TCP connection buffer structure, including size, data and direction */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Length; /**< Length of data in the TCP application buffer */
|
||||
uint8_t Data[TCP_WINDOW_SIZE]; /**< TCP application data buffer */
|
||||
bool Direction; /**< Buffer transmission direction, either TCP_PACKETDIR_IN or TCP_PACKETDIR_OUT */
|
||||
bool Ready; /**< If data from host, indicates buffer ready to be read, otherwise indicates
|
||||
* buffer ready to be sent to the host
|
||||
*/
|
||||
bool InUse; /** Indicates if the buffer is locked to to the current direction, and cannot be changed */
|
||||
} TCP_ConnectionBuffer_t;
|
||||
|
||||
/** Type define for a TCP connection information structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t SequenceNumberIn; /**< Current TCP sequence number for host-to-device */
|
||||
uint32_t SequenceNumberOut; /**< Current TCP sequence number for device-to-host */
|
||||
TCP_ConnectionBuffer_t Buffer; /**< Connection application data buffer */
|
||||
} TCP_ConnectionInfo_t;
|
||||
|
||||
/** Type define for a complete TCP connection state */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Port; /**< Connection port number on the device */
|
||||
uint16_t RemotePort; /**< Connection port number on the host */
|
||||
IP_Address_t RemoteAddress; /**< Connection protocol IP address of the host */
|
||||
TCP_ConnectionInfo_t Info; /**< Connection information, including application buffer */
|
||||
uint8_t State; /**< Current connection state, a value from the TCP_ConnectionStates_t enum */
|
||||
} TCP_ConnectionState_t;
|
||||
|
||||
/** Type define for a TCP port state */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Port; /**< TCP port number on the device */
|
||||
uint8_t State; /**< Current port state, a value from the TCP_PortStates_t enum */
|
||||
void (*ApplicationHandler) (TCP_ConnectionState_t* ConnectionState,
|
||||
TCP_ConnectionBuffer_t* Buffer); /**< Port application handler */
|
||||
} TCP_PortState_t;
|
||||
|
||||
/** Type define for a TCP packet header */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t SourcePort; /**< Source port of the TCP packet */
|
||||
uint16_t DestinationPort; /**< Destination port of the TCP packet */
|
||||
|
||||
uint32_t SequenceNumber; /**< Data sequence number of the packet */
|
||||
uint32_t AcknowledgmentNumber; /**< Data acknowledgment number of the packet */
|
||||
|
||||
unsigned char Reserved : 4; /**< Reserved, must be all 0 */
|
||||
unsigned char DataOffset : 4; /**< Offset of the data from the start of the header, in 4 byte chunks */
|
||||
uint8_t Flags; /**< TCP packet flags */
|
||||
uint16_t WindowSize; /**< Current data window size (bytes remaining in reception buffer) */
|
||||
|
||||
uint16_t Checksum; /**< TCP checksum */
|
||||
uint16_t UrgentPointer; /**< Urgent data pointer */
|
||||
} TCP_Header_t;
|
||||
|
||||
/* External Variables: */
|
||||
TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
|
||||
|
||||
/* Function Prototypes: */
|
||||
void TCP_Init(void);
|
||||
void TCP_Task(void);
|
||||
bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
|
||||
uint8_t TCP_GetPortState(uint16_t Port);
|
||||
bool TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State);
|
||||
uint8_t TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);
|
||||
TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);
|
||||
int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart);
|
||||
|
||||
#if defined(INCLUDE_FROM_TCP_C)
|
||||
static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,
|
||||
IP_Address_t DestinationAddress, uint16_t TCPOutSize);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* User Datagram Protocol (UDP) packet handling routines. This protocol handles high throughput, low
|
||||
* reliability packets which are typically used to encapsulate streaming data.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_UDP_C
|
||||
#include "UDP.h"
|
||||
|
||||
/** Processes a UDP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if a sub-protocol handler has created a response packet.
|
||||
*
|
||||
* \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[in] UDPHeaderInStart Pointer to the start of the incoming packet's UDP header
|
||||
* \param[out] UDPHeaderOutStart Pointer to the start of the outgoing packet's UDP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart)
|
||||
{
|
||||
UDP_Header_t* UDPHeaderIN = (UDP_Header_t*)UDPHeaderInStart;
|
||||
UDP_Header_t* UDPHeaderOUT = (UDP_Header_t*)UDPHeaderOutStart;
|
||||
|
||||
int16_t RetSize = NO_RESPONSE;
|
||||
|
||||
DecodeUDPHeader(UDPHeaderInStart);
|
||||
|
||||
switch (SwapEndian_16(UDPHeaderIN->DestinationPort))
|
||||
{
|
||||
case UDP_PORT_DHCP_REQUEST:
|
||||
RetSize = DHCP_ProcessDHCPPacket(IPHeaderInStart,
|
||||
&((uint8_t*)UDPHeaderInStart)[sizeof(UDP_Header_t)],
|
||||
&((uint8_t*)UDPHeaderOutStart)[sizeof(UDP_Header_t)]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to see if the protocol processing routine has filled out a response */
|
||||
if (RetSize > 0)
|
||||
{
|
||||
/* Fill out the response UDP packet header */
|
||||
UDPHeaderOUT->SourcePort = UDPHeaderIN->DestinationPort;
|
||||
UDPHeaderOUT->DestinationPort = UDPHeaderIN->SourcePort;
|
||||
UDPHeaderOUT->Checksum = 0;
|
||||
UDPHeaderOUT->Length = SwapEndian_16(sizeof(UDP_Header_t) + RetSize);
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (sizeof(UDP_Header_t) + RetSize);
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* User Datagram Protocol (UDP) packet handling routines. This protocol handles high throughput, low
|
||||
* reliability packets which are typically used to encapsulate streaming data.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_UDP_C
|
||||
#include "UDP.h"
|
||||
|
||||
/** Processes a UDP packet inside an Ethernet frame, and writes the appropriate response
|
||||
* to the output Ethernet frame if a sub-protocol handler has created a response packet.
|
||||
*
|
||||
* \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header
|
||||
* \param[in] UDPHeaderInStart Pointer to the start of the incoming packet's UDP header
|
||||
* \param[out] UDPHeaderOutStart Pointer to the start of the outgoing packet's UDP header
|
||||
*
|
||||
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
|
||||
*/
|
||||
int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart)
|
||||
{
|
||||
UDP_Header_t* UDPHeaderIN = (UDP_Header_t*)UDPHeaderInStart;
|
||||
UDP_Header_t* UDPHeaderOUT = (UDP_Header_t*)UDPHeaderOutStart;
|
||||
|
||||
int16_t RetSize = NO_RESPONSE;
|
||||
|
||||
DecodeUDPHeader(UDPHeaderInStart);
|
||||
|
||||
switch (SwapEndian_16(UDPHeaderIN->DestinationPort))
|
||||
{
|
||||
case UDP_PORT_DHCP_REQUEST:
|
||||
RetSize = DHCP_ProcessDHCPPacket(IPHeaderInStart,
|
||||
&((uint8_t*)UDPHeaderInStart)[sizeof(UDP_Header_t)],
|
||||
&((uint8_t*)UDPHeaderOutStart)[sizeof(UDP_Header_t)]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to see if the protocol processing routine has filled out a response */
|
||||
if (RetSize > 0)
|
||||
{
|
||||
/* Fill out the response UDP packet header */
|
||||
UDPHeaderOUT->SourcePort = UDPHeaderIN->DestinationPort;
|
||||
UDPHeaderOUT->DestinationPort = UDPHeaderIN->SourcePort;
|
||||
UDPHeaderOUT->Checksum = 0;
|
||||
UDPHeaderOUT->Length = SwapEndian_16(sizeof(UDP_Header_t) + RetSize);
|
||||
|
||||
/* Return the size of the response so far */
|
||||
return (sizeof(UDP_Header_t) + RetSize);
|
||||
}
|
||||
|
||||
return NO_RESPONSE;
|
||||
}
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 IP.c.
|
||||
*/
|
||||
|
||||
#ifndef _UDP_H_
|
||||
#define _UDP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
#include "DHCP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Source UDP port for a DHCP request */
|
||||
#define UDP_PORT_DHCP_REQUEST 67
|
||||
|
||||
/** Destination UDP port for a DHCP reply */
|
||||
#define UDP_PORT_DHCP_REPLY 68
|
||||
|
||||
/** Source UDP port for a DNS request/response */
|
||||
#define UDP_PORT_DNS 53
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a UDP packet header */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t SourcePort; /**< Packet source port */
|
||||
uint16_t DestinationPort; /**< Packet destination port */
|
||||
uint16_t Length; /**< Total packet length, in bytes */
|
||||
uint16_t Checksum; /**< Optional UDP packet checksum */
|
||||
} UDP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 IP.c.
|
||||
*/
|
||||
|
||||
#ifndef _UDP_H_
|
||||
#define _UDP_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "EthernetProtocols.h"
|
||||
#include "Ethernet.h"
|
||||
#include "ProtocolDecoders.h"
|
||||
#include "DHCP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Source UDP port for a DHCP request */
|
||||
#define UDP_PORT_DHCP_REQUEST 67
|
||||
|
||||
/** Destination UDP port for a DHCP reply */
|
||||
#define UDP_PORT_DHCP_REPLY 68
|
||||
|
||||
/** Source UDP port for a DNS request/response */
|
||||
#define UDP_PORT_DNS 53
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a UDP packet header */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t SourcePort; /**< Packet source port */
|
||||
uint16_t DestinationPort; /**< Packet destination port */
|
||||
uint16_t Length; /**< Total packet length, in bytes */
|
||||
uint16_t Checksum; /**< Optional UDP packet checksum */
|
||||
} UDP_Header_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,200 +1,200 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Simple webserver application for demonstrating the RNDIS demo and TCP/IP stack. This
|
||||
* application will serve up a static HTTP webpage when requested by the host.
|
||||
*/
|
||||
|
||||
#include "Webserver.h"
|
||||
|
||||
/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the
|
||||
* given location, and gives extra connection information.
|
||||
*/
|
||||
char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"
|
||||
"Server: LUFA RNDIS\r\n"
|
||||
"Content-type: text/html\r\n"
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given
|
||||
* given URL is invalid, and gives extra error information.
|
||||
*/
|
||||
char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"
|
||||
"Server: LUFA RNDIS\r\n"
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
/** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically
|
||||
* broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run.
|
||||
*/
|
||||
char PROGMEM HTTPPage[] =
|
||||
"<html>"
|
||||
" <head>"
|
||||
" <title>"
|
||||
" LUFA Webserver Demo"
|
||||
" </title>"
|
||||
" </head>"
|
||||
" <body>"
|
||||
" <h1>Hello from your USB AVR!</h1>"
|
||||
" <p>"
|
||||
" Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack."
|
||||
" <br /><br />"
|
||||
" <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"
|
||||
" <hr />"
|
||||
" <i>LUFA Version: </i>" LUFA_VERSION_STRING
|
||||
" </p>"
|
||||
" </body>"
|
||||
"</html>";
|
||||
|
||||
|
||||
/** Initializes the Webserver application, opening the appropriate HTTP port in the TCP handler and registering the application
|
||||
* callback routine for packets sent to the HTTP protocol port.
|
||||
*/
|
||||
void Webserver_Init(void)
|
||||
{
|
||||
/* Open the HTTP port in the TCP protocol so that HTTP connections to the device can be established */
|
||||
TCP_SetPortState(TCP_PORT_HTTP, TCP_Port_Open, Webserver_ApplicationCallback);
|
||||
}
|
||||
|
||||
/** Indicates if a given request equals the given HTTP command.
|
||||
*
|
||||
* \param[in] RequestHeader HTTP request made by the host
|
||||
* \param[in] Command HTTP command to compare the request to
|
||||
*
|
||||
* \return Boolean true if the command matches the request, false otherwise
|
||||
*/
|
||||
static bool IsHTTPCommand(uint8_t* RequestHeader, char* Command)
|
||||
{
|
||||
/* Returns true if the non null terminated string in RequestHeader matches the null terminated string Command */
|
||||
return (strncmp((char*)RequestHeader, Command, strlen(Command)) == 0);
|
||||
}
|
||||
|
||||
/** Application callback routine, executed each time the TCP processing task runs. This callback determines what request
|
||||
* has been made (if any), and serves up appropriate responses.
|
||||
*
|
||||
* \param[in] ConnectionState Pointer to a TCP Connection State structure giving connection information
|
||||
* \param[in,out] Buffer Pointer to the application's send/receive packet buffer
|
||||
*/
|
||||
void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer)
|
||||
{
|
||||
char* BufferDataStr = (char*)Buffer->Data;
|
||||
static uint8_t PageBlock = 0;
|
||||
|
||||
/* Check to see if a packet has been received on the HTTP port from a remote host */
|
||||
if (TCP_APP_HAS_RECEIVED_PACKET(Buffer))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "GET"))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "GET / "))
|
||||
{
|
||||
PageBlock = 0;
|
||||
|
||||
/* Copy the HTTP 200 response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP200Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
|
||||
/* Lock the buffer to Device->Host transmissions only while we send the page contents */
|
||||
TCP_APP_CAPTURE_BUFFER(Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the HTTP 404 response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP404Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
}
|
||||
else if (IsHTTPCommand(Buffer->Data, "HEAD"))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "HEAD / "))
|
||||
{
|
||||
/* Copy the HTTP response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP200Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the HTTP response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP404Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
}
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
else if (IsHTTPCommand(Buffer->Data, "TRACE"))
|
||||
{
|
||||
/* Echo the host's query back to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, Buffer->Length);
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown request, just clear the buffer (drop the packet) */
|
||||
TCP_APP_CLEAR_BUFFER(Buffer);
|
||||
}
|
||||
}
|
||||
else if (TCP_APP_HAVE_CAPTURED_BUFFER(Buffer))
|
||||
{
|
||||
uint16_t RemLength = strlen_P(&HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE]);
|
||||
uint16_t Length;
|
||||
|
||||
/* Determine the length of the loaded block */
|
||||
Length = ((RemLength > HTTP_REPLY_BLOCK_SIZE) ? HTTP_REPLY_BLOCK_SIZE : RemLength);
|
||||
|
||||
/* Copy the next buffer sized block of the page to the packet buffer */
|
||||
strncpy_P(BufferDataStr, &HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE], Length);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, Length);
|
||||
|
||||
/* Check to see if the entire page has been sent */
|
||||
if (PageBlock++ == (sizeof(HTTPPage) / HTTP_REPLY_BLOCK_SIZE))
|
||||
{
|
||||
/* Unlock the buffer so that the host can fill it with future packets */
|
||||
TCP_APP_RELEASE_BUFFER(Buffer);
|
||||
|
||||
/* Close the connection to the host */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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
|
||||
*
|
||||
* Simple webserver application for demonstrating the RNDIS demo and TCP/IP stack. This
|
||||
* application will serve up a static HTTP webpage when requested by the host.
|
||||
*/
|
||||
|
||||
#include "Webserver.h"
|
||||
|
||||
/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the
|
||||
* given location, and gives extra connection information.
|
||||
*/
|
||||
char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"
|
||||
"Server: LUFA RNDIS\r\n"
|
||||
"Content-type: text/html\r\n"
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given
|
||||
* given URL is invalid, and gives extra error information.
|
||||
*/
|
||||
char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"
|
||||
"Server: LUFA RNDIS\r\n"
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
/** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically
|
||||
* broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run.
|
||||
*/
|
||||
char PROGMEM HTTPPage[] =
|
||||
"<html>"
|
||||
" <head>"
|
||||
" <title>"
|
||||
" LUFA Webserver Demo"
|
||||
" </title>"
|
||||
" </head>"
|
||||
" <body>"
|
||||
" <h1>Hello from your USB AVR!</h1>"
|
||||
" <p>"
|
||||
" Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack."
|
||||
" <br /><br />"
|
||||
" <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"
|
||||
" <hr />"
|
||||
" <i>LUFA Version: </i>" LUFA_VERSION_STRING
|
||||
" </p>"
|
||||
" </body>"
|
||||
"</html>";
|
||||
|
||||
|
||||
/** Initializes the Webserver application, opening the appropriate HTTP port in the TCP handler and registering the application
|
||||
* callback routine for packets sent to the HTTP protocol port.
|
||||
*/
|
||||
void Webserver_Init(void)
|
||||
{
|
||||
/* Open the HTTP port in the TCP protocol so that HTTP connections to the device can be established */
|
||||
TCP_SetPortState(TCP_PORT_HTTP, TCP_Port_Open, Webserver_ApplicationCallback);
|
||||
}
|
||||
|
||||
/** Indicates if a given request equals the given HTTP command.
|
||||
*
|
||||
* \param[in] RequestHeader HTTP request made by the host
|
||||
* \param[in] Command HTTP command to compare the request to
|
||||
*
|
||||
* \return Boolean true if the command matches the request, false otherwise
|
||||
*/
|
||||
static bool IsHTTPCommand(uint8_t* RequestHeader, char* Command)
|
||||
{
|
||||
/* Returns true if the non null terminated string in RequestHeader matches the null terminated string Command */
|
||||
return (strncmp((char*)RequestHeader, Command, strlen(Command)) == 0);
|
||||
}
|
||||
|
||||
/** Application callback routine, executed each time the TCP processing task runs. This callback determines what request
|
||||
* has been made (if any), and serves up appropriate responses.
|
||||
*
|
||||
* \param[in] ConnectionState Pointer to a TCP Connection State structure giving connection information
|
||||
* \param[in,out] Buffer Pointer to the application's send/receive packet buffer
|
||||
*/
|
||||
void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer)
|
||||
{
|
||||
char* BufferDataStr = (char*)Buffer->Data;
|
||||
static uint8_t PageBlock = 0;
|
||||
|
||||
/* Check to see if a packet has been received on the HTTP port from a remote host */
|
||||
if (TCP_APP_HAS_RECEIVED_PACKET(Buffer))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "GET"))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "GET / "))
|
||||
{
|
||||
PageBlock = 0;
|
||||
|
||||
/* Copy the HTTP 200 response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP200Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
|
||||
/* Lock the buffer to Device->Host transmissions only while we send the page contents */
|
||||
TCP_APP_CAPTURE_BUFFER(Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the HTTP 404 response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP404Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
}
|
||||
else if (IsHTTPCommand(Buffer->Data, "HEAD"))
|
||||
{
|
||||
if (IsHTTPCommand(Buffer->Data, "HEAD / "))
|
||||
{
|
||||
/* Copy the HTTP response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP200Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the HTTP response header into the packet buffer */
|
||||
strcpy_P(BufferDataStr, HTTP404Header);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
|
||||
}
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
else if (IsHTTPCommand(Buffer->Data, "TRACE"))
|
||||
{
|
||||
/* Echo the host's query back to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, Buffer->Length);
|
||||
|
||||
/* All data sent, close the connection */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown request, just clear the buffer (drop the packet) */
|
||||
TCP_APP_CLEAR_BUFFER(Buffer);
|
||||
}
|
||||
}
|
||||
else if (TCP_APP_HAVE_CAPTURED_BUFFER(Buffer))
|
||||
{
|
||||
uint16_t RemLength = strlen_P(&HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE]);
|
||||
uint16_t Length;
|
||||
|
||||
/* Determine the length of the loaded block */
|
||||
Length = ((RemLength > HTTP_REPLY_BLOCK_SIZE) ? HTTP_REPLY_BLOCK_SIZE : RemLength);
|
||||
|
||||
/* Copy the next buffer sized block of the page to the packet buffer */
|
||||
strncpy_P(BufferDataStr, &HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE], Length);
|
||||
|
||||
/* Send the buffer contents to the host */
|
||||
TCP_APP_SEND_BUFFER(Buffer, Length);
|
||||
|
||||
/* Check to see if the entire page has been sent */
|
||||
if (PageBlock++ == (sizeof(HTTPPage) / HTTP_REPLY_BLOCK_SIZE))
|
||||
{
|
||||
/* Unlock the buffer so that the host can fill it with future packets */
|
||||
TCP_APP_RELEASE_BUFFER(Buffer);
|
||||
|
||||
/* Close the connection to the host */
|
||||
TCP_APP_CLOSECONNECTION(ConnectionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 Webserver.c.
|
||||
*/
|
||||
|
||||
#ifndef _WEBSERVER_H_
|
||||
#define _WEBSERVER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Maximum size of a HTTP response per transmission */
|
||||
#define HTTP_REPLY_BLOCK_SIZE 128
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Webserver_Init(void);
|
||||
void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 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 Webserver.c.
|
||||
*/
|
||||
|
||||
#ifndef _WEBSERVER_H_
|
||||
#define _WEBSERVER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
|
||||
#include "TCP.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Maximum size of a HTTP response per transmission */
|
||||
#define HTTP_REPLY_BLOCK_SIZE 128
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Webserver_Init(void);
|
||||
void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue