/** 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 of data
 */
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"), FrameINData->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]);

	printf_P(PSTR("  + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));
	#endif
}
Example #2
0
/** 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
}
Example #3
0
/** 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;
}