From 3f7c54bc345d86f880795de73e339e9d3e448c10 Mon Sep 17 00:00:00 2001 From: mlalondesvn Date: Sat, 15 Sep 2007 02:35:59 +0000 Subject: [PATCH] MODIF - Now using checksum code from uIP (issue remains!) git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/Ethduino@2 b05466c9-153a-0410-ad00-ea1d4d8a27b5 --- Makefile | 4 +-- arp.cpp | 4 ++- enc28j60.cpp | 4 +-- icmp.cpp | 20 +++++++++++-- ip.cpp | 2 +- main.h | 2 +- net.cpp | 79 ++++++++++++++++++++++++++++++++++++++++------------ net.h | 7 ++++- 8 files changed, 94 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index a7d45a2..601f3a0 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ # TARGET = main ARDUINO_VERSION = 0009 -INSTALL_DIR = /Applications/arduino-$(ARDUINO_VERSION) +INSTALL_DIR = /Users/mlalonde/Applications/Development/Arduino/arduino-$(ARDUINO_VERSION) ############################################################################### @@ -66,7 +66,7 @@ INSTALL_DIR = /Applications/arduino-$(ARDUINO_VERSION) # PORT = /dev/tty.usbserial-A* UPLOAD_RATE = 19200 -AVRDUDE_PROGRAMMER = stk500 +AVRDUDE_PROGRAMMER = arduino # HINT: If you want to use the automatic reset feature which comes with Arduino # Diecimila, put the follwoing in your avrdude.conf: diff --git a/arp.cpp b/arp.cpp index 4561a24..aa93047 100644 --- a/arp.cpp +++ b/arp.cpp @@ -73,16 +73,18 @@ void arpArpIn(unsigned int len, struct netEthArpHeader* packet) // copy sender's address info to dest. fields packet->arp.dhwaddr = packet->arp.shwaddr; packet->arp.dipaddr = packet->arp.sipaddr; + // fill in our information packet->arp.shwaddr = ArpMyAddr.ethaddr; packet->arp.sipaddr = HTONL(ArpMyAddr.ipaddr); + // change op to reply packet->arp.opcode = htons(ARP_OPCODE_REPLY); // in ethernet header packet->eth.dest = packet->eth.src; packet->eth.src = ArpMyAddr.ethaddr; - + #ifdef ARP_DEBUG SPrint_P(PSTR("Sending ARP Reply\r\n")); arpPrintHeader( &packet->arp ); diff --git a/enc28j60.cpp b/enc28j60.cpp index 59b3ed3..9f82888 100644 --- a/enc28j60.cpp +++ b/enc28j60.cpp @@ -383,7 +383,7 @@ void enc28j60Init(void) // ETXST defaults to 0x0000 (beginnging of ram) enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); enc28j60Write(ETXSTH, TXSTART_INIT>>8); -/* + // Needs register implementation #ifdef ENC28J60_PACKET_FILTER_ENABLED // do bank 1 stuff, packet filter: @@ -403,7 +403,7 @@ void enc28j60Init(void) enc28j60Write(EPMCSL, 0xf9); enc28j60Write(EPMCSH, 0xf7); #endif -*/ + // do bank 2 stuff // enable MAC receive enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); diff --git a/icmp.cpp b/icmp.cpp index 882b3e3..69d2105 100644 --- a/icmp.cpp +++ b/icmp.cpp @@ -51,17 +51,33 @@ void icmpIpIn(icmpip_hdr* packet) void icmpEchoRequest(icmpip_hdr* packet) { - uint32_t tempIp; + uint32_t tempIp, tempId; // change type to reply packet->icmp.type = ICMP_TYPE_ECHOREPLY; + // recalculate checksum packet->icmp.icmpchksum = 0; - packet->icmp.icmpchksum = netChecksum((netIpHeader*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN); + packet->icmp.icmpchksum = ipChecksum((netIpHeader*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN); + SPrint_P(PSTR("ICMP Checksum: ")); + Serial.println((long int)packet->icmp.icmpchksum, HEX); + // return to sender tempIp = packet->ip.destipaddr; packet->ip.destipaddr = packet->ip.srcipaddr; packet->ip.srcipaddr = tempIp; + + // Set the proper transaction id + tempId = packet->ip.ipid; + packet->ip.ipid = tempId; + SPrint_P(PSTR("ipID: ")); + Serial.println((long int)tempId, HEX); + + tempId = packet->icmp.id; + packet->icmp.id = tempId; + SPrint_P(PSTR("icmp.id: ")); + Serial.println((long int)tempId, HEX); + // add ethernet routing arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0); diff --git a/ip.cpp b/ip.cpp index c4ff8c2..57ee36e 100644 --- a/ip.cpp +++ b/ip.cpp @@ -86,7 +86,7 @@ void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len, uint8_t* data) // calculate and apply IP checksum // DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER ethIpHeader->ip.ipchksum = netChecksum(ðIpHeader->ip, IP_HEADER_LEN); - + // add ethernet routing // check if we need to send to gateway if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) diff --git a/main.h b/main.h index ffc4dd2..04dd4e9 100644 --- a/main.h +++ b/main.h @@ -41,7 +41,7 @@ // Network options #define IPADDRESS IPDOT(192l,168l,0l,126l) #define NETMASK IPDOT(255l,255l,0l,0l) -#define GATEWAY IPDOT(192l,168l,0l,1l) +#define GATEWAY IPDOT(192l,168l,255l,255l) #define ETHADDR0 0xCC /*'78'*/ #define ETHADDR1 0x00 /*'53'*/ diff --git a/net.cpp b/net.cpp index 18f8f1f..84692ef 100644 --- a/net.cpp +++ b/net.cpp @@ -30,29 +30,72 @@ uint32_t htonl(uint32_t val) return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16); } +static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len) +{ + uint16_t t; + + uint32_t *dataptr; + uint32_t *last_byte; + + dataptr = (uint32_t *) data; + last_byte = (uint32_t *) data + len - 1; + + while(dataptr < last_byte) { // At least two more bytes + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if(sum < t) { + sum++; // carry + } + dataptr += 2; + } + + if(dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if(sum < t) { + sum++; // carry + } + } + + // Return sum in host byte order. + return sum; +} + +uint16_t ipChecksum(netIpHeader *data, uint16_t len) +{ + return htons(generateChecksum(0, (netIpHeader *)data, len)); +} uint16_t netChecksum(netIpHeader *data, uint16_t len) { - register uint32_t sum = 0; + uint16_t sum; + sum = generateChecksum(0, &data[len], len); + SPrintln_P(PSTR("uip_ipchksum: sum 0x")); + Serial.println((long int)sum, HEX); + return (sum == 0) ? 0xffff : htons(sum); + +/* register uint32_t sum = 0; - for (;;) { - if (len < 2) - break; + for (;;) { + if (len < 2) + break; //sum += *((uint16_t *)data)++; sum += *((uint16_t *)data); data+=2; - len -= 2; - } - if (len) - sum += *(uint8_t *) data; - - while ((len = (uint16_t) (sum >> 16)) != 0) - sum = (uint16_t) sum + len; - + len -= 2; + } + + if (len) + sum += *(uint8_t *) data; + + while ((len = (uint16_t) (sum >> 16)) != 0) + sum = (uint16_t) sum + len; +#if NET_DEBUG > 6 Serial.print("Checksum: "); - Serial.println((uint16_t) sum ^ 0xFFFF, HEX); - - return (uint16_t) sum ^ 0xFFFF; + Serial.println((uint16_t) ~sum, HEX); +#endif + return (uint16_t) ~sum; +*/ } void netPrintEthAddr(struct netEthAddr* ethaddr) @@ -97,7 +140,7 @@ void netPrintEthHeader(struct netEthHeader* eth_hdr) void netPrintIpHeader(struct netIpHeader* ipheader) { SPrint_P(PSTR("IP Header\r\n")); - SPrint_P(PSTR("Ver : %d\r\n", (ipheader->vhl)>>4); + SPrint_P(PSTR("Ver : %d\r\n", (ipheader->vhl)>>4); SPrint_P(PSTR("Length : %d\r\n", htons(ipheader->len)); if(ipheader->proto == IP_PROTO_ICMP) SPrint_P(PSTR("Protocol: ICMP\r\n")); @@ -107,9 +150,9 @@ void netPrintIpHeader(struct netIpHeader* ipheader) SPrint_P(PSTR("Protocol: UDP\r\n")); else SPrint_P(PSTR("Protocol: %d\r\n", ipheader->proto); - + SPrint_P(PSTR("SourceIP: ")); netPrintIPAddr(htonl(ipheader->srcipaddr)); Serial.println(); - SPrint_P(PSTR("Dest IP: ")); netPrintIPAddr(htonl(ipheader->destipaddr)); Serial.println(); + SPrint_P(PSTR("Dest IP: ")); netPrintIPAddr(htonl(ipheader->destipaddr)); Serial.println(); } void netPrintTcpHeader(struct netTcpHeader* tcpheader) diff --git a/net.h b/net.h index f7ba7c5..3623920 100644 --- a/net.h +++ b/net.h @@ -189,9 +189,14 @@ uint16_t htons(uint16_t val); //! Host-to-Network LONG (32-bit) byte-order swap (function). uint32_t htonl(uint32_t val); -//! Calculate IP-style checksum from data. +//! Calculate IP checksum from data. +uint16_t ipChecksum(netIpHeader *data, uint16_t len); + +//! Calculate IP Header checksum from data. uint16_t netChecksum(netIpHeader *data, uint16_t len); +static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len); + //! Print Ethernet address in XX:XX:XX:XX:XX:XX format. void netPrintEthAddr(struct netEthAddr* ethaddr); //! Print IP address in dot notation.