Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages   Examples  

/opentcp/icmp.c

Go to the documentation of this file.
00001 /*
00002  *Copyright (c) 2000-2002 Viola Systems Ltd.
00003  *All rights reserved.
00004  *
00005  *Redistribution and use in source and binary forms, with or without 
00006  *modification, are permitted provided that the following conditions 
00007  *are met:
00008  *
00009  *1. Redistributions of source code must retain the above copyright 
00010  *notice, this list of conditions and the following disclaimer.
00011  *
00012  *2. Redistributions in binary form must reproduce the above copyright 
00013  *notice, this list of conditions and the following disclaimer in the 
00014  *documentation and/or other materials provided with the distribution.
00015  *
00016  *3. The end-user documentation included with the redistribution, if 
00017  *any, must include the following acknowledgment:
00018  *      "This product includes software developed by Viola 
00019  *      Systems (http://www.violasystems.com/)."
00020  *
00021  *Alternately, this acknowledgment may appear in the software itself, 
00022  *if and wherever such third-party acknowledgments normally appear.
00023  *
00024  *4. The names "OpenTCP" and "Viola Systems" must not be used to 
00025  *endorse or promote products derived from this software without prior 
00026  *written permission. For written permission, please contact 
00027  *opentcp@opentcp.org.
00028  *
00029  *5. Products derived from this software may not be called "OpenTCP", 
00030  *nor may "OpenTCP" appear in their name, without prior written 
00031  *permission of the Viola Systems Ltd.
00032  *
00033  *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 
00034  *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00035  *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00036  *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE 
00037  *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00038  *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00039  *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
00040  *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00041  *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00042  *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00043  *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00044  *====================================================================
00045  *
00046  *OpenTCP is the unified open source TCP/IP stack available on a series 
00047  *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
00048  *
00049  *For more information on how to network-enable your devices, or how to 
00050  *obtain commercial technical support for OpenTCP, please see 
00051  *<http://www.violasystems.com/>.
00052  */
00053 
00072 #include <inet/debug.h>
00073 #include <inet/datatypes.h>
00074 #include <inet/ethernet.h>
00075 #include <inet/ip.h>
00076 #include <inet/tcp_ip.h>
00077 #include <inet/system.h>
00078 
00097 INT16 process_icmp_in (struct ip_frame* frame, UINT16 len) 
00098 {
00099         UINT8 type;
00100         UINT8 code;
00101         UINT16 checksum;
00102         UINT16 i;
00103         UINT16 j;
00104         UINT8 tbuf[16];
00105                 
00106         /* Is this ICMP?        */
00107         
00108         ICMP_DEBUGOUT("Processing ICMP...\n\r");
00109         
00110         if( frame->protocol != IP_ICMP ) {
00111                 ICMP_DEBUGOUT("ERROR: The protocol is not ICMP\n\r");
00112                 return(-1);
00113         }
00114         
00115         /* Calculate checksum for received packet       */
00116 
00117         checksum = 0;
00118         i = len;
00119         
00120         NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
00121         
00122         while(i>15){
00123                 
00124                 RECEIVE_NETWORK_BUF(tbuf, 16);  
00125                 
00126                 checksum = ip_checksum_buf(checksum, tbuf,16);
00127                 
00128                 i -= 16;        
00129         }
00130 
00131         for(j=0; j < i; j++)
00132                 checksum = ip_checksum(checksum, RECEIVE_NETWORK_B(), (UINT8)j);
00133         
00134         checksum = ~ checksum;
00135         
00136         if(checksum != IP_GOOD_CS) {
00137                 ICMP_DEBUGOUT("ERROR: ICMP Checksum failed!\n\r");
00138                 return (-1);
00139         }
00140         
00141         ICMP_DEBUGOUT("ICMP Checksum OK\n\r");
00142         
00143         /* Start processing the message */
00144         
00145         NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
00146         
00147         type = RECEIVE_NETWORK_B();
00148         code = RECEIVE_NETWORK_B();
00149         
00150         /* We have already checked the CS, skip it      */
00151         
00152         RECEIVE_NETWORK_B();
00153         RECEIVE_NETWORK_B();
00154 
00155         switch(type) {
00156                 case ICMP_ECHO_REQUEST:
00157                 
00158                         if(code != 0) {
00159                                 ICMP_DEBUGOUT("ERROR:Misformed ICMP ECHO Request\n\r");
00160                                 return(-1);
00161                         }
00162                         
00163                         ICMP_DEBUGOUT("ICMP ECHO Request received\n\r");
00164                         
00165                         /* Is it a packet for setting temporary IP?     */
00166                         
00167                         if(len == (ICMP_ECHOREQ_HLEN + ICMP_TEMPIPSET_DATALEN) )
00168                         {
00169                                 /* Yep, set temporary IP address        */
00170                                 
00171                                 ICMP_DEBUGOUT("PING with 102 bytes of data, getting temp. IP\r\n");                     
00172                                 localmachine.localip = frame->dip;
00173                                 localmachine.defgw = frame->sip;
00174                                 localmachine.netmask = 0;
00175                         }
00176                         
00177                         
00178                         /* Same IP?             */
00179                         
00180                         if(localmachine.localip != frame->dip)
00181                                 return(-1);
00182 
00183                         /* Reply it     */
00184                         
00185                         TXBUF[0] = ICMP_ECHO_REPLY;
00186                         TXBUF[1] = 0;
00187                         TXBUF[2] = 0;
00188                         TXBUF[3] = 0;
00189                         
00190                         /* Copy with truncate if needed */
00191                         
00192                         if(len > NETWORK_TX_BUFFER_SIZE)
00193                                 len = NETWORK_TX_BUFFER_SIZE;
00194                         
00195                         RECEIVE_NETWORK_BUF(&TXBUF[4], len);
00196                         
00197                         /* Calculate Checksum for packet to be sent     */
00198                         
00199                         checksum = 0;
00200                         
00201                         checksum = ip_checksum_buf(checksum, &TXBUF[0], len);
00202         
00203                         checksum = ~ checksum;
00204                         
00205                         /* Put the checksum on place    */
00206                         
00207                         TXBUF[2] = (UINT8)(checksum>>8);
00208                         TXBUF[3] = (UINT8)checksum;
00209                         
00210                         /* Send it                                              */
00211                         
00212                         process_ip_out(frame->sip, IP_ICMP, 0, 100, &TXBUF[0], len);
00213                         
00214                         ICMP_DEBUGOUT("ICMP Reply sent\n\r");
00215                         
00216                         return(0);
00217                         
00218                 
00219                 break;
00220                 
00221                 case ICMP_ECHO_REPLY:
00222                 
00223                 break;
00224         
00225                 default:                                /* Unrecognized ICMP message    */
00226                         
00227                         ICMP_DEBUGOUT("Unregognized ICMP message\n\r");
00228                         return(-1); 
00229         }
00230         
00231 }
00232 
00233 
00234 
00235 
00236 

Generated on Sun Aug 3 20:32:59 2003 for OpenTCP by doxygen1.2.18