📄 ping.c
字号:
/* Ping utility */
#define VERSION "0.18"
/* Debug option to use structured data (alphabetic chars 'a'-'w') */
#define ASCDATA 1 /* Set non-zero to use ASCII (not random) data in ping */
#include "ping.h"
//#define CFGFILE "tcplean.cfg" /* Default config filename */
//#define CFGEXT ".cfg" /* Default config extension */
#define REMOTEIP "192.168.253.1"
#define LOCALIP "192.168.253.2"
#define IDCFG "a"
#define NETCFG "ether ne 0x08000000"
//#define IPCFG "192.168.35.2"
#define MASKCFG "255.255.255.0"
#define GATECFG "192.168.253.1"
#define MAXNETCFG 40 /* Max length of a net config string */
#define WAITIME 1000 /* Default delay between pings (msec) */
#define MINWAIT 10 /* Minimum delay time */
#define ARPTIME 500 /* Delay between ARP cycles */
#define DATALEN 32 /* Default ICMP data length */
#define MAXTRIES 2
GENFRAME genframe; /* Frame for network Tx/Rx */
ARPKT arpkt;
IPKT ipkt;
ICMPKT icmpkt;
//char cfgfile[MAXPATH+5]=CFGFILE; /* Config filename */
//char netcfg[MAXNETCFG+1]="??"; /* Network config string */
extern BYTE bcast[MACLEN]; /* Broadcast Ethernet addr */
NODE locnode; /* My Ethernet and IP addresses */
NODE remnode; /* Remote Ethernet and IP addresses */
int floodmode; /* Flag to enable flood ping mode */
int arped; /* Flag to show if remote has been ARPed */
WORD datalen=DATALEN; /* Length of ICMP data */
WORD txseq, rxseq; /* ICMP sequence numbers */
BYTE *testdata; /* Block of test data */
LWORD remip; /* Remote IP address */
WORD waitime=WAITIME; /* Waiting time in msec */
LWORD txcount, rxcount, errcount; /* Transaction counters */
int breakflag=0; /* Flag to indicate ctrl-break pressed */
extern int netdebug; /* Debug flag: net packet display */
extern NODE *(*get_locnode_n)(int n); /* Upcall to get local node */
//extern ARPKT arpkt;
/* Prototypes */
WORD read_netconfig(NODE *np);
NODE *locnode_n(int n);
void do_transmit(GENFRAME *gfp);
int do_receive(GENFRAME *gfp);
void do_poll(void);
void disp_usage(void);
void break_handler(int sig);
extern unsigned char Readkey(void);
extern void Port_Init(void);
void Ping_test(void)
{
int i, len, err=0,tries=0;
WORD dtype;
GENFRAME *gfp;
char *p, c, temps[18];
char argv[256];
Uart_Printf("\nPING v" VERSION ""); // Sign on
get_locnode_n = locnode_n; // Set upcall ptr to func
//signal(SIGINT, break_handler); // Trap ctrl-C
Uart_Printf("\nEnter Command line:(Example: ping 192.168.253.3)\n");
p=argv;
breakflag=0;
remip=0;
tries=0;
Uart_GetString(p);
p=argv;
while (*p++!='\0') // Process command-line args
{
if ((c=*p)=='-')
{
switch (*(p+1))
{
case 'v':
case 'V': // -V: verbose (debug) mode
netdebug = 1;
break;
case 'f':
case 'F': // -F: flood mode
floodmode = 1;
break;
default: // Otherwise error
err = 1;
}
}
else if((c>=0x30)&&(c<=0x39)) // Destination IP address
{
remip = atoip(p);
while(((*p++)!=' ')&&((*p++)!='\0'));
p--;
}
}
if ((testdata=_malloc_(datalen*2))==0) // Allocate mem for test data
{
printf("Can't allocate %u bytes for test data\n", datalen*2);
//exit(1);
}
for (i=0; i<datalen*2; i++) // Test block is 2x data size
#if ASCDATA
testdata[i] = (BYTE)(i%23 + 'a'); // ..same data as DOS ping
#else
testdata[i] = (BYTE)rand(); // ..or random test data..
#endif
if (err) // Prompt user if error
disp_usage(); // Read net config
else if (!(dtype=read_netconfig(&locnode)))// Get node cfg from tcplean.cfg
// and Set &locnode;
Uart_Printf("\nInvalid configuration ");
else
{
remnode.ip = remip; // Set remote addr
memcpy(remnode.mac, bcast, MACLEN); // ..as broadcast
genframe.g.dtype = dtype; // Set frame driver type
gfp = &genframe; // Get pointer to frame
Uart_Printf("IP %s", ipstr(locnode.ip, temps));
Uart_Printf(" mask %s", ipstr(locnode.mask, temps));
if (locnode.gate)
Uart_Printf(" gate %s", ipstr(locnode.gate, temps));
if (dtype & DTYPE_ETHER)
Uart_Printf(" Ethernet %s", ethstr(locnode.mac, temps));
if (gfp->g.dtype & DTYPE_SLIP) // If SLIP..
{
arped = 1; // ..don't try ARPing!
Uart_Printf(" SLIP");
}
if (datalen > (len=icmp_maxdata(gfp)*2))// Don't exceed 2 frames
{
Uart_Printf("\nWARNING: data length reduced to %u bytes", len);
datalen = len;
}
if (!remip)
Uart_Printf("\nEntered Server mode");
else
{
// Check an IP address to see if it is on a subnet, return 0 if not
if (!on_subnet(remip, &locnode) && !locnode.gate)
Uart_Printf("\nWARNING: no gateway specified!");
Uart_Printf("\n%s ", arped ? "Pinging" : "Resolving");
Uart_Printf("%s", ipstr(gate_ip(&remnode, &locnode), temps));
}
Uart_Printf("\nPress EXINTn to exit");
while(!breakflag)
{
if (remip) // If client (not server)
{
if (tries++ > MAXTRIES) // Giving up?
{
breakflag = 1;
}
if (!arped) // If not ARPed..
{ // ..and timeout..
//if (mstimeout(&mstimer, ARPTIME))
do_transmit(gfp); //..send ARP
}
else if (floodmode) // If flood ping..
{ // ..and response or timeout
if (txseq==rxseq )//|| mstimeout(&mstimer, waitime))
{
//mstimeout(&mstimer, 0); // ..refresh timer
do_transmit(gfp); // ..transmit next packet
}
}
else // If normal pinging..
{ // ..and timeout
// if (mstimeout(&mstimer, waitime))
do_transmit(gfp); // ..transmit next packet
}
}
do_poll();
do_receive(gfp); // Check responses
if (c=Readkey()) // if Any exintX pressed,break...
{
do_poll();
while (i = do_receive(gfp))
{
do_poll();
}
breakflag = 1; // Poll net drivers
}
}
close_net(dtype);// Shut down net driver
}
free(testdata); // Free test data memory
Uart_Printf("ICMP echo: %lu sent, %lu received, %lu errors\n",
txcount, rxcount, errcount);
}
/* Read network config file to get IP address netmask and gateway
Complete configing the node struct
** Return driver type, 0 if error */
WORD read_netconfig(NODE *np)
{
WORD dtype=0;
BYTE b;
np->ip=atoip(LOCALIP); /* Get local node's IP*/
dtype = open_net(NETCFG); /* read net type from tcplean.cfg */
memcpy(np->mac, ether_addr(dtype), MACLEN);/* Get local MAC*/
b = (BYTE)(np->ip >> 24);
np->mask = atoip(MASKCFG);//temps); /* Get netmask */
np->gate = atoip(GATECFG);//temps); /* Get gateway IP addr */
return(dtype);
}
/* Return ptr to local node 'n' (n=0 for first), return 0 if doesn't exist
** Used by IP functions to get my netmask & gateway addresses */
NODE *locnode_n(int n)
{
return(n==0 ? &locnode : 0);
}
/* Do next transmission cycle */
void do_transmit(GENFRAME *gfp)
{
ICMPKT *icmp;
BYTE *data;
int txlen;
if (!arped) /* If not arped, send ARP */
{
//Uart_Printf("ARP "); /* Make packet */
txlen = make_arp(gfp, &locnode, &remnode, ARPREQ);
}
else
{
icmp = getframe_datap(gfp); /* Send echo req */
icmp->c.seq = ++txseq;
#if ASCDATA
data = testdata; /* ..using plain data */
#else
data = &testdata[txseq%datalen-1]; /* ..or random */
#endif
memcpy(icmp->data, data, datalen);
icmp->c.ident = 1; /* Make packet */
txlen = make_icmp(gfp, &locnode, &remnode, ICREQ, 0, datalen);
txcount++;
}
put_frame(gfp, txlen); /* Transmit packet */
}
/* Check for incoming packets, send response if required */
int do_receive(GENFRAME *gfp)
{
NODE node;
ICMPKT *icmp;
IPKT *ip;
ARPKT *arp;
BYTE *data;
int rxlen, txlen, len,ret=0;
char temps[18];
if ((rxlen=get_frame(gfp)) > 0) /* Any incoming frames? */
{
ip = getframe_datap(gfp);
data=(BYTE *)getframe_datap(gfp);
if (is_arp(gfp, rxlen))
{ /* ARP response? */
arp = &arpkt;//getframe_datap(gfp);
if (arp->op==ARPRESP && arp->sip==remip)
{
memcpy(remnode.mac, arp->smac, MACLEN);
arped = 1;
}
else if (arp->op==ARPREQ && arp->dip==locnode.ip)
{ /* ARP request? */
node.ip = arp->sip; /* Make ARP response */
memcpy(node.mac, arp->smac, MACLEN);
txlen = make_arp(gfp, &locnode, &node, ARPRESP);
put_frame(gfp, txlen); /* Send packet */
}
else
Uart_Printf("\nReceive a unknown ARP packet.");
}
else if ((rxlen=is_ip(gfp, rxlen))!=0) //&& // IP datagram?
{
ip=&ipkt;
if( (ip->i.dip==locnode.ip) || (ip->i.dip==BCASTIP))
{
if ((rxlen=is_icmp(ip, rxlen))!=0) // ICMP?
{
icmp = (ICMPKT *)ip;
if (icmp->c.type == ICREP) // Echo response?
{
Uart_Printf("\nReply from %s seq=%u len=%u ",
ipstr(icmp->i.sip, temps), icmp->c.seq, rxlen);
rxseq = icmp->c.seq; // Check response
#if ASCDATA
data = testdata;
#else
data = &testdata[rxseq%datalen];
#endif
if (rxlen==datalen && !memcmp(icmp->data, data, rxlen))
{
Uart_Printf("OK\n");
rxcount++;
}
else
{
Uart_Printf("ERROR\n");
errcount++;
}
}
else if (icmp->c.type==ICREQ) // Echo request?
{
getip_srce(gfp, &node);
len = (WORD)maxi(rxlen, 0); // Make response
txlen = make_icmp(gfp, &locnode, &node, ICREP,
icmp->c.code, (WORD)len);
put_frame(gfp, txlen); // Send packet
}
}
else
Uart_Printf("\n Receive a unknow IP packet.");
}
}
ret=1;
}
return(ret);
}
/* Poll the network interface to keep it alive */
void do_poll(void)
{
poll_net(genframe.g.dtype);
}
/* Display usage help */
void disp_usage(void)
{
Uart_Printf("Usage: PING [options] [IP_addr]\n");
Uart_Printf(" If no IP address given, enters server mode\n");
Uart_Printf("Options: \n");
Uart_Printf(" -v Verbose (debug) mode\n");
Uart_Printf("Example: PING -v 192.168.253.1\n");
}
/* Ctrl-break handler: set flag and return */
void break_handler(int sig)
{
breakflag = sig;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -