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

📄 ping.c

📁 W3100是WIZnet公司专门为以太网互联和嵌入式设备推出的硬件TCP/IP协议栈芯片
💻 C
字号:
/*
********************************************************************************
* Wiznet.
* 5F Simmtech Bldg., 228-3, Nonhyun-dong, Kangnam-gu,
* Seoul, Korea
*
* (c) Copyright 2002, Wiznet, Seoul, Korea
*
* Filename      : PING.C
* Programmer(s) : Wooyoul Kim
* Version       : 1.0 
* Created       : 2002/10/20
* Modified      : 
* Description   : Implemation of Ping
		  To send 'ping-request' to peer & To receive 'ping-reply' from peer.
********************************************************************************
*/

/*
###############################################################################
File Include Section
###############################################################################
*/
#include <reg51.h>                   	// 8051 SFR definition file
#include "serial.h"                     // serial related functions
#include "util.h"			// Useful function
#include "sockutil.h"			// Util of W3100A
#include "ping.h"                       // header file

/*
###############################################################################
Define Part
###############################################################################
*/

/*
###############################################################################
Local Variable Declaration Section
###############################################################################
*/

/*
###############################################################################
Function Implementation Section
###############################################################################
*/


/*
Description   :  Send ping-request to the specified peer and receive ping-reply from the specified peer.
Argument      :  count - Ping reqeust count. 
			 If count is -1 then to send ping request to the specified peer infinitely.
                 size  - Data size to be sent, The range is greater than 0 and less than 1460
                 time  - wait ping reply time
                 addr  - Peer Ip Address(Decimal Dotted-notation)
                 log   - result of ping
Return Value  :  1 - success, -1 - fail because free socket is not found or can't be opened.
Note          :  
*/
char ping(int count, u_int size, u_int time, char* addr, PINGLOG* log)
{
	PING xdata PingRequest;		// Variable for Ping Request
	PING xdata PingReply;		// Variable for Ping Reply
	u_long peerip;                  // 32 bit Peer IP Address
	char tempip[4];			// ip address received from a destination
	char xdata addrstr[16];         // Decimal dotted-notation IP address string
	u_int xdata port;               // port number received from a destination
	u_int i,len;
	SOCKET s = -1;                  // socket variable for pinging
	char bLoop = 0;                 // Infinite = 1, finite = 0
	char IsReceived = 0;            // Received packet = 1, not received packet = 0
	int xdata RemainTime=0;       // Remained Time for waiting to ping-reply
	
	/* Initialize PingRequest */
	static u_int xdata RandomID = 0x1234;		// Ping-Request ID
	static u_int xdata RandomSeqNum = 0x4321;       // Ping-Request packet's sequence number
	PingRequest.Type = 8;           		// Ping-Request 
	PingRequest.Code = 0;                           // always 0
	PingRequest.CheckSum = 0;                       // value of checksum before calucating checksum of ping-request packet
	PingRequest.ID = RandomID++;                    // set ping-request's ID to random integer value
	PingRequest.SeqNum = RandomSeqNum++;            // set ping-request's sequence number to ramdom integer value
	for(i = 0 ; i < 1452; i++)	PingRequest.Data[i] = 'a' + i % 23;	// fill 'a'~'w' characters into ping-request's data 

	/* Initialize result of pinging */
	(*log).CheckSumErr=0;				// Checksum Error
	(*log).UnreachableMSG=0;                        // received unreachable message
	(*log).TimeExceedMSG=0;                         // received time exceeded message
	(*log).UnknownMSG = 0;                          // received unknown message
	(*log).ARPErr=0;                                // fail to send arp-packet
	(*log).PingRequest=0;				// count of sending ping-request to the specified peer 
	(*log).PingReply=0;                             // count of receiving ping-reply from the specified peer
	(*log).Loss=0;                                  // count of occurring timeout. 

        /* Verify arguments */	
	if(count == -1) bLoop = 1;				// if it is infinite 
	else if( count < 1 || count > 0x7FFF) count = 4;        // set count to defalut value
	if(size < 1 || size > 1452)	size = 32;              // set size to default value
	if(time < 1 || time > 0x7FFF)	time = 10;              // set time to default value

	/* Create a ping socket */
	if((s = getSocket(SOCK_CLOSED,0)) == -1) return -1;	// if it isn't exist free socket, Error
	setIPprotocol(s,IPPROTO_ICMP);                          // Set upper-protocol of IP proctol
	if(socket(s,SOCK_IPL_RAW,3000,0)==-1) return -1;        // Open IP_RAW Mode , if fail then Error

	peerip = inet_addr(addr);				// convert address's string into 32bit address

	PutString("\r\nPinging ");PutString(addr);PutString(" with ");PutString(ITOA(size,addrstr,10));PutStringLn(" bytes of data :\r\n");

	/* Ping Service */
	while(bLoop || count > 0)				// if Infinite or count > 0, Loop 
	{
                if(IsPressedKey()==1)			// Is pressed "Ctrl-C" or "Ctrl-Break"?
			if(GetByte()==0x03)	bLoop=count=0;
		IsReceived = 0;
		count--;
		RemainTime = time;                              
		PingRequest.SeqNum++;                           // Increase Sequence number for next ping-request packet
		PingRequest.CheckSum = 0;
		PingRequest.CheckSum = checksum((u_char*)&PingRequest,size+8);	// update checksum field

		(*log).PingRequest++;				// Increase PingRequest's value

		if(sendto(s, (char xdata*)&PingRequest,size+8,(u_char*)&peerip,3000)==-1)	// Send Ping-Request to the specified peer. If fail, then it is occurred ARP Error.
		{
			(*log).ARPErr++;			// Increase ARPErr
			close(s);                               // close the pinging socket
			/* Reopen pinging socket */
			setIPprotocol(s,IPPROTO_ICMP);          
			if(socket(s,SOCK_IPL_RAW,3000,0)==-1) return -1;
			continue;
		}
		while(RemainTime-- > 0)	// until wait_time is remaining 
		{
			if((len = select(s,SEL_RECV)) > 0)		// Is pinging socket  received a packet?
			{
				len = recvfrom(s,(char xdata *)&PingReply,len,tempip,&port);	// receive a packet from unknown peer
				inet_ntoa((u_char*)&tempip,addrstr);                            // convert 32 bit unknown peer IP address into string of IP Address.
				PutString("Reply from ");PutString(addrstr);
				if(checksum((char xdata *)&PingReply,len) != 0)			// if the packet's checksum value is correct
				{                                                               // not correct
					(*log).CheckSumErr++;                                   // checksum error
					if( *((u_long*)tempip) == peerip ) IsReceived = 1;       
					PutStringLn(" : Checksum Error"); 
				}
				else if(PingReply.Type == 0)					// if the received packet is ping-reply 
				{
					if((PingReply.ID != PingRequest.ID) || (PingReply.SeqNum != PingRequest.SeqNum)	// verify id,sequence nubmer, and ip address
					       || (*((u_long*)tempip) != peerip) )
					{							// fail to verify 
						PutStringLn(" : Unknown peer.");
						(*log).UnknownMSG++;
					}
					else                                                    // success
					{
						IsReceived = 1;
						PutString(" : bytes=");PutString(ITOA(len-8,tempip,10));PutString(" time<");PutString(ITOA(time-RemainTime,tempip,10));PutStringLn("ms");
						(*log).PingReply++;
					}
				}
				else if( PingReply.Type == 3)  					// If the packet is unreachable message
				{                                                               
					IsReceived = 1;
					PutStringLn(" : Destination Unreachable.");
					(*log).UnreachableMSG++;
				}
				else if( PingReply.Type == 11)                 			// If the packet is time exceeded message
				{
				        IsReceived = 1;
					PutStringLn(" : TTL expired in transit.");
					(*log).TimeExceedMSG++;
				}
				else                                                            // if the packet is unknown message
				{
					PutString(" : Unknown Message. (type = ");PutString(ITOA(PingReply.Type,tempip,10));PutStringLn(")");
					(*log).UnknownMSG++;
				}
			}
			else if(select(s,SEL_CONTROL)==SOCK_CLOSED) 				// if it is occurred to fail to send arp packet
			{
				(*log).ARPErr++;
				close(s);							// close the pinging socket
				setIPprotocol(s,IPPROTO_ICMP);                                  // Reopen the pinging socket
				if(socket(s,SOCK_IPL_RAW,3000,0)==-1) return -1;
				break;
			}
			if(RemainTime == 0 && IsReceived == 0)					// If it is not received packet from the specified peer during waiting ping-reply packet.
			{
				(*log).Loss++;
				PutStringLn("Request timed out.");
			}
			wait_1us(200);
		}
	}
	PutStringLn("");

	/* Release pinging socket */
	setIPprotocol(s,0);
	close(s);
	return 1;
}


/*
Description   :  Display result of ping 
Argument      :  log - result of ping
Return Value  :  None.
Note          :  
*/
void DisplayPingStatistics(PINGLOG log)
{
	char Num[7];
	PutStringLn("Ping statistics :");
    	PutString("\tPackets: Sent = ");PutString(ITOA(log.PingRequest,Num,10));
	PutString(", Received = ");PutString(ITOA(log.PingReply+log.CheckSumErr+log.UnknownMSG+log.UnreachableMSG+log.TimeExceedMSG,Num,10));
	PutString(", Lost = ");PutStringLn(ITOA(log.Loss+log.ARPErr,Num,10));
	if(log.CheckSumErr > 0)
	{
		PutString("\t\tChecksum Error Packets = ");PutStringLn(ITOA(log.CheckSumErr,Num,10));
	}
	if(log.UnreachableMSG > 0)
	{
		PutString("\t\tUnreachable Message Packets = ");PutStringLn(ITOA(log.UnreachableMSG,Num,10));
	}
	if(log.TimeExceedMSG > 0)
	{
		PutString("\t\tTime Exceeded Messsage Packets = ");PutStringLn(ITOA(log.TimeExceedMSG,Num,10));
	}
	if(log.UnknownMSG > 0)
	{
		PutString("\t\tUnknown Message Packets = ");PutStringLn(ITOA(log.UnknownMSG,Num,10));
	}
	if(log.ARPErr > 0)
	{
		PutString("\t\tFail To Send ARP Packet  = ");PutStringLn(ITOA(log.ARPErr,Num,10));
	}
	if(log.Loss > 0)
	{
		PutString("\t\tRequest timed out = ");PutStringLn(ITOA(log.Loss,Num,10));
	}
	if(log.PingReply > 0)
	{
		PutString("\t\tPing Reply Packets = ");PutStringLn(ITOA(log.PingReply,Num,10));
	}
}

⌨️ 快捷键说明

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