lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] PING App Issues [RAW]


From: address@hidden
Subject: Re: [lwip-users] PING App Issues [RAW]
Date: Sun, 10 May 2009 09:01:31 +0200
User-agent: Thunderbird 2.0.0.21 (Macintosh/20090302)

The pbuf leak might still be in there, but the checksum generation has already been corrected in CVS (I assume you are using 1.3.0, you don't tell that).

Simon


HM2 wrote:
I ran into a number of issues using the PING app from the contrib section.
I am using RAW mode.  The PING app just did requests, so I wrote some
additional code for it to handle replies now as well.  That seems to work
fine,  but  working on this I then noticed some other issues.  The previous
first routine ping_prepare_echo() was doing the checksum at the wrong place.
It needs to be last, after the sample data is built, since the checksum
covers that area as well.  Also, there was a pbuf leak in the ping_recv()
routine.  It needs to free the main pbuf, or after enough pings, the pool is
consumed.  The significant portions of my code changes are given below.

Regards,  Chris.


// Prepare a ECHO ICMP REQUEST
static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) {
  int i;
  ICMPH_TYPE_SET(iecho,ICMP_ECHO);
  ICMPH_CODE_SET(iecho, 0);
  iecho->chksum = 0;
  iecho->id     = PING_ID;
  iecho->seqno  = htons(++ping_seq_num);
  // fill the additional data buffer with some data
  for(i = 0; i < PING_DATA_SIZE; i++) {
    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = i+48; // easier to
look at ASCII
    }
  iecho->chksum = inet_chksum(iecho, len); // CNS, checksum needs to be done
after data
}


// CNS, Prepare a ECHO REPLY
static void ping_prepare_reply( struct icmp_echo_hdr *ireply, u16_t len,
struct icmp_echo_hdr *iecho) {
   int i,m;
   ICMPH_TYPE_SET(ireply,ICMP_ER); // echo reply
   ICMPH_CODE_SET(ireply, 0);
   ireply->id     = iecho->id;  // copy ID from request
   ireply->seqno  = iecho->seqno;  // copy seqno from request
   ireply->chksum = 0;
   // copy data from echo request
 // Ping Size may not be standard, so calc from actual msg size and sub
header
 m = len-sizeof(struct icmp_echo_hdr);
   for(i = 0; i < m; i++) {
     ((char*)ireply)[sizeof(struct icmp_echo_hdr) + i] =
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i];
     }
   ireply->chksum = inet_chksum(ireply, len);
}


// Ping Rcve using the raw ip
static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, struct
ip_addr *addr) {
 LWIP_UNUSED_ARG(arg);
   struct icmp_echo_hdr *iecho;
   struct icmp_echo_hdr *ireply;
 struct pbuf *r;
 int hlen;
 struct in_addr val;

  if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
    iecho = p->payload;
 // CNS this section generates REPLY to any ECHO REQUEST
    if (iecho->_type_code == ICMP_ECHO) {  // rcvd echo, generate echo reply
  hlen = p->tot_len;      // length of ping request, typ 40 bytes
  r = pbuf_alloc(PBUF_IP, hlen, PBUF_RAM); // new pbuf
    if (r!=NULL) {
   ireply=r->payload;
      ping_prepare_reply(ireply, hlen,iecho);
      raw_sendto(pcb, r, addr);
   pbuf_free(r);       // dump new pbuf
   r = NULL;
   }
  }
 // this section handles replies to our ECHO REQUEST
    if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
  val.s_addr = addr->addr;
    printf("Ping Reply %s\n", inet_ntoa(val));
       LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
       ip_addr_debug_print(PING_DEBUG, addr);
       LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time)));
       // do some ping result processing
       PING_RESULT(1);
       }
    }
  pbuf_free(p); // CNS, free the org pbuf, otherwise leak!
  p=NULL;
  return 1;  // eat the event
}







_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users






reply via email to

[Prev in Thread] Current Thread [Next in Thread]