|
|
|
/*! \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 <avr/pgmspace.h>
|
|
|
|
#include "programStrings.h"
|
|
|
|
#include "HardwareSerial.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NET_CHECKSUM_DEBUG
|
|
|
|
#include "enc28j60.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
uint16_t tempId;
|
|
|
|
|
|
|
|
// change type to reply
|
|
|
|
packet->icmp.type = ICMP_TYPE_ECHOREPLY;
|
|
|
|
|
|
|
|
// recalculate checksum
|
|
|
|
packet->icmp.icmpchksum = 0x0000;
|
|
|
|
packet->icmp.icmpchksum = nicGetChecksum((uint8_t*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN);
|
|
|
|
|
|
|
|
#ifdef NET_CHECKSUM_DEBUG
|
|
|
|
SPrintln(" ");
|
|
|
|
SPrint("Hardware Checksum: 0x");
|
|
|
|
Serial.println((uint16_t)HTONS(packet->icmp.icmpchksum), HEX);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// 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, (((uint8_t*)packet)-ETH_HEADER_LEN));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ICMP_DEBUG_PRINT
|
|
|
|
void icmpPrintHeader(icmpip_hdr* packet)
|
|
|
|
{
|
|
|
|
SPrint("ICMP Packet:\r\n");
|
|
|
|
// print source IP address
|
|
|
|
SPrint("SrcIpAddr: "); netPrintIPAddr(htonl(packet->ip.srcipaddr)); Serial.println();
|
|
|
|
// print dest IP address
|
|
|
|
SPrint("DstIpAddr: "); netPrintIPAddr(htonl(packet->ip.destipaddr)); Serial.println();
|
|
|
|
// print type
|
|
|
|
SPrint("Type : ");
|
|
|
|
switch(packet->icmp.type)
|
|
|
|
{
|
|
|
|
case ICMP_TYPE_ECHOREQUEST: SPrint("ECHO REQUEST"); break;
|
|
|
|
case ICMP_TYPE_ECHOREPLY: SPrint("ECHO REPLY"); break;
|
|
|
|
default: SPrint("UNKNOWN"); break;
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
// print code
|
|
|
|
SPrint("Code : 0x"); Serial.print(packet->icmp.icode); Serial.println();
|
|
|
|
}
|
|
|
|
#endif
|