⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernet.c

📁 ixp2400的一个小程序
💻 C
字号:
//  Copyright (C) 2002-2003 Intel Corporation, All Rights Reserved.
//  Permission is hereby granted to merge this program code with 
//  other program material to create a derivative work.  This 
//  derivative work may be distributed in compiled object form only.
//  Any other publication of this program, in any form, without the 
//  explicit permission of the copyright holder is prohibited.
//
//  Send questions and comments to erik.j.johnson@intel.com, 
//  aaron.kunze@intel.com
//-------------------------------------------------------------------
// ethernet.c - Chapter 6
// This file implements functions to process Ethernet II packets.
//

#include <dl_buf.c>
#include <dl_source.h>
#include "ethernet.h"
#include "ethernet_internal.h"

// Some Ethernet basics to be used for validating the packet
// and checking Ethernet fields
#define MIN_ETHERNET_LENGTH		64
#define MAX_ETHERNET_LENGTH		158
#define ETHERNET_ADDR_SIZE		6
#define ETHERNET_HEADER_SIZE	14

// The format of the Ethernet packet header
typedef __declspec(packed) struct _ethernet_header
{
	unsigned int destination_addr_hi32; 
	unsigned int destination_addr_lo16 : 16; 
	unsigned int source_addr_hi16      : 16;
	unsigned int source_addr_lo32;
	short protocol;
} ethernet_header;

extern dl_buf_handle_t			dlBufHandle;
extern dl_meta_t				dlMeta;
extern __declspec(gp_reg) int 	dlNextBlock;

//-------------------------------------------------------------------
// ethernet_init
//
//    Description:
//      Sets up any global settings needed to run any of the
//      Ethernet functions.  This needs to be called only
//		once.  Right now all it does is set up the hash
//		multiplier.
//
//    Parameters:
//		None.
//
//    Side effects: Hash multiplier is set.
//
//    See also: n/a
//
//    Example Usage: ethernet_init();
//
void ethernet_init()
{
}

//-------------------------------------------------------------------
// ethernet_validate
//
//    Description:
//      Verifies that the passed in packet is long enough to be an
//		Ethernet II packet and has a valid source MAC address.
//		Also tells the caller if the packet is addressed to the 
//		local address, a multicast address, and/or a broadcast 
//		address.  The local address is determined from a place in 
//		SRAM that is set by the XScale core.
//
//    Parameters:
//      n/a
//
//    Side effects: n/a
//
//    See also: n/a
//
//    Example Usage: ethernet_validate()
//
void ethernet_validate()
{
	ethernet_header header;
	int i = 0;
	__declspec(sram) ethernet_control_block *control = 
		(__declspec(sram) ethernet_control_block*)
			(ETHERNET_DATA);

	// Check the packet length
	if (dlMeta.bufferSize < MIN_ETHERNET_LENGTH ||
		dlMeta.bufferSize > MAX_ETHERNET_LENGTH)
	{
		dlNextBlock = ETHERNET_VALIDATE_INVALID;
		return;
	}

	// Now, get the Ethernet header
	header = *(__declspec(dram) ethernet_header*)
	            (Dl_BufGetData(dlBufHandle) + 
	             dlMeta.offset);

	/*// Check for a broadcast or multicast source address
	if ((header.source_addr_hi16 >> 8) & 0x1)
	{
		dlNextBlock = ETHERNET_VALIDATE_INVALID;
		return;
	}
*/
	// Check for broadcast or multicast destination address
	if ((header.destination_addr_hi32 >> 24) & 0x1)
	{
		if (header.destination_addr_hi32 != 0xffffffff &&
			header.destination_addr_lo16 != 0xffff)
		{
			dlNextBlock = ETHERNET_VALIDATE_MULTICAST;
			return;
		}
		dlNextBlock = ETHERNET_VALIDATE_BROADCAST;
		return;
	}

	// Check to see if the packet is locally addressed
/*	if (header.destination_addr_hi32 != 
							control->device_addr_hi32 &&
		header.destination_addr_lo16 != 
							control->device_addr_lo16)
	{
		dlNextBlock = ETHERNET_VALIDATE_OTHER;
		return;
	}
	*/
	dlNextBlock = ETHERNET_VALIDATE_LOCAL;
	return;
}

//-------------------------------------------------------------------
// ethernet_strip_header
//
//    Description:
//      Removes the Ethernet header from the packet puts
//		the Ethernet protocol number in dl_next_block.
//
//    Parameters:
//      n/a
//
//    Side effects: n/a
//
//    See also: n/a
//
//    Example Usage: ethernet_strip_header();
//
void ethernet_strip_header()
{
	ethernet_header header;

	// Get the ethernet header so we can extract the
	// protocol
	header = *(__declspec(dram) ethernet_header*)
	            (Dl_BufGetData(dlBufHandle) + 
	             dlMeta.offset);
	dlNextBlock = header.protocol;

	// Adjust the pointer and length
	dlMeta.bufferSize -= ETHERNET_HEADER_SIZE;
	dlMeta.offset += ETHERNET_HEADER_SIZE;
}

//-------------------------------------------------------------------
// ethernet_add_header
//
//    Description:
//      Adds an Ethernet header to an IP packet.  This function uses 
//		the next hop ID as an index into a table and retrieves a MAC 
//		address to put in the destination address of the Ethernet 
//		packet.  The source MAC address	is set to the MAC address of 
//		the device.  The Ethernet protocol number is passed in.
//
//    Parameters:
//      Inputs: eth_proto		 The Ethernet protocol number
//								 to insert in the packet.
//      Constants: n/a
//      Labels: n/a
//
//    Side effects: n/a
//
//    See also: n/a
//
//    Example Usage: ethernet_add_header(ETH_PROTO_IP)
//
void ethernet_add_header(unsigned int eth_proto)
{
	ethernet_arp_table_entry  table_entry;
	__declspec(sram) ethernet_control_block *control = 
		(__declspec(sram) ethernet_control_block*)
			(ETHERNET_DATA);
	unsigned int			  eth_address_hi32;
	unsigned int			  eth_address_lo16;
	bool					  found = 0;
	volatile	__declspec(dram) ethernet_header* 
			          header;
    //ethernet_header header;
	// Look up the next hop IP address in the array
	// in memory, using the next hop ID as the index.
	table_entry = 
			control->arp_table_array[dlMeta.nextHopId];

	// If the entry is not valid, drop this packet.
	if (!table_entry.valid)
	{
		//dl_set_exception(ETHERNET_EXCEPTION_ID ,0);
		dlNextBlock = IX_EXCEPTION;
		return;
	}

	eth_address_hi32 = 
			table_entry.ethernet_address_hi32;
	eth_address_lo16 = 
			table_entry.ethernet_address_lo16;

	// Since we found a MAC address, we can add the 
	// header
	dlMeta.bufferSize += ETHERNET_HEADER_SIZE;
	dlMeta.offset -= ETHERNET_HEADER_SIZE;

	header = (__declspec(dram) ethernet_header*)
            	(Dl_BufGetData(dlBufHandle) + 
	             dlMeta.offset);
 
	// Set the destination address in the header to be
	// the Ethernet address from the table.
	header->destination_addr_hi32 = eth_address_hi32;
	header->destination_addr_lo16 = eth_address_lo16;

	// Set the source address to be the device's MAC 
	// address
	header->source_addr_hi16 = 
			control->device_addr_hi32 >> 16;
	header->source_addr_lo32 = 
			(control->device_addr_hi32 << 16) |
			(control->device_addr_lo16);

	// Set the protocol number to be the passed in
	// protocol number
	header->protocol = eth_proto;

	dlNextBlock = ETHERNET_ADD_HEADER_PASS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -