app_ping.c

来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 763 行 · 第 1/2 页

C
763
字号
/*
 * FILENAME: app_ping.c
 *
 * Copyright 1997- 2000 By InterNiche Technologies Inc. All rights reserved
 *
 * Generic ping command 
 * for sample utilitys. This uses the utilities in ..\inet\ping.c 
 * which comtains the fully portable but less functional ping lower 
 * layer. This is somewhat attached to the menus system, but outside 
 * of that is fairly portable; assumeing cticks & other NetPort IP 
 * system basics are present.
 *
 * MODULE: MISCLIB
 *
 * ROUTINES: ping_init(), ping_new(), ping_delete(), ping_addq(), 
 * ROUTINES: ping_delq(), ping_search(), ping_start(),  ping_send(), 
 * ROUTINES:ping_end(), pingUpcall(), ping_recv(), ping_check(),
 * ROUTINES: ping_demux(), ping_stats(),
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */
/* Portions Copyright 1993 by NetPort software */

#include "ipport.h"

#ifdef PING_APP   /* whole file can be ifdefed out */

#include "in_utils.h"

/* On superloop systems, define away task supoport */

#ifdef SUPERLOOP
#define  TK_WAKE(task)
#define  TK_BLOCK()
#endif   /* SUPERLOOP */

#include "q.h"
#include "netbuf.h"
#include "net.h"
#include "ip.h"
#include "icmp.h"

#include "menu.h"
#include "app_ping.h"

#include "dns.h"      


PING_INFO pingq = NULL;    /* Pointer to the first ping session */


struct   queue    pingRcvq;      /* received but unprocessed ping replys */
extern   char *   prompt;
extern   ip_addr  activehost;    /* default ping host */
extern   u_long   pingdelay;     /* 1 second between pings */
extern   int      deflength;     /* default ping packet data length */


#ifdef IN_MENUS
/* array of menu option, see menu.h */
struct menu_op settings[] = 
{
   "ping",     stooges,        "menu to set/view values for ping",
   "ping",     ping_start,     "Ping [host] [#times]",
   "endping",  ping_end,       "terminate the current ping session",
   "pstats",   ping_stats,     "display statistics about ping",
   NULL,
};
#endif   /* IN_MENUS */

/* FUNCTION: ping_init()
 * 
 * Initialize for pinging operations. Presently this function adds
 * the ping menu to MAIN menu.
 *
 * PARAM1: void
 *
 * RETURNS: 0
 */

int 
ping_init(void)
{
   pingq=NULL ;    

#ifdef IN_MENUS
   install_menu(settings);
#endif   /* IN_MENUS */
   return 0;
}


/* FUNCTION: ping_new()
 * 
 * 1. Allocate memory for a PingInfo structure Initialise elements
 *    to default values.
 * 2. Add it to the global queue, so that ping_check() can do the
 * house keeping. 
 *
 * PARAM1: none
 *
 * RETURNS: Pointer to the newly allocated structure 
 */

PING_INFO 
ping_new(void)
{
   PING_INFO p;

   p=(PING_INFO)PING_ALLOC(sizeof(struct PingInfo)) ;
   if ( p == NULL )
   {
      /* Memory allocation failed. */
      dtrap("app_ping 0\n");
   }
   else
   {
      if ( ping_addq(p) != SUCCESS )
      {
         /* Can't add to queue */
         dtrap("app_ping 1\n");
         ping_delete(p);
         p=NULL;
      }
      else
      {
         p->delay      =pingdelay;
         p->length     =deflength;
         p->ipadd      =activehost;
         p->nextping   =0;
         p->times      =1L;
         p->pio        =NULL;
         p->out        =0;             /* reset counters */
         p->in         =0;
      }
   }

   return p;
}


/* FUNCTION: ping_delete()
 * 
 * 1. Remove the PingInfo structure from the global queue.
 * 2. Free memory allocated for it.
 *
 * PARAM1: PING_INFO p - Pointer to PingInfo structure (IN)
 *
 * RETURNS: 0 on SUCCESS or ENP_ error code.
 */

int 
ping_delete(PING_INFO p)
{
   int   retValue=SUCCESS;

   if ( p == NULL )
      return PING_DEL_NULL_ARGUMENT ;

   /* Remove the connection from the queue */
   retValue = ping_delq(p) ;
   if ( retValue != SUCCESS )
   {
      dtrap("app_ping 2\n");
   }

   PING_FREE(p);
   p=NULL;

   return retValue;
}



/* FUNCTION: ping_addq()
 * 
 * Add a PingInfo object to global queue (of open connections)
 *
 * PARAM1: PING_INFO p - Pointer to object to be added
 *
 * RETURNS: 0 on SUCCESS or ENP_ error code.
 */

int 
ping_addq(PING_INFO p)
{
   if ( pingq == NULL )     
   {
      /* Queue is empty */
      pingq=p;
      p->next = NULL ;
   }
   else
   {
      /* Add it to the front of the queue */
      p->next = pingq ;
      pingq=p;
   }
   return SUCCESS ;
}



/* FUNCTION: ping_delq()
 * 
 * Delete a PingInfo object from the global queue
 * No Free (deallocation) is done. Only the queue is updated 
 *
 * PARAM1: PING_INFO p - Pointer to object to be deleted
 *
 * RETURNS: 0 on SUCCESS or ENP_ error code.
 */

int 
ping_delq(PING_INFO p)
{
   PING_INFO temp_obj;
   PING_INFO prev_obj;

   if ( p == NULL )
   {
      return PING_DELQ_BAD_OBJECT ;
   }

   if ( pingq == NULL )     
   {
      /* Queue is empty */
      return PING_DELQ_Q_EMPTY ;
   }
   else
   {
      /* Find the item and delete it */

      /* Check if it is the first item */
      if ( pingq == p )
      {
         /* Yes it is the first in the queue */
         pingq=p->next ;
         return SUCCESS ;
      }

      /* Find in the rest of the queue */
      prev_obj = pingq ;
      temp_obj = pingq->next ;

      while ( temp_obj !=NULL ) 
      {
         if ( temp_obj == p )
         {
            prev_obj->next = temp_obj->next ;
            return SUCCESS ;
         }
         prev_obj = temp_obj ;
         temp_obj = temp_obj->next ;
      }

      if ( temp_obj == NULL )
         return PING_DELQ_OBJ_NOT_FOUND ;

   }
   return SUCCESS;
}


/* FUNCTION: ping_search()
 * 
 * Ping can be done by multiple 
 * mechnisms (standard menu, telnet etc.). We will have only one ping 
 * session per mechanism. It is assumed that each mechanism (eg a 
 * telnet session) will use a unique GEN_IO structure. This function 
 * searches the list of PingInfo structures to find a match. Returns 
 * a pointer to PingInfo struct on success. Otherwise returns NULL. 
 * Remarks : This function can be used for finding out if we already 
 * have ping session or not (for a particular telnet session). It 
 * will be used when 1. User wants to do a new ping 2. User wants to 
 * terminate an earlier ping.
 *
 * PARAM1: GEN_IO pio - device for console output
 *
 * RETURNS: Pointer to PingInfo structure (if found). Otherwise NULL. 
 */

PING_INFO 
ping_search(GEN_IO pio)
{
   PING_INFO p;

   p=pingq;
   while ( p )
   {
      if ( p->pio == pio )
         break ;
      else
         p = p->next ;
   }

   return p;
}



/* FUNCTION: ping_start()
 * 
 * Called from menus to do a ping. 
 * Will handle an optional hosts name to ping and number of times to 
 * ping on the command line. Defaults to 1 ping to the active host. 0 
 * times will ping forever.
 *
 * PARAM1: GEN_IO pio - device for console output
 *
 * RETURNS: 0 on success, or one of the PING error codes
 */

int
ping_start(void * pio)
{
   int   e;
   char *   arg2;
   char *   arg3;
   char *   name;
   ip_addr ipadd;
   long  ping_times=1L;

   PING_INFO p;

   ipadd = activehost;
   arg2  = nextarg(((GEN_IO)pio)->inbuf);       /* get 1 or 2 args from command line */
   arg3  = nextarg(arg2);
   name  = arg2 ;

   if (*arg3)  /* If arg3 is present, null terminate arg2 */
   {
      while (*arg2 > ' ') arg2++ ;  /* scan to end of arg2 */
         *arg2 = 0;  /* null terminate string */
      arg2 = name;   /* Restore arg2 to start of string */
   }

   /* The second argument is either hostname(IP/dnsname) or number of times */
   if (*arg2)  /* first arg may be number or host */
   {
      /* if it's all digits, assume number */
      while (*arg2 > ' ')
      {
         if (*arg2 > '9' || *arg2 < '0')
         {
            /* not a digit; assume arg2 is a name */
            e = in_reshost(name, &ipadd, RH_VERBOSE | RH_BLOCK);
            if (e)
            {
               ns_printf(pio,"Unable to set up ping host \"%s\"\n", name);
               return -1;
            }
            break;   /* with arg2 pointer at non-digit && non-space */
         }
         arg2++;     /* check next char of arg */
      }
      if (*arg2 <= ' ') /* 2nd arg looks like a count */
      {
         ping_times = atol(name);
         if ((ping_times == 0) && (*name !='0'))
            ping_times=-1;    /* So that the error below can be displayed */ 
      }
   }
   if (*arg3)  /* if user specified 2 args, 2nd ard is ping_times */
   {
      ping_times = atol(arg3);
      if ((ping_times == 0) && (*arg3 !='0'))
         ping_times=-1;    /* So that the error below can be displayed */ 
   }

   if (ping_times < 0)
   {
      ns_printf(pio,"last arg must be number of times to ping (1-n)\n");
      ns_printf(pio,"or use 0 to ping forever. Default is 1\n");
      return PING_ST_BAD_ARG2;
   }

   if (!ipadd)
   {
      ns_printf(pio,"specify valid IP host, or use default active host\n");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?