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

📄 ping.c

📁 一种基于ARM7的嵌入式Webserver
💻 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 + -