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

📄 pinglib.c

📁 vxWorks ping demo
💻 C
📖 第 1 页 / 共 2 页
字号:
/* pingLib.c - Packet InterNet Grouper (PING) library *//* Copyright 1994-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).01j,12mar99,p_m  Fixed SPR 8742 by documentating ping() configuration global                 variables.01i,05feb99,dgp  document errno values01h,17mar98,jmb  merge jmb patch of 04apr97 from HPSIM: corrected                 creation/deletion of task delete hook.01g,30oct97,cth  changed stack size of tPingTxn from 3000 to 6000 (SPR 8222).01f,26aug97,spm  removed compiler warnings (SPR #7866)01e,30sep96,spm  corrected ping error for little-endian machines (SPR #4235)01d,13mar95,dzb  changed to use free() instead of cfree() (SPR #4113)01c,24jan95,jdi  doc tweaks01b,10nov94,rhp  minor edits to man pages01a,25oct94,dzb  written*//*DESCRIPTIONThis library contains the ping() utility, which tests the reachabilityof a remote host.The routine ping() is typically called from the VxWorks shell to check thenetwork connection to another VxWorks target or to a UNIX host.  ping()may also be used programmatically by applications that require such a test.The remote host must be running TCP/IP networking code that responds toICMP echo request packets.  The ping() routine is re-entrant, thus maybe called by many tasks concurrently.The routine pingLibInit() initializes the ping() utility and allocatesresources used by this library.  It is called automatically whenthe configuration macro INCLUDE_PING is defined.*//* includes */#include "vxWorks.h"#include "string.h"#include "stdioLib.h"#include "wdLib.h"#include "netLib.h"#include "sockLib.h"#include "inetLib.h"#include "semLib.h"#include "taskLib.h"#include "taskHookLib.h"#include "hostLib.h"#include "ioLib.h"#include "tickLib.h"#include "sysLib.h"#include "vxLib.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "netinet/ip_icmp.h"#include "pingLib.h"/* defines */#define pingError(pPS)	{ pPS->flags |= PING_OPT_SILENT; goto release; }/* globals */int	_pingTxLen = 64;			/* size of icmp echo packet */int	_pingTxInterval = PING_INTERVAL;	/* packet interval in seconds */int	_pingTxTmo = PING_TMO;			/* packet timeout in seconds */extern	int errno;/* locals */LOCAL PING_STAT	*	pingHead = NULL;	/* ping list head */LOCAL SEM_ID		pingSem = NULL;		/* mutex for list access */LOCAL int		pingSeq = 0;		/* spawned task seq counter *//* static forward declarations */LOCAL void pingTx (PING_STAT *pPS, struct sockaddr *toAddr, int delay);LOCAL void pingRxPrint (PING_STAT *pPS, int len, struct sockaddr_in *from);LOCAL void pingTimeout (PING_STAT *pPS);LOCAL void pingFinish (WIND_TCB *pTcb);/********************************************************************************* pingLibInit - initialize the ping() utility** This routine allocates resources used by the ping() utility.* It must be called before ping() is used.  It is called automatically* when the configuration macro INCLUDE_PING is defined.** RETURNS:* OK, or ERROR if the ping() utility could not be initialized.*/STATUS pingLibInit (void)    {    if (pingSem == NULL)			/* already initialized ? */	{	if ((pingSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |	    SEM_INVERSION_SAFE)) == NULL)	    return (ERROR);        }    return (OK);    }/********************************************************************************* ping - test that a remote host is reachable** This routine tests that a remote host is reachable by sending ICMP* echo request packets, and waiting for replies.  It may called from* the VxWorks shell as follows:* .CS*    -> ping "remoteSystem", 1, 0* .CE* where <remoteSystem> is either a host name that has been previously added* to the remote host table by a call to hostAdd(), or an Internet address in* dot notation (for example, "90.0.0.2").** The second parameter, <numPackets>, specifies the number of ICMP packets* to receive from the remote host.  If <numPackets> is 1, this routine waits* for a single echo reply packet, and then prints a short message* indicating whether the remote host is reachable.  For all other values* of <numPackets>, timing and sequence information is printed as echoed* packets are received.  If <numPackets> is 0, this routine runs continuously.* * If no replies are received within a 5-second timeout period, the* routine exits.  An ERROR status is returned if no echo replies* are received from the remote host.** The following flags may be given through the <options> parameter:* .iP PING_OPT_SILENT* Suppress output.  This option is useful for applications that * use ping() programmatically to examine the return status.* .iP PING_OPT_DONTROUTE* Do not route packets past the local network.** .RS 4 4* \&NOTE: The following global variables can be set from the target shell* or Windsh to configure the ping() parameters:* .iP _pingTxLen * Size of the ICMP echo packet (default 64).* .iP _pingTxInterval* Packet interval in seconds (default 1 second).* .iP _pingTxTmo* Packet timeout in seconds (default 5 seconds).*.RE** RETURNS:* OK, or ERROR if the remote host is not reachable.** ERRNO: EINVAL, S_pingLib_NOT_INITIALIZED, S_pingLib_TIMEOUT**/STATUS ping    (    char *		host,		/* host to ping */    int			numPackets,	/* number of packets to receive */    ulong_t		options		/* option flags */    )    {    PING_STAT *		pPS;			/* current ping stat struct */    struct sockaddr_in	to;			/* addr of Tx packet */    struct sockaddr_in	from;			/* addr of Rx packet */    int			fromlen = sizeof (from);/* size of Rx addr */    int			ix = 1;			/* bytes read */    int			txPriority;		/* priority of Tx task */    int			txInterval;		/* packet interval in ticks */    int			txTmo;			/* packet timeout in ticks */    int			seq = pingSeq++;	/* unique sequence number */    char		tName [PING_TASK_NAME_LEN]; /* spawned names */    STATUS		status = ERROR;		/* return status */    if (pingSem == NULL)			/* already initialized ? */        {	errno = S_pingLib_NOT_INITIALIZED;	return (ERROR);	}    if (numPackets < 0)				/* numPackets positive ? */	{	errno = EINVAL;	return (ERROR);	}    /* allocate size for ping statistics/info structure */    if ((pPS = (PING_STAT *) calloc (1, sizeof (PING_STAT))) == NULL)	return (ERROR);    semTake (pingSem, WAIT_FOREVER);		/* get access to list */    pPS->statNext = pingHead;			/* push session onto list */    if (pingHead == NULL)        if (taskDeleteHookAdd ((FUNCPTR) pingFinish) == ERROR)	    {	    free ((char *) pPS);            semGive (pingSem);			/* give up access to list */	    return (ERROR);	    }    pingHead = pPS;    semGive (pingSem);				/* give up access to list */    pPS->tMin = 999999999;			/* init min rt time */    pPS->numPacket = numPackets;		/* save num to send */    pPS->flags = options;			/* save flags field */    pPS->clkTick = sysClkRateGet ();		/* save sys clk rate */    taskPriorityGet (0, &txPriority);    txPriority = min (255, txPriority + 1);	/* Tx task 1 lower priority */    txInterval = _pingTxInterval * pPS->clkTick;/* init interval value */    txTmo = _pingTxTmo * pPS->clkTick;		/* init timeout value */    pPS->pBufIcmp = (struct icmp *) pPS->bufTx;	/* pointer to icmp header out */    pPS->pBufTime = (ulong_t *) (pPS->bufTx + 8);/* pointer to time out */    pPS->idRx = taskIdSelf ();			/* get own task Id  */    /* create sem for timing out a pended socket read */    if ((pPS->semIdTimeout = semBCreate (SEM_Q_FIFO, SEM_EMPTY)) == NULL)	pingError (pPS);    /* initialize the socket address struct */    to.sin_family = AF_INET;    if ((to.sin_addr.s_addr = inet_addr (host)) == ERROR)	{	if ((to.sin_addr.s_addr = hostGetByName (host)) == ERROR)	    {            if (!(options & PING_OPT_SILENT))	        printf ("ping: unknown host %s\n", host);	    pingError (pPS);	    }	inet_ntoa_b (to.sin_addr, pPS->toInetName);        }        strcpy (pPS->toHostName, host);		/* save host name */    _pingTxLen = min (_pingTxLen, PING_MAXPACKET);/* sanity check global */    pPS->dataLen = _pingTxLen - 8;		/* compute size of data */    /* open raw socket for ICMP communication */    if ((pPS->pingFd = socket (AF_INET, SOCK_RAW, ICMP_PROTO)) < 0)	pingError (pPS);    sprintf (tName, "tPingTmo%d", seq);		/* assign unique task name */    if ((pPS->idTimeout = taskSpawn (tName, 0, 0, 3000, (FUNCPTR) pingTimeout,        (int) pPS, 0,0,0,0,0,0,0,0,0)) == ERROR)	pingError (pPS);        if (options & PING_OPT_DONTROUTE)		/* disallow packet routing ? */        if (setsockopt (pPS->pingFd, SOL_SOCKET, SO_DONTROUTE, (char *) &ix,	    sizeof (ix)) == ERROR)	    pingError (pPS);    if (!(options & PING_OPT_SILENT) && pPS->numPacket != 1)	{        printf ("PING %s", pPS->toHostName);	/* print out dest info */        if (pPS->toInetName[0])            printf (" (%s)", pPS->toInetName);        printf (": %d data bytes\n", pPS->dataLen);	}        pPS->pBufIcmp->icmp_type = ICMP_ECHO;	/* set up Tx buffer */    pPS->pBufIcmp->icmp_code = 0;    pPS->pBufIcmp->icmp_id = pPS->idRx & 0xffff;    for (ix = 4; ix < pPS->dataLen; ix++)	/* skip 4 bytes for time */        pPS->bufTx [8 + ix] = ix;    if ((pPS->wdTimeout = wdCreate()) == NULL)	/* create timeout watchdog */	pingError (pPS);    if ((wdStart (pPS->wdTimeout, txTmo, (FUNCPTR) semGive,        (int) pPS->semIdTimeout)) == ERROR)	/* start timeout watchdog */	pingError (pPS);

⌨️ 快捷键说明

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