pinging

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

pinging

Marcin Prusinski
Hey !
I was looking for example that will help me send some icmp echo
requests. I only found post of Larry Piggins who wrote exactly something
i need, but i couldn't find the code.
I'm using standalone version of LWIP.
I'm just a begginer and I can't figure out how to compute ICMP ECHO
checksum.
Thanks in advance for any info that could help me.
Cheers,
Marcin


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: pinging

Jonathan Larmour
Marcin Prusinski wrote:
> Hey !
> I was looking for example that will help me send some icmp echo
> requests. I only found post of Larry Piggins who wrote exactly something
> i need, but i couldn't find the code.

You need to make a raw socket, i.e. NETCONN_RAW, ensuring LWIP_RAW is on in
your configuration.

> I'm using standalone version of LWIP.
> I'm just a begginer and I can't figure out how to compute ICMP ECHO
> checksum.

Here's some code obtained from elsewhere:

static int inet_cksum(u_short *addr, int len)
{
     register int nleft = len;
     register u_short *w = addr;
     register u_short answer;
     register u_int sum = 0;
     u_short odd_byte = 0;

     /*
      *  Our algorithm is simple, using a 32 bit accumulator (sum),
      *  we add sequential 16 bit words to it, and at the end, fold
      *  back all the carry bits from the top 16 bits into the lower
      *  16 bits.
      */
     while( nleft > 1 )  {
         sum += *w++;
         nleft -= 2;
     }

     /* mop up an odd byte, if necessary */
     if( nleft == 1 ) {
         *(u_char *)(&odd_byte) = *(u_char *)w;
         sum += odd_byte;
     }

     /*
      * add back carry outs from top 16 bits to low 16 bits
      */
     sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
     sum += (sum >> 16);                     /* add carry */
     answer = ~sum;                          /* truncate to 16 bits */
     return (answer);
}

Hope this helps,

Jifl
--
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
Company legal info, address and number:   http://www.ecoscentric.com/legal
------["The best things in life aren't things."]------      Opinions==mine


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: pinging

Jonathan Larmour
Jonathan Larmour wrote:

> Marcin Prusinski wrote:
>> Hey !
>> I was looking for example that will help me send some icmp echo
>> requests. I only found post of Larry Piggins who wrote exactly
>> something i need, but i couldn't find the code.
>
> You need to make a raw socket, i.e. NETCONN_RAW, ensuring LWIP_RAW is on
> in your configuration.
>
>> I'm using standalone version of LWIP.
>> I'm just a begginer and I can't figure out how to compute ICMP ECHO
>> checksum.
>
> Here's some code obtained from elsewhere:
[snip]

Actually, you could also directly use lwip's own checksumming routines if
you like. If you #include "lwip/inet.h" you can get this function from there:
u16_t inet_chksum(void *dataptr, u16_t len);

Jifl
--
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
Company legal info, address and number:   http://www.ecoscentric.com/legal
------["The best things in life aren't things."]------      Opinions==mine


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: pinging

Marcin Prusinski
In reply to this post by Jonathan Larmour
> Here's some code obtained from elsewhere:
>
> static int inet_cksum(u_short *addr, int len)
> {
>      register int nleft = len;
>      register u_short *w = addr;
>      register u_short answer;
>      register u_int sum = 0;
>      u_short odd_byte = 0;
>
>      /*
>       *  Our algorithm is simple, using a 32 bit accumulator (sum),
>       *  we add sequential 16 bit words to it, and at the end, fold
>       *  back all the carry bits from the top 16 bits into the lower
>       *  16 bits.
>       */
>      while( nleft > 1 )  {
>          sum += *w++;
>          nleft -= 2;
>      }
>
>      /* mop up an odd byte, if necessary */
>      if( nleft == 1 ) {
>          *(u_char *)(&odd_byte) = *(u_char *)w;
>          sum += odd_byte;
>      }
>
>      /*
>       * add back carry outs from top 16 bits to low 16 bits
>       */
>      sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
>      sum += (sum >> 16);                     /* add carry */
>      answer = ~sum;                          /* truncate to 16 bits */
>      return (answer);
> }
Thanks for the reply,
I have one more question about this checksum. In ICMP ECHO header -
there are those fields:
type - 8 bits
code - 8 bits
checksum - 16 bits
id 16 bits
and seq number 16 bits
in exactly this order. Which fields are being computed in checksum ?
Should I use /inet_chksum/ like that:
/inet_chksum(iecho,1)/ ?  - where iecho is pointer to icmp_echo_hdr .
Then what's the point of 16 bit chksum field for 16 bit of data ?

Marcin


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: pinging

Jonathan Larmour
Marcin Prusinski wrote:

>
> Thanks for the reply,
> I have one more question about this checksum. In ICMP ECHO header -
> there are those fields:
> type - 8 bits
> code - 8 bits
> checksum - 16 bits
> id 16 bits
> and seq number 16 bits
> in exactly this order. Which fields are being computed in checksum ?

The whole IP header. You set the checksum field itself to 0 when working
it out.

> Should I use /inet_chksum/ like that:
> /inet_chksum(iecho,1)/ ?  - where iecho is pointer to icmp_echo_hdr .
> Then what's the point of 16 bit chksum field for 16 bit of data ?

http://www.tcpipguide.com/free/t_IPDatagramGeneralFormat.htm

Try something like:

#include "lwip/icmp.h"

{
   struct icmp_echo_hdr ping_pkt;
   static u16_t icmp_seq;
   u16t chksum;

   ping_pkt._type_code = ICMP_ECHO;
   ping_pkt.chksum = 0;
   ping_pkt.id = 0x8765;
   ping_pkt.seqno = icmp_seq++;
   chksum = inet_chksum( &ping_pkt, sizeof(ping_pkt);
   ping_pkt.chksum = chksum;


And then you can send ping_pkt down the raw socket you should have created
with netconn_new_with_proto_and_callback(NETCONN_RAW, IP_PROTO_ICMP,
NULL); or whatever is appropriate to the API you are using.

At least that's what I think... I haven't tried the above, so it may not
be quite right.

Jifl
--
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
Company legal info, address and number:   http://www.ecoscentric.com/legal
------["The best things in life aren't things."]------      Opinions==mine


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users