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

/opentcp/tcp.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 
00085 #include <inet/debug.h>
00086 #include <inet/datatypes.h>
00087 #include <inet/timers.h>
00088 #include <inet/ethernet.h>
00089 #include <inet/ip.h>
00090 #include <inet/tcp_ip.h>
00091 #include <inet/system.h>
00092 
00102 struct tcp_frame received_tcp_packet;
00103 
00118 struct tcb tcp_socket[NO_OF_TCPSOCKETS + 1]; 
00119 
00120 UINT8 tcp_tempbuf[MIN_TCP_HLEN + 1]; 
00123 /***********************************************************************/
00124 /*******        TCP API functions                                                                       ********/
00125 /***********************************************************************/
00126 
00155 INT8 tcp_getsocket (UINT8 soctype, UINT8 tos, UINT16 tout, INT32 (*listener)(INT8, UINT8, UINT32, UINT32) )
00156 {
00157         INT8 i;
00158         struct tcb* soc;
00159         
00160         if( NO_OF_TCPSOCKETS < 0 )
00161                 return(-1);
00162         
00163         if( NO_OF_TCPSOCKETS == 0 )
00164                 return(-1);
00165         
00166         if( (soctype != TCP_TYPE_SERVER) &&
00167                 (soctype != TCP_TYPE_CLIENT) &&
00168                 (soctype != TCP_TYPE_CLIENT_SERVER) &&
00169                 (soctype != TCP_TYPE_NONE)                              ) {
00170                 TCP_DEBUGOUT("Invalid socket type requested\r\n");
00171                 return(-1);
00172         }
00173         
00174         if(listener == 0) {
00175                 TCP_DEBUGOUT("ERROR:Event listener function not specified\r\n");
00176                 return(-1);
00177         }
00178         
00179         TCP_DEBUGOUT("Searching for free TCP socket...\r\n");
00180         
00181         for(i=0; i < NO_OF_TCPSOCKETS; i++)     {
00182                 soc = &tcp_socket[i];                   /* Get Socket   */
00183         
00184                 if(soc->state == TCP_STATE_FREE) {
00185                         /* We found it  */
00186                         
00187                         TCP_DEBUGOUT("Free socket found\r\n");
00188                         
00189                         soc->state = TCP_STATE_RESERVED;
00190                         soc->type = soctype;
00191                         soc->tos = tos;
00192                         soc->event_listener = listener;
00193                         soc->rem_ip = 0;
00194                         soc->remport = 0;
00195                         soc->locport = 0;
00196                         soc->flags = 0;
00197                         soc->tout = tout*TIMERTIC;
00198                         
00199                         return(i);
00200                 }
00201         
00202         }
00203         
00204         /* We are there so no socket found      */
00205         
00206         TCP_DEBUGOUT("No socket found\r\n");
00207         return(-1);
00208 
00209 }
00210 
00228 INT8 tcp_releasesocket (INT8 sochandle)
00229 {
00230         struct tcb* soc;
00231         
00232         if( NO_OF_TCPSOCKETS < 0 )
00233                 return(-1);
00234         
00235         if( NO_OF_TCPSOCKETS == 0 )
00236                 return(-1);
00237         
00238         if( sochandle > NO_OF_TCPSOCKETS ) {
00239                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00240                 return(-1);
00241         }
00242         
00243         if( sochandle < 0 ) {
00244                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00245                 return(-1);
00246         }
00247         
00248         soc = &tcp_socket[sochandle];           /* Get referense        */
00249         
00250         if( (soc->state != TCP_STATE_FREE) &&
00251                 (soc->state != TCP_STATE_RESERVED) &&
00252                 (soc->state != TCP_STATE_CLOSED)                ) {
00253                 TCP_DEBUGOUT("Socket is not on valid state to be released\r\n");
00254                 return(-1);
00255         }
00256         
00257         /* We are there so all OK       */
00258         
00259         soc->state = TCP_STATE_FREE;
00260         soc->type = TCP_TYPE_NONE;
00261         soc->tos = 0;
00262         soc->event_listener = 0;
00263         soc->rem_ip = 0;
00264         soc->remport = 0;
00265         soc->locport = 0;
00266         soc->flags = 0;
00267         
00268         return(sochandle);
00269 
00270 }
00271 
00290 INT8 tcp_listen (UINT8 sochandle, UINT16 port)
00291 {
00292         struct tcb* soc;
00293 
00294         if( NO_OF_TCPSOCKETS < 0 )
00295                 return(-1);
00296         
00297         if( NO_OF_TCPSOCKETS == 0 )
00298                 return(-1);
00299         
00300         if( sochandle > NO_OF_TCPSOCKETS ) {
00301                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00302                 return(-1);
00303         }
00304         
00305         if( sochandle < 0 ) {
00306                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00307                 return(-1);
00308         }
00309         
00310         soc = &tcp_socket[sochandle];           /* Get referense        */
00311                 
00312         if( (soc->type & TCP_TYPE_SERVER) == 0 ) {
00313                 TCP_DEBUGOUT("Socket has no server properties\r\n");
00314                 return(-1);
00315         }
00316         
00317         if( soc->event_listener == 0) {
00318                 TCP_DEBUGOUT("ERROR:No event listener function specified\r\n");
00319                 return(-1);
00320         }
00321         
00322         
00323         if( (soc->state != TCP_STATE_RESERVED) &&
00324                 (soc->state != TCP_STATE_LISTENING)     &&
00325                 (soc->state != TCP_STATE_CLOSED) &&             
00326                 (soc->state != TCP_STATE_TIMED_WAIT)            ) {
00327                 TCP_DEBUGOUT("Not possible to listen, socket on connected state\r\n");
00328                 return(-1);
00329         
00330         }
00331         
00332                         
00333         /* Init socket          */
00334                                 
00335         soc->state = TCP_STATE_LISTENING;
00336         /*soc->type = TCP_TYPE_SERVER;*/
00337         soc->flags = 0;
00338         soc->rem_ip = 0;
00339         soc->remport = 0;
00340         soc->locport = port;
00341         soc->send_unacked = 0;
00342         soc->myflags = 0;
00343         soc->send_next = 0xFFFFFFFF;
00344         soc->send_mtu = TCP_DEF_MTU;
00345         soc->receive_next = 0;
00346         soc->retries_left = 0;
00347                         
00348         TCP_DEBUGOUT("TCP listening socket created\r\n");
00349                         
00350         return(sochandle);
00351 
00352 }
00353 
00354 
00377 INT8 tcp_connect (UINT8 sochandle, UINT32 ip, UINT16 rport, UINT16 myport )
00378 {
00379         struct tcb* soc;
00380         
00381         TCP_DEBUGOUT("FUNCTION: tcp_connect\r\n");
00382 
00383         if( NO_OF_TCPSOCKETS < 0 )
00384                 return(-1);
00385         
00386         if( NO_OF_TCPSOCKETS == 0 )
00387                 return(-1);
00388         
00389         if( sochandle > NO_OF_TCPSOCKETS ) {
00390                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00391                 return(-1);
00392         }
00393         
00394         if( sochandle < 0 ) {
00395                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00396                 return(-1);
00397         }
00398         
00399         /* Is the local port defined    */
00400         
00401         if( myport == 0 )
00402                 myport = tcp_getfreeport();
00403         
00404         if( myport == 0 )
00405                 return(-1);
00406         
00407         soc = &tcp_socket[sochandle];           /* Get referense        */
00408         
00409         /* Do we have client properties?        */
00410         
00411         if( (soc->type & TCP_TYPE_CLIENT) == 0 ) {
00412                 TCP_DEBUGOUT("Socket has no client properties\r\n");
00413                 return(-1);
00414         }
00415         
00416         if( soc->event_listener == 0) {
00417                 TCP_DEBUGOUT("ERROR:No event listener function specified\r\n");
00418                 return(-1);
00419         }
00420         
00421         /* Are we on LISTENING, RESERVED or CLOSED state        */
00422         
00423         if( (soc->state != TCP_STATE_RESERVED) &&
00424                 (soc->state != TCP_STATE_LISTENING) &&
00425                 (soc->state != TCP_STATE_CLOSED)                ) {
00426                 TCP_DEBUGOUT("Socket on unvalid state to initialize CONNECT\r\n");
00427                 return(-1);
00428         }
00429         
00430         /* Then just set parameters and send SYN        */
00431         
00432         soc->rem_ip = ip;
00433         soc->remport = rport;
00434         soc->locport = myport;
00435         soc->flags = 0;
00436         soc->send_mtu = TCP_DEF_MTU;
00437         
00438         /* get initial sequence number  */
00439         
00440         soc->send_unacked = tcp_initseq(); 
00441         soc->send_next = soc->send_unacked + 1;
00442         soc->myflags = TCP_FLAG_SYN;
00443         tcp_sendcontrol(sochandle);
00444         tcp_newstate(soc, TCP_STATE_SYN_SENT);
00445         
00446         return(sochandle);
00447 }
00448 
00449 
00450 
00481 INT16 tcp_send (INT8 sockethandle, UINT8* buf, UINT16 blen, UINT16 dlen)
00482 {
00483         struct tcb* soc;
00484         UINT8 i;
00485 
00486         
00487         TCP_DEBUGOUT("Entering to send TCP data packet\r\n");
00488         
00489         kick_WD();
00490         
00491         if( sockethandle < 0 ) {
00492                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (<0)\r\n");
00493                 return(-1);
00494         }
00495         
00496         if( sockethandle > NO_OF_TCPSOCKETS ) {
00497                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (>NO_OF_TCPSOCKETS)\r\n");
00498                 return(-1);
00499         }
00500         
00501         soc = &tcp_socket[sockethandle];                                /* Get socket   */
00502         
00503         if(soc->state != TCP_STATE_CONNECTED) {
00504                 TCP_DEBUGOUT("TCP is not connected!!\r\n");
00505                 return(-1);
00506         }
00507         
00508         if(soc->send_unacked != soc->send_next) {
00509                 TCP_DEBUGOUT("TCP contains unacked data, cannot send more\r\n");
00510                 return(-1);
00511         }
00512         
00513         if( dlen > blen )
00514                 dlen = blen;
00515         
00516         if(dlen + MIN_TCP_HLEN > soc->send_mtu) {
00517                 if(soc->send_mtu > MIN_TCP_HLEN)
00518                         dlen = soc->send_mtu - MIN_TCP_HLEN;
00519                 else
00520                         return(-1);
00521         }
00522         
00523         soc->send_next += dlen;
00524         
00525         soc->myflags = TCP_FLAG_ACK | TCP_FLAG_PUSH;
00526         process_tcp_out(sockethandle, buf - MIN_TCP_HLEN, blen + MIN_TCP_HLEN + 1, dlen);
00527         
00528         return(dlen);
00529 }
00530 
00531 
00549 INT8 tcp_close (UINT8 sochandle)
00550 {
00551         struct tcb* soc;
00552         
00553         TCP_DEBUGOUT("FUNCTION: tcp_close\r\n");
00554 
00555         if( NO_OF_TCPSOCKETS < 0 )
00556                 return(-1);
00557         
00558         if( NO_OF_TCPSOCKETS == 0 )
00559                 return(-1);
00560         
00561         if( sochandle > NO_OF_TCPSOCKETS ) {
00562                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00563                 return(-1);
00564         }
00565         
00566         if( sochandle < 0 ) {
00567                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00568                 return(-1);
00569         }
00570         
00571         soc = &tcp_socket[sochandle];           /* Get referense        */      
00572         
00573         switch(soc->state) {
00574                 case TCP_STATE_LISTENING:
00575                         tcp_newstate(soc, TCP_STATE_CLOSED);
00576                         break;
00577                 
00578                 case TCP_STATE_SYN_RECEIVED:
00579                         soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
00580                         soc->send_unacked++;
00581                         soc->send_next++;
00582                         tcp_sendcontrol(sochandle);
00583                         tcp_newstate(soc, TCP_STATE_FINW1);
00584                         break;
00585                 
00586                 case TCP_STATE_SYN_SENT:
00587                 
00588                         tcp_newstate(soc, TCP_STATE_CLOSED);
00589                 
00590                         break;
00591                 
00592                 case TCP_STATE_FINW1:
00593                 case TCP_STATE_FINW2:
00594                 case TCP_STATE_CLOSING:
00595                 case TCP_STATE_TIMED_WAIT:
00596                 case TCP_STATE_LAST_ACK:
00597                 
00598                         /* We are closing already       */
00599                         
00600                         break;
00601                 
00602                 case TCP_STATE_CONNECTED:
00603                 
00604                         /* Is there unacked data?       */
00605                         
00606                         if(soc->send_unacked == soc->send_next ) {
00607                                 /* There is no unacked data     */
00608                                 
00609                                 soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
00610                                 soc->send_next++;
00611                                 tcp_sendcontrol(sochandle);
00612                                 tcp_newstate(soc, TCP_STATE_FINW1);                             
00613                         } else {
00614                                 /* Can't do much but raise pollable flag to soc->flags          */
00615                                 /* and process it on tcp_poll                                                           */
00616                                 
00617                                 soc->flags |= TCP_INTFLAGS_CLOSEPENDING;
00618                                 
00619                                 
00620                                 return(sochandle);
00621                         }
00622                 
00623                         break;
00624         
00625                 default:
00626                         return(-1);
00627         }
00628         
00629         return(sochandle);
00630 
00631 }
00632 
00633 
00634 
00648 INT8 tcp_getstate (UINT8 sochandle)
00649 {
00650         struct tcb* soc;
00651 
00652         if( NO_OF_TCPSOCKETS < 0 )
00653                 return(-1);
00654         
00655         if( NO_OF_TCPSOCKETS == 0 )
00656                 return(-1);
00657         
00658         if( sochandle > NO_OF_TCPSOCKETS ) {
00659                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00660                 return(-1);
00661         }
00662         
00663         if( sochandle < 0 ) {
00664                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00665                 return(-1);
00666         }
00667         
00668         soc = &tcp_socket[sochandle];           /* Get referense        */      
00669 
00670         return(soc->state);
00671 
00672 }
00673 
00674 
00690 INT16 tcp_checksend (UINT8 sochandle)
00691 {
00692         struct tcb* soc;
00693 
00694         if( NO_OF_TCPSOCKETS < 0 )
00695                 return(-1);
00696         
00697         if( NO_OF_TCPSOCKETS == 0 )
00698                 return(-1);
00699         
00700         if( sochandle > NO_OF_TCPSOCKETS ) {
00701                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00702                 return(-1);
00703         }
00704         
00705         soc = &tcp_socket[sochandle];           /* Get referense        */      
00706         
00707         if(soc->state != TCP_STATE_CONNECTED)
00708                 return(-1);
00709 
00710         if(soc->send_unacked == soc->send_next)
00711                 return(soc->send_mtu);
00712         
00713         return(-1);
00714 
00715 
00716 }
00717 
00718 
00719 
00736 INT8 tcp_abort (UINT8 sochandle)
00737 {
00738         struct tcb* soc;
00739         
00740         TCP_DEBUGOUT("FUNCTION: tcp_abort\r\n");
00741 
00742         if( NO_OF_TCPSOCKETS < 0 )
00743                 return(-1);
00744         
00745         if( NO_OF_TCPSOCKETS == 0 )
00746                 return(-1);
00747         
00748         if( sochandle > NO_OF_TCPSOCKETS ) {
00749                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00750                 return(-1);
00751         }
00752         
00753         if( sochandle < 0 ) {
00754                 TCP_DEBUGOUT("Socket handle non-valid\r\n");
00755                 return(-1);
00756         }
00757         
00758         soc = &tcp_socket[sochandle];           /* Get referense        */      
00759 
00760         switch (soc->state)     {
00761                 case TCP_STATE_FREE:
00762                         return(-1);
00763                         
00764                 case TCP_STATE_RESERVED:
00765                 case TCP_STATE_CLOSED:
00766                         return(sochandle);
00767                 
00768                 case TCP_STATE_TIMED_WAIT:
00769                 case TCP_STATE_LISTENING:
00770                         tcp_newstate(soc, TCP_STATE_CLOSED);
00771                         return(sochandle);
00772                 
00773                 case TCP_STATE_SYN_SENT:
00774                 case TCP_STATE_SYN_RECEIVED:
00775                 case TCP_STATE_CONNECTED:
00776                 case TCP_STATE_FINW1:
00777                 case TCP_STATE_FINW2:
00778                 case TCP_STATE_CLOSING:
00779                 case TCP_STATE_LAST_ACK:
00780                 
00781                         soc->myflags = TCP_FLAG_RESET;
00782                         tcp_sendcontrol(sochandle);
00783                         tcp_newstate(soc, TCP_STATE_CLOSED);
00784                         return(sochandle);
00785                         
00786                 default:
00787                         return(-1);
00788         }
00789         
00790 
00791 }
00792 
00793 
00794 
00808 void tcp_poll (void)
00809 {
00810         struct tcb* soc;
00811         static UINT8 handle = 0;
00812         UINT8 i;
00813         INT32 temp;
00814         UINT8 old_retries;
00815         
00816         for(i=0; i < NO_OF_TCPSOCKETS; i++ ) {
00817                 
00818                 if(handle > NO_OF_TCPSOCKETS)
00819                         handle = 0;
00820 
00821                 soc = &tcp_socket[handle];
00822                 
00823                 switch(soc->state) {
00824                         case TCP_STATE_FREE:
00825                         case TCP_STATE_RESERVED:
00826                         case TCP_STATE_CLOSED:
00827                         case TCP_STATE_LISTENING:
00828                                 
00829                                 break;
00830                                 
00831                         case TCP_STATE_CONNECTED:
00832                         
00833                                 /* In CONNECTED State we have                                   */ 
00834                                 /* something to do only if we have unacked data */
00835                                 /* or if connection has been IDLE too long or   */
00836                                 /* unserved close is isuued by user                             */
00837                                 
00838                                 /*if(soc->send_next > soc->send_unacked)
00839                                         temp = soc->send_next - soc->send_unacked;
00840                                 else
00841                                         temp = soc->send_unacked - soc->send_next;
00842                                 */
00843                                 
00844                                 temp = soc->send_next - soc->send_unacked;
00845                                 
00846                                 /* Unserved Close?                      */
00847                                 
00848                                 if(soc->flags & TCP_INTFLAGS_CLOSEPENDING) {
00849                                         /* Can we send the close now    */
00850                                         
00851                                         if(temp == 0) {
00852                                                 soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
00853                                                 soc->send_next++;
00854                                                 tcp_sendcontrol(handle);
00855                                                 tcp_newstate(soc, TCP_STATE_FINW1);     
00856                                                 soc->flags ^= TCP_INTFLAGS_CLOSEPENDING;
00857                                                 
00858                                                 handle++;
00859                                                 
00860                                                 return;         
00861                                                 
00862                                         }
00863                                 }
00864                                 
00865                                 /* Socket timeout?                      */
00866                                 
00867                                 if(check_timer(soc->persist_timerh) == 0) {
00868                                 
00869                                         soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
00870                                         soc->send_next++;
00871                                         tcp_sendcontrol(handle);
00872                                         tcp_newstate(soc, TCP_STATE_FINW1);     
00873                                         
00874                                         /* Inform application   */
00875                                         
00876                                         soc->event_listener(handle, TCP_EVENT_CLOSE, soc->rem_ip, soc->remport);
00877                                         
00878                                         handle++;
00879                 
00880                                         return;                 
00881                                 }       
00882                                 
00883                                 /* Is there unacked data?       */
00884                                 
00885                                 if(temp == 0)
00886                                         break;
00887                                 
00888                                 /* Is there timeout?                                    */
00889                                 
00890                                 if( check_timer(soc->retransmit_timerh) != 0 )
00891                                         break;
00892                                 
00893                                 /* De we have retries left                              */
00894                                 
00895                                 if(soc->retries_left == 0) {
00896                                         /* No retries, must reset       */
00897                                         
00898                                         TCP_DEBUGOUT("Retries used up, resetting\r\n");
00899                                         
00900                                         soc->myflags = TCP_FLAG_RESET;
00901                                         tcp_sendcontrol(handle);
00902                                         
00903                                         /* Inform application   */
00904 
00905                                         soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
00906                                 
00907                                         if(soc->type & TCP_TYPE_SERVER )
00908                                                 tcp_newstate(soc, TCP_STATE_LISTENING);
00909                                         else
00910                                                 tcp_newstate(soc, TCP_STATE_CLOSED);
00911                                         
00912                                         handle++;
00913                 
00914                                         return;                                                                         
00915                                 }
00916                                 
00917                                 soc->retries_left--;
00918                                 init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
00919                                                                 
00920                                 /* Yep, there is unacked data                   */
00921                                 /* Application should send the old data */
00922                                 
00923                                 if(temp>soc->send_mtu)
00924                                         temp = soc->send_mtu;
00925                                 
00926                                 /* Rewind Send Next because the send process will adjust it                     */
00927                                 /* So cheat the tcp_send to think there is no unacked data                      */
00928                                 
00929                                 soc->send_next = soc->send_unacked;
00930                                 
00931                                 /* tcp_send will set the retiries_left to maximum but this is           */
00932                                 /* retransmitting already so we need to retain it in order to           */
00933                                 /* avoid dead-lock                                                                                                      */
00934                                 
00935                                 old_retries = soc->retries_left;
00936                                 
00937                                 temp = soc->event_listener(handle, TCP_EVENT_REGENERATE, (UINT32)temp, 0);
00938                         
00939                                 soc->retries_left = old_retries;
00940                         
00941                                 if(temp <= 0) {
00942                                         
00943                                         /* No data by application, must be something wrong      */
00944                                         soc->myflags = TCP_FLAG_RESET;
00945                                         tcp_sendcontrol(handle);
00946                                         
00947                                         /* Inform application   */
00948 
00949                                         soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
00950                                                                         
00951                                         if(soc->type & TCP_TYPE_SERVER )
00952                                                 tcp_newstate(soc, TCP_STATE_LISTENING);
00953                                         else
00954                                                 tcp_newstate(soc, TCP_STATE_CLOSED);
00955                                         
00956                                         handle++;
00957                 
00958                                         return;                                 
00959                                         
00960                                 }
00961                                 
00962                                 /* Application has send data    */
00963                                 
00964                                 handle++;
00965                 
00966                                 return;
00967                                 
00968                         
00969                         case TCP_STATE_SYN_SENT:
00970                         case TCP_STATE_SYN_RECEIVED:
00971                         
00972                                 /* Is there timeout?    */
00973                                 if( check_timer(soc->retransmit_timerh) != 0 )
00974                                         break;
00975                                         
00976                                 TCP_DEBUGOUT("Timeout\r\n");
00977                                         
00978                                 /* Yep, timeout. Is there reties left?  */
00979                                 if( soc->retries_left ) {
00980                                         soc->retries_left--;
00981                                         init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
00982                                         tcp_sendcontrol(handle);
00983                                         
00984                                         handle++;
00985                 
00986                                         return;                         
00987                                 } else {
00988                                         /* Retries used up      */
00989                                         TCP_DEBUGOUT("Retries used up, resetting\r\n");
00990                                         
00991                                         if(soc->type & TCP_TYPE_SERVER )
00992                                                 tcp_newstate(soc, TCP_STATE_LISTENING);
00993                                         else
00994                                                 tcp_newstate(soc, TCP_STATE_CLOSED);
00995                                         
00996                                         soc->myflags = TCP_FLAG_RESET;
00997                                         tcp_sendcontrol(handle);
00998                                         
00999                                         /* Inform application   */
01000 
01001                                         soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01002                                         
01003                                         handle++;
01004                 
01005                                         return;
01006                                 }
01007                                 
01008                                 break;
01009                                 
01010                         case TCP_STATE_TIMED_WAIT:
01011                                 
01012                                 /* Is there timeout?    */
01013                                 
01014                                 if( check_timer(soc->retransmit_timerh) != 0 )
01015                                         break;
01016                                         
01017                                 TCP_DEBUGOUT("Timeout\r\n");
01018                                 
01019                                 if(soc->retries_left) {
01020                                         soc->retries_left--;
01021                                         init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
01022                                         break;
01023                                 }
01024                                 
01025                                 if(soc->type & TCP_TYPE_SERVER )
01026                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01027                                 else
01028                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01029                                         
01030                                 break;
01031                         
01032                         case TCP_STATE_LAST_ACK:
01033                         case TCP_STATE_FINW1:
01034                         case TCP_STATE_CLOSING:
01035                         
01036                                 /* Is there timeout?    */
01037                                 
01038                                 if( check_timer(soc->retransmit_timerh) != 0 )
01039                                         break;
01040                                         
01041                                 TCP_DEBUGOUT("Timeout\r\n");            
01042                                                 
01043                                 /* Yep, timeout. Is there reties left?  */
01044                                 
01045                                 if( soc->retries_left ) {
01046                                         soc->retries_left--;
01047                                         init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
01048                                         soc->myflags = TCP_FLAG_FIN | TCP_FLAG_ACK;
01049                                         tcp_sendcontrol(handle);
01050                                         
01051                                         handle++;
01052                 
01053 
01054                                         return;                         
01055                                 } else {
01056                                         /* Retries used up      */
01057                                         TCP_DEBUGOUT("Retries used up, resetting\r\n");
01058                                         
01059                                         if(soc->type & TCP_TYPE_SERVER )
01060                                                 tcp_newstate(soc, TCP_STATE_LISTENING);
01061                                         else
01062                                                 tcp_newstate(soc, TCP_STATE_CLOSED);
01063                                         
01064                                         soc->myflags = TCP_FLAG_RESET;
01065                                         tcp_sendcontrol(handle);
01066                                         
01067                                         /* Inform application   */
01068 
01069                                         soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01070                                         
01071                                         handle++;
01072                 
01073                                         return;
01074                                 }                       
01075                                 
01076                                 break;
01077                         
01078                         case TCP_STATE_FINW2:
01079                         
01080                                 /* Is there timeout?    */
01081                                 
01082                                 if( check_timer(soc->retransmit_timerh) != 0 )
01083                                         break;
01084                                         
01085                                 TCP_DEBUGOUT("Timeout\r\n");            
01086                                                 
01087                                 /* Yep, timeout. Is there reties left?  */
01088                                 
01089                                 if( soc->retries_left ) {
01090                                         /* Still keep waiting for FIN   */
01091                                 
01092                                         soc->retries_left--;
01093                                         init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
01094                                         break;                  
01095                                 } else {
01096                                         /* Retries used up      */
01097                                         TCP_DEBUGOUT("Retries used up, resetting\r\n");
01098                                         
01099                                         if(soc->type & TCP_TYPE_SERVER )
01100                                                 tcp_newstate(soc, TCP_STATE_LISTENING);
01101                                         else
01102                                                 tcp_newstate(soc, TCP_STATE_CLOSED);
01103                                         
01104                                         soc->myflags = TCP_FLAG_RESET;
01105                                         tcp_sendcontrol(handle);
01106                                         
01107                                         /* Inform application   */
01108 
01109                                         soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01110                                 
01111                                         handle++;
01112                 
01113                                         return;
01114                                 }       
01115                                 
01116                                 break;
01117                         
01118                         default:
01119                                 break;  
01120                         
01121                 }
01122                 
01123                 /* Go to next socket if there was no event      */
01124                 
01125                 handle++;
01126                 
01127         }
01128         
01129 }
01130 
01131 
01132 
01150 INT8 tcp_init (void)
01151 {
01152         UINT16 i;
01153         INT16 h;
01154         struct tcb* soc;
01155         
01156         if( NO_OF_TCPSOCKETS < 0 )
01157                 return(-1);
01158         
01159         if( NO_OF_TCPSOCKETS == 0 )
01160                 return(0);
01161         
01162         TCP_DEBUGOUT("Initializing TCP");
01163         
01164         for(i=0; i < NO_OF_TCPSOCKETS; i++) {
01165                 soc = &tcp_socket[i];                   /* Get Socket   */
01166                 h = -1;
01167                 
01168                 soc->state = TCP_STATE_FREE;
01169                 soc->type = TCP_TYPE_NONE;
01170                 soc->flags = 0;
01171                 soc->rem_ip = 0;
01172                 soc->remport = 0;
01173                 soc->locport = 0;
01174                 soc->myflags = 0;
01175                 soc->send_mtu = TCP_DEF_MTU;
01176                 soc->tos = 0;
01177                 soc->tout = 0;
01178                 soc->event_listener = 0;
01179                 
01180                 /* Reserve Timers       */
01181                 
01182                 h = get_timer();
01183                 
01184                 /*
01185                 if( h < 0 ) {
01186                         TCP_DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
01187                         return(-1);
01188                 }
01189                 */
01190                 
01191                 init_timer(h,0);                                        /* No timeout   */
01192                 
01193                 soc->persist_timerh = h;
01194                 
01195                 h = get_timer();
01196                 
01197                 /*
01198                 if( h < 0 ) {
01199                         TCP_DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
01200                         return(-1);
01201                 }
01202                 */
01203                 
01204                 init_timer(h,0);                                        /* No timeout   */
01205                 
01206                 soc->retransmit_timerh = h;
01207                 
01208                 soc->retries_left = 0;           
01209                 
01210                 TCP_DEBUGOUT(".");
01211                 
01212         
01213         }
01214         
01215         TCP_DEBUGOUT("\n\rTCP Initialized\n\r");
01216         
01217         /* Return number of sockets initialized */
01218         
01219         return(i+1);
01220         
01221 
01222 }
01223 
01224 
01225 
01226 
01227 /*******************************************************************************/
01228 /*******        TCP Internal functions                                                                          ********/
01229 /*******************************************************************************/
01230 
01231 
01246 INT16 process_tcp_in (struct ip_frame* frame, UINT16 len)
01247 {
01248         struct tcb* soc;
01249         UINT16 hlen;
01250         UINT8 olen;
01251         UINT16 dlen;
01252         UINT32 diff;
01253         UINT16 i;
01254         INT8 sochandle; 
01255         INT16 temp;
01256         
01257         /* Is this TCP? */
01258         
01259         TCP_DEBUGOUT("Processing TCP...\n\r");
01260         
01261         if( frame->protocol != IP_TCP ) {
01262                 TCP_DEBUGOUT("ERROR: The protocol is not TCP\n\r");
01263                 return(-1);
01264         }
01265         
01266         /* Calculate checksum for received packet       */
01267 
01268         
01269         NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
01270         
01271         if( tcp_check_cs(frame, len) == 1) {
01272                 TCP_DEBUGOUT("TCP Checksum OK\n\r");
01273         } else {
01274                 TCP_DEBUGOUT("ERROR:TCP Checksum failed\r\n");
01275                 return(-1);
01276         } 
01277 
01278         /* Get the header       */
01279         
01280         NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
01281         
01282         received_tcp_packet.sport = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01283         received_tcp_packet.sport |= RECEIVE_NETWORK_B();
01284         
01285         received_tcp_packet.dport = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01286         received_tcp_packet.dport |= RECEIVE_NETWORK_B();
01287         
01288         received_tcp_packet.seqno = (((UINT32)RECEIVE_NETWORK_B()) << 24);
01289         received_tcp_packet.seqno |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
01290         received_tcp_packet.seqno |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
01291         received_tcp_packet.seqno |= RECEIVE_NETWORK_B();
01292         
01293         received_tcp_packet.ackno = (((UINT32)RECEIVE_NETWORK_B()) << 24);
01294         received_tcp_packet.ackno |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
01295         received_tcp_packet.ackno |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
01296         received_tcp_packet.ackno |= RECEIVE_NETWORK_B();
01297 
01298         received_tcp_packet.hlen_flags = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01299         received_tcp_packet.hlen_flags |= RECEIVE_NETWORK_B();
01300         
01301         received_tcp_packet.window = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01302         received_tcp_packet.window |= RECEIVE_NETWORK_B();
01303         
01304         received_tcp_packet.checksum = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01305         received_tcp_packet.checksum |= RECEIVE_NETWORK_B();
01306         
01307         received_tcp_packet.urgent = ((UINT16)RECEIVE_NETWORK_B()) << 8;
01308         received_tcp_packet.urgent |= RECEIVE_NETWORK_B();
01309         
01310         /* Little check for options     */
01311         
01312         hlen = received_tcp_packet.hlen_flags & 0xF000;
01313         hlen >>= 10;
01314         
01315         if( hlen < MIN_TCP_HLEN ) {
01316                 TCP_DEBUGOUT("ERROR: Received TCP Header too short\r\n");
01317                 return(-1);
01318         }
01319         
01320         if(hlen == MIN_TCP_HLEN)
01321                 TCP_DEBUGOUT("TCP does not contain options\r\n");
01322         
01323         olen = hlen - MIN_TCP_HLEN;
01324         
01325         if( olen > MAX_TCP_OPTLEN ) {
01326                 TCP_DEBUGOUT("ERROR: Received TCP header contains too long option field\r\n");
01327                 return(-1);
01328         }
01329         
01330         /* Calculate data length        */
01331         
01332         if( hlen > len ) {
01333                 TCP_DEBUGOUT("ERROR: TCP header longer than packet\r\n");
01334                 return(-1);
01335         }
01336         
01337         dlen = len - hlen - olen;
01338         
01339         /* Get options (if any) */
01340         
01341         for(i=0; i<olen;i++)
01342                 received_tcp_packet.opt[i] = RECEIVE_NETWORK_B();
01343                 
01344         /* Try to find rigth socket to process with             */
01345         
01346         sochandle = tcp_mapsocket(frame, &received_tcp_packet);
01347         
01348         if(sochandle < 0) {
01349                 TCP_DEBUGOUT("ERROR: Processing TCP packet failed\r\n");
01350                 tcp_sendreset(&received_tcp_packet, frame->sip);
01351                 return(-1);
01352         }
01353         
01354         received_tcp_packet.buf_index = frame->buf_index + hlen;
01355         NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);
01356         
01357         
01358         
01359         /* Get socket reference */
01360         
01361         soc = &tcp_socket[sochandle];
01362         
01363         /* Process the packet on TCP State Machine              */
01364         
01365         switch(soc->state) {
01366                 case TCP_STATE_CONNECTED:
01367                 
01368                         TCP_DEBUGOUT("CONNECTED State\r\n");
01369                         
01370                         /* Check for RESET      */
01371                         
01372                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET)     {
01373                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01374 
01375                                 /* Inform application   */
01376 
01377                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);                             
01378                                 
01379                                 if(soc->type & TCP_TYPE_SERVER)
01380                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01381                                 else
01382                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01383                                         
01384                                 return(-1);
01385                         }
01386                         
01387                         /* Check for SYN (If the peer didn't get our SYN+ACK or ACK)    */
01388                         
01389                         if( received_tcp_packet.hlen_flags & TCP_FLAG_SYN )     {
01390                                 /* Is it the SYN+ACK we have already ACKed but maybe ACK lost?  */
01391                                 
01392                                 if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK )     {
01393                                         /* It's SYN+ACK but how about sequence  */
01394                                         
01395                                         if( (received_tcp_packet.seqno + 1) == soc->receive_next ) {
01396                                         
01397                                                 if( received_tcp_packet.ackno == soc->send_next ) {
01398                                                 
01399                                                         TCP_DEBUGOUT("Received SYN+ACK again\r\n");
01400                                                         
01401                                                         /* ACK the SYN  */
01402                                                         soc->myflags = TCP_FLAG_ACK;
01403                                                         tcp_sendcontrol(sochandle);
01404                                                         return(0);
01405                                                 }
01406                                                 
01407                                         }
01408                                 
01409                                  /* It is maybe SYN again so it haven't get our SYN + ACK       */
01410                                  /* Let our retransmission handle it                                            */
01411                                  
01412                                  return(0);
01413                                 
01414                                 
01415                                 }
01416                         
01417                         }
01418                         
01419                         /* Do we have unacked data?             */
01420                         
01421                         if( soc->send_unacked != soc->send_next ) {
01422                         
01423                                 /* Yep, is the ACK valid?       */
01424                                 
01425                                 if( (received_tcp_packet.hlen_flags & TCP_FLAG_ACK) == 0) {
01426                                 
01427                                         TCP_DEBUGOUT("Packet without ACK and unacked data. Packet not processed\r\n");
01428                                         return(0);
01429                                 }
01430                                 
01431                                 if( received_tcp_packet.ackno == soc->send_next ) {
01432                                 
01433                                         /* We don't have unacked data now       */
01434                                 
01435                                         soc->send_unacked = soc->send_next;
01436                                 
01437                                         /* Inform application   */
01438                                 
01439                                         soc->event_listener(sochandle, TCP_EVENT_ACK, soc->rem_ip, soc->remport);
01440                                 
01441                                 }
01442 
01443                         
01444                         }
01445                         
01446                         /* Is the sequence OK   */
01447                         
01448                         if(soc->receive_next != received_tcp_packet.seqno)
01449                         {
01450                                 /* Out of range, inform what we except  */
01451                         
01452                                 DEBUGOUT("Too big sequence number received\r\n");
01453                                 
01454                                 soc->myflags = TCP_FLAG_ACK;
01455                                 tcp_sendcontrol(sochandle);
01456                                 return(0);
01457                         }
01458                         
01459                         /* Generate data event to application   */
01460                                 
01461                         soc->event_listener(sochandle, TCP_EVENT_DATA, dlen, 0);
01462                                 
01463                         soc->receive_next += dlen;                      
01464                                         
01465                         /* Is the FIN flag set? */
01466                         
01467                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN )     {
01468                                 TCP_DEBUGOUT("Other end want's to close\r\n");
01469                                 
01470                                 /* Inform application if we don't have unacked data     */
01471                                 
01472                                 if( soc->send_unacked == soc->send_next) {
01473                                 
01474                                         soc->event_listener(sochandle, TCP_EVENT_CLOSE, soc->rem_ip, soc->remport);
01475                                 
01476                                         /* ACK FIN and set our own FIN  */
01477                                 
01478                                         soc->receive_next++;
01479                                         soc->send_next++;
01480                                         soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
01481                                 
01482                                         tcp_newstate(soc, TCP_STATE_LAST_ACK);
01483                                         tcp_sendcontrol(sochandle);
01484                                 
01485                                         return(0);
01486                                 }
01487                         }
01488                         
01489                         /* ACK the data if there was it */
01490                         
01491                         if(dlen) {
01492                                 soc->myflags = TCP_FLAG_ACK;
01493                                 tcp_sendcontrol(sochandle);
01494                         }
01495                         
01496                         tcp_newstate(soc, TCP_STATE_CONNECTED);                 
01497                         
01498 
01499                         return(0);
01500                         
01501                 
01502                         break;
01503         
01504                 case TCP_STATE_FREE:
01505                         
01506                         /* Reset connection     */
01507                         tcp_sendreset(&received_tcp_packet, frame->sip);
01508                         return(-1);
01509                 
01510                         break;
01511                 
01512                 case TCP_STATE_CLOSED:
01513                         
01514                         /* Reset connection     */
01515                         tcp_sendreset(&received_tcp_packet, frame->sip);
01516                         return(-1);             
01517                 
01518                         break;
01519                 
01520                 case TCP_STATE_LISTENING:
01521                 
01522                         TCP_DEBUGOUT("LISTENING State...\r\n");
01523                 
01524                         /* Check Flags  */
01525                         
01526                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
01527                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01528                                 tcp_newstate(soc, TCP_STATE_LISTENING);
01529                                 return(-1);
01530                         }
01531                         
01532                         if(received_tcp_packet.hlen_flags & TCP_FLAG_ACK) {
01533                                 TCP_DEBUGOUT("ERROR:Ack received\r\n");
01534                                 tcp_newstate(soc, TCP_STATE_LISTENING);
01535                                 /* Reset connection     */
01536                                 tcp_sendreset(&received_tcp_packet, frame->sip);
01537                                 return(-1);     
01538                         }
01539                         
01540                         if((received_tcp_packet.hlen_flags & TCP_FLAG_SYN) == 0) {
01541                                 TCP_DEBUGOUT("ERROR:No SYN set on packet\r\n");
01542                                 tcp_newstate(soc, TCP_STATE_LISTENING);
01543                                 /* Reset connection     */
01544                                 tcp_sendreset(&received_tcp_packet, frame->sip);
01545                                 return(-1);
01546                         }
01547                         
01548                         /* OK, SYN received     */
01549                         
01550                         /* Inform application and see if accepted       */
01551                         
01552                         temp = (INT16)soc->event_listener(sochandle, TCP_EVENT_CONREQ, soc->rem_ip, soc->remport);
01553                         
01554                         if( temp == -1) {
01555                                 TCP_DEBUGOUT("Application disregarded connection request\r\n");
01556                                 tcp_sendreset(&received_tcp_packet, frame->sip);
01557                                 return(-1);
01558                         }
01559                         
01560                         if( temp == -2 ) {
01561                                 TCP_DEBUGOUT("Application wants to think about accepting conreq\r\n");
01562                                 return(1);
01563                         }
01564                         
01565                         /* The connection request was accepted  */
01566                         
01567                         TCP_DEBUGOUT("Next state SYN_RECEIVED\r\n");
01568                         if(soc->flags & TCP_INTFLAGS_CLOSEPENDING)
01569                                 soc->flags ^= TCP_INTFLAGS_CLOSEPENDING;
01570                         tcp_newstate(soc, TCP_STATE_SYN_RECEIVED);
01571                         soc->receive_next = received_tcp_packet.seqno + 1;      /* Ack SYN              */
01572                         soc->send_unacked = tcp_initseq();
01573                         
01574                         soc->myflags = TCP_FLAG_SYN | TCP_FLAG_ACK;
01575                         tcp_sendcontrol(sochandle);
01576                         soc->send_next = soc->send_unacked + 1;
01577                         
01578                         return(1);
01579                         
01580                         break;
01581                         
01582                 case TCP_STATE_SYN_RECEIVED:
01583                 
01584                         TCP_DEBUGOUT("SYN_RECEIVED State...\r\n");
01585                         
01586                         /* Check Flags  */
01587                         
01588                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET)     {
01589                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01590                                 
01591                                 /* Inform application   */
01592                                 
01593                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01594                                 
01595                                 if(soc->type & TCP_TYPE_SERVER)
01596                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01597                                 else
01598                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01599                                         
01600                                 return(-1);
01601                         }
01602                         
01603                         /* Is it SYN+ACK (if we are the because of simultaneous open)   */
01604                         
01605                         if( (received_tcp_packet.hlen_flags & TCP_FLAG_SYN) &&
01606                                 (received_tcp_packet.hlen_flags & TCP_FLAG_ACK) ) {                     
01607                                 
01608                                 if( received_tcp_packet.ackno != soc->send_next ) {
01609                                         TCP_DEBUGOUT("SYN+ACK received but wrong Ack\n\r");
01610                                         return(-1);
01611                                 }
01612                                 
01613                                 TCP_DEBUGOUT("SYN+ACK received, this side established\n\r");
01614                                 
01615                                 /* Get peer's seq number        */
01616                                 
01617                                 soc->receive_next =  received_tcp_packet.seqno;
01618                                 soc->receive_next++;                                                    /* ACK SYN      */
01619                                 
01620                                 /* We have no unacked data      */
01621                                 
01622                                 soc->send_unacked = soc->send_next;
01623                                 
01624                                 tcp_newstate(soc, TCP_STATE_CONNECTED);
01625                                 soc->myflags = TCP_FLAG_ACK;
01626                                 tcp_sendcontrol(sochandle);
01627                                 
01628                                 /* Inform application   */
01629                                 
01630                                 soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
01631                                 
01632                                 return(0);                                      
01633                                                                 
01634                         }
01635                         
01636                         /* Is it ACK?           */
01637                         
01638                         if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK )     {
01639                                 if( received_tcp_packet.ackno != soc->send_next ) {
01640                                         TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
01641                                         return(-1);
01642                                 }
01643                                 
01644                                 if( received_tcp_packet.seqno != soc->receive_next ) {
01645                                         TCP_DEBUGOUT("ACK received but Wrong SEQ number\n\r");
01646                                         return(-1);
01647                                 }
01648                                 
01649                                 TCP_DEBUGOUT("ACK received, this side CONNECTED\r\n");
01650                                 
01651                                 /* We have no unacked data      */
01652                                 
01653                                 soc->send_unacked = soc->send_next;
01654                                 
01655                                 tcp_newstate(soc, TCP_STATE_CONNECTED);
01656 
01657                                 /* Inform application   */
01658                                 
01659                                 soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
01660                                                                 
01661                                 return(0);
01662                                         
01663                         }
01664                         
01665                         /* Is it SYN?           */
01666                         
01667                         if( received_tcp_packet.hlen_flags & TCP_FLAG_SYN ) {
01668                                 TCP_DEBUGOUT("Repeated SYN\r\n");
01669                                 return(0);
01670                         }
01671                         
01672                         /* We didn't understood this one, keep on trying but info with RESET    */
01673                         
01674                         TCP_DEBUGOUT("Unrecognized packet\n\r");
01675                         
01676                         tcp_sendreset(&received_tcp_packet, frame->sip);
01677                         
01678                         return(-1);
01679                         
01680                         break;
01681                         
01682                 case TCP_STATE_SYN_SENT:
01683                 
01684                         TCP_DEBUGOUT("SYN_SENT State\r\n");
01685                         
01686                         /* Check for RESET      */
01687                         
01688                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
01689                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01690                                 
01691                                 /* Inform application   */
01692 
01693                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01694                                                                 
01695                                 if(soc->type & TCP_TYPE_SERVER)
01696                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01697                                 else
01698                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01699                                         
01700                                 return(-1);
01701                         }
01702                         
01703                         /* Is it SYN+ACK?       */
01704                         
01705                         if( (received_tcp_packet.hlen_flags & TCP_FLAG_SYN) &&
01706                                 (received_tcp_packet.hlen_flags & TCP_FLAG_ACK) ) {
01707                                 /* Rigth ACK?   */
01708                                 
01709                                 if( received_tcp_packet.ackno != soc->send_next ) {
01710                                         TCP_DEBUGOUT("SYN+ACK received but wrong Ack\n\r");
01711                                         return(-1);
01712                                 }
01713                                 
01714                                 TCP_DEBUGOUT("SYN+ACK received, this side established\n\r");
01715                                 
01716                                 /* Get peer's seq number        */
01717                                 
01718                                 soc->receive_next =  received_tcp_packet.seqno;
01719                                 soc->receive_next++;                                                    /* ACK SYN      */
01720                                 
01721                                 /* We have no unacked data      */
01722                                 
01723                                 soc->send_unacked = soc->send_next;
01724                                 
01725                                 tcp_newstate(soc, TCP_STATE_CONNECTED);
01726                                 soc->myflags = TCP_FLAG_ACK;
01727                                 tcp_sendcontrol(sochandle);
01728                                 
01729                                 /* Inform application   */
01730 
01731                                 soc->event_listener(sochandle, TCP_EVENT_CONNECTED, soc->rem_ip, soc->remport);
01732                                                                 
01733                                 return(0);                      
01734                                 
01735                         }
01736                         
01737                         /* Is it SYN (simultaneous open)        */
01738                         
01739                         if(received_tcp_packet.hlen_flags & TCP_FLAG_SYN) {
01740                                 TCP_DEBUGOUT("Simultaneous open, next SYN_RECEIVED\r\n");
01741                         
01742                                 /* Get peer's seq number        */
01743                                 
01744                                 soc->receive_next =  received_tcp_packet.seqno;
01745                                 soc->receive_next++;                                                    /* ACK SYN      */                              
01746                                 
01747                                 tcp_newstate(soc, TCP_STATE_SYN_RECEIVED);
01748                                 soc->myflags = TCP_FLAG_SYN | TCP_FLAG_ACK;
01749                                 tcp_sendcontrol(sochandle);
01750                                 
01751                                 return(0);
01752                         
01753                         }
01754                         
01755                         /* This is something we didn't understood, maybe the other peer has     */
01756                         /* still old connection on or something                                                         */
01757                         TCP_DEBUGOUT("TCP packet out of nowhere received...\r\n");
01758                         tcp_sendreset(&received_tcp_packet, frame->sip);
01759                         
01760                         return(-1);
01761                 
01762                         break;
01763                 
01764                 case TCP_STATE_FINW1:
01765                 
01766                         TCP_DEBUGOUT("FINW1 State\r\n");
01767                         
01768                         /* Check for RESET      */
01769                         
01770                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
01771                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01772                                 
01773                                 /* Inform application   */
01774 
01775                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
01776                                                                 
01777                                 if(soc->type & TCP_TYPE_SERVER)
01778                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01779                                 else
01780                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01781                                         
01782                                 return(-1);
01783                         }
01784                         
01785                         /* Is it FIN+ACK?                       */
01786                         
01787                         if( (received_tcp_packet.hlen_flags & TCP_FLAG_FIN) &&
01788                                 (received_tcp_packet.hlen_flags & TCP_FLAG_ACK) ) {
01789                                 /* Rigth ACK?   */
01790                                 
01791                                 if( received_tcp_packet.ackno != soc->send_next ) {
01792                                         TCP_DEBUGOUT("FIN+ACK received but wrong Ack\n\r");
01793                                         return(-1);
01794                                 }
01795                                 
01796                                 TCP_DEBUGOUT("FIN+ACK received, next TIMED_WAIT\n\r");
01797                                 
01798                                 /* ACK FIN and all data */
01799                                 
01800                                 soc->receive_next = received_tcp_packet.seqno;
01801                                 soc->receive_next++;
01802                                 soc->receive_next += dlen;
01803                                 
01804                                 /* We have no unacked data      */
01805                                 
01806                                 soc->send_unacked = soc->send_next;
01807                                 
01808                                 tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
01809                                 soc->myflags = TCP_FLAG_ACK;
01810                                 tcp_sendcontrol(sochandle);
01811                                                         
01812                                 return(0);
01813                         
01814                         }
01815                         
01816                         /* Is it just FIN       */
01817                         
01818                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN       ) {
01819                                 
01820                                 TCP_DEBUGOUT("Simultaneous close, next CLOSING\n\r");
01821                                 
01822                                 /* ACK FIN and all data */
01823                                 
01824                                 soc->receive_next = received_tcp_packet.seqno;
01825                                 soc->receive_next++;
01826                                 soc->receive_next += dlen;
01827                                 
01828                                 tcp_newstate(soc, TCP_STATE_CLOSING);
01829                                 soc->myflags = TCP_FLAG_ACK;
01830                                 tcp_sendcontrol(sochandle);                     
01831                                 return(0);
01832                         
01833                         }                       
01834                         
01835                         /* Is it just ACK?      */
01836                         
01837                         if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK       ) {
01838                                 /* Rigth ACK?   */
01839                                 
01840                                 if( received_tcp_packet.ackno != soc->send_next ) {
01841                                         TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
01842                                         return(-1);
01843                                 }
01844                                 
01845                                 TCP_DEBUGOUT("Our FIN is ACKed but peer don't agree to disconnect yet\r\n");
01846                                 TCP_DEBUGOUT("Next FINW2\r\n");
01847                                 
01848                                 /* We have no unacked data      */
01849                                 
01850                                 soc->send_unacked = soc->send_next;
01851                                 
01852                                 tcp_newstate(soc, TCP_STATE_FINW2);
01853                                 
01854                                 return(0);
01855                                                         
01856                         }
01857                                                 
01858                         break;
01859                         
01860                 case TCP_STATE_FINW2:
01861                 
01862                         TCP_DEBUGOUT("FINW2 State\r\n");
01863                         
01864                         /* Check for RESET      */
01865                         
01866                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
01867                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01868                                 
01869                                 /* Inform application   */
01870 
01871                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);                             
01872                                 
01873                                 if(soc->type & TCP_TYPE_SERVER)
01874                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01875                                 else
01876                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01877                                         
01878                                 return(-1);
01879                         }                       
01880                 
01881                         /* Do we finally get FIN?       */
01882                 
01883                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN       ) {
01884                                 
01885                                 TCP_DEBUGOUT("FIN received, next TIMED_WAIT\n\r");
01886                                 
01887                                 /* ACK FIN and all data */
01888                                 
01889                                 soc->receive_next = received_tcp_packet.seqno;
01890                                 soc->receive_next++;
01891                                 soc->receive_next += dlen;
01892                                 
01893                                 tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
01894                                 soc->myflags = TCP_FLAG_ACK;
01895                                 tcp_sendcontrol(sochandle);                     
01896                                 return(0);
01897                         
01898                         }               
01899                 
01900                         break;
01901                         
01902                 case TCP_STATE_CLOSING:
01903                 
01904                         TCP_DEBUGOUT("CLOSING State...\r\n");
01905                         
01906                         /* Check for RESET      */
01907                         
01908                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET)     {
01909                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01910 
01911                                 /* Inform application   */
01912 
01913                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);                             
01914                                 
01915                                 if(soc->type & TCP_TYPE_SERVER)
01916                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01917                                 else
01918                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01919                                         
01920                                 return(-1);
01921                         }                       
01922                         
01923                         /* Is it ACK?                   */
01924                         
01925                         if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK       ) {
01926                                 /* Rigth ACK?   */
01927                                 
01928                                 if( received_tcp_packet.ackno != soc->send_next ) {
01929                                         TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
01930                                         return(-1);
01931                                 }
01932                                 
01933                                 TCP_DEBUGOUT("Our FIN is ACKed and peer wants to close too\r\n");
01934                                 TCP_DEBUGOUT("Next TIMED_WAIT\r\n");
01935 
01936                                 /* We have no unacked data      */
01937                                 
01938                                 soc->send_unacked = soc->send_next;
01939                                 
01940                                 tcp_newstate(soc, TCP_STATE_TIMED_WAIT);
01941                                 
01942                                 return(0);
01943                                                         
01944                         }
01945         
01946                         /* Is it repeated FIN?  */
01947                         
01948                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN       ) {
01949                                 
01950                                 TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
01951                                 
01952                                 /* ACK FIN and all data */
01953                                 
01954                                 soc->receive_next = received_tcp_packet.seqno;
01955                                 soc->receive_next++;
01956                                 soc->receive_next += dlen;
01957                                 
01958                                 soc->myflags = TCP_FLAG_ACK;
01959                                 tcp_sendcontrol(sochandle);                     
01960                         
01961                                 return(0);
01962                         
01963                         }
01964 
01965                 
01966                         break;
01967                 
01968                 case TCP_STATE_LAST_ACK:
01969                 
01970                         TCP_DEBUGOUT("LAST_ACK State...\r\n");
01971                         
01972                         /* Check for RESET      */
01973                         
01974                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
01975                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
01976                                 
01977                                 /* Inform application   */
01978 
01979                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);                             
01980                                 
01981                                 if(soc->type & TCP_TYPE_SERVER)
01982                                         tcp_newstate(soc, TCP_STATE_LISTENING);
01983                                 else
01984                                         tcp_newstate(soc, TCP_STATE_CLOSED);
01985                                         
01986                                 return(-1);
01987                         }                       
01988                         
01989                         /* Is it ACK?   */
01990                         
01991                         if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK       ) {
01992                                 /* Rigth ACK?   */
01993                                 
01994                                 if( received_tcp_packet.ackno != soc->send_next ) {
01995                                         TCP_DEBUGOUT("ACK received but wrong Ack\n\r");
01996                                         return(-1);
01997                                 }
01998                                 
01999                                 TCP_DEBUGOUT("Last ACK received, next LISTENING or CLOSED\r\n");
02000                                 
02001                                 /* We have no unacked data      */
02002                                 
02003                                 soc->send_unacked = soc->send_next;                             
02004                                 
02005                                 if(soc->type & TCP_TYPE_SERVER)
02006                                         tcp_newstate(soc, TCP_STATE_LISTENING);
02007                                 else
02008                                         tcp_newstate(soc, TCP_STATE_CLOSED);
02009                                                                                                 
02010                                 return(0);
02011                                                         
02012                         }                       
02013 
02014                         /* Is it repeated FIN?  */
02015                         
02016                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN       ) {
02017                                 
02018                                 TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
02019                                 
02020                                 /* ACK FIN and all data */
02021                                 
02022                                 soc->receive_next = received_tcp_packet.seqno;
02023                                 soc->receive_next++;
02024                                 soc->receive_next += dlen;
02025                                         
02026                                 soc->myflags = TCP_FLAG_FIN | TCP_FLAG_ACK;
02027                                 tcp_sendcontrol(sochandle);
02028                                                         
02029                                 return(0);
02030                         
02031                         }                       
02032                         
02033                 
02034                         break;
02035                         
02036                 case TCP_STATE_TIMED_WAIT:
02037                 
02038                         TCP_DEBUGOUT("TIMED_WAIT State...\r\n");
02039                         
02040                         /* Check for RESET      */
02041                         
02042                         if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
02043                                 TCP_DEBUGOUT("ERROR:Reset received\r\n");
02044 
02045                                 /* Inform application   */
02046 
02047                                 soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);                             
02048                                 
02049                                 if(soc->type & TCP_TYPE_SERVER)
02050                                         tcp_newstate(soc, TCP_STATE_LISTENING);
02051                                 else
02052                                         tcp_newstate(soc, TCP_STATE_CLOSED);
02053                                         
02054                                 return(-1);
02055                         }                       
02056                         
02057                         /* Is it repeated FIN?  */
02058                         
02059                         if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN       ) {
02060                                 
02061                                 TCP_DEBUGOUT("Repeated FIN, repeat ACK\n\r");
02062                                 
02063                                 /* ACK FIN and all data */
02064                                 
02065                                 soc->receive_next = received_tcp_packet.seqno;
02066                                 soc->receive_next++;
02067                                 soc->receive_next += dlen;
02068                                         
02069                                 soc->myflags = TCP_FLAG_ACK;
02070                                 tcp_sendcontrol(sochandle);
02071                                                         
02072                                 return(0);
02073                         
02074                         }
02075                 
02076                         
02077                 
02078                         break;
02079         
02080         
02081                 default:
02082                 
02083                         TCP_DEBUGOUT("ERROR:TCP State machine in unknown state!!\r\n");
02084                         
02085                         tcp_sendreset(&received_tcp_packet, frame->sip);
02086                         
02087                         RESET_SYSTEM();
02088         
02089         }
02090         
02091         TCP_DEBUGOUT("Should not be there!\r\n");
02092         
02093         return(-1);
02094                 
02095 }
02096 
02097 
02115 INT16 process_tcp_out (INT8 sockethandle, UINT8* buf, UINT16 blen, UINT16 dlen)
02116 {
02117         struct tcb* soc;
02118         UINT16 cs;
02119         UINT8 cs_cnt;
02120         UINT16 i;
02121         UINT8* buf_start;
02122         
02123         TCP_DEBUGOUT("Entering to send TCP packet\r\n");
02124         
02125         if( sockethandle < 0 ) {
02126                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (<0)\r\n");
02127                 return(-1);
02128         }
02129         
02130         if( sockethandle > NO_OF_TCPSOCKETS ) {
02131                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (>NO_OF_TCPSOCKETS)\r\n");
02132                 return(-1);
02133         }
02134         
02135         if( (dlen + MIN_TCP_HLEN) > blen ) {
02136                 TCP_DEBUGOUT("ERROR:Transmit buffer too small for TCP header\r\n");
02137                 return(-1);
02138         } 
02139         
02140         soc = &tcp_socket[sockethandle];                                /* Get socket   */
02141         
02142         buf_start = buf;
02143         
02144         if( (dlen + MIN_TCP_HLEN) > soc->send_mtu ) {
02145                 TCP_DEBUGOUT("ERROR:Send MTU exceeded\r\n");
02146                 return(-1);
02147         }
02148         
02149         /* Assemble TCP header to buffer        */
02150         
02151         *buf++ = (UINT8)(soc->locport >> 8);
02152         *buf++ = (UINT8)soc->locport;
02153         *buf++ = (UINT8)(soc->remport >> 8);
02154         *buf++ = (UINT8)soc->remport;
02155         *buf++ = (UINT8)(soc->send_unacked >>24);
02156         *buf++ = (UINT8)(soc->send_unacked >>16);
02157         *buf++ = (UINT8)(soc->send_unacked >>8);
02158         *buf++ = (UINT8)(soc->send_unacked);
02159         *buf++ = (UINT8)(soc->receive_next >>24);
02160         *buf++ = (UINT8)(soc->receive_next >>16);
02161         *buf++ = (UINT8)(soc->receive_next >>8);
02162         *buf++ = (UINT8)(soc->receive_next);
02163         *buf =  MIN_TCP_HLEN >> 2;
02164         *buf <<= 4;
02165         buf++;
02166         *buf++ = soc->myflags;
02167         *buf++ = (UINT8)(TCP_DEF_MTU >> 8);
02168         *buf++ = (UINT8)TCP_DEF_MTU;
02169         *buf++ = 0;                                                             /* Checksum     */
02170         *buf++ = 0;
02171         *buf++ = 0;                                                             /* Urgent       */
02172         *buf++ = 0;
02173         
02174          
02175         /* Calculate checksum   */
02176         
02177         cs = 0;
02178         cs_cnt = 0;
02179         
02180         /* Do it firstly to IP pseudo header    */
02181         
02182         cs = ip_checksum(cs, (UINT8)(localmachine.localip >> 24), cs_cnt++);    
02183         cs = ip_checksum(cs, (UINT8)(localmachine.localip >> 16), cs_cnt++);
02184         cs = ip_checksum(cs, (UINT8)(localmachine.localip >> 8), cs_cnt++);
02185         cs = ip_checksum(cs, (UINT8)localmachine.localip, cs_cnt++);
02186         
02187         cs = ip_checksum(cs, (UINT8)(soc->rem_ip >> 24), cs_cnt++);     
02188         cs = ip_checksum(cs, (UINT8)(soc->rem_ip >> 16), cs_cnt++);
02189         cs = ip_checksum(cs, (UINT8)(soc->rem_ip >> 8), cs_cnt++);
02190         cs = ip_checksum(cs, (UINT8)soc->rem_ip, cs_cnt++);     
02191         
02192         cs = ip_checksum(cs, 0, cs_cnt++);
02193         
02194         cs = ip_checksum(cs, (UINT8)IP_TCP, cs_cnt++);
02195                 
02196         cs = ip_checksum(cs, (UINT8)((dlen + MIN_TCP_HLEN) >> 8), cs_cnt++);
02197         cs = ip_checksum(cs, (UINT8)(dlen + MIN_TCP_HLEN), cs_cnt++);
02198         
02199         /* Go to TCP header + data      */
02200         
02201         buf = buf_start;
02202         
02203         for(i=0; i < (dlen + MIN_TCP_HLEN); i++)
02204                 cs = ip_checksum(cs, *buf++, cs_cnt++);
02205         
02206         cs = ~ cs;
02207 
02208 #if 0
02209         /* Is the padding required?     */
02210         
02211         if(dlen & 0x01) {
02212                 TCP_DEBUGOUT("Padding required\r\n");
02213                 *buf = 0;
02214                 dlen++;
02215         }
02216 #endif
02217         
02218         /* Save checksum in correct place       */
02219         
02220         buf = buf_start + 16;
02221         *buf++ = (UINT8)(cs >> 8);
02222         *buf = (UINT8)cs;
02223         
02224         /* Send it to IP        */
02225         
02226         TCP_DEBUGOUT("Sending TCP...\r\n");
02227         
02228         process_ip_out(soc->rem_ip, IP_TCP, soc->tos, 100, buf_start, dlen + MIN_TCP_HLEN);
02229         
02230         TCP_DEBUGOUT("TCP packet sent\r\n");
02231         
02232         return(0);
02233         
02234 
02235 }
02236 
02237 
02238 
02250 void tcp_sendcontrol (UINT8 sockethandle)
02251 {
02252         UINT8 i;
02253 
02254         
02255         TCP_DEBUGOUT("Entering to send TCP control packet\r\n");
02256         
02257         kick_WD();
02258         
02259         if( sockethandle < 0 ) {
02260                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (<0)\r\n");
02261                 return;
02262         }
02263         
02264         if( sockethandle > NO_OF_TCPSOCKETS ) {
02265                 TCP_DEBUGOUT("ERROR:Socket Handle not valid (>NO_OF_TCPSOCKETS)\r\n");
02266                 return;
02267         }
02268         
02269         process_tcp_out(sockethandle, &tcp_tempbuf[0], MIN_TCP_HLEN + 1, 0);
02270         
02271         return;
02272         
02273         
02274 }
02275 
02291 void tcp_sendreset (struct tcp_frame *frame, UINT32 remip)
02292 {
02293         struct tcb* soc;
02294 
02295         soc = &tcp_socket[NO_OF_TCPSOCKETS];                            /* Get socket   */
02296 
02297 
02298         /* Is this itself a reset packet?       */
02299         
02300         if( frame->hlen_flags & TCP_FLAG_RESET )
02301                 return;
02302 
02303         /* Set temporary tcb variables  */
02304         
02305         soc->rem_ip = remip;
02306         soc->remport = frame->sport;
02307         soc->locport = frame->dport;
02308         soc->tos = 0;
02309         
02310         /* Does the packet have ACK flag set?   */
02311         
02312         if( frame->hlen_flags & TCP_FLAG_ACK ) {
02313                 /* Jup, use it as our seq       */
02314                 
02315                 soc->send_unacked = frame->ackno;
02316                 soc->myflags = TCP_FLAG_RESET;  
02317                 soc->receive_next = frame->seqno;
02318         } else {
02319                 soc->send_unacked = 0;
02320                 soc->myflags = TCP_FLAG_RESET | TCP_FLAG_ACK;   
02321                 soc->receive_next = frame->seqno+1;
02322         }
02323                 
02324         
02325         soc->send_mtu = TCP_DEF_MTU;
02326         
02327         tcp_sendcontrol(NO_OF_TCPSOCKETS);
02328 
02329 }
02330 
02331 
02343 UINT32 tcp_initseq (void)
02344 {
02345 
02346         TCP_DEBUGOUT("Calculating initial sequence number\r\n");
02347         
02348         return( ( (UINT32)base_timer << 24) | 0x00FFFFFF );
02349 
02350 }
02351 
02366 INT8 tcp_mapsocket (struct ip_frame* ipframe, struct tcp_frame* tcpframe)
02367 {
02368         struct tcb* soc;
02369         UINT8 i;
02370 
02371         
02372         /* Check if there is already connection on      */
02373         
02374         for( i=0; i < NO_OF_TCPSOCKETS; i++) {
02375                 soc = &tcp_socket[i];                                   /* Get socket   */
02376                 
02377                 if(soc->state == TCP_STATE_LISTENING)
02378                         continue;                                                       /* No match             */
02379                 if(soc->remport != tcpframe->sport)
02380                         continue;                                               
02381                 if(soc->locport != tcpframe->dport)
02382                         continue;                                               
02383                 if(soc->rem_ip != ipframe->sip) 
02384                         continue;                                               
02385                 
02386                 /* There is connection on already       */
02387                 
02388                 TCP_DEBUGOUT("Active connection socket found\r\n");
02389                 
02390                 return(i);
02391         }
02392         
02393         /* Allocate listening one if SYN packet (Connection Request)    */
02394         
02395         TCP_DEBUGOUT("No active connection, checking if SYN packet\r\n");
02396         
02397         /* Is it SYN?   */
02398         
02399         if( (tcpframe->hlen_flags & TCP_FLAG_SYN) == 0 )
02400                 return(-1);
02401         if( tcpframe->hlen_flags & TCP_FLAG_ACK )
02402                 return(-1);
02403         if( tcpframe->hlen_flags & TCP_FLAG_RESET )
02404                 return(-1);
02405         if( tcpframe->hlen_flags & TCP_FLAG_FIN )
02406                 return(-1);
02407         
02408         TCP_DEBUGOUT("Trying to allocate listening one for SYN packet\r\n");
02409         
02410         /* Search listening sockets     */
02411         
02412         for( i=0; i < NO_OF_TCPSOCKETS; i++) {
02413                 soc = &tcp_socket[i];                           /* Get socket   */
02414         
02415                 if(soc->state != TCP_STATE_LISTENING)
02416                         continue;       
02417                 
02418                 if(soc->locport != tcpframe->dport)
02419                         continue;
02420                 
02421                 /* Bind it      */
02422                 
02423                 soc->rem_ip = ipframe->sip;
02424                 soc->remport = tcpframe->sport;
02425                 
02426                 TCP_DEBUGOUT("Allocated new socket\r\n");
02427                 
02428                 return(i);
02429                 
02430         }
02431         
02432         /* No success   */
02433         
02434         TCP_DEBUGOUT("ERROR:No socket found or allocated for TCP packet\r\n");
02435         
02436         return(-1);
02437 
02438 }
02439 
02440 
02452 void tcp_newstate (struct tcb* soc, UINT8 nstate)
02453 {
02454         soc->state = nstate;
02455         soc->retries_left = TCP_DEF_RETRIES;
02456 
02457         /* In some states we don't want to wait for many retries (e.g. TIMED_WAIT)      */
02458         
02459         switch(soc->state) {
02460                 case TCP_STATE_TIMED_WAIT:
02461                         soc->retries_left = 1;
02462                         break;
02463                 
02464                 case TCP_STATE_LAST_ACK:
02465                 case TCP_STATE_FINW1:
02466                 case TCP_STATE_FINW2:
02467                 case TCP_STATE_CLOSING:
02468                         soc->retries_left = 3;
02469                         break;
02470                 
02471                 default:
02472                         break;
02473         
02474         }
02475         
02476         
02477         /* KeepAlive timer      */
02478         if(soc->state == TCP_STATE_CONNECTED)
02479                 init_timer(soc->persist_timerh, soc->tout);
02480         
02481         /* Retransmit timer     */
02482         
02483         init_timer(soc->retransmit_timerh, TCP_DEF_RETRY_TOUT*TIMERTIC);
02484         
02485         return;
02486 
02487 
02488 }
02489 
02501 UINT16 tcp_getfreeport (void)
02502 {
02503         struct tcb* soc;
02504         static UINT16 lastport = 1;
02505         UINT16 start;
02506         UINT16 i;
02507         
02508 
02509         /* Try with every port to every socket untill free found        */
02510                 
02511         for( start = lastport++; start != lastport; lastport++) {
02512                 if(lastport == TCP_PORTS_END)
02513                         lastport = 1;
02514                         
02515                 for(i = 0; i < NO_OF_TCPSOCKETS; i++) {
02516                         soc = &tcp_socket[i];                                   /* Get socket   */
02517                         
02518                         if( (soc->state > TCP_STATE_CLOSED) && (soc->locport == lastport) ) {
02519                                 /* Blaah, this socket has reserved the port, go to next one     */
02520                                 break; 
02521                         }
02522                         
02523                 }       
02524                         
02525                 /* Did we found it?     */
02526                         
02527                 if( i == NO_OF_TCPSOCKETS)
02528                         break; 
02529                         
02530         }
02531                 
02532         if(lastport == start) {
02533                 TCP_DEBUGOUT("Out of TCP ports!!\n\r");
02534                 return(0);
02535         }
02536                 
02537         return(lastport);
02538                 
02539 }
02540 
02541 
02542 
02557 UINT8 tcp_check_cs (struct ip_frame* ipframe, UINT16 len)
02558 {
02559         UINT16 cs;
02560         UINT8 cs_cnt;
02561         UINT16 i;
02562         
02563         cs = 0;
02564         cs_cnt = 0;
02565         
02566         /* Do it firstly to IP pseudo header    */
02567         
02568         cs = ip_checksum(cs, (UINT8)(ipframe->sip >> 24), cs_cnt++);    
02569         cs = ip_checksum(cs, (UINT8)(ipframe->sip >> 16), cs_cnt++);
02570         cs = ip_checksum(cs, (UINT8)(ipframe->sip >> 8), cs_cnt++);
02571         cs = ip_checksum(cs, (UINT8)ipframe->sip, cs_cnt++);
02572         
02573         cs = ip_checksum(cs, (UINT8)(ipframe->dip >> 24), cs_cnt++);    
02574         cs = ip_checksum(cs, (UINT8)(ipframe->dip >> 16), cs_cnt++);
02575         cs = ip_checksum(cs, (UINT8)(ipframe->dip >> 8), cs_cnt++);
02576         cs = ip_checksum(cs, (UINT8)ipframe->dip, cs_cnt++);    
02577         
02578         cs = ip_checksum(cs, 0, cs_cnt++);
02579         
02580         cs = ip_checksum(cs, (UINT8)ipframe->protocol, cs_cnt++);
02581                 
02582         cs = ip_checksum(cs, (UINT8)(len >> 8), cs_cnt++);
02583         cs = ip_checksum(cs, (UINT8)len, cs_cnt++);
02584         
02585         /* Go to TCP data       */
02586         
02587         for(i=0; i < len; i++)
02588                 cs = ip_checksum(cs, RECEIVE_NETWORK_B(), cs_cnt++);
02589         
02590         cs = ~ cs;
02591         
02592         if(cs != IP_GOOD_CS) {
02593                 return (0);
02594         }
02595         
02596         /* It's OK      */
02597         
02598         return(1);
02599         
02600 
02601 }
02602 

Generated on Sat Jan 25 17:13:15 2003 for OpenTCP by doxygen1.2.18