00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <const.h>
00015
00016 #include <arch/mem.h>
00017
00018 #include <kernel/clock.h>
00019 #include <kernel/console.h>
00020 #include <kernel/speaker.h>
00021 #include <kernel/kmalloc.h>
00022 #include <kernel/semaphore.h>
00023
00024 #include <net/ip.h>
00025 #include <net/network.h>
00026
00027 #include <net/tcp.h>
00028
00029
00030
00031
00032
00033
00034
00035 uint16_t tcp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr)
00036 {
00037 const uint16_t *buf=buff;
00038 uint16_t *ip_src=(void *)&src_addr, *ip_dst=(void *)&dest_addr;
00039 uint32_t sum;
00040 size_t length=len;
00041
00042
00043 sum = 0;
00044 while (len > 1)
00045 {
00046 sum += *buf++;
00047 if (sum & 0x80000000)
00048 sum = (sum & 0xFFFF) + (sum >> 16);
00049 len -= 2;
00050 }
00051
00052 if ( len & 1 )
00053
00054 sum += *((uint8_t *)buf);
00055
00056
00057 sum += *(ip_src++);
00058 sum += *ip_src;
00059 sum += *(ip_dst++);
00060 sum += *ip_dst;
00061 sum += htons(IPPROTO_TCP);
00062 sum += htons(length);
00063
00064
00065 while (sum >> 16)
00066 sum = (sum & 0xFFFF) + (sum >> 16);
00067
00068
00069 return ( (uint16_t)(~sum) );
00070 }
00071
00072 void connect_sound()
00073 {
00074
00075 sound(0x580);
00076 delay(20);
00077
00078 nosound();
00079 }
00080
00081 void disconnect_sound()
00082 {
00083
00084 sound(0x420);
00085 delay(20);
00086
00087 nosound();
00088 }
00089
00090 tcp_state_t *tcp_conn=NULL;
00091 semaphore_t tcp_mutex;
00092
00093 void to_tcp_layer(tcp_t *packet, size_t len, in_addr_t ip_src, in_addr_t ip_dst)
00094 {
00095
00096 int i;
00097 uint8_t *data_buf = ((uint8_t *)packet) +
00098 (packet->tcp_hdr_len * sizeof(dword));
00099 bool chk;
00100
00101
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
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
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
00153 kprintf("\n\rOnly one TCP connection is allowed!");
00154
00155
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
00174
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
00185
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
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
00218
00219
00220
00221
00222
00223
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
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
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
00257 if ( (tcp_conn->state == TCP_ESTABLISHED) )
00258 {
00259 if ( (packet->tcp_ack) && ((len - packet->tcp_hdr_len*4)==0) )
00260 {
00261
00262 UP(&tcp_mutex);
00263 return;
00264 }
00265
00266
00267 packet->tcp_dst ^= packet->tcp_src;
00268 packet->tcp_src ^= packet->tcp_dst;
00269 packet->tcp_dst ^= packet->tcp_src;
00270
00271
00272 packet->tcp_ack_num = htonl(ntohl(packet->tcp_seq_num) + len - packet->tcp_hdr_len*4);
00273
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
00277
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
00289
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 }
00302
00303 int tcp_module_init()
00304 {
00305 INIT_MUTEX(&tcp_mutex);
00306 return(0);
00307 }
00308
00309 int tcp_module_close()
00310 {
00311 return(0);
00312 }
00313