www.pudn.com > test11.rar > hello_plugs.c, change:2008-07-31,size:23357b


 
 
// ex:set tabstop=4: 
// +-------------------- 
// | Includes 
// | 
 
#include "excalibur.h" 
#include "hello_plugs_menu.h" 
#include "plugs.h" 
 
 
#if __nios16__ 
	#define SMALL 1 
#endif 
 
 
// Set __adapter__ to the current design... 
 
#include "plugs_example_designs.h" 
 
 
// +-------------------- 
// | Types 
 
enum 
	{ 
	k_menu_settings = 1, 
	k_menu_actions,		// ping & nslookup 
	}; 
 
// +--------------------------------- 
// | Global State 
// | 
// | (If you must have globals, put them 
// | in one struct for tidiness! And name 
// | the one instance "g".) 
 
typedef struct 
	{ 
	ns_plugs_persistent_network_settings pns; 
 
	int arp_scan_replies[256];	// matrix of who has responded 
 
	int sniff_pause;	// if set, prints dots instead of packets 
	int sniff_count;	// total packets sniffed in session 
	} ns_globals; 
 
static ns_globals g; // = {0}; 
 
// +---------------------------------------- 
// | Local Prototypes 
// | 
 
static int r_reset_settings(int x); 
static int r_reinitialize(int x); 
static int show_abbreviated_settings(int x); 
 
 
// +---------------------------------------- 
// | Initialization and Utilities 
// | 
 
 
// +---------------------------------------- 
// | r_get_settings_from_flash 
// | 
// | If there's flash memory, get the settings from 
// | the conventional location in flash. If the 
// | index looks crazy, or there's no flash, then 
// | reset the settings to our default values. 
// | 
 
void r_get_settings_from_flash(void) 
	{ 
	int i; 
 
#ifdef nasys_main_flash 
	g.pns = *nasys_plugs_persistent_network_settings; 
	if(g.pns.signature != 0x00005afe) 
		r_reset_settings(0); 
#else 
	r_reset_settings(0); 
#endif 
	} 
 
 
int r_save_settings(int x) 
	{ 
#ifdef nasys_main_flash 
	printf("erasing flash\n"); 
	nr_flash_erase_sector((void *)-1,(void *)nasys_plugs_persistent_network_settings); 
 
	printf("writing flash at 0x%08x\n",nasys_plugs_persistent_network_settings); 
    g.pns.signature = 0x00005afe; 
 
	nr_flash_write_buffer((void *)-1,(void *)nasys_plugs_persistent_network_settings,(void *)&g.pns,sizeof(g.pns)); 
#endif 
	} 
 
 
int r_set_settings(void) 
	{ 
	int result; 
 
 
	nr_plugs_terminate(); 
 
	result = nr_plugs_initialize(0, &g.pns.settings, 
			__adapter__, 
			__adapter_irq__, 
			__adapter_struct_addr__); 
 
	if(result < 0) 
        goto go_home; 
 
    // after initializing, pull the settings back into our globals 
    result = nr_plugs_get_settings(0,&g.pns.settings); 
    if(result) 
        goto go_home; 
 
go_home: 
    if(result < 0) 
        nr_plugs_print_error_message("[r_set_settings]",result); 
 
	return result; 
	} 
 
 
void r_initialize(void) 
	{ 
	nr_zerorange((char *)(&g),sizeof(g)); 
	r_get_settings_from_flash(); 
	r_set_settings(); // initializes plugs, too 
	} 
 
 
// ++================================================= 
// || Network Settings Menu Procs 
// || 
 
// Routines 
 
 
static int show_ip_address(ns_plugs_network_settings *ns) 
    { 
	printf("            ip address: "); 
	nr_plugs_print_ip_address_decimal(ns->ip_address); 
 
    if(ns->flags & ne_plugs_flag_dhcp) 
        printf("        (obtained via dhcp)"); 
 
	printf("\n"); 
    } 
 
static int show_settings(int x) 
	{ 
#if SMALL 
	return show_abbreviated_settings(x); 
#else 
    ns_plugs_network_settings ns; 
    nr_plugs_get_settings(0,&ns);  // show the settings plugs library reports, regardless what WE set 
 
	printf("\n Network Settings \n\n"); 
	printf("      ethernet address: "); 
	nr_plugs_print_ethernet_address(&ns.ethernet_address); 
	printf("\n"); 
 
    show_ip_address(&ns); 
 
	printf(" nameserver ip address: "); 
	nr_plugs_print_ip_address_decimal(ns.nameserver_ip_address); 
	printf("\n"); 
 
	printf("           subnet mask: "); 
	nr_plugs_print_ip_address_decimal(ns.subnet_mask); 
	printf("\n"); 
 
	printf("    gateway ip address: "); 
	nr_plugs_print_ip_address_decimal(ns.gateway_ip_address); 
	printf("\n"); 
 
	printf("\n"); 
#endif // SMALL 
	} 
 
static int show_abbreviated_settings(int x) 
	{ 
    ns_plugs_network_settings ns; 
 
    nr_plugs_get_settings(0,&ns);  // show the settings plugs library reports, regardless what WE set 
 
    show_ip_address(&ns); 
	printf("\n"); 
	} 
 
static int input_ip_address(char *prompt, net_32 *ip_inout) 
	{ 
	int result; 
	char s[64]; 
 
	nr_plugs_ip_to_string(*ip_inout,s); 
	result = r_input_string(prompt,0,s); 
	nr_plugs_string_to_ip(s,ip_inout); 
 
	return result; 
	} 
 
static int r_input_long(char *prompt, long *x_inout) 
	{ 
	int result; 
	char s[64]; 
 
	nr_plugs_long_to_string(*x_inout,s); 
	result = r_input_string(prompt,0,s); 
	*x_inout = nr_plugs_string_to_long(s); 
 
	return result; 
	} 
 
static int r_edit_settings(int x) 
	{ 
	char s[64]; 
	ns_plugs_network_settings *settings; 
    int result; 
 
	settings = &g.pns.settings; 
 
	nr_plugs_ethernet_to_string(&settings->ethernet_address,s); 
	result = r_input_string("      ethernet address",0,s); 
    if(result < 0) 
        goto go_home; 
 
	nr_plugs_string_to_ethernet(s,&settings->ethernet_address); 
 
    // | 
    // | use dhcp [y/n] 
    // | 
        { 
        int dhcp_flag = settings->flags & ne_plugs_flag_dhcp; 
        s[0] = dhcp_flag ? 'Y' : 'N'; 
        s[1] = 0; 
 
ask_about_dhcp: 
        result = r_input_string("              use dhcp",0,s); 
        if(result < 0) 
            goto go_home; 
 
        if(s[0] == 'Y' || s[0] == 'y') 
            settings->flags |= ne_plugs_flag_dhcp; 
        else if(s[0] == 'N' || s[0] == 'n') 
            settings->flags &= ~ne_plugs_flag_dhcp; 
        else 
            goto ask_about_dhcp; 
        } 
 
    // | 
    // | no dhcp? do it the hard way 
    // | 
    if(!(settings->flags & ne_plugs_flag_dhcp)) 
        { 
	    result = input_ip_address("            ip address",&settings->ip_address); 
        if(result < 0) 
            goto go_home; 
 
	    result = input_ip_address(" nameserver ip address",&settings->nameserver_ip_address); 
        if(result < 0) 
            goto go_home; 
 
	    result = input_ip_address("           subnet mask",&settings->subnet_mask); 
        if(result < 0) 
            goto go_home; 
 
	    result = input_ip_address("    gateway ip address",&settings->gateway_ip_address); 
        if(result < 0) 
            goto go_home; 
        } 
 
	printf("\n"); 
go_home: 
    if(result >= 0) 
	    r_set_settings(); 
     
    return result; 
	} 
 
static int r_reset_settings(int x) 
	{ 
	ns_plugs_network_settings settings = {0,0,0,0,0,0,0}; 
 
	settings.ethernet_address.u32=0x11121314; 
	settings.ethernet_address.l16=0x1516 + nr_timer_milliseconds(); 
	settings.nameserver_ip_address = nm_ip2n(10,0,0,1); 
	settings.subnet_mask = nm_ip2n(255,255,255,0); 
	settings.gateway_ip_address = nm_ip2n(10,0,0,255); 
 
    // dhcp on first setting. It's good. 
 
    settings.flags = ne_plugs_flag_dhcp; 
	settings.ip_address = nm_ip2n(10,0,0,51); 
	g.pns.settings = settings; 
 
    r_reinitialize(0); 
 
	return 0; 
	} 
 
static int r_reinitialize(int x) 
	{ 
    printf("Reinitializing...\n"); 
	 
	r_set_settings(); 
 
	return 0; 
	} 
 
// ++================================================= 
// || Network Action Menu Items 
// || 
 
#if !SMALL 
// +----------------------------------------------------- 
// | Ping Proc and Pinger 
 
// Utility to do unaligned long-int read from packet 
unsigned long get_bytes_32(void *address) 
	{ 
	unsigned char *w = address; 
	return ((long)w[0] << 24) + ((long)w[1] << 16) + ((long)w[2] << 8) + w[3]; 
	} 
// Utility to do unaligned long-int write to packet 
void put_bytes_32(void *address,unsigned long x) 
	{ 
	unsigned char *w = address; 
	w[0] = x >> 24; 
	w[1] = x >> 16; 
	w[2] = x >> 8; 
	w[3] = x; 
	} 
 
// +---------------------------------- 
// | ping_proc -- gets called for icmp packets 
// | from the ip address being pinged. 
 
int ping_proc(int plug_handle, 
		void *context, 
		ns_plugs_packet *p, 
		void *payload, 
		int payload_length) 
	{ 
	ns_plugs_icmp_packet *icmpp = payload; 
	ns_plugs_ip_packet *ipp = p[ne_plugs_ip].header; 
	long time; 
 
	// | 
	// | We don't expect them to be pinging us 
	// | back or anything, and this plug will 
	// | filter for only the remote host 
	// | we're pinging, but if they do send 
	// | a ping-request, we'll print a message 
	// | mentioning it. 
	// | 
	// | We mostly expect the first case: ping reply to our ping. 
	// | 
 
	if(icmpp->type == ne_plugs_icmp_ping_reply) 
		{ 
		time = get_bytes_32(icmpp->payload); 
		time = nr_timer_milliseconds() - time; 
 
		printf(" [ping_proc] got ping reply from "); 
		nr_plugs_print_ip_address(ipp->source_ip_address); 
		printf(" (%d msec)\n",time); 
		} 
	else if(icmpp->type == ne_plugs_icmp_ping_request) 
		{ 
		printf("ping_proc: got ping request from "); 
		nr_plugs_print_ip_address(ipp->source_ip_address); 
		printf("!\n"); 
		} 
	else 
		printf("ping_proc: got icmp type %d\n",icmpp->type); 
	} 
 
#define k_ping_count 4 
 
int r_ping_host(int x) // both PING menu items come here, debug with x=1. 
	{ 
	int ping_plug; 
	static char *default_host = "www.altera.com"; 
	char host[64]; 
	char *hostp; 
	net_32 ip; 
	int result; 
	char data[64]; 
	ns_plugs_icmp_packet *ping_request = (ns_plugs_icmp_packet *)data; 
				// overlay it on data, for nonzero payload 
	int len; 
	int i; 
 
	host[0] = 0; 
 
	// x = 1 means have debuggin turned on 
	x = x ? (ne_plugs_flag_debug_rx | ne_plugs_flag_debug_tx) : 0; 
 
	while(1) 
		{ 
		printf("\n\n"); 
		result = r_input_string("  Internet host to ping by name (<ESC> to finish)", 
				default_host,host); 
		if(result < 0)	 
			break; 
 
		// Allocate the plug of icmp type 
 
		result = nr_plugs_create(&ping_plug, 
			ne_plugs_icmp, 
			0,	// port number, does not matter here 
			ping_proc, 
			0, 
			x);	// flags set depending on menu choice 
 
		if(result) 
			{ 
			printf(" Could not create ping plugs.\n"); 
			nr_plugs_print_error_message("[ping test]",result); 
			continue; 
			} 
 
		// | 
		// | First, see if, perchance, it was a 
		// | dot-separated numerical string 
		// | 
 
		if(host[0] >= '0' && host[0] <= '9') 
			{ 
			nr_plugs_string_to_ip(host,&ip); 
			ip = nr_n2h32(ip); 
			hostp = 0; 
			} 
		else 
			{ 
			ip = 0; 
			hostp = host; 
			} 
 
		// Connect to remote host by name 
 
		result = nr_plugs_connect(ping_plug,hostp,ip,0);	// talk to remote host 
 
		if(result) 
			{ 
			printf(" Lookup failure on %s.\n",host); 
			nr_plugs_print_error_message("[ping test]",result); 
 
			// Delete the plug, since we can't connect, and we'll allocate again 
			nr_plugs_destroy(ping_plug); 
 
			continue; 
			} 
		printf("Connected!\n\n"); 
 
 
		// | Construct the ping request 
 
		ping_request->type = ne_plugs_icmp_ping_request; 
		ping_request->code = 0; 
 
		ping_request->payload[0] = 0; 
		ping_request->payload[1] = 3; 
		ping_request->payload[2] = 4; 
		ping_request->payload[3] = 8; 
 
		// "length" is packet + data 
 
		len = sizeof(ns_plugs_icmp_packet) + 4; 
		for(i = 0; i < k_ping_count; i++) 
			{ 
			printf("Sending ping %d of %d.\n",i+1,k_ping_count); 
 
			// | Pass the time as payload 
			put_bytes_32(ping_request->payload,nr_timer_milliseconds()); 
 
			nr_plugs_send(ping_plug,(void *)data,len,0); 
 
			// Wait 1 second, pumping the ether all the time 
				{ 
				long t0 = nr_timer_milliseconds(); 
				while(nr_timer_milliseconds() - t0 < 1000) 
					nr_plugs_idle(); 
				} 
			} 
 
		// All done pinging, delete the plug 
 
		result = nr_plugs_destroy(ping_plug); 
		} 
	} 
 
 
// +-------------------------------------------------- 
// | DNS lookup routine 
// | 
 
int r_dns_lookup(int x) 
	{ 
	static char *default_host = "www.altera.com"; 
	char host[64]; 
	net_32 ip; 
	int result; 
 
	host[0] = 0; 
 
	printf("\nEnter host names to look up, <ESC> when finished.\n\n"); 
 
	while(1) 
		{ 
		printf("\n\n"); 
		result = r_input_string("  Internet host to look up by name",default_host,host); 
		if(result < 0)	 
			break; 
 
		result = nr_plugs_name_to_ip(host,&ip); 
 
		if(result) 
			{ 
			printf("Lookup failed!\n"); 
			nr_plugs_print_error_message("[dns lookup test]",result); 
			} 
		else 
			{ 
			printf("The IP address of %s is ",host); 
			nr_plugs_print_ip_address_decimal(ip); 
			printf(".\n"); 
			} 
		} 
 
	return 0; 
	} 
 
#endif // SMALL 
 
// +-------------------------------------------------- 
// | Arp Scan plug handler and main routine 
// | 
 
int r_arp_plug_proc(int arp_plug, 
		void *context, 
		ns_plugs_packet *p, 
		void *payload, 
		int payload_length) 
	{ 
	ns_plugs_arp_packet *ap = payload; // get payload in proper type 
 
	if(ap->op == nm_n2h16(ne_plugs_arp_reply)) // is it a reply we want? 
		{ 
		// is it a reply within our own subnet (where we care?) 
		if(((ap->sender_ip_address ^ g.pns.settings.ip_address) & g.pns.settings.subnet_mask) == 0) 
			{ 
			int x; 
 
			x = (ap->sender_ip_address >> 24) & 0xff; 
 
			printf("arp_proc: reply from "); 
			nr_plugs_print_ip_address(ap->sender_ip_address); 
			printf("\n"); 
 
			g.arp_scan_replies[x] = x + 0x1000; 
			} 
		} 
	} 
 
int r_arp_scan(int x) 
	{ 
	int arp_plug; 
	long i; 
	ns_plugs_arp_packet a; 
	int result; 
    ns_plugs_network_settings settings; 
    net_32 our_ip_address; 
    net_32 base_ip_address; 
 
	printf("\n\n About to send ARP requests\nfor 256 addresses in subnet.\n"); 
 
    // Get our current settings for ethernet and base ip address to scan 
 
    result = nr_plugs_get_settings(0,&settings); 
    if(result < 0) 
        goto go_home; 
 
	// Create the Plug for the arp protocol 
 
	result = nr_plugs_create(&arp_plug,ne_plugs_arp,0,r_arp_plug_proc,0,ne_plugs_flag_ethernet_broadcast); 
	if(result) 
		goto go_home; 
 
	// clear the scan reply table 
 
	for(i = 0; i < 256; i++) 
		g.arp_scan_replies[i] = 0; 
	 
	// set up an arp request to use over & over 
 
	a.hardware_type = nm_h2n16(1); 
	a.protocol_type = nm_h2n16(0x0800); 
	a.hardware_size = 6; 
	a.protocol_size = 4; 
	a.op = nm_h2n16(ne_plugs_arp_request); 
	a.sender_ethernet_address = settings.ethernet_address; 
	a.sender_ip_address = settings.ip_address; 
	a.target_ethernet_address.u32 = 0; 
	a.target_ethernet_address.l16 = 0; 
 
	// Send out all the requests 
 
	for(i = 0; i < 256; i++) 
        	{ 
        	a.target_ip_address = 
                	(settings.ip_address & nm_h2n32(0xFFFFff00)) + nm_h2n32(i); 
        	nr_plugs_send(arp_plug,&a,sizeof(a),0); 
        	nr_delay(4); 
        	nr_plugs_idle(); 
        	} 
 
	// Wait some seconds 
		{ 
		long t0 = nr_timer_milliseconds(); 
		while(nr_timer_milliseconds() - t0 < 2500) 
			nr_plugs_idle(); // (in case we're in polled mode operation) 
		} 
	 
	// ---------------------------------------- 
	// Print out the scan result, in a sort of pretty way 
	printf("\n"); 
	for(i = 0; i < 256; i++) 
		{ 
		if(g.arp_scan_replies[i]) 
			printf("%3d ",i); 
		else 
			printf(" .  "); 
		if(i % 16 == 15) 
			printf("\n"); 
		} 
	printf("\n"); 
 
	// close down the plug 
	nr_plugs_destroy(arp_plug); 
go_home: 
    if(result < 0) 
		nr_plugs_print_error_message("[arp scan test]",result); 
	return 0; 
	} 
 
// +-------------------------------------------------- 
// | Packet Sniffer handler and main routine 
// | 
 
int r_eth_plug_proc(int plugHandle, 
		void *context, 
		ns_plugs_packet *p, 
		void *payload, 
		int payload_length) 
	{ 
	g.sniff_count++; 
 
	if(g.sniff_pause) 
		printf("."); 
	else 
		{ 
		printf("------------------\n"); 
		printf("Packet Sniffer\n(Press <ESC> to finish sniffing, <SPACE> to pause)\n\n"); 
 
		// Use convenient packet-printing utility 
 
		nr_plugs_print_ethernet_packet(payload,payload_length," [sniff] "); 
		} 
 
	return 0; 
	} 
 
int r_sniffer(int x) 
	{ 
	int eth_plug; 
	int i; 
	ns_plugs_arp_packet a; 
	int c; 
 
	printf("\n\n About to begin displaying all\nethernet packets received.\n"); 
 
	// Create the Plug for the eth protocol 
 
	nr_plugs_create(ð_plug, 
		ne_plugs_ethernet, 
		0, 
		r_eth_plug_proc, 
		0, 
		ne_plugs_flag_ethernet_all); // flag says, "anything the interface gets" 
	 
	// Wait for an escape key, and give the 
	// plugs library lots of time to do its stuff. 
 
	g.sniff_pause = 0; 
	g.sniff_count = 0; 
 
	while((c = nr_uart_rxchar(0)) != 27) 
		{ 
		if(c == ' ') 
			g.sniff_pause = !g.sniff_pause; 
		nr_plugs_idle(); 
		} 
 
	nr_plugs_destroy(eth_plug); 
 
	printf("\nSniffed %d packets.\n\n",g.sniff_count); 
	} 
 
#if !SMALL 
// +---------------------------------------------------- 
// | TCP Telnet routines 
// | 
 
typedef struct 
	{ 
	int connected; // 0:waiting, 1:connected, 2:disconnected 
	net_32 remote_ip_address; 
	net_16 remote_port; 
 
	long bytes_sent; 
	long bytes_received; 
	} s_telnet_status; 
 
int tcp_listen_proc(int plug_handle, 
		void *context, 
		host_32 remote_ip_address, 
		host_16 remote_port) 
	{ 
	volatile s_telnet_status *status = context; 
 
	status->connected = 1; 
	status->remote_ip_address = remote_ip_address; 
	status->remote_port = remote_port; 
 
	status->bytes_sent = 0; 
	status->bytes_received = 0; 
 
	printf("[tcp_listen_proc] Accepted connection from "); 
	nr_plugs_print_ip_address(nr_h2n32(remote_ip_address)); 
	printf(" port %d\n",remote_port); 
 
	return 0; 
	} 
 
int tcp_proc(int plug_handle, 
		void *context, 
		ns_plugs_packet *p, 
		void *payload, 
		int payload_length) 
	{ 
	volatile s_telnet_status *status = context; 
	int i; 
 
	if(payload) 
		{ 
		unsigned char *s = payload; 
 
		status->bytes_received += payload_length; 
 
		for(i = 0; i < payload_length; i++) 
			printf("%c",s[i]); 
 
			{ 
			char reply[100]; 
			int reply_length = 0; 
			// | 
			// | Handle funny telnet requests 
			// | 
 
			for(i = 0; i < payload_length; i++) 
				{ 
				if(s[i] == 255) 
					{ 
					i++; 
					if(s[i] == 253 || s[i] == 254) 
						{ 
						reply[reply_length++] = 255; 
						reply[reply_length++] = s[i++] - 2; 
						reply[reply_length++] = s[i++]; 
						} 
					} 
				} 
 
			if(reply_length) 
				nr_plugs_send(plug_handle,reply,reply_length,0); 
			} 
		} 
	else 
		{ 
		status->connected = 2; // let them know we are disconnected 
		} 
	 
	return 0; 
	} 
 
// +--------------------- 
// | Once a session is established, either by 
// | listening or connecting, we can come 
// | here and trade keystrokes until 
// | either they disconnect or we get an 
// | ESC key. 
// | 
 
int r_telnet_session(int tcp_plug, volatile s_telnet_status *status) 
	{ 
	int still_running; 
	int result = 0; 
 
	still_running = 1; 
	while(still_running) 
		{ 
		int c; 
 
		if((c = nr_uart_rxchar(0)) > 0) 
			{ 
			if(c == 27) 
				still_running = 0; 
			else 
				{ 
				nr_plugs_send(tcp_plug,&c,1,0); 
				status->bytes_sent++; 
				} 
			} 
 
		if(status->connected == 2) 
			still_running = 0; 
 
		nr_plugs_idle(); 
		} 
	 
	result = nr_plugs_connect(tcp_plug,0,0,0); 
	 
	printf("\nConnection closed.\n"); 
	printf("%d bytes sent, %d bytes received.\n\n",status->bytes_sent,status->bytes_received); 
 
go_home: 
	return result; 
	} 
 
int r_telnet_accept(int x) 
	{ 
	long local_port = 23; 
	int result; 
	int tcp_plug = 0; 
	int still_running; 
	s_telnet_status status = {0,0,0,0,0}; 
 
	result = r_input_long("Port to listen on",&local_port); 
	if(result) 
		goto go_home; 
 
	result = nr_plugs_create 
			( 
			&tcp_plug, 
			ne_plugs_tcp, 
			local_port, 
			tcp_proc, 
			&status, 
			0 
			); 
 
	result = nr_plugs_listen 
			( 
			tcp_plug, 
			tcp_listen_proc, 
			&status 
			); 
	 
	still_running = 1; 
 
	// | 
	// | Wait for connection to be established, then 
	// | go to the session routine. (Allow ESC to 
	// | bail out.) 
	// | 
 
	while(status.connected == 0) 
		{ 
		nr_plugs_idle(); 
		if(nr_uart_rxchar(0) == 27) 
			{ 
			nr_plugs_idle(); 
			printf("\nAborted.\n"); 
			goto go_home; 
			} 
		} 
	 
	result = r_telnet_session(tcp_plug,&status); 
 
go_home: 
	if(tcp_plug) 
		result = nr_plugs_destroy(tcp_plug); 
	return 0; 
	} 
 
int r_telnet_connect(int x) 
	{ 
	static char *default_host = "www.altera.com"; 
	char host[64]; 
	long remote_port = 23; 
	int result; 
	int tcp_plug = 0; 
	int still_running; 
	s_telnet_status status = {0,0,0,0,0}; 
 
	host[0] = 0; 
 
	result = r_input_string("  Internet host to connect to",default_host,host); 
	if(result) 
		goto go_home; 
 
	result = r_input_long("  Port to connect to",&remote_port); 
	if(result) 
		goto go_home; 
 
	result = nr_plugs_create 
			( 
			&tcp_plug, 
			ne_plugs_tcp, 
			0, // let library choose a port number 
			tcp_proc, 
			&status, 
			0 
			); 
 
	result = nr_plugs_connect 
			( 
			tcp_plug, 
			host, 
			0, 
			remote_port 
			); 
	 
	if(result) 
		{ 
		printf("Error connecting to host %s.\n",host); 
		nr_plugs_print_error_message("[tcp connect test]",result); 
		goto go_home; 
		} 
 
	result = r_telnet_session(tcp_plug,&status); 
go_home: 
	if(tcp_plug) 
		result = nr_plugs_destroy(tcp_plug); 
	return 0; 
	} 
 
// +--------------------- 
// | Blink the Link LED for a bit, 
// | then return. 
// | 
 
int r_blink_link_led(int x) 
	{ 
	int i; 
	 
#ifdef na_lan91c111_0 
	printf ("\n Link must be already active for the LAN91C111.\n"); 
#endif 
 
	printf("\n\n  Blinking the LED...\n"); 
	for(i = 0; i < 10; i++) 
		{ 
		nr_plugs_set_mac_led(0,0); 
		nr_plugs_idle(); 
		nr_delay(100); 
		nr_plugs_set_mac_led(0,1); 
		nr_plugs_idle(); 
		nr_delay(100); 
		} 
	nr_plugs_set_mac_led(0,-1); 
	printf("\n\n  Done blinking the LED.\n"); 
	} 
 
// +--------------------- 
// | Guess what the next routine does 
// | 
 
 
#endif // SMALL 
 
int r_exit_to_monitor(int x) 
	{ 
	nr_plugs_terminate(); 
 
	// Disable timer1, in case nr_timer_milliseconds() got used 
#ifdef na_timer1 
	na_timer1->np_timercontrol = np_timercontrol_stop_mask; 
	na_timer1->np_timerstatus = 0; // clear any last irq 
#endif 
 
	exit(0); 
	return 0; // (never happens) 
	} 
 
int main(void) 
	{ 
 
    setbuf(stdout,0); 
	// Call initialization routines 
 
	r_initialize(); 
 
 
	// Set up the menus, and run them 
 
	r_menu_set_idler((r_menu_proc)nr_plugs_idle); 
 
	// Settings menu 
	r_menu_add_item(k_menu_settings,"Network Settings",show_settings,0); // 1st item is title 
	r_menu_add_item(k_menu_settings,"Reset All Settings, Attempt DHCP",r_reset_settings,0); 
	r_menu_add_item(k_menu_settings,"Reinitialize",r_reinitialize,0); 
	r_menu_add_item(k_menu_settings,"Enter New Settings",r_edit_settings,0); 
	r_menu_add_item(k_menu_settings,"Save To Flash",r_save_settings,0); 
 
	// Remote menu 
 
	r_menu_add_item(k_menu_actions,"Network Actions",show_abbreviated_settings,0); // 1st item is title 
#if !SMALL 
	r_menu_add_item(k_menu_actions,"Ping Remote Host",r_ping_host,0); 
	r_menu_add_item(k_menu_actions,"Ping Remote Host (Debug On)",r_ping_host,1); 
	r_menu_add_item(k_menu_actions,"Look Up IP Address",r_dns_lookup,0); 
#endif 
	r_menu_add_item(k_menu_actions,"ARP Scan",r_arp_scan,0); 
	r_menu_add_item(k_menu_actions,"Monitor All Traffic (Sniffer)",r_sniffer,0); 
#if !SMALL 
	r_menu_add_item(k_menu_actions,"Accept Telnet Connection",r_telnet_accept,0); 
	r_menu_add_item(k_menu_actions,"Open Telnet Connection",r_telnet_connect,0); 
	r_menu_add_item(k_menu_actions,"Blink Link LED",r_blink_link_led,0); 
#endif 
 
	// Main menu 
	r_menu_add_item(0,"Main Menu",0,0); 
	r_menu_add_link(0,k_menu_settings); 
	r_menu_add_link(0,k_menu_actions); 
	r_menu_add_item(0,"Exit to monitor",r_exit_to_monitor,0); 
 
	r_menu_run(); 
	}