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

📄 plugs.c

📁 altera epxa1的例子程序
💻 C
📖 第 1 页 / 共 5 页
字号:

present_but_unresolved:
	// We put entries in the cache with ethernet_address == 0
	// to signify that we want it. The ARP handler only fills
	// in mac addr's that already have an entry for the ip.

	// Not found in cache
	// If we're already in dispatch, we cannot conduct a
	// transaction, so just fail
	if(g->in_dispatch)
		{
		result = ne_plugs_error_arp;
		goto go_home;
		}

	//
	// Should we send an ARP request?
	t1 = nr_timer_milliseconds();

	if(t1 - ti < nk_plugs_arp_retry_interval)
		goto scan_cache;


	ti = t1;	// retry timer shall go again from here...

	if(retry_count >= nk_plugs_arp_retry_count)
		{
		result = ne_plugs_error_arp_timed_out;
		goto go_home;
		}

	retry_count++;

	// Not in the cache, & is time to send out a request, and wait...
	// If we wait too long, well, report an error then.
		{
		ns_plugs_arp_packet request;

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

#if PLUGS_DEBUG
		if(flags & ne_plugs_flag_debug_tx)
			{
			printf("   [plugs] | sending arp request for ");
			nr_plugs_print_ip_address(request.target_ip_address);
			printf("\n");
			}
#endif
//MR		result = nr_plugs_send(a->arp_plug,&request,28,0);
		result = nr_plugs_send(a->arp_plug,(void *)&request,28,0);
		if(result)
			goto go_home;
		}
	goto scan_cache;

go_home:
	return result;
	}

void packet_append_bytes(char **dst,void *src, int length)
	{
	char *src_c = (char *)src;
	char *w = *dst;

	while(length--)
		*w++ = *src_c++;

	*dst = w;
	}

void packet_append_n16(char **dst,net_16 x)
	{
	packet_append_bytes(dst,&x,2);
	}

// Send must construct an entire ethernet packet
// for whatever protocol it is sending.
// The address can be deduced from the packet

// Note -- the adapter's send routine
// is not reentrant, so it should disable
// interrupts until it has made its
// best attempt to send.

// Note -- In the case of an ip packet,
// this routine can end up recursively
// calling itself as part of the ARP exchange.
// (The nr_plugs_ip_to_ethernet routine will need
// to send an arp request the first time an
// ip address is encountered.) (If the adapter
// requires mac address.) Usually we'll have
// the address in cache already, though, from the
// incoming ip message.

// plug_handle -- if this is a small integer,
// then it is presumed to be just a protocol
// number. This is so we can send a packet
// without a plug allocated, in some cases.
// Specifically, this lets us send tcp rst
// messages in response to spurious packets.
// If used like this, the adapter index must
// be coded into the low flags bits.

int nr_plugs_send_to(int plug_handle,
		void *payload,
		int payload_length,
		long flags,
		net_32 ip_address,
		net_16 port)
	{
	s_plugs_globals *g = &ng_plugs_globals;
	int result = 0;
	ns_plugs_ethernet_packet *ep;
	char ep_contents[1500];			// this should be supplied by each adapter
	char *ep_w;						// progressive walk along the packet...
	int plug_protocol;
	net_16 plug_local_port;
	int adapter_index;
	s_plugs_adapter_entry *a;

	// |
	// | Extract the protocol, flags, and source port
	// | either from the plug pointer, or inferentially
	// | from the (fake) plug_handle
	// |

	if(plug_handle < ne_plugs_last_protocol) // not a plug handle!
		{
		plug_protocol = plug_handle;
		plug_local_port = 0;
#if PLUGS_DEBUG
		plug_handle = -1; // so debug printing reveals the fake plug-ness
		adapter_index = flags & ne_plugs_flag_adapter_index_mask;
#endif
		}
	else
		{
		s_plugs_plug *plug;

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

		plug_protocol = plug->protocol;
		plug_local_port = plug->local_port;
		flags |= plug->flags;
		adapter_index = plug->flags & ne_plugs_flag_adapter_index_mask;
		}

	a = &g->adapter[adapter_index];

#if PLUGS_DEBUG
	if(flags & ne_plugs_flag_debug_tx)
		{
		printf("   [plugs] +-----------------------\n");
		printf("   [plugs] | plug %d (%s): sends %d byte payload\n",
			plug_handle,
			get_protocol_name(plug_protocol),
			payload_length);
		}
#endif

	ep = (ns_plugs_ethernet_packet *)ep_contents;
	ep_w = (char *)ep_contents;

	if(plug_protocol == ne_plugs_ethernet)
		{
		// ethernet protocol means your "payload" is, in fact,
		// the whole ethernet packet. 1st 14 bytes is the header.

		packet_append_bytes(&ep_w,payload,payload_length);
		}
	else if(plug_protocol == ne_plugs_arp)
		{
		// arp protocol: payload is presumed to be
		// a 28-byte arp packet. We don't even
		// check the length.

		ns_plugs_arp_packet *arp_packet;
		net_48 broadcast_ethernet_address;

		arp_packet = (ns_plugs_arp_packet *)payload;

		// ethernet header
		broadcast_ethernet_address.u32 = 0xffffFFFF;
		broadcast_ethernet_address.l16 = 0xffff;
		packet_append_bytes(&ep_w,
				(flags & ne_plugs_flag_ethernet_broadcast)
//MR					? &broadcast_ethernet_address
					? (void *)&broadcast_ethernet_address
//MR					: &arp_packet->target_ethernet_address,
					: (void *)&arp_packet->target_ethernet_address,
				6);
//MR		packet_append_bytes(&ep_w,&a->settings.ethernet_address,6);
		packet_append_bytes(&ep_w,(void *)&a->settings.ethernet_address,6);
		packet_append_n16(&ep_w,nm_h2n16(ne_plugs_ethernet_arp));

		// arp packet as delivered to us
		packet_append_bytes(&ep_w,payload,28);
		}

	else if
			(
			plug_protocol == ne_plugs_ip
			|| plug_protocol == ne_plugs_icmp
			|| plug_protocol == ne_plugs_udp
			|| plug_protocol == ne_plugs_tcp_raw
			)
		{
		// | icmp, udp, tcp: payload is just the data to be
		// | sent to the port and address specified in
		// | the nr_plugs_connect call.

		ns_plugs_ip_packet *ip_packet;
		net_48 ep_ethernet_address;

		// | look up ethernet destination
		result = nr_plugs_ip_to_ethernet
				(
				adapter_index,
				ip_address,
				&ep_ethernet_address,flags
				);
		if(result)
			goto go_home;

		// |
		// | ethernet header

//MR		packet_append_bytes(&ep_w,&ep_ethernet_address,6);
		packet_append_bytes(&ep_w,(void *)&ep_ethernet_address,6);
//MR		packet_append_bytes(&ep_w,&a->settings.ethernet_address,6);
		packet_append_bytes(&ep_w,(void *)&a->settings.ethernet_address,6);
		packet_append_n16(&ep_w,nm_h2n16(ne_plugs_ethernet_ip));

		// |
		// | construct ip header in place (not appending)

		ip_packet = (ns_plugs_ip_packet *)ep_w;
//MR		ep_w += sizeof(ns_plugs_ip_packet);
		ep_w += sizeof(ns_plugs_ip_packet) - 1;

		ip_packet->version_header_length = 0x45; // 0x45 for no options
		ip_packet->tos = 0;			// zero
//MR		ip_packet->length = nr_h2n16(sizeof(ns_plugs_ip_packet) + payload_length
		ip_packet->length = nr_h2n16(sizeof(ns_plugs_ip_packet) - 1 + payload_length
				+ ((plug_protocol == ne_plugs_udp)
//MR				? sizeof(ns_plugs_udp_packet) : 0)); // header + payload length
				? sizeof(ns_plugs_udp_packet) - 1: 0)); // header + payload length

		ip_packet->identifier = nr_h2n16(g->ip_identifier++);		// bump for each packet
		ip_packet->flags_fragment = nm_h2n16(0);		// fragment miscellany
		ip_packet->time_to_live = 128;		// some typical value

		ip_packet->protocol = (plug_protocol == ne_plugs_icmp) ? ne_plugs_ip_icmp :
				(plug_protocol == ne_plugs_udp) ? ne_plugs_ip_udp :
				ne_plugs_ip_tcp;

		ip_packet->header_checksum = 0;
		ip_packet->source_ip_address = a->settings.ip_address;
		ip_packet->destination_ip_address = ip_address;

		// |
		// | maybe append udp header

		if(plug_protocol == ne_plugs_udp)
			{
//MR			int udp_packet_length = sizeof(ns_plugs_udp_packet) + payload_length;
			int udp_packet_length = sizeof(ns_plugs_udp_packet) - 1 + payload_length;

			packet_append_n16(&ep_w,plug_local_port);
			packet_append_n16(&ep_w,port);
			packet_append_n16(&ep_w,nr_n2h16(udp_packet_length));
			packet_append_n16(&ep_w,0);		// no stinking checksum
			}

		// |
		// | append the payload

		packet_append_bytes(&ep_w,payload,payload_length);

		// |
		// | After the whole packet is together,
		// | work backwards out and do the checksums.
		// | maybe calculate icmp checksum, so courteously!

		if(plug_protocol == ne_plugs_icmp)
			{
			ns_plugs_icmp_packet *icmp_packet;

			icmp_packet = (ns_plugs_icmp_packet *)ip_packet->payload;

			// | clear checksum, first
			icmp_packet->checksum = 0;
//MR			icmp_packet->checksum = r_calculate_checksum(ip_packet->payload,payload_length,0,0);
			icmp_packet->checksum = r_calculate_checksum((void *)ip_packet->payload,payload_length,0,0);
			}
		else if(plug_protocol == ne_plugs_udp)
			{
			ns_plugs_udp_packet *udp_packet = (ns_plugs_udp_packet *)ip_packet->payload;
//MR			int udp_packet_length = sizeof(ns_plugs_udp_packet) + payload_length;
			int udp_packet_length = sizeof(ns_plugs_udp_packet) - 1 + payload_length;

			udp_packet->checksum = r_calculate_checksum(
//MR					udp_packet,
					(void *)udp_packet,
					udp_packet_length,
					ip_packet,
					udp_packet_length);
			}
		else if(plug_protocol == ne_plugs_tcp_raw
				|| (flags & ne_plugs_flag_tcp_checksum))
			{
			ns_plugs_tcp_packet *tcp_packet = (ns_plugs_tcp_packet *)ip_packet->payload;

			tcp_packet->checksum = 0;
			tcp_packet->checksum = r_calculate_checksum(
//MR					tcp_packet,
					(void *)tcp_packet,
					payload_length,
					ip_packet,
					payload_length);
			}

//MR		ip_packet->header_checksum = r_calculate_checksum(ip_packet,
		ip_packet->header_checksum = r_calculate_checksum((void *)ip_packet,
//MR				sizeof(ns_plugs_ip_packet),0,0);
				sizeof(ns_plugs_ip_packet) - 1,0,0);
		}
#if PLUGS_DEBUG
	else
		printf("   [plugs] | nr_plugs_send: unknown plug %d protocol %d\n",
				plug_handle,plug_protocol);
#endif


#if PLUGS_DEBUG
	if(flags & ne_plugs_flag_debug_tx)
		nr_plugs_print_ethernet_packet(ep,ep_w - ep_contents,"   [plugs] | ");
#endif

	// |
	// | Send the packet to the hardware adapter
	// |
	result = a->adapter_description->tx_frame_proc
			(
			a->adapter_address,
			ep_contents,
			ep_w - ep_contents
			);

go_home:

#if PLUGS_DEBUG
	if(result)
		{
		if(flags & ne_plugs_flag_debug_tx)
			printf("   [plugs] | ERROR nr_plugs_send_to result = %d\n",result);
		}
#endif

	return result;
	}

int nr_plugs_send(int plug_handle,
		void *payload,
		int payload_length,
		long flags)
	{
//HB Removed to get rid of warning message	s_plugs_globals *g = &ng_plugs_globals;
	s_plugs_plug *plug;
//HB Removed to get rid of warning message	int plugIndex;
	int result;

//printf("*** nr_plugs_send() 1 plug_handle=%08x ***\n",plug_handle);
	plug = r_plug_from_handle(plug_handle);
//printf("*** nr_plugs_send() 2 plug=%x ***\n",plug);

	// |
	// | For a tcp connection, shunt it through
	// | r_tcp_send (which eventually
	// | calls through to nr_plugs_send_to,
	// | after building the tcp packet &c.)
	// |

#if PLUGS_TCP
	if(plug->protocol == ne_plugs_tcp)
		{
//printf("*** nr_plugs_send() 3 ***\n");
		result = r_tcp_send
				(
				plug_handle,
				plug,
				ne_plugs_flag_tcp_ack | ne_plugs_flag_tcp_psh,
				payload,
				payload_length
				);
//printf("*** nr_plugs_send() 4 ***\n");
		}
	else
#endif
		{
//printf("*** nr_plugs_send() 5 ***\n");
		result = nr_plugs_send_to(plug_handle,payload,payload_length,flags,
				plug->remote_ip_address,
				plug->remote_port);
//printf("*** nr_plugs_send() 6 ***\n");
		}

//printf("*** nr_plugs_send() 7 ***\n");
	return result;
	}

// +------------------------
// | Mundane stuff, like setting
// | the LED and such

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

	return a->adapter_description->set_led_proc
			(
			a->adapter_address,
			led_onoff
			);
	}

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

	return a->adapter_description->set_loopback_proc
			(
			a->adapter_address,
			loopback_onoff
			);
	}

// +-----------------------------------
// | nr_plugs_idle
// | Poll for events and other interesting things.
//
int nr_plugs_idle(void)
	{
	s_plugs_globals *g = &ng_plugs_globals;
	int adapter_index;
	s_plugs_adapter_entry *a;

	if(!g->running)
		return ne_plugs_error_not_initialized; // | plugs not initialized

	if(g->in_idle)
		return ne_plugs_error;

	// +--------------------
	// | Can't call more than one deep for check_for_events, thank you.
	// |

	g->in_idle++;

	a = g->adapter;
	for(adapter_index = 0; adapter_index < g->adapter_count; adapter_index++)
		{
		a->adapter_description->check_for_events_proc
				(
				a->adapter_address,
				nr_plugs_dispatch_packet,
				a				// context is adapter pointer
				);
		a++;
		}

	g->in_idle--;
	return 0;
	}


⌨️ 快捷键说明

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