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

TCP (Transmition Control Protocol) layer
[Networking]


Data Structures

struct  socket_t
 A socket structure. More...

struct  tcp
 TCP packet structure. More...

struct  tcp_state_t
 A TCP connection states machine structure. More...


Defines

#define TCP_CLOSED   0
 TCP connection closed state.

#define TCP_SYN_RCVD   1
 TCP SYN received state.

#define TCP_SYN_SENT   2
 TCP SYN sent state.

#define TCP_ESTABLISHED   3
 TCP connection established state.

#define TCP_CLOSING   4
 TCP closing state.


Typedefs

typedef tcp tcp_t
 TCP packet structure.


Functions

void to_tcp_layer (tcp_t *packet, size_t len, in_addr_t ip_src, in_addr_t ip_dst)
int tcp_module_init ()
int tcp_module_close ()

Detailed Description

The TCP (Transmition Control Protocol) layer.

Define Documentation

#define TCP_CLOSED   0
 

TCP connection closed state.

Definition at line 18 of file tcp.h.

#define TCP_CLOSING   4
 

TCP closing state.

Definition at line 26 of file tcp.h.

#define TCP_ESTABLISHED   3
 

TCP connection established state.

Definition at line 24 of file tcp.h.

#define TCP_SYN_RCVD   1
 

TCP SYN received state.

Definition at line 20 of file tcp.h.

#define TCP_SYN_SENT   2
 

TCP SYN sent state.

Definition at line 22 of file tcp.h.


Typedef Documentation

typedef struct tcp tcp_t
 

TCP packet structure.


Function Documentation

int tcp_module_close  
 

Definition at line 309 of file tcp.c.

00310 {
00311         return(0);
00312 }

int tcp_module_init  
 

Definition at line 303 of file tcp.c.

00304 {
00305         INIT_MUTEX(&tcp_mutex);
00306         return(0);
00307 }

void to_tcp_layer tcp_t   packet,
size_t    len,
in_addr_t    ip_src,
in_addr_t    ip_dst
 

Definition at line 93 of file tcp.c.

00094 {
00095 // Process a TCP packet from the IP layer                               //
00096         int i;
00097         uint8_t *data_buf =     ((uint8_t *)packet) +
00098                                 (packet->tcp_hdr_len * sizeof(dword));
00099         bool chk;
00100 
00101         // Calculate the checksum                                       //
00102         chk = tcp_checksum(
00103                         packet,
00104                         len,
00105                         ip_src,
00106                         ip_dst
00107                         );
00108         if ( chk )
00109         {
00110                 kprintf("\n\rTCP checksum error! %04X", chk);
00111                 return;
00112         }
00113 
00114         DOWN(&tcp_mutex);
00115 
00116         // Dump the UDP packet                                          //
00117         kprintf(        "\n\rTCP packet received: %u(%u) bytes"
00118                 "\n\rsender  = %u.%u.%u.%u:%u"
00119                 "\n\rreceiver= %u.%u.%u.%u:%u"
00120                 "\n\rseq=%u, ack=%u, win=%u",
00121                 len - (packet->tcp_hdr_len)*sizeof(dword),
00122                 len,
00123 
00124                 IP_A(ntohl(ip_src)), IP_B(ntohl(ip_src)),
00125                 IP_C(ntohl(ip_src)), IP_D(ntohl(ip_src)),
00126                 ntohs(packet->tcp_src),
00127 
00128                 IP_A(ntohl(ip_dst)), IP_B(ntohl(ip_dst)),
00129                 IP_C(ntohl(ip_dst)), IP_D(ntohl(ip_dst)),
00130                 ntohs(packet->tcp_dst),
00131 
00132                 ntohl(packet->tcp_seq_num), ntohl(packet->tcp_ack_num),
00133                 ntohs(packet->tcp_win_size)
00134         );
00135 
00136         // Dump the flags                                               //
00137         kprintf("\n\rURG:%u ACK:%u PSH:%u RST:%u SYN:%u FIN:%u",
00138                 packet->tcp_urg,
00139                 packet->tcp_ack,
00140                 packet->tcp_psh,
00141                 packet->tcp_rst,
00142                 packet->tcp_syn,
00143                 packet->tcp_fin
00144         );
00145 
00146         kprintf("\n\rData:\n\r");
00147         for(i=0; i<(len-packet->tcp_hdr_len*4); i++)
00148                 kputchar( data_buf[i]  );
00149 
00150         if ( (packet->tcp_syn) && (tcp_conn!=NULL))
00151         {
00152                 // For now only one connection is allowed :-(           //
00153                 kprintf("\n\rOnly one TCP connection is allowed!");
00154 
00155                 // Send an RST                                          //
00156                 packet->tcp_ack_num = htonl(ntohl(packet->tcp_seq_num) + len - packet->tcp_hdr_len*4 + 1);
00157                 packet->tcp_seq_num = tcp_conn->seq_num;
00158                 packet->tcp_hdr_len = 5;
00159                 len = sizeof(tcp_t);
00160                 packet->tcp_ack = 1;
00161                 packet->tcp_rst = 1;
00162                 packet->tcp_syn = 0;
00163                 packet->tcp_chk = 0;
00164                 packet->tcp_chk = tcp_checksum(packet, len, ip_dst, ip_src);
00165                 send_ip_packet(ip_src, packet, len, 255, IPPROTO_TCP);
00166 
00167                 UP(&tcp_mutex);
00168                 return;
00169         }
00170 
00171         if ( (packet->tcp_syn) && !(packet->tcp_ack) && (tcp_conn==NULL) )
00172         {
00173                 // SYN received!                                        //
00174                 // Open a new connection using sockets                  //
00175                 tcp_conn = kmalloc(sizeof(tcp_state_t));
00176                 memset(tcp_conn, 0, sizeof(tcp_state_t));
00177 
00178                 tcp_conn->socket.ip_src = ip_src;
00179                 tcp_conn->socket.port_src = packet->tcp_src;
00180                 tcp_conn->socket.ip_dst = ip_dst;
00181                 tcp_conn->socket.port_dst = packet->tcp_dst;
00182                 tcp_conn->state = TCP_SYN_RCVD;
00183 
00184                 // Send SYN + ACK (seq+1)                               //
00185                 // Swap source and destination ports                    //
00186                 packet->tcp_dst ^= packet->tcp_src;
00187                 packet->tcp_src ^= packet->tcp_dst;
00188                 packet->tcp_dst ^= packet->tcp_src;
00189 
00190                 packet->tcp_ack_num = htonl(ntohl(packet->tcp_seq_num) + 1);
00191                 packet->tcp_seq_num = tcp_conn->seq_num = htonl(36363636);
00192                 tcp_conn->seq_num = htonl(ntohl(tcp_conn->seq_num) + 1);
00193                 packet->tcp_ack = 1;
00194                 packet->tcp_chk = 0;
00195                 packet->tcp_chk = tcp_checksum(packet, len, ip_dst, ip_src);
00196                 send_ip_packet(ip_src, packet, len, 255, IPPROTO_TCP);
00197 
00198                 UP(&tcp_mutex);
00199                 return;
00200         }
00201         if ( (packet->tcp_rst) && (tcp_conn!=NULL) )
00202         {
00203                 // Free the TCP connection structure            //
00204                 kfree(tcp_conn);
00205                 tcp_conn = NULL;
00206                 disconnect_sound();
00207                 kprintf("\n\rTCP connection closed!\n\r");
00208 
00209                 UP(&tcp_mutex);
00210                 return;
00211         }
00212         if ( (packet->tcp_fin) && (tcp_conn!=NULL) )
00213         {
00214                 if ( tcp_conn->state != TCP_ESTABLISHED )
00215                         return;
00216 
00217                 // FIN received!                                        //
00218                 // Close the connection                                 //
00219 
00220                 // Send ACK (seq+1) and close also our connection       //
00221                 // setting the FIN flag on                              //
00222 
00223                 // Swap source and destination ports                    //
00224                 packet->tcp_dst ^= packet->tcp_src;
00225                 packet->tcp_src ^= packet->tcp_dst;
00226                 packet->tcp_dst ^= packet->tcp_src;
00227 
00228                 packet->tcp_ack_num = htonl(ntohl(packet->tcp_seq_num) + len - packet->tcp_hdr_len*4 + 1);
00229                 packet->tcp_seq_num = tcp_conn->seq_num;
00230                 packet->tcp_hdr_len = 5;
00231                 len = sizeof(tcp_t);
00232                 packet->tcp_ack = 1;
00233                 packet->tcp_chk = 0;
00234                 packet->tcp_chk = tcp_checksum(packet, len, ip_dst, ip_src);
00235                 send_ip_packet(ip_src, packet, len, 255, IPPROTO_TCP);
00236 
00237                 // Go into the CLOSING state (wait for ACK)             //
00238                 tcp_conn->state = TCP_CLOSING;
00239 
00240                 UP(&tcp_mutex);
00241                 return;
00242         }
00243         if ( (packet->tcp_ack) && (tcp_conn->state==TCP_SYN_RCVD) )
00244         {
00245                 // Connection established!                              //
00246                 kprintf("\n\rTCP connection established!");
00247                 connect_sound();
00248                 tcp_conn->state = TCP_ESTABLISHED;
00249 
00250                 UP(&tcp_mutex);
00251                 return;
00252         }
00253 
00254         if ( tcp_conn != NULL )
00255         {
00256                 // In the other cases ack every packet                  //
00257                 if ( (tcp_conn->state == TCP_ESTABLISHED) )
00258                 {
00259                         if ( (packet->tcp_ack) && ((len - packet->tcp_hdr_len*4)==0) )
00260                         {
00261                                 // Empty packet with ack! Do not reply  //
00262                                 UP(&tcp_mutex);
00263                                 return;
00264                         }
00265 
00266                         // Swap source and destination ports            //
00267                         packet->tcp_dst ^= packet->tcp_src;
00268                         packet->tcp_src ^= packet->tcp_dst;
00269                         packet->tcp_dst ^= packet->tcp_src;
00270 
00271                         // Send an echo packet to acknowledge           //
00272                         packet->tcp_ack_num = htonl(ntohl(packet->tcp_seq_num) + len - packet->tcp_hdr_len*4);
00273                         // tcp_conn->seq_num = htonl(ntohl(tcp_conn->seq_num) + 1);
00274                         packet->tcp_seq_num = tcp_conn->seq_num;
00275                         tcp_conn->seq_num = htonl(ntohl(tcp_conn->seq_num) + len - packet->tcp_hdr_len*4);
00276                         // packet->tcp_hdr_len = 5;
00277                         // len = sizeof(tcp_t);
00278                         packet->tcp_ack = 1;
00279                         packet->tcp_chk = 0;
00280                         packet->tcp_chk = tcp_checksum(packet, len, ip_dst, ip_src);
00281                         send_ip_packet(ip_src, packet, len, 255, IPPROTO_TCP);
00282 
00283                         UP(&tcp_mutex);
00284                         return;
00285                 }
00286                 if ( (tcp_conn->state == TCP_CLOSING) )
00287                 {
00288                         // ACK received!                                //
00289                         // Free the TCP connection structure            //
00290                         kfree(tcp_conn);
00291                         tcp_conn = NULL;
00292                         disconnect_sound();
00293                         kprintf("\n\rTCP connection closed!\n\r");
00294 
00295                         UP(&tcp_mutex);
00296                         return;
00297                 }
00298         }
00299 
00300         UP(&tcp_mutex);
00301 }


Generated on Fri Feb 20 15:32:22 2004 for Minirighi by doxygen1.2.18