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

📄 plugs.c

📁 altera epxa1的例子程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//
//
// Implementation of the plugs
// tcp/ip stack for embedded systems
//
//#define PLUGS_DEBUG 1
#include <stdio.h>
#include "nios_compatibility.h"
#include "plugs.h"
#include "plugs_private.h"



// +------------------------
// | Debug bit 4 means show debug on system plugs
// |

#if (PLUGS_DEBUG & 4)
	#define nk_plugs_default_debug (ne_plugs_flag_debug_tx | ne_plugs_flag_debug_rx)
#else
	#define nk_plugs_default_debug (0)
#endif

// +------------------------
// | Local Prototypes

static void r_add_to_arp_cache_from_ip_packet
		(
		s_plugs_adapter_entry *a,
		ns_plugs_ethernet_packet *p
		);

static void r_add_to_arp_cache
		(
		s_plugs_adapter_entry *a,
		net_32 ip_address,
		net_32 ethu32,net_16 ethl16
		);

static int r_plugs_dns_proc
		(
		int plug_handle,
		void *context,
		ns_plugs_packet *p,
		void *payload,
		int payload_length
		);

static int r_tcp_dispatch
		(
		s_plugs_adapter_entry *a,
		int plug_handle,
		s_plugs_plug *plug,
		ns_plugs_packet *sub_protocol,
		void *payload,
		int payload_length
		);

static int r_tcp_send
		(
		int plug_handle,
		s_plugs_plug *plug,
		int flags,
		void *payload,
		long payload_length
		);

static s_plugs_plug *r_plug_from_handle(int plug_handle);

// ---------------------------
// Byte-swapping subroutines

host_16 nr_n2h16(net_16 n)
	{
	return nm_n2h16(n);
	}

host_32 nr_n2h32(net_32 n)
	{
	return nm_n2h32(n);
	}



static s_plugs_plug *r_plug_from_handle(int plug_handle)
	{
	s_plugs_plug *plug;
	s_plugs_globals *g = &ng_plugs_globals;

	plug_handle -= nk_plugs_plug_number_base;
	plug = &g->plug[plug_handle];

	return plug;
	}

// --------------------
// r_calculate_checksum(base,byte_count,ip_header)
//
// Return complement of 1's-complement
// checksum of the specified range
// Return in network byte order.
//
// If ip_header pointer is included, add in
// the pseudo header as used by udp & tcp
// And possibly add in the (host-ordered)
// pseudo_length, too.
//

net_16 r_calculate_checksum(void *base,int byte_count,ns_plugs_ip_packet *ip_packet,host_16 pseudo_length)
	{
	net_16 *w = base;
	host_32 x;
	unsigned long result = 0;

	while(byte_count > 0)
		{
		x = nr_n2h16(*w++);
		if(byte_count == 1)
			x &= 0xff00;

		result += x;

		byte_count -= 2;
		}

	// | Add in udp/tcp pseudo-header, maybe
	if(ip_packet)
		{
		result += nr_n2h16(ip_packet->source_ip_address & 0x0000ffff);
		result += nr_n2h16(ip_packet->source_ip_address >> 16);
		result += nr_n2h16(ip_packet->destination_ip_address & 0x0000ffff);
		result += nr_n2h16(ip_packet->destination_ip_address >> 16);
		result += ip_packet->protocol;
		result += pseudo_length;
		}


	// | strangely, tcp/ip checksums require
	// | that the carry-bit be added back in.
	// | And, do it twice, to account for the case
	// | where adding the halves overflows. You
	// | only need to do it twice at most. Really.
	// |

	result = (result & 0xffff) + (result >> 16);
	result = (result & 0xffff) + (result >> 16);

	// |
	// | Never have checksum == 0
	// |

	if(result == 0)
		result = 0xffff;

	return ~(nr_h2n16((host_16)result));
	}

#if PLUGS_PING
// --------------------------------------------------------
// ICMP Handler
//
// This handler only responds to one thing: a ping (echo request)
//

#define k_plugs_ping_reply_size 1536

static int r_plugs_icmp_proc
		(
		int plug_handle,
		void *context,
		ns_plugs_packet *p,
		void *payload,
		int payload_length
		)
	{
	char response_b[k_plugs_ping_reply_size]; // (raw bytes) upper bound for ping we can reply to!
	ns_plugs_icmp_packet *icmpp = payload;
	ns_plugs_icmp_packet *response = (ns_plugs_icmp_packet *)response_b;

	if(icmpp->type == ne_plugs_icmp_ping_request)
		{
		char *ws,*wd;
		int i;
		ns_plugs_ip_packet *ipp;

		// | copy payload portion of ping request
		ws = payload;
		ws += 4;
		wd = (char *)(response->payload);

		if(payload_length >= k_plugs_ping_reply_size)
			payload_length = k_plugs_ping_reply_size;

		for(i = payload_length - 4; i > 0; i--)
			*wd++ = *ws++;

		response->type = ne_plugs_icmp_ping_reply;
		response->code = 0;

		// | Send the almost-identical packet on out
		// | Use send_to to send it to the originator

		ipp = p[ne_plugs_ip].header;
//MR		nr_plugs_send_to(plug_handle,response,payload_length,0,ipp->source_ip_address,0);
		nr_plugs_send_to(plug_handle,(void *)response,payload_length,0,ipp->source_ip_address,0);
		}

	return 0;
	}
#endif


// ---------------------------------------------------------

// Arp Handler
//
// When we get an arp "reply" packet,
// we'll save its information into the
// cache IF there is an entry for it already
// there.
// When we get an arp "request" packet,
// we'll reply to it if its about us.

int r_plugs_arp_proc
		(
		int plug_handle,
		void *context,
		ns_plugs_packet *p,
		void *payload,
		int payload_length
		)
	{
	ns_plugs_arp_packet *ap = payload;
	ns_plugs_arp_packet response;
	s_plugs_adapter_entry *a = context;

	switch(ap->op)
		{
		case nm_h2n16(1):		// arp request
			if(a->settings.ip_address == ap->target_ip_address)
				{
				// | Request for us!
				// | construct an answer and send it.

				response.hardware_type = nm_h2n16(1);
				response.protocol_type = nm_h2n16(0x0800);
				response.hardware_size = 6;		// 6 for ethernet
				response.protocol_size = 4;		// 4 for IP
				response.op = nm_h2n16(2);			// reply
				response.sender_ethernet_address = a->settings.ethernet_address;
				response.sender_ip_address = a->settings.ip_address;
				response.target_ethernet_address = ap->sender_ethernet_address;
				response.target_ip_address = ap->sender_ip_address;

				nr_plugs_send
						(
						plug_handle,
//MR						&response,
						(void *)&response,
						28,
						ne_plugs_flag_ethernet_broadcast
						);
				}
			break;

		case nm_h2n16(2):		// arp reply
			//
			// | walk through our arp cache, and see if we want this reply
				{
				s_plugs_arp_cache_entry *w;
				int i;

				w = a->arp_cache;
				for(i = 0; i < nk_plugs_arp_cache_count; i++)
					{
					if(w->ip_address == ap->sender_ip_address)
						w->ethernet_address = ap->sender_ethernet_address;
					w++;
					}
				}
			break;
			} // switch
	return 0;
	}


// Nothing wrong with two plugs listening
// on the same port. No sir! Perfectly
// legal. But we wont let it happen
// accidentally.

#define nk_plugs_minimum_fresh_port_number 32769

net_16 get_port_number(s_plugs_globals *g)
	{
	int v;
	s_plugs_plug *plug;
	int i;

try_again:
	v = g->port_number++; // will be zero the very first time...
	if(v == 0)
		v = g->port_number = nk_plugs_minimum_fresh_port_number;

	v = nr_h2n16(v);

	plug = g->plug;
	for(i = 0; i < PLUGS_PLUG_COUNT; i++)
		if(v == plug++->local_port)
			goto try_again;

	return v;
	}

int nr_plugs_initialize
		(
		long flags,
		ns_plugs_network_settings *network_settings,
		void *adapter_address,
		ns_plugs_adapter_description *adapter_description
		)
	{
	s_plugs_globals *g = &ng_plugs_globals;
	int result = 0;
	s_plugs_adapter_entry *a;

	// +---------------------------------
	// | Initialize can be used to start up the plugs
	// | stack from scratch, or to add one more adapter
	// |

	if(!(flags & ne_plugs_flag_add_adapter))
		{
		// +----------------------
		// | clear and reset everything
		// | Only the 1st adapter gets a DNS socket
		// |


		nr_zerorange((char *)g,sizeof(s_plugs_globals));

		// +---------------
		// | Mark the globals as Up And Running

		g->running = 1;

#if PLUGS_DNS
		// +------
		// | Install a DNS handler
		// | ONLY the first adapter installed gets
		// | a DNS handler.
		// |

		result = nr_plugs_create
				(
				&g->dns_plug,
				ne_plugs_udp,
				0,
				r_plugs_dns_proc,
				0,
				nk_plugs_default_debug);

		result = nr_plugs_connect
				(
				g->dns_plug,
				0,
				nr_n2h32(network_settings->nameserver_ip_address),
				ne_plugs_udp_dns
				);
#endif
		}

	// +---------------
	// | Install the adapter
	// | Stash the adapter pointer
	// |

	a = &g->adapter[g->adapter_count];

	a->adapter_address = adapter_address;
	a->adapter_description = adapter_description;


	// +-----------------
	// | Install this adapter's network settings.
	// | If there's a flash, maybe get settings from flash
	// |

#ifdef nasys_plugs_persistent_network_settings

	// | 0 means use the stored index,

	if((int)network_settings == 0)
		network_settings = &nasys_plugs_persistent_network_settings->settings
			[
			nasys_plugs_persistent_network_settings->settings_index
			];
#endif

	a->settings = *network_settings;

	// +--------------------
	// | Install this adapter's arp proc
	// |

	result = nr_plugs_create
			(
			&a->arp_plug,
			ne_plugs_arp,
			1,
			r_plugs_arp_proc,
			a, // | use context to hold "our adapter".
			ne_plugs_flag_ethernet_broadcast + nk_plugs_default_debug
			);


#if PLUGS_PING
	// +------
	// | Install this adapter's ICMP ping handler
	// |

	result = nr_plugs_create
			(
			&a->icmp_plug,
			ne_plugs_icmp,
			1,
			r_plugs_icmp_proc,
			0,
			nk_plugs_default_debug
			);

	result = nr_plugs_connect
			(a->icmp_plug,	0, -1,-1); 
			
#endif

	// +---------------
	// | Reset the adapter

	result = (a->adapter_description->reset_proc)
			(
			a->adapter_address,
			network_settings
			);
#if PLUGS_DEBUG
	printf("   [plugs] +-----------------------\n");
	printf("   [plugs] | initialized adapter %s at 0x%08x, ",
			a->adapter_description->adapter_name,
			(int)a->adapter_address);
	nr_plugs_print_ip_address(network_settings->ip_address);
	printf("\n");
//MR #endif PLUGS_DEBUG
#endif

	g->adapter_count++;

	return result;
	}

int nr_plugs_terminate(void)
	{
	s_plugs_globals *g = &ng_plugs_globals;
	int i;

	for(i = 0; i < PLUGS_PLUG_COUNT; i++)
		nr_plugs_destroy(i + nk_plugs_plug_number_base);

	nr_zerorange((char *)g,sizeof(s_plugs_globals));

	return 0;
	}

int nr_plugs_get_settings
		(
		int adapter_index,
		ns_plugs_network_settings *network_settings_out
		)
	{
	s_plugs_globals *g = &ng_plugs_globals;
	s_plugs_adapter_entry *a = &g->adapter[adapter_index];

	*network_settings_out = a->settings;
	return 0;
	}

int ethernet_address_equal(net_48 *ea1,net_48 *ea2)
	{
	return ea1->u32 == ea2->u32
			&& ea1->l16 == ea2->l16;

⌨️ 快捷键说明

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