[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] RE : ICMP ping send/receive
From: |
Frédéric BERNON |
Subject: |
[lwip-users] RE : ICMP ping send/receive |
Date: |
Thu, 11 Oct 2007 17:45:21 +0200 |
(Note I reply with the list in copy)
This is a part of code I use to send "ping" (I suppose there is some other ping
availables with netconn & raw api). Note it need CVS HEAD for LWIP_SO_RCVTIMEO
option (need to be set to 1 in your lwipopts.h). Sorry, comments are in french
(but code is simple). There is two functions specific to my port (but I think
you can easily create) :
/**
* return number of milliseconds since boot time (or any other reference)
*/
u32_t sys_start_tickcount();
/**
* return number of milliseconds since "ref"
*/
u32_t sys_stop_tickcount( u32_t ref);
/*----------------------------------------------------------------------------*/
int Ping( u32_t addr, u32_t length, int verbose)
/*----------------------------------------------------------------------------*/
{ /* Variables de travail */
int iResult = 0;
#if LWIP_SOCKET && LWIP_ICMP
static int seq_num = 0;
int timeout = PING_TIMEOUT;
int err = 0;
int iIndex;
int hSocket;
u32_t ulTickCount;
char reply[64];
struct icmp_echo_hdr* pecho;
struct icmp_echo_hdr* pechoreply=(struct icmp_echo_hdr*)reply;
struct sockaddr_in saLocal;
struct sockaddr_in to;
int fromlen;
struct sockaddr_in from;
/* Affichage dans la console */
if (verbose) printf("Ping %lu.%lu.%lu.%lu : bytes=%i\n", ((addr &
0x000000FF)>>0), ((addr & 0x0000FF00)>>8), ((addr & 0x00FF0000)>>16), ((addr &
0xFF000000)>>24), length);
/* Allocation de la trame à envoyer... */
if (!(pecho = malloc(sizeof(struct icmp_echo_hdr)+length))) return ENOMEM;
/* Remplissage de la donnée de la trame ICMP "Echo" */
for( iIndex=0; iIndex<length; iIndex++)
{ ((char*)(pecho))[sizeof(struct icmp_echo_hdr)+iIndex]=('a'+(iIndex%26));
}
/* Ouverture d'une socket en mode "raw" pour ICMP */
hSocket = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
if (hSocket >= 0)
{ /* Préparation de l'Adresse Locale */
memset(&saLocal, 0, sizeof(saLocal));
saLocal.sin_family = AF_INET;
saLocal.sin_port = htons(INADDR_ANY);
saLocal.sin_addr.s_addr = htons(INADDR_ANY);
/* Liaison à l'Adresse Locale */
if (bind( hSocket, (struct sockaddr *)&saLocal, sizeof(saLocal))==0)
{ /* Paramétrage du timeout de réception */
err = setsockopt( hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
sizeof(timeout));
/* Préparation de la trame ICMP "Echo" */
ICMPH_TYPE_SET(pecho,ICMP_ECHO);
pecho->chksum = 0;
pecho->id = htons(0x1234); /* Pour repérer ces "Pings" */
pecho->seqno = htons(seq_num++);
pecho->chksum = inet_chksum(pecho, sizeof(struct
icmp_echo_hdr)+length);
/* Préparation de l'adresse à "pinger" */
memset( &to, 0, sizeof(to));
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
to.sin_port = htons(INADDR_ANY);
to.sin_addr.s_addr = addr;
/* Si le "ping" est bien envoyé... */
if ((err = sendto( hSocket, pecho, sizeof(struct icmp_echo_hdr)+length,
0, (struct sockaddr*)&to, sizeof(to)))>=0)
{ /* Réception de l' "Echo" (avec mesure du délai en ms) */
ulTickCount = sys_start_tickcount();
do
{ err = recvfrom( hSocket, reply, sizeof(reply), 0, (struct
sockaddr*)&from, (socklen_t *)&fromlen);
}
while ((err>0) && ((pechoreply->id!=pecho->id) ||
(pechoreply->seqno!=pecho->seqno)) &&
(sys_stop_tickcount(ulTickCount)<=timeout) );
ulTickCount = sys_stop_tickcount(ulTickCount);
/* Si le "ping" est bien reçu... */
if (err>0)
{ /* Affichage dans la console */
if (verbose) printf("Ping Reply from %lu.%lu.%lu.%lu : bytes=%i,
delay=%lums\n", ((addr & 0x000000FF)>>0), ((addr & 0x0000FF00)>>8), ((addr &
0x00FF0000)>>16), ((addr & 0xFF000000)>>24), (err-sizeof(struct
icmp_echo_hdr))/*length*/, ulTickCount);
iResult = 0;
}
/* Si on a eu une "non-réception"... */
else
{ /* Affichage dans la console */
if (verbose) printf("Ping Request timed out...\n");
iResult = ETIMEDOUT;
}
}
/* Si on n'a pas pu envoyer... */
else
{ /* Mémoriser l'erreur */
iResult = errno;
/* Affichage dans la console */
if (verbose) printf("Ping sendto==%i\n", iResult);
}
}
/* Fermeture de la Socket */
closesocket(hSocket);
}
/* Si on n'a pas pu ouvrir la Socket... */
else
{ /* Mémoriser l'erreur */
iResult = errno;
/* Affichage dans la console */
if (verbose) printf("Ping socket==%i\n", iResult);
}
/* Désallocation de la trame à envoyer... */
free(pecho);
#endif /* LWIP_SOCKET && LWIP_ICMP */
return iResult;
}
I do the same kind of probe with my gateway. The code I do is something like
that :
// Si la Gateway est définie et qu'on ne ping pas la Gateway...
if (netPing( inet_addr(szIPGateway), 32, TRUE)!=0)
{ iPingErrors++;
if (iPingErrors>=MAXPINGERRORS)// Environ MAXPINGERRORS*50sec
{ // Log du problème du PING
tmSyslog( LOG_MAKEPRI(LOG_LOCAL0,LOG_EMERG), "PING Gateway
Failure...");
// Enregistrer le fichier de Log en Flash
XmlSave( lpXML_IPPNX_LOG_TABLE, IPPNX_LOG_TABLE_FILENAME);
// Déclencher le "Software reset"
tmEncMp4XcastPicmat_SoftwareReset();
}
}
else
{ // Réinitialisation du compteur
iPingErrors = 0;
}
I hope it can help you.
====================================
Frédéric BERNON
HYMATOM SA
Chef de projet informatique
Microsoft Certified Professional
Tél. : +33 (0)4-67-87-61-10
Fax. : +33 (0)4-67-70-85-44
Email : address@hidden
Web Site : http://www.hymatom.fr
====================================
P Avant d'imprimer, penser à l'environnement
-----Message d'origine-----
De : Andy Kunz [mailto:address@hidden
Envoyé : jeudi 11 octobre 2007 17:14
À : Frédéric BERNON
Objet : ICMP ping send/receive
Frédéric,
Thanks for your efforts on lwIP. I have enjoyed quite a bit of growth of my
own understanding as a result of reading through the code.
This question comes to you after reading item # 7272 regarding optional ICMP.
I am working on an lwIP/FreeRTOS project and we are having occasional trouble
with the IP stack locking up. Sometimes only for 1/2 hour, sometimes it never
recovers (after days). (Sniffers show us that when "locked up", the board does
not reply to a ping even though it sometimes will generate SNMP traps).
We have experienced problems with TCP messages, for instance, not coming out of
the system in a timely manner as well - perhaps this is the same problem.
With as intermittent as the problem is, I was instructed to "hide" it rather
than delve into the inner workings of the stack to find the source of the
issue. (Our customer is pushing for a shipment of _something_ rather than
nothing).
The implementation I was told to create is this:
The code should send several pings to the gateway. If no reply is received,
assume the worst and reset the controller.
Attempting to write a ping send/response has turned out to be much more
difficult than I would have expected. Rather than a simple socket setup such
as used here
http://www.jbox.dk/sanos/source/utils/sh/ping.c.html
(which doesn't work because among other things IPPROTO_ICMP is not supported).
After googling for the past few days and all this morning for various
possibilities, I do not find any relatively simple ability to create an ICMP
echo request message using facilities in lwIP (unless I am overlooking
something in a gross manner). I suppose I can capture the reply in
icmp_input() in icmp.c. There does not appear to be something of this sort
available as part of the lwIP downloads.
My question to you is, do you know of a ping generator that runs in lwIP? I
would expect it to only require a few lines of code - ICMP is supposed to be
simple.
Any feedback (even negative comments!) would be appreciated!
Thanks.
Andy
_______________________________________________
Message sent via/by Savannah
http://savannah.nongnu.org/
Frédéric BERNON.vcf
Description: Frédéric BERNON.vcf
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lwip-users] RE : ICMP ping send/receive,
Frédéric BERNON <=