lwip-users
[Top][All Lists]
Advanced

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

[lwip-users] [lwip] Standalone debugging to Ethernet


From: leon . woestenberg
Subject: [lwip-users] [lwip] Standalone debugging to Ethernet
Date: Thu, 09 Jan 2003 00:09:54 -0000

Hello,

as promised on wednesday, here is my lwIP independent
function that outputs correctly checksummed UDP packets
on Ethernet.

It assumes 16-bit addressing.

I will not give any support on this, but it may act as an example.

Regards,

Leon Woestenberg

Axon Digital Design
Phone: +31 13 511 6666
Fax: +31 13 511 4151
web: www.axon.tv

/**
 * Dump an array of bytes inside a UDP message's data field.
 *
 * It is a self-contained function, independent of higher protocol layers
or other
 * functions, so it allows you to debug these higher layers, such as lwIP.
 *
 * @param p pointer to an array of bytes, at least with length 'len'
 * @param len number of bytes available at the address pointed to by 'p'
 */
void debug_send(unsigned char *p, unsigned int len)
{
      int tries = 0, i;

  // network interface state
  extern struct netif *ethif;

  // exit if link has failed
  PACKETPP = CS_PP_LINESTATUS;
  if ((PPDATA & 0x0080U/*LinkOK*/) == 0) return; // TODO: find a correct
error code

  // transmit command
  TXCMD = 0x00C9U;
      // send at least minimum frame length of 60 bytes
  TXLENGTH = (14 + 20 + 8 + len < 60) ? 60 : (14 + 20 + 8 + len);

  PACKETPP = CS_PP_BUSSTATUS;
  // not ready for transmission and still within 100 retries?
  while (((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100))
  {
    // throw away the last committed received frame
    PACKETPP = CS_PP_RXCFG;
    PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/);
    PACKETPP = CS_PP_BUSSTATUS;
  }
  // ready to transmit?
  if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0)
  {
    u16_t data;
    u32_t checksum = 0;
    u32_t udp_checksum = 0;

    // destination Ethernet address
    RXTXREG = 0xa000U;
    RXTXREG = 0xc524U;
    RXTXREG = 0x6d72U;
    // source Ethernet address
    RXTXREG = htons(((u16_t)ethif->hwaddr[0] << 8U) |
(u16_t)ethif->hwaddr[1]);
    RXTXREG = htons(((u16_t)ethif->hwaddr[2] << 8U) |
(u16_t)ethif->hwaddr[3]);
    RXTXREG = htons(((u16_t)ethif->hwaddr[4] << 8U) |
(u16_t)ethif->hwaddr[5]);
    // frame type
    RXTXREG = htons(0x0800);
    // TOS, version
    data = ((0x40 | 0x05) << 8) | 0x00;
    RXTXREG = htons(data);
    checksum += data;
    // length
    data = 20 + 8 + len;
    RXTXREG = htons(data);
    checksum += data;
    // identifier
    data = 0;
    RXTXREG = htons(data);
    checksum += data;
    // fragment offset
    RXTXREG = htons(data);
    checksum += data;
    // TTL, UDP protocol
    data = (255U << 8) | 17U;
    RXTXREG = htons(data);
    checksum += data;

    checksum += (htonl(debug_ip_addr.addr) & 0xffff0000UL) >> 16;
    checksum += (htonl(debug_ip_addr.addr) & 0x0000ffffUL);
    checksum += (htonl(debug_gw_addr.addr) & 0xffff0000UL) >> 16;
    checksum += (htonl(debug_gw_addr.addr) & 0x0000ffffUL);

    while(checksum >> 16) {
      checksum = (checksum & 0x0000ffffUL) + (checksum >> 16);
    }
    // checksum
    RXTXREG = htons(~(checksum & 0x0000ffffUL));

    // source IP
    RXTXREG = htons((htonl(debug_ip_addr.addr) & 0xffff0000UL) >> 16);
    // source IP
    RXTXREG = htons( htonl(debug_ip_addr.addr) & 0x0000ffffUL);
    // destination IP
    RXTXREG = htons((htonl(debug_gw_addr.addr) & 0xffff0000UL) >> 16);
    // destination IP
    RXTXREG = htons( htonl(debug_gw_addr.addr) & 0x0000ffffUL);
    // source port 3000
    RXTXREG = htons(3000);
    // destination port 3000
    RXTXREG = htons(3000);
    // UDP length
    data = (8 + len);
    RXTXREG = htons(data);
    // UDP checksum (not present)

    udp_checksum = debug_chksum(p, len);
    while(udp_checksum >> 16) {
      udp_checksum = (udp_checksum & 0x0000ffffUL) + (udp_checksum >> 16);
    }

    udp_checksum += (u32_t)htons((htonl(debug_ip_addr.addr) & 0xffff0000UL)
>> 16);
    udp_checksum += (u32_t)htons((htonl(debug_ip_addr.addr) &
0x0000ffffUL));
    udp_checksum += (u32_t)htons((htonl(debug_gw_addr.addr) & 0xffff0000UL)
>> 16);
    udp_checksum += (u32_t)htons((htonl(debug_gw_addr.addr) &
0x0000ffffUL));
    udp_checksum += (u32_t)htons(17);
    udp_checksum += (u32_t)htons(8 + len);
    udp_checksum += (u32_t)htons(3000);
    udp_checksum += (u32_t)htons(3000);
    udp_checksum += (u32_t)htons(8 + len);
    while(udp_checksum >> 16) {
      udp_checksum = (udp_checksum & 0x0000ffffUL) + (udp_checksum >> 16);
    }

    RXTXREG = ~(udp_checksum & 0x0000ffffUL);
        // UDP data
    for (i = 0; i < len; i += 2)
    {
      data = (p[i] << 8) | p[i + 1];
      RXTXREG = htons(data);
    }
        // pad to 60 bytes
        while (i < 60)
        {
      RXTXREG = 0;
          i += 2;
        }
  }
}

static u32_t debug_chksum(void *dataptr, int len)
{
  u32_t acc = 0;
  u16_t *ptr = (u16_t *)dataptr;

  for(acc = 0; len > 1; len -= 2) {
    acc += *ptr;
    ptr++;
  }
  /* add up any odd byte */
  if(len == 1) {
    acc += htons((u16_t)((*(u8_t *)ptr) & 0xffU) << 8);
  }
  return acc;
}



[This message was sent through the lwip discussion list.]




reply via email to

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