Web 51 - ICMP

ARP  software.html  TCP part 1

ICMP - Internet Control Message Protocol

ICMP - Internet Control Message Protocol is described in RFC792. ICMP is an integral part of IP. It is a service protocol designed to provide feedback and signal extraordinary events in IP based networks. The protocol itself can signal wide range of faults; however, various implementations implement ICMP only partially. Almost all implementations, including Web 51, support at least Echo_reply or Echo. The Echo / Echo_reply command pair is used by ICMP to test reachability of individual Internet nodes. Nearly all operating systems that support IP contain some kind of PING program, which acts as a user interface to this command pair. First, PING sends an ICMP packet with the Echo command. Target node is supposed to reply with an ICMP packet containing the Echo_reply command. This reply is then evaluated by PING, and the time interval betwenn the request and the corresponding reply is displayed.

Processing of a received ICMP packet

Basic ICMP implementation in WWW8052 supports only Echo_reply according to RFC792 (Internet Control Message Protocol) and RFC1700 (Assigned Numbers).
void ProcessICMP (void) {

The packet received is copied into an Echo_reply packet (well, it would be sufficient to copy data part only...)

  copy_r2x (&rx_eth_pkt.hdr.pktDest, &tx_eth_pkt.hdr.pktDest, swapword(EthRcvHdr.rcv_hdr_size));

Received header is overwritten by the pre-constructed header in EEPROM.

  //MakeICMPheader ();
  tx_eth_pkt.hdr.pktSrc = flash_my_ether;
  tx_eth_pkt.hdr.pktType = 0x0800;	//IP
  tx_eth_pkt.pkt.ip.ipheader.VerLen = 0x45; //IP ver = 4., std. header length = 5
  tx_eth_pkt.pkt.ip.ipheader.TOS = 0;	//IP type of service
  tx_eth_pkt.pkt.ip.ipheader.FragOff = 0;	//fragment offset
  tx_eth_pkt.pkt.ip.ipheader.TTL = 64; 	//time to live (in gateway hops)
  tx_eth_pkt.pkt.ip.ipheader.Proto = 1;	//protocol (ICMP=1, TCP=6, EGP=8, UDP=17)
  tx_eth_pkt.pkt.ip.ipheader.CkSum = 0;
  tx_eth_pkt.pkt.ip.ipheader.SrcAddr = flash_my_ip; //26 IP address of source
  tx_eth_pkt.pkt.ip.ipdata.icmp.Type = 0; //0=reply, 8=request, others=who-cares
  tx_eth_pkt.pkt.ip.ipdata.icmp.Code = 0; //code
  tx_eth_pkt.pkt.ip.ipdata.icmp.CkSum = 0; //ICMPchecksum
  //

Add packet length.

  tx_eth_pkt.pkt.ip.ipheader.Len = rx_eth_pkt.pkt.ip.ipheader.Len;

Add sender/target IP addresses, packet number, and calculate and store IP header checksum.

  MakeIPreply ();

Calculate and store ICMP packet checksum.

  chkacc = 0;
  chklen = rx_eth_pkt.pkt.ip.ipheader.Len;
  chklen -= sizeof(rx_eth_pkt.pkt.ip.ipheader);       //checksum only from ICMP
  chkaddr = &tx_eth_pkt.pkt.ip.ipdata.ipdta;
  in_checksum ();
  chkacc ^= 0xFFFF;
  tx_eth_pkt.pkt.ip.ipdata.icmp.CkSum = chkacc;

Finally, send the packet.

  xmit_frame(swapword(EthRcvHdr.rcv_hdr_size));
  return;
}

ICMP implementation in Web 51

Implementation of ICMP Echo_reply is similar to implementation of ARP. Again, pre-constructed part of the packet is stored in the processor's EEPROM.
icmpheader:
my1eth: .ascii  "??????"        ;PKT_SRC = myether
        .word   0x0800          ;PKT_TYPE 0800 = IP
        .byte   0x45            ;IP ver = 4., std. header length = 5
        .byte   0               ;IP type of service
        .ascii  "??"            ;packet length (length-header_length)
        .ascii  "??"            ;datagram id
        .word   0               ;fragment offset (frags:3,fo:13)
        .byte   64              ;time to live (in gateway hops)
        .byte   1               ;protocol (ICMP=1, TCP=6, EGP=8, UDP=17)
        .word   0               ;header checksum
my1ip:  .ascii  "????"          ;IP address of source
        .ascii  "????"          ;IP address of destination
        .byte   0               ;ICMPtype ;0=reply, 8=request, others=who-cares
        .byte   0               ;ICMPcode
        .word   0               ;ICMPchecksum
sizeoficmpheader equ ($ - icmpheader)

Portions labelled my1eth and my1ip are filled in by cloning. Other parts marked by '?' are filled in with real values by MakeIPreply procedure after the packet is constructed. Resulting ICMP implementation is a little more complicated than ARP implementation, since it is necessary to move lots of data from the received packet to the trasmitted packet and to calculate two checksums.

ProcessICMP:
        mov     r7,#0		; use service stack
        lcall   changeStack
        lcall   pcode
        .pcode  pr2x PKT_DEST, PKT_DEST, @SWAP(rcv_hdr+EN_RBUF_SIZE_LO)	;echo packet
        .pcode  pe2x PKT_SRC, icmpheader, #BYTE sizeoficmpheader
        .pcode  pr2x IP_LEN, IP_LEN, #2
        .pcode  pcall MakeIPreply
        .pcode  pmovwi BYTE chkacc, #0
        .pcode  pr2s BYTE chklen, IP_LEN, #2
        .pcode  psubwi BYTE chklen, #IP_HEADER_LEN		;checksum only from ICMP
        .pcode  pmovbi BYTE chkaddr,   @BYTE(stackOffset)	;MSB
        .pcode  pmovbi BYTE chkaddr+1, #IP_DATA			;LSB
        .pcode  in_checksum
        .pcode  pxorwi BYTE chkacc, #0xFFFF
        .pcode  ps2x IC_CKSUM, BYTE chkacc, #2
        .pcode  xmit_frame @SWAP(rcv_hdr+EN_RBUF_SIZE_LO)
        .byte   0
        RET




Sponzored by LPhard Ltd. Graphics by GIMP Created by EasyPad

(c)Copyright 2000 - 2002, HW server & Radek Benedikt
Web51@HW.cz, Web51.HW.cz
ARP  Obsah  TCP part 1