Subversion Repositories HomeAutomation

Rev

Rev 363 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*********************************************************************
  2.  *
  3.  *                  ICMP Module for Microchip TCP/IP Stack
  4.  *
  5.  *********************************************************************
  6.  * FileName:        ICMP.c
  7.  * Dependencies:    ICMP.h
  8.  *                  string.h
  9.  *                  StackTsk.h
  10.  *                  Helpers.h
  11.  *                  IP.h
  12.  *                  MAC.h
  13.  * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
  14.  * Complier:        Microchip C18 v3.02 or higher
  15.  *                  Microchip C30 v2.01 or higher
  16.  * Company:         Microchip Technology, Inc.
  17.  *
  18.  * Software License Agreement
  19.  *
  20.  * This software is owned by Microchip Technology Inc. ("Microchip")
  21.  * and is supplied to you for use exclusively as described in the
  22.  * associated software agreement.  This software is protected by
  23.  * software and other intellectual property laws.  Any use in
  24.  * violation of the software license may subject the user to criminal
  25.  * sanctions as well as civil liability.  Copyright 2006 Microchip
  26.  * Technology Inc.  All rights reserved.
  27.  *
  28.  * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL
  29.  * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
  30.  * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
  31.  * INFRINGEMENT.  Microchip shall in no event be liable for special,
  32.  * incidental, or consequential damages.
  33.  *
  34.  *
  35.  * Author               Date    Comment
  36.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37.  * Nilesh Rajbharti     4/30/01 Original        (Rev 1.0)
  38.  * Nilesh Rajbharti     2/9/02  Cleanup
  39.  * Nilesh Rajbharti     5/22/02 Rev 2.0 (See version.log for detail)
  40.  * Howard Schlunder     9/9/04  Added ENC28J60 DMA checksum support
  41.  * Howard Schlunder     1/5/06  Increased DMA checksum efficiency
  42.  ********************************************************************/
  43.  
  44. #include <string.h>
  45. #include "..\Include\StackTsk.h"
  46. #include "..\Include\Helpers.h"
  47. #include "..\Include\ICMP.h"
  48. #include "..\Include\IP.h"
  49. #include "..\Include\MAC.h"
  50.  
  51. #if defined(STACK_USE_ICMP)
  52.  
  53.  
  54. // ICMP packet definition
  55. typedef struct _ICMP_PACKET
  56. {
  57.     BYTE    Type;
  58.     BYTE    Code;
  59.     WORD    Checksum;
  60.     WORD    Identifier;
  61.     WORD    SequenceNumber;
  62.     BYTE    Data[MAX_ICMP_DATA];
  63. } ICMP_PACKET;
  64. #define ICMP_HEADER_SIZE    (sizeof(ICMP_PACKET) - MAX_ICMP_DATA)
  65.  
  66. static void SwapICMPPacket(ICMP_PACKET* p);
  67.  
  68.  
  69. /*********************************************************************
  70.  * Function:        BOOL ICMPGet(ICMP_CODE *code,
  71.  *                              BYTE *data,
  72.  *                              BYTE *len,
  73.  *                              WORD *id,
  74.  *                              WORD *seq)
  75.  *
  76.  * PreCondition:    MAC buffer contains ICMP type packet.
  77.  *
  78.  * Input:           code    - Buffer to hold ICMP code value
  79.  *                  data    - Buffer to hold ICMP data
  80.  *                  len     - Buffer to hold ICMP data length
  81.  *                  id      - Buffer to hold ICMP id
  82.  *                  seq     - Buffer to hold ICMP seq
  83.  *
  84.  * Output:          TRUE if valid ICMP packet was received
  85.  *                  FALSE otherwise.
  86.  *
  87.  * Side Effects:    None
  88.  *
  89.  * Overview:        None
  90.  *
  91.  * Note:            None
  92.  ********************************************************************/
  93. BOOL ICMPGet(ICMP_CODE *code,
  94.              BYTE *data,
  95.              BYTE *len,
  96.              WORD *id,
  97.              WORD *seq)
  98. {
  99.     ICMP_PACKET packet;
  100.     WORD CalcChecksum;
  101.     WORD ReceivedChecksum;
  102. #if defined(NON_MCHP_MAC)
  103.     WORD checksums[2];
  104. #endif
  105.  
  106.     // Obtain the ICMP Header
  107.     MACGetArray((BYTE*)&packet, ICMP_HEADER_SIZE);
  108.  
  109.  
  110. #if !defined(NON_MCHP_MAC)
  111.     // Calculate the checksum using the Microchip MAC's DMA module
  112.     // The checksum data includes the precomputed checksum in the
  113.     // header, so a valid packet will always have a checksum of
  114.     // 0x0000 if the packet is not disturbed.
  115.     ReceivedChecksum = 0x0000;
  116.     CalcChecksum = MACCalcRxChecksum(0+sizeof(IP_HEADER), *len);
  117. #endif
  118.  
  119.     // Obtain the ICMP data payload
  120.     *len -= ICMP_HEADER_SIZE;
  121.     MACGetArray(data, *len);
  122.  
  123. #if defined(NON_MCHP_MAC)
  124.     // Calculte the checksum in local memory without hardware help
  125.     ReceivedChecksum = packet.Checksum;
  126.     packet.Checksum = 0;
  127.  
  128.     checksums[0] = ~CalcIPChecksum((BYTE*)&packet, ICMP_HEADER_SIZE);
  129.     checksums[1] = ~CalcIPChecksum(data, *len);
  130.    
  131.     CalcChecksum = CalcIPChecksum((BYTE*)checksums, 2 * sizeof(WORD));
  132. #endif
  133.  
  134.  
  135.     SwapICMPPacket(&packet);
  136.  
  137.     *code = packet.Type;
  138.     *id = packet.Identifier;
  139.     *seq = packet.SequenceNumber;
  140.  
  141.     return ( CalcChecksum == ReceivedChecksum );
  142. }
  143.  
  144. /*********************************************************************
  145.  * Function:        void ICMPPut(NODE_INFO *remote,
  146.  *                               ICMP_CODE code,
  147.  *                               BYTE *data,
  148.  *                               BYTE len,
  149.  *                               WORD id,
  150.  *                               WORD seq)
  151.  *
  152.  * PreCondition:    ICMPIsTxReady() == TRUE
  153.  *
  154.  * Input:           remote      - Remote node info
  155.  *                  code        - ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST
  156.  *                  data        - Data bytes
  157.  *                  len         - Number of bytes to send
  158.  *                  id          - ICMP identifier
  159.  *                  seq         - ICMP sequence number
  160.  *
  161.  * Output:          None
  162.  *
  163.  * Side Effects:    None
  164.  *
  165.  * Note:            A ICMP packet is created and put on MAC.
  166.  *
  167.  ********************************************************************/
  168. void ICMPPut(NODE_INFO *remote,
  169.              ICMP_CODE code,
  170.              BYTE *data,
  171.              BYTE len,
  172.              WORD id,
  173.              WORD seq)
  174. {
  175.     ICMP_PACKET packet;
  176.     WORD ICMPLen;
  177.     BUFFER MyTxBuffer = MACGetTxBuffer(TRUE);
  178.  
  179.     // Abort if there is no where in the Ethernet controller to
  180.     // store this packet.
  181.     if(MyTxBuffer == INVALID_BUFFER)
  182.         return;
  183.  
  184.     IPSetTxBuffer(MyTxBuffer, 0);
  185.  
  186.  
  187.     ICMPLen = ICMP_HEADER_SIZE + (WORD)len;
  188.  
  189.     packet.Code             = 0;
  190.     packet.Type             = code;
  191.     packet.Checksum         = 0;
  192.     packet.Identifier       = id;
  193.     packet.SequenceNumber   = seq;
  194.  
  195.     memcpy((void*)packet.Data, (void*)data, len);
  196.  
  197.     SwapICMPPacket(&packet);
  198.  
  199. #if defined(NON_MCHP_MAC)
  200.     packet.Checksum         = CalcIPChecksum((BYTE*)&packet,
  201.                                     ICMPLen);
  202. #endif
  203.  
  204.     IPPutHeader(remote,
  205.                 IP_PROT_ICMP,
  206.                 (WORD)(ICMP_HEADER_SIZE + len));
  207.  
  208.     IPPutArray((BYTE*)&packet, ICMPLen);
  209.  
  210. #if !defined(NON_MCHP_MAC)
  211.     // Calculate and write the ICMP checksum using the Microchip MAC's DMA
  212.     packet.Checksum = MACCalcTxChecksum(sizeof(IP_HEADER), ICMPLen);
  213.     IPSetTxBuffer(MyTxBuffer, 2);
  214.     MACPutArray((BYTE*)&packet.Checksum, 2);
  215. #endif
  216.  
  217.  
  218.     MACFlush();
  219. }
  220.  
  221. /*********************************************************************
  222.  * Function:        void SwapICMPPacket(ICMP_PACKET* p)
  223.  *
  224.  * PreCondition:    None
  225.  *
  226.  * Input:           p - ICMP packet header
  227.  *
  228.  * Output:          ICMP packet is swapped
  229.  *
  230.  * Side Effects:    None
  231.  *
  232.  * Overview:        None
  233.  *
  234.  * Note:            None
  235.  ********************************************************************/
  236. static void SwapICMPPacket(ICMP_PACKET* p)
  237. {
  238.     p->Identifier           = swaps(p->Identifier);
  239.     p->SequenceNumber       = swaps(p->SequenceNumber);
  240.     p->Checksum             = swaps(p->Checksum);
  241. }
  242.  
  243.  
  244. #endif //#if defined(STACK_USE_ICMP)
  245.