[Top][All Lists]
[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.]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lwip-users] [lwip] Standalone debugging to Ethernet,
leon . woestenberg <=