lwip-users
[Top][All Lists]
Advanced

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

[lwip-users] PING App Issues [RAW]


From: HM2
Subject: [lwip-users] PING App Issues [RAW]
Date: Sat, 9 May 2009 11:56:14 -0700

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
}









reply via email to

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