Ping Client

Does Net+OS contain a Ping client? I want to observe the connection to a server by pinging the server at regular intervalls. Any ideas how to do this alternatively?

You have to modify the icmp.c file, where the ICMP_ECHO_REPLY request is not handled so far.

ping is done by sending a “icmp echo request” the peer will send you a “icmp echo reply”. without “ping-support” from net+os, you can send this echo request using a raw-socket or raw udp packet. you can use etherreal to find out what you have to send or read the RFC792.

Did you ever find a way to implement a ping client with NET+OS?

I mean in real application, not in bootloader?

There is a ping client available in the Treck api. Look for tfNgPingOpenStart and tfNgPingOpenStartEx in trsocket.h. You can use it in the following way (and maybe add some error handling):


int s;
char hostaddr[] = “192.168.2.1”;
struct sockaddr_storage ipNgAddr;

tfMemSet(&ipNgAddr, 0, sizeof(struct sockaddr_storage));
ipNgAddr.ss_family = AF_INET; /* IPv4 address /
ipNgAddr.ss_len = sizeof(struct sockaddr_storage);
/
set the address we want to ping */
errorCode = inet_pton(AF_INET, hostaddr, &(ipNgAddr.addr.ipv4.sin_addr));

//ping with: 500ms delay, 56KB packets, 100 pings, ID 42, call void pingReply(int socket) on ECHO_REPLY
s = tfNgPingOpenStartEx( &ipNgAddr, 500, 56, 100, (ttUser32Bit)42, (ttPingCBFuncPtr)pingReply);

// wait till done

tfPingClose(s);


Later,
Philo

While there may be a ping API buried in the Treck stack, I don’t believe this is currently supported by Digi. However, I put together my own ping client using the attached code.

Well I guess a raw socket is the right way: I send and receive the ICMP packets via a raw socket. Unfortunately the raw socket type is not described in the API reference for Net+OS 6.0. I just took SOCK_RAW as type of socket parameter in socket().

I meant “frame type” not “request”. Sorry!

thank you! did you modify the IcmpReceive routine? i guess the application image does not use the bootloader’s icmp routines. modifying the icmp.c file would take no effect to the application image, does it?

icmp.c is part of the bsp. The bsp is build as a library and linked to your application, so the application image will be affected by this changes.

In Net+OS 6.0 the image.bin is not affected by changes in the icmp.c file. The net.lib (which includes icmp.c) is only included in the bootloader image (rom.bin).

image.bin assumes that the bootloader is running. The function is called in the ethernet interrupt installed by bootloader

The Treck API is undocumented by Digi that I could find. I went to the Treck site and found a general document, but Digi seems to have modified it.

Anyway, Philo is close, but the user still needs some way to check the result. Here is what works for me:

int ping(unsigned long dwAddr)
{
int s;
struct sockaddr_storage ipNgAddr;

tfMemSet(&ipNgAddr, 0, sizeof(struct sockaddr_storage)); 
ipNgAddr.ss_family = AF_INET; /* IPv4 address */ 
ipNgAddr.ss_len = sizeof(struct sockaddr_storage); 
// set the address we want to ping
ipNgAddr.addr.ipv4.sin_addr.s_addr = dwAddr;

//ping with: 500ms delay, 56KB packets, 1 ping, ID 42
s = tfNgPingOpenStartEx( &ipNgAddr, 
                         500, 
                         56, 
                         1, 
                         (ttUser32Bit)42, 
                         (ttPingCBFuncPtr)NULL);

if( s != TM_SOCKET_ERROR )
{	
	ttPingInfo	PI;
	
	// wait till done
	unsigned long hip, lop;
	NATotalTicks(&hip, &lop);

	while( (2*BSP_TICKS_PER_SECOND) > NADeltaTicks(hip, lop)  )
	{
		tfPingGetStatistics(s, &PI);
		if( PI.pgiReceived > 0 )
		{
			tfPingClose(s);
			return TRUE;
		}
		tx_thread_sleep(BSP_TICKS_PER_SECOND/10);
	}
	
	tfPingClose(s);
}
return FALSE;

}

Yes, I have used a similar routine for years (~1991 - 2004 for Digi). The problem is that I found some machines out there don’t respond to it. (Mostly new Windows boxes.) It works 99% of the time. I switched to the treck one because it uses a real ICMP packet and works on everything.

-Erik

The code I provided creates a ‘real’ ICMP packet on the network… You actually form it from scratch.

Except that IPPROTO_ICMP is not defined, and if I manually define it (using the define from Linux), socket() returns -1.

Looking at your code, except for the headers, your lack of packing and use of defines that don’t exist in NetOS leads me to believe that you are using Linux.

Like I said, you can do it with a zero as the third parameter to socket() and it works 99% of the time (just remember to pack your structures).

-Erik