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

📄 pinglib.c

📁 vxWorks ping demo
💻 C
📖 第 1 页 / 共 2 页
字号:
    sprintf (tName, "tPingTx%d", seq);		/* assign unique Tx task name */    if ((pPS->idTx = taskSpawn (tName, txPriority, 0, 6000, (FUNCPTR) pingTx,	(int) pPS, (int) &to, txInterval, 0,0,0,0,0,0,0)) == ERROR)	pingError (pPS);    /* receive echo reply packets from remote host */    while (!pPS->numPacket || (pPS->numRx != pPS->numPacket))	{	if ((ix = recvfrom (pPS->pingFd, (char *) pPS->bufRx, PING_MAXPACKET,	    0, (struct sockaddr *) &from, &fromlen)) == ERROR)            {	    if (errno == EINTR)	        continue;	    break;	    }        if (ix == 0 && pPS->idTimeout == NULL)	/* shutdown from timeout ? */	    {	    if (options & PING_OPT_DEBUG)                printf ("ping: timeout\n");            errno = S_pingLib_TIMEOUT;		/* timeout error */	    break;	    }	if ((wdStart (pPS->wdTimeout, txTmo, (FUNCPTR) semGive,	    (int) pPS->semIdTimeout)) == ERROR)	/* start timeout watchdog */	    break;	pingRxPrint (pPS, ix, &from);		/* printout Rx info */        }    if (pPS->numRx > 0)	status = OK;				/* host is reachable */release:					/* error encountered */    pingFinish (taskTcb (pPS->idRx));		/* cleanup & print end stats */    return (status);    }/********************************************************************************* pingTx - send ICMP echo request packets to a remote host* * This routine sends ICMP echo request packets to the remote host* specified by the structure pointed to by <toAddr>.  Each packet* is given a sequence number and a current tick count, so that a* roundtrip time may be computed.** RETURNS:* N/A.*/LOCAL void pingTx    (    PING_STAT *		pPS,		/* ping stats structure */    struct sockaddr *	toAddr,		/* remote host address */    int			delay		/* delay between Tx packets */    )    {    int			ix;    while (1)					/* FOREVER */	{  	*pPS->pBufTime = tickGet ();		/* load current tick count */        pPS->pBufIcmp->icmp_seq = pPS->numTx++;	/* increment seq number */        pPS->pBufIcmp->icmp_cksum = 0;	pPS->pBufIcmp->icmp_cksum = checksum ((u_short *) pPS->pBufIcmp,	    _pingTxLen);			/* checksum new packet */        /* transmit ICMP packet */	if ((ix = sendto (pPS->pingFd, (char *) pPS->pBufIcmp,	    _pingTxLen, 0, toAddr, sizeof (struct sockaddr))) != _pingTxLen)	    if (pPS->flags & PING_OPT_DEBUG)	        printf ("ping: wrote %s %d chars, ret=%d\n", pPS->toHostName,		    _pingTxLen, ix);        taskDelay (delay);			/* wait Tx interval */        }    }/********************************************************************************* pingRxPrint - print out information about a received packet** This routine prints out information about a received ICMP echo reply* packet.  First, the packet is checked for minimum length and* correct message type and destination.** RETURNS:* N/A.*/LOCAL void pingRxPrint    (    PING_STAT *		pPS,		/* ping stats structure */    int			len,		/* Rx message length */    struct sockaddr_in *from		/* Rx message address */    )    {    struct ip *		ip = (struct ip *) pPS->bufRx;    long *		lp = (long *) pPS->bufRx;    struct icmp *	icp;    int			ix;    int			hlen;    int			triptime;    ulong_t		now = tickGet();    char		fromHostName [MAXHOSTNAMELEN + 1];    char		fromInetName [INET_ADDR_LEN];        /* convert address notation */    inet_ntoa_b (from->sin_addr, fromInetName);    if ((hostGetByAddr (from->sin_addr.s_addr, fromHostName)) == ERROR)	*fromHostName = NULL;			/* hostname not found */        hlen = ip->ip_hl << 2;    if (len < hlen + ICMP_MINLEN)		/* at least min length ? */	{	if (pPS->flags & PING_OPT_DEBUG)	    printf ("packet too short (%d bytes) from %s\n", len,		fromInetName);	return;        }    len -= hlen;				/* strip IP header */    icp = (struct icmp *) (pPS->bufRx + hlen);    if (icp->icmp_type != ICMP_ECHOREPLY)	/* right message ? */	{	if (pPS->flags & PING_OPT_DEBUG)	/* debug odd message */	    {	    if (*fromHostName != NULL)                printf ("%d bytes from %s (%s): ", len, fromHostName,		    fromInetName);	    else 	        printf ("%d bytes from %s: ", len, fromInetName);	    icp->icmp_type = min (icp->icmp_type, ICMP_TYPENUM); 	    printf ("icmp_type=%d\n", icp->icmp_type);	    for(ix = 0; ix < 12; ix++)	        printf ("x%2.2lx: x%8.8lx\n", (unsigned long)ix * sizeof (long), *lp++);	    printf ("icmp_code=%d\n", icp->icmp_code);	    }	return;        }    if (icp->icmp_id != (pPS->idRx & 0xffff))      return;					/* wasn't our ECHO */    /* print out Rx packet stats */    if (!(pPS->flags & PING_OPT_SILENT) && pPS->numPacket != 1)	{	if (*fromHostName != NULL)            printf ("%d bytes from %s (%s): ", len, fromHostName, fromInetName);	else             printf ("%d bytes from %s: ", len, fromInetName);        printf ("icmp_seq=%d. ", icp->icmp_seq);        triptime = (now - *((ulong_t *) icp->icmp_data)) *	    (1000 / pPS->clkTick);        printf ("time=%d. ms\n", triptime);        pPS->tSum += triptime;        pPS->tMin = min (pPS->tMin, triptime);        pPS->tMax = max (pPS->tMax, triptime);	}    pPS->numRx++;				/* bump recv count */    }/********************************************************************************* pingTimeout - shutdown a ping socket** This routine performs a shutdown of a ping raw socket.  It is called* before the ping session starts, and it immediately pends trying to* take a binary semaphore.  Once the semaphore is given by the timeout* watchdog, this routine does a shutdown on the socket, thereby unblocking* the reader(s) of the socket.** RETURNS:* N/A.*/LOCAL void pingTimeout    (    PING_STAT *		pPS		/* ping stats structure */    )    {    semTake (pPS->semIdTimeout, WAIT_FOREVER);	/* wait until tmo gives sem */    pPS->idTimeout = NULL;			/* timeout happened */    (void) shutdown (pPS->pingFd, 0);		/* shutdown ping socket */    }/********************************************************************************* pingFinish - return all allocated resources and print out final statistics** This routine returns all resources allocated for the ping session, and* prints out a stats summary.** The ping session is located in the session list (pingHead) by searching* the ping stats structure for the receiver task ID.  This is necessary* because this routine is passed a pointer to the task control block, and does* not have ready access to the ping stats structure itself.  This accomodates* the use of task delete hooks as a means of calling this routine.** RETURNS:* N/A.*/LOCAL void pingFinish    (    WIND_TCB *		pTcb		/* pointer to task control block */    )    {    PING_STAT *		pPS;			/* ping stats structure */    PING_STAT **	ppPrev;			/* pointer to prev statNext */    semTake (pingSem, WAIT_FOREVER);		/* get list access */    ppPrev = &pingHead;    for (pPS = pingHead; (pPS != NULL) && (taskTcb (pPS->idRx) != pTcb);        pPS = pPS->statNext)			/* find session in list */        ppPrev = &pPS->statNext;    if (pPS == NULL)				/* session found ? */	{        semGive (pingSem);			/* give up list access */	return;	}    *ppPrev = pPS->statNext;			/* pop session off list */    if (pingHead == NULL)        (void) taskDeleteHookDelete ((FUNCPTR) pingFinish);     semGive (pingSem);				/* give up list access */    /* return all allocated/created resources */    if (pPS->wdTimeout)	wdDelete (pPS->wdTimeout);    if (pPS->semIdTimeout)        semDelete (pPS->semIdTimeout);    if (pPS->idTx)        taskDelete (pPS->idTx);    if (pPS->idTimeout)        taskDelete (pPS->idTimeout);    if (pPS->pingFd)        (void) close (pPS->pingFd);    if (!(pPS->flags & PING_OPT_SILENT))	/* print final report ? */	{        if (pPS->numRx)				/* received at least one ? */	    {	    if (pPS->numPacket != 1)		/* full report */		{                printf ("----%s PING Statistics----\n", pPS->toHostName);                printf ("%d packets transmitted, ", pPS->numTx);                printf ("%d packets received, ", pPS->numRx);                if (pPS->numTx)                    printf ("%d%% packet loss", ((pPS->numTx - pPS->numRx) *			100) / pPS->numTx);                printf ("\n");                if (pPS->numRx)                    printf ("round-trip (ms)  min/avg/max = %d/%d/%d\n",			pPS->tMin, pPS->tSum / pPS->numRx, pPS->tMax);                }            else				/* short report */	        printf ("%s is alive\n", pPS->toHostName);            }        else	    printf ("no answer from %s\n", pPS->toHostName);	}    free ((char *) pPS);			/* free stats memory space */    }

⌨️ 快捷键说明

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