www.pudn.com > tcpipstack.rar > TINYTC3.C
/* TINYTC3.C - Tiny-TCP source fragment Part 3 of the TCP layer. * Copyright (C) 1986, IMAGEN Corporation * "This code may be duplicated in whole or in part provided that [1] there * is no commercial gain involved in the duplication, and [2] that this * copyright notice is preserved on all copies. Any other duplication * requires written notice of the author." |===================================================================| | The author of this code hereby licenses all duplication and/or | | modification of this code, in whole or in part, consistent with | | the terms of the GNU Library General Public License. | | - Geoffrey H. Cooper 10/29/97 | |===================================================================| |===================================================================| | My changes can be considered public domain. Geof's statement | | will cover everything. | | - Rick Rodman 09/02/97 | |===================================================================| 941012 rr split into fragments */ #include "tinytcp.h" #include#ifdef PC #include #endif /* ----- globals from tinytcp.c ------------------------------------- */ extern IP_Address local_IP_address; /* local IP address */ extern int tcp_id; /* TCP ID, gets incremented */ extern struct tcp_Socket * tcp_allsocs; /* socket linklist */ /* ----- retransmitter ---------------------------------------------- */ /* Retransmitter - called periodically to perform tcp retransmissions */ Void tcp_Retransmitter( Void ) { S8 struct tcp_Socket * s; S8 short x; /* Go through all of the open sockets and see if there is anything to send */ for( s = tcp_allsocs; s; s = s -> next ) { x = False; if( s -> dataSize > 0 || s -> unhappy ) { /* send the data */ tcp_Send( s ); x = True; } /* anything sent? */ if( x || s -> state != TS_ESTAB ) s -> timeout -= tcp_RETRANSMITTIME; if( s -> timeout <= 0 ) { if( s -> state == TS_TIMEWT ) { printf( "Closed. [222]\n" ); s -> state = TS_CLOSED; /* cast to Procref removed on following */ if( s -> dataHandler != 0 ) ( s -> dataHandler )(( void * ) s, ( Byte * ) 0, 0 ); else printf( "got close, no handler\n" ); /* Unthread this socket from the linklist */ tcp_Unthread( s ); } else { printf( "Timeout, aborting\n" ); tcp_Abort( s ); } } } } /* ----- Unthread a socket from the socket list, if it's there ------ */ Void tcp_Unthread( ds ) struct tcp_Socket *ds; { S8 struct tcp_Socket *s, **sp; if( ds == ( struct tcp_Socket * ) 0 ) return; sp = &tcp_allsocs; /* -> -> socket */ for(;;) { s = *sp; /* what pointer points to */ if( s == ( struct tcp_Socket * ) 0 ) break; /* end of list? */ if( s == ds ) { /* matches one to delete? */ *sp = s -> next; /* unlink it from the list */ break; /* all done */ } sp = &s -> next; /* move to the next one */ } ds -> next = ( struct tcp_Socket * ) 0; /* clear next pointer */ } /* ----- busy-wait loop for tcp. Also calls an "application proc" --- */ int tcp( application ) #ifdef USE_TYPEDEFS Procrefv application; #else Void ( *application ) P(( void )); #endif { S8 struct in_Header * ip; S8 Longword timeout, start; sed_Receive( ( Byte * ) 0 ); timeout = 0L; /* There was a while( tcp_allsocs ) here. However, if we don't have any open, we still want the program to loop, so I changed it to for(;;). */ for(;;) { start = ( Longword ) MsecClock(); /* Have we received a packet? */ ip = ( struct in_Header * ) sed_IsPacket(); if( ip == ( struct in_Header * ) 0 ) { /* No, we haven't. */ if( MsecClock() > timeout ) { /* Anything to retransmit? */ tcp_Retransmitter(); /* Set next transmit time */ timeout = MsecClock() + tcp_RETRANSMITTIME; } /* There's nothing to do. Let the user enter a command. */ application(); continue; } /* We have received a packet. Process it */ #ifdef ETHERNET /* ARP protocol is supported on ethernet only */ if( sed_CheckPacket( ( Word * ) ip, 0x806 ) == 1 ) { /* do arp */ sar_CheckPacket( ( struct arp_Header * ) ip ); } else #endif /* ethernet */ if( sed_CheckPacket( ( Word * ) ip, 0x800 ) == 1 ) { /* do IP */ if( rev_longword( ip -> destination ) != local_IP_address ) { printf( "IP address doesn't match\n" ); /* But ignore that for now (SLIP) */ } if( checksum( ( Word * ) ip, IP_HBYTES( ip )) != 0xFFFF ) { printf( "Checksum bad\n" ); /* But ignore that, too, for now (SLIP) */ } if( IP_PROTOCOL( ip ) == 6 ) /* tcp/ip */ tcp_Handler( ip ); /* protocol 1 is icmp. the first byte of the data is an 8 for ping (echo) requests; the reply Byte should have a zero */ } /* recycle buffer */ sed_Receive( ( Byte * ) ip ); /* How much time elapsed as we were processing the packet? */ /* rr doesn't see the point of this x = ( int )( MsecClock() - start ); timeout -= ( Longword ) x; rr doesn't see the point of this */ } return 1; /* Actually unreachable, but Microsoft C gives you a 'no return value' error. */ } /* end of tinytc3.c */