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();
}