📄 ping.c
字号:
/* Ping utility for 'TCP/IP Lean' (c) Iosoft Ltd. 2000
This software is only licensed for distribution with the book 'TCP/IP Lean',
and may only be used for personal experimentation by the purchaser
of that book, on condition that this copyright notice is retained.
For commercial licensing, contact license@iosoft.co.uk
This is experimental software; use it entirely at your own risk. The author
offers no warranties of any kind, including its fitness for purpose. */
/*
** v0.01 JPB 3/1/00
** v0.02 JPB 7/1/00 Added random data
** Added ICMP data size limit
** v0.03 JPB 11/1/00 Fixed divide-by-zero if zero data length specified
** v0.04 JPB 17/1/00 Changed 'netframe' to 'genframe', added fragment offset
** v0.05 JPB 17/1/00 Added transmit fragmentation
** v0.06 JPB 18/1/00 Added receive framentation
** v0.07 JPB 19/1/00 Added logfile capability
** Split off network functions from tcpfs.c into net.c
** v0.08 JPB 20/1/00 Added support for multiple networks
** v0.09 JPB 20/1/00 Improved packet demultiplexing
** v0.10 JPB 24/1/00 Removed subframe ptrs - subframe is now appended to frame
** IP headers with options are now resized
** v0.11 JPB 25/1/00 Added gateway capability
** v0.12 JPB 27/1/00 Adapted for compatibility with router code
** v0.13 JPB 24/2/00 Changed keyscan to ESC or ctrl-C
** v0.14 JPB 25/2/00 Removed server mode switch (use absence of IP address)
** v0.15 JPB 29/2/00 Fixed bug in non-Ethernet logging
** v0.16 JPB 1/3/00 Fixed 'gate_ip' problem when no gateway specified
** v0.17 JPB 23/3/00 Used upcall pointers in TCP.C
** v0.18 JPB 3/7/00 Changed default config file to TCPLEAN.CFG
** Revised header for book CD
*/
#define VERSION "0.18"
/* Debug option to use structured data (alphabetic chars 'a'-'w') */
#define ASCDATA 0 /* Set non-zero to use ASCII (not random) data in ping */
#include <stdio.h>
#include <ctype.h>
//#include <stdlib.h>
#include <string.h>
//#include <conio.h>
//#include <signal.h>
#include "ether.h"
#include "netutil.h"
#include "net.h"
#include "ip.h"
//#include "ping.h"
#include "uart.h"
#include "mac.h"
#define CFGFILE "tcplean.cfg" /* Default config filename */
#define CFGEXT ".cfg" /* Default config extension */
#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 */
//int ReceiveBuffer_empty(void); //判断缓冲区是否空
//void i_printf(char * /*formatted output*/, ...);
GENFRAME genframe; /* Frame for network Tx/Rx */
//char cfgfile[MAXPATH+5]=CFGFILE; /* Config filename */
//char netcfg[MAXNETCFG+1]="??"; /* Network config string */
extern BYTE bcast[6]; /* Broadcast Ethernet addr */
extern volatile U8 MyMacSrcAddr[6] ;
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; /* 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 UserBuff UserReceiveBuff; //输入缓冲区
/* Prototypes */
WORD read_netconfig(char *fname, NODE *np);
NODE *locnode_n(int n);
void do_transmit(GENFRAME *gfp);
void do_receive(GENFRAME *gfp);
void do_poll(void);
void disp_usage(void);
void break_handler(int sig);
//extern void test_ping();
void i_printf(char * /*formatted output*/, ...);
void test_ping(void)
{
// int i, args=0, len, err=0;
// LWORD mstimer;
// WORD dtype;
GENFRAME *gfp;
char *p, c, temps[18];
int i;
locnode.dtype=0;
for(i=0;i<MACLEN;i++)
locnode.mac[i]=MyMacSrcAddr[i];
locnode.ip=10; //ip 10.11.112.5
locnode.ip=(locnode.ip<<8)+11;
locnode.ip=(locnode.ip<<8)+112;
locnode.ip=(locnode.ip<<8)+5;
locnode.mask=255; //mask 255.255.255.0
locnode.mask=(locnode.mask<<8)+255;
locnode.mask=(locnode.mask<<8)+255;
locnode.mask=(locnode.mask<<8)+255;
locnode.mask=(locnode.mask<<8)+0;
locnode.gate=10; //gate 10.11.112.1
locnode.gate=(locnode.gate<<8)+11;
locnode.gate=(locnode.gate<<8)+112;
locnode.gate=(locnode.gate<<8)+1;
i_printf("Ready for PING\n "); /* Sign on */
for(;;)
{
if (UserReceiveBuff.head!=UserReceiveBuff.rear) //从缓冲区读数据
{
genframe.g.len=UserReceiveBuff.length[UserReceiveBuff.head];
genframe.g.dtype=DTYPE_ETHER; //以太网类型数据包
genframe.g.fragoff=0;
memcpy(genframe.buff,(char *)(&UserReceiveBuff.frame[UserReceiveBuff.head]),genframe.g.len);
//复制数据
//for(i=0;i<genframe.g.len;i++)
// { genframe.buff[i]=UserReceiveBuff.frame[UserReceiveBuff.head]
// .LLCData[i];
// }
// ShowFrame(&UserReceiveBuff.frame[UserReceiveBuff.head]); //打印以太网数据包
UserReceiveBuff.head=(UserReceiveBuff.head+1)%UserBuffSize;
gfp=&genframe;
if(netdebug)
disp_frame(gfp, gfp->g.len, 0); //显示数据包
do_receive(gfp);
}
}
}
/* 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
{
printf("ARP "); /* Make packet
txlen = make_arp(gfp, &locnode, &remnode, ARPREQ);
}
else
{
icmp =(ICMPKT *) getframe_datap(gfp); /* Send echo req
icmp->c.seq = ++txseq;
#if ASCDATA
data = testdata; /* ..using plain data
#else
data = &testdata[txseq%datalen]; /* ..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 */
void do_receive(GENFRAME *gfp)
{
NODE node;
ICMPKT *icmp;
IPKT *ip;
ARPKT arp;
BYTE *data;
int rxlen, txlen, len;
char temps[18];
int i;
// WORD op;
// LWORD sip,dip;
rxlen=gfp->g.len;
if ((rxlen/*=get_frame(gfp)*/) > 0) /* Any incoming frames? */
{
ip =&(gfp->buff[0xe]);//(IPKT *) getframe_datap(gfp);
if (is_arp(gfp, rxlen))
{ /* ARP response? */
// arp =(ARPKT *) getframe_datap(gfp);
// memcpy(&arp,&(gfp->buff[0xe]),sizeof(arp));
arp.hrd=gfp->buff[0xe];
arp.hrd=(arp.hrd<<8)+gfp->buff[0xf];
arp.pro=gfp->buff[0x10];
arp.pro=(arp.pro<<8)+gfp->buff[0x11];
arp.hln=gfp->buff[0x12];
arp.pln=gfp->buff[0x13];
arp.op=gfp->buff[0x14]; //arp操作码
arp.op=(arp.op<<8)+gfp->buff[0x15];
for (i=0;i<MACLEN;i++) //源MAC地址
arp.smac[i]=gfp->buff[0x16+i];
arp.sip=gfp->buff[0x1c]; //arp源IP
arp.sip=(arp.sip<<8)+gfp->buff[0x1d];
arp.sip=(arp.sip<<8)+gfp->buff[0x1e];
arp.sip=(arp.sip<<8)+gfp->buff[0x1f];
for (i=0;i<MACLEN;i++) //目的MAC地址
arp.dmac[i]=gfp->buff[0x20+i];
arp.dip=gfp->buff[0x26]; //arp目的IP
arp.dip=(arp.dip<<8)+gfp->buff[0x27];
arp.dip=(arp.dip<<8)+gfp->buff[0x28];
arp.dip=(arp.dip<<8)+gfp->buff[0x29];
if (arp.op==ARPRESP && arp.sip==remip)
{
memcpy(remnode.mac, arp.smac, MACLEN);
printf("OK\n");
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 */
if(netdebug)
disp_frame(gfp, txlen, 1); //显示数据包
}
return;
}
rxlen=is_ip(gfp, rxlen);
// printf("received ip %x H, local ip %x H",ip->i.dip,locnode.ip);
//else if ((rxlen=is_ip(gfp, rxlen))!=0) && /* IP datagram? */
// ip->i.dip==locnode.ip || ip->i.dip==BCASTIP)
if((rxlen!=0)&&(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? */
{
printf("Reply 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))
{
printf("OK\n");
rxcount++;
}
else
{
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 */
if(netdebug)
disp_frame(gfp, txlen, 1); //显示数据包
}
}
}
}
}
/* Poll the network interface to keep it alive */
/*void do_poll(void)
{
poll_net(genframe.g.dtype);
}*/
/* 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 + -