/*! \file icmp.c \brief ICMP Protocol Library. */ //***************************************************************************** // // File Name : 'icmp.c' // Title : ICMP (Internet Control Message Protocol) Protocol Library // Author : Pascal Stang // Created : 9/10/2004 // Revised : 7/3/2005 // Version : 0.1 // Target MCU : Atmel AVR series // Editor Tabs : 4 // //***************************************************************************** #include "net.h" #include "nic.h" #include "arp.h" #include "icmp.h" #include "HardwareSerial.h" #include "debug.h" #ifdef ICMP_DEBUG_PRINT #include #include "programStrings.h" #include "HardwareSerial.h" #endif //extern void nicSend(unsigned int len, unsigned char* packet); // global variables // functions void icmpInit(void) { } void icmpIpIn(icmpip_hdr* packet) { // check ICMP type switch(packet->icmp.type) { case ICMP_TYPE_ECHOREQUEST: // echo request icmpEchoRequest(packet); break; default: break; } } void icmpEchoRequest(icmpip_hdr* packet) { uint32_t tempIp; // 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); // return to sender tempIp = packet->ip.destipaddr; packet->ip.destipaddr = packet->ip.srcipaddr; packet->ip.srcipaddr = tempIp; // add ethernet routing arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0); // debugging #if NET_DEBUG >= 2 icmpPrintHeader(packet); debugPrintHexTable(htons(packet->ip.len), (u08*)packet); #endif // send it (packet->ip.len+ETH_HEADER_LEN nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((u08*)packet)-ETH_HEADER_LEN)); } #ifdef ICMP_DEBUG_PRINT void icmpPrintHeader(icmpip_hdr* packet) { SPrint_P(PSTR("ICMP Packet:\r\n")); // print source IP address SPrint_P(PSTR("SrcIpAddr: ")); netPrintIPAddr(htonl(packet->ip.srcipaddr)); Serial.println(); // print dest IP address SPrint_P(PSTR("DstIpAddr: ")); netPrintIPAddr(htonl(packet->ip.destipaddr)); Serial.println(); // print type SPrint_P(PSTR("Type : ")); switch(packet->icmp.type) { case ICMP_TYPE_ECHOREQUEST: SPrint_P(PSTR("ECHO REQUEST")); break; case ICMP_TYPE_ECHOREPLY: SPrint_P(PSTR("ECHO REPLY")); break; default: SPrint_P(PSTR("UNKNOWN")); break; } Serial.println(); // print code SPrint_P(PSTR("Code : 0x")); Serial.print(packet->icmp.icode); Serial.println(); } #endif