3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <net/packet.h>
30 #include <net/socket.h>
35 /* Mutex for socket function */
36 MUTEX_CREATE (mutex_tcp_accept
);
37 MUTEX_CREATE (mutex_tcp_read_cache
);
39 proto_tcp_conn_t proto_tcp_conn_list
;
40 proto_tcp_backlog_t proto_tcp_backlog_list
;
42 extern netif_t netif_list
;
44 static unsigned short proto_tcp_dup
;
45 static unsigned proto_tcp_seq
;
46 static proto_ip_t proto_ip_prealloc
;
47 static proto_tcp_t proto_tcp_prealloc
;
48 static packet_t packet_prealloc
;
51 proto_tcp_conn_t
*net_proto_tcp_conn_check (net_ipv4 ip_source
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
, unsigned char *ret
);
52 int net_proto_tcp_conn_add (fd_t
*fd
);
53 int net_proto_tcp_conn_set (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
);
54 int net_proto_tcp_conn_estabilish (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_ipv4 ip_dest
, net_port port_dest
);
55 int net_proto_tcp_conn_estabilish_reply (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
56 int net_proto_tcp_read_cache (proto_tcp_conn_t
*conn
, char *data
, unsigned len
);
57 int net_proto_tcp_read_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
);
58 int net_proto_tcp_write (netif_t
*eth
, net_ipv4 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
);
59 int net_proto_tcp_write_data (proto_tcp_conn_t
*conn
, char *data
, unsigned len
);
60 int net_proto_tcp_write_data_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
61 int net_proto_tcp_conn_disconnected (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
62 int net_proto_tcp_conn_close (proto_tcp_conn_t
*conn
);
63 unsigned net_proto_tcp_conn_del (proto_tcp_conn_t
*conn
);
64 proto_tcp_conn_t
*net_proto_tcp_conn_find (int fd
);
65 int net_proto_tcp_backlog_add (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
);
66 int net_proto_tcp_conn_invite (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
);
69 * User-friendly socket functions
71 int net_proto_tcp_socket (fd_t
*fd
)
73 return net_proto_tcp_conn_add (fd
);
76 extern unsigned long timer_ticks
;
77 int net_proto_tcp_connect (int fd
, sockaddr_in
*addr
)
81 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
87 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
88 ret
= net_proto_tcp_conn_estabilish (conn
, netif
, addr
->sin_addr
, addr
->sin_port
);
90 unsigned long stime
= timer_ticks
;
93 if (!(conn
->flags
& O_NONBLOCK
)) {
101 if ((stime
+8000) < timer_ticks
)
104 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHED
)
107 /* when connection cant be accepted succefully first time, try it again */
108 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHERROR
) {
109 ret
= net_proto_tcp_conn_estabilish (conn
, netif
, addr
->sin_addr
, addr
->sin_port
);
110 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
114 /* non-blocking mode */
123 int net_proto_tcp_send (int fd
, char *msg
, unsigned size
)
125 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
130 int ret
= net_proto_tcp_write_data (conn
, msg
, size
);
133 unsigned long stime
= timer_ticks
;
136 if (!(conn
->flags
& O_NONBLOCK
)) {
137 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
139 if ((stime
+350) < timer_ticks
)
146 /* non-blocking mode */
149 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
151 if ((stime
+100) < timer_ticks
)
163 int net_proto_tcp_recv (int fd
, char *msg
, unsigned size
)
165 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
172 //kprintf ("recv () - %d\n", fd);
175 if (!(conn
->flags
& O_NONBLOCK
)) {
176 unsigned long stime
= timer_ticks
;
178 while (!conn
->len
/* || conn->state != PROTO_TCP_CONN_STATE_READY*/) {
179 if ((stime
+10000) < timer_ticks
)
182 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
183 if (net_proto_tcp_conn_del (conn
));
190 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
191 if (net_proto_tcp_conn_del (conn
));
199 if ((conn
->len
-conn
->offset
) > size
) {
200 memcpy (msg
, conn
->data
+conn
->offset
, size
);
201 //printf ("msg11: %d %d\n", conn->offset, size);
202 conn
->offset
+= size
;
206 ret
= conn
->len
-conn
->offset
;
208 memcpy (msg
, conn
->data
+conn
->offset
, conn
->len
-conn
->offset
);
209 //printf ("msg22: %d %d %d\n", conn->offset, size, conn->len);
216 //kprintf ("recv () - %d -- DATA: %d : %d\n", fd, ret, size);
221 int net_proto_tcp_close (int fd
)
223 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
228 if (conn
->state
== PROTO_TCP_CONN_STATE_DISCONNECTED
)
231 int ret
= net_proto_tcp_conn_close (conn
);
236 int net_proto_tcp_fcntl (int fd
, int cmd
, long arg
)
238 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
254 int net_proto_tcp_bind (int fd
, sockaddr_in
*addr
, socklen_t len
)
256 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
262 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
263 net_proto_tcp_conn_set (conn
, netif
, addr
->sin_port
, 0, 0);
271 int net_proto_tcp_listen (int fd
, int backlog
)
273 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
281 int net_proto_tcp_accept (int fd
, sockaddr_in
*addr
, socklen_t
*addrlen
)
283 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
290 proto_tcp_backlog_t
*backlog
= 0;
293 if (!(conn
->flags
& O_NONBLOCK
)) {
295 for (backlog
= proto_tcp_backlog_list
.next
; backlog
!= &proto_tcp_backlog_list
; backlog
= backlog
->next
) {
296 if (backlog
->conn
== conn
) {
305 /* non-blocking mode */
306 for (backlog
= proto_tcp_backlog_list
.next
; backlog
!= &proto_tcp_backlog_list
; backlog
= backlog
->next
) {
307 if (backlog
->conn
== conn
) {
314 //printf ("accept ()\n");
319 net_ipv4 ip
= backlog
->ip
;
320 net_port port
= backlog
->port
;
321 unsigned seq
= backlog
->seq
;
323 int ret
= net_proto_tcp_conn_invite (conn
, ip
, port
, seq
);
325 /* remove from queue accepted connection */
326 backlog
->next
->prev
= backlog
->prev
;
327 backlog
->prev
->next
= backlog
->next
;
334 fd_t
*fd_new
= fd_create (FD_SOCK
);
339 net_proto_tcp_conn_add (fd_new
);
341 proto_tcp_conn_t
*conn_new
= net_proto_tcp_conn_find (fd_new
->id
);
346 net_proto_tcp_conn_set (conn_new
, conn
->netif
, conn
->port_source
, conn
->netif
->ip
, port
);
348 conn_new
->ip_dest
= ip
;
351 addr
->sin_port
= port
;
352 addr
->sin_family
= AF_INET
;
358 * Hardcore code - syn, ack, psh, fin, etc :P
360 unsigned net_proto_tcp_handler (packet_t
*packet
, proto_ip_t
*ip
, char *buf
, unsigned len
)
362 proto_tcp_t
*tcp
= (proto_tcp_t
*) buf
;
364 unsigned char ret
= 0;
366 /* First check ip address and ports, that we want this data */
367 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_check (ip
->ip_dest
, tcp
->port_dest
, ip
->ip_source
, tcp
->port_source
, &ret
);
369 if (!conn
&& ret
== 0)
372 //printf ("tcp->flags: 0x%x, ret: %d, conn: 0x%x, fd: %d\n", tcp->flags, ret, conn, conn->fd);
374 /* connection from client before accept () */
376 /* client want connect to our server */
377 if (tcp
->flags
== 0x02) {
378 mutex_lock (&mutex_tcp_accept
);
380 unsigned ret
= net_proto_tcp_backlog_add (conn
, ip
->ip_source
, tcp
->port_source
, tcp
->seq
);
382 mutex_unlock (&mutex_tcp_accept
);
390 unsigned data_cache
= 0;
393 if (tcp
->flags
& 0x08) {
394 /* needed for calculate real offset from 4bit number */
395 unsigned offset
= tcp
->data_offset
* 4;
397 /* now calculate accurate length of tcp _data_ */
398 unsigned size
= swap16 (ip
->total_len
) - (offset
+ (ip
->head_len
*4));
399 //kprintf (">>>> %d : %d : %d\n", offset, size, len);
400 //mutex_lock (&mutex_tcp_read_cache);
401 net_proto_tcp_read_cache (conn
, buf
+offset
, size
);
402 //mutex_unlock (&mutex_tcp_read_cache);
404 net_proto_tcp_read_ok (conn
, ip
, tcp
, size
);
409 /* sended data was delivered succefully */
410 if (tcp
->flags
& 0x10) {
411 /* HACK: It is interesting, that no push flag, and there could be some data to read */
413 /* needed for calculate real offset from 4bit number */
414 unsigned offset
= tcp
->data_offset
* 4;
416 /* now calculate accurate length of tcp _data_ */
417 unsigned size
= swap16 (ip
->total_len
) - (offset
+ (ip
->head_len
*4));
419 /* there are data for read */
421 /* data was cached, so no need cache it again */
423 //kprintf (">>>>2 %d : %d : %d\n", offset, size, len);
424 mutex_lock (&mutex_tcp_read_cache
);
425 net_proto_tcp_read_cache (conn
, buf
+offset
, size
);
426 mutex_unlock (&mutex_tcp_read_cache
);
428 net_proto_tcp_read_ok (conn
, ip
, tcp
, size
);
431 /* when data are'nt available, lets normal work - acknowledgement */
432 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISH
) {
433 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHERROR
;
434 net_proto_tcp_write_data_ok (conn
, ip
, tcp
);
436 net_proto_tcp_write_data_ok (conn
, ip
, tcp
);
440 /* connection estabilish respond */
441 if (tcp
->flags
== 0x12) {
442 return net_proto_tcp_conn_estabilish_reply (conn
, ip
, tcp
);
445 /* another side close connection */
446 if (tcp
->flags
& 0x01) {
447 DPRINT ("TCP -> fd %d connection closed by remote host\n", conn
->fd
);
448 net_proto_tcp_conn_disconnected (conn
, ip
, tcp
); // FIXME: problem in server with hangind the whole program
451 /* another side close connection */
452 if (tcp
->flags
& 0x04) {
453 DPRINT ("TCP -> fd %d connection reseted by peer\n", conn
->fd
);
454 net_proto_tcp_conn_disconnected (conn
, ip
, tcp
);
460 int net_proto_tcp_read_cache (proto_tcp_conn_t
*conn
, char *data
, unsigned len
)
462 if (!data
|| !conn
|| !len
)
466 conn
->data
= (char *) kmalloc (sizeof (char) * (len
+ 1));
468 memcpy (conn
->data
, data
, len
);
470 char *newdata
= (char *) kmalloc (sizeof (char) * (conn
->len
+ len
+ 1));
475 memcpy (newdata
, conn
->data
, conn
->len
);
476 memcpy (newdata
+conn
->len
, data
, len
);
480 conn
->data
= newdata
;
486 //kprintf ("DATA: %d - #'%s'#\n", len, data);
490 conn
->data
[conn
->len
] = '\0';
495 int net_proto_tcp_read_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
)
497 if (!ip_old
|| !tcp_old
|| !conn
)
500 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
505 tcp
->port_source
= conn
->port_source
; // increase client port too
506 tcp
->port_dest
= conn
->port_dest
;
508 tcp
->seq
= tcp_old
->ack
;
510 /* this small thing did bad work when e.g. 10 10 10 fe get to calculation,
511 it returns 10 10 10 08, no 10 10 11 08 */
512 unsigned seq
= swap32 (tcp_old
->seq
);
515 tcp
->ack
= swap32 (seq
);
518 tcp
->data_offset
= 5;
520 tcp
->window
= tcp_old
->window
+ swap16 (64);
523 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
525 /*if (proto_tcp_dup == tcp_old->checksum) {
526 printf ("Duplicated packet :)");
531 //printf ("read_ok: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
533 conn
->seq
= tcp
->ack
;
534 conn
->ack
= tcp
->seq
;
536 //printf ("read_ok2: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
538 proto_tcp_dup
= tcp_old
->checksum
;
548 int net_proto_tcp_write (netif_t
*eth
, net_ipv4 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
)
558 unsigned get
= arp_cache_get (dest
, &mac_dest
);
561 arp_send_request (eth
, dest
);
564 /* 100ms for waiting on ARP reply */
566 get
= arp_cache_get (dest
, &mac_dest
);
571 /* TODO: make better waiting for ARP reply */
584 packet_t
*packet
= &packet_prealloc
;
589 memcpy (&packet
->mac_source
, eth
->dev
->dev_addr
, 6);
590 memcpy (&packet
->mac_dest
, mac_dest
, 6);
591 packet
->type
= NET_PACKET_TYPE_IPV4
;
594 proto_ip_t
*ip
= &proto_ip_prealloc
;
599 /* there are some fixed values - yeah it is horrible */
607 ip
->proto
= NET_PROTO_IP_TYPE_TCP
;
608 ip
->ip_source
= eth
->ip
;
611 unsigned l
= (tcp
->data_offset
*4);
613 /* calculate total length of packet (tcp/ip) */
614 ip
->total_len
= swap16 (l
+sizeof (proto_tcp_t
)+len
);
616 char *buf_tcp
= (char *) kmalloc ((len
+l
+1) * sizeof (char));
621 memcpy (buf_tcp
, (char *) tcp
, l
);
624 memcpy (buf_tcp
+l
, data
, len
);
626 buf_tcp
[l
+len
] = '\0';
628 /* calculate checksum and put it to tcp header */
629 proto_tcp_t
*tcp_
= (proto_tcp_t
*) buf_tcp
;
631 tcp_
->checksum
= checksum16_tcp (eth
->ip
, dest
, buf_tcp
, l
+len
);
633 /* send tcp header+data to ip layer */
634 unsigned ret
= net_proto_ip_send (eth
, packet
, ip
, (char *) buf_tcp
, l
+len
);
641 int net_proto_tcp_write_data (proto_tcp_conn_t
*conn
, char *data
, unsigned len
)
643 if (!conn
|| !len
|| !data
)
646 proto_tcp_t
*tcp
= &proto_tcp_prealloc
;
651 tcp
->port_source
= conn
->port_source
;
652 tcp
->port_dest
= conn
->port_dest
;
654 unsigned seq
= swap32 (proto_tcp_seq
);
657 //tcp->ack = swap32 (seq);
659 proto_tcp_seq
= swap32 (seq
);
662 tcp
->seq
= conn
->seq
;
663 tcp
->ack
= conn
->ack
;
665 tcp
->seq
= conn
->ack
;
666 tcp
->ack
= conn
->seq
;
671 //printf ("TCP -> seq: 0x%x | ack: 0x%x | proto_seq: 0x%x\n", tcp->seq, conn->ack, proto_tcp_seq);
674 tcp
->data_offset
= 5;
676 tcp
->window
= swap16 (32768);
679 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, data
, len
);
682 conn
->state
= PROTO_TCP_CONN_STATE_WAIT
;
687 int net_proto_tcp_write_data_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
689 if (!ip_old
|| !tcp_old
|| !conn
)
692 /* cross - because we change now sides :) */
693 conn
->seq
= tcp_old
->ack
;
694 conn
->ack
= tcp_old
->seq
;
696 //printf ("data_ok: seq: 0x%x | ack: 0x%x\n", tcp_old->ack, tcp_old->seq);
698 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
703 /* try connect to server */
704 int net_proto_tcp_conn_estabilish (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_ipv4 ip_dest
, net_port port_dest
)
709 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
714 tcp
->port_source
= swap16 (netif_port_get ()); // increase client port too
715 tcp
->port_dest
= port_dest
;
717 /* setup new connection */
718 net_proto_tcp_conn_set (conn
, eth
, tcp
->port_source
, ip_dest
, tcp
->port_dest
);
720 tcp
->seq
= conn
->seq
;
721 tcp
->ack
= conn
->ack
;
724 tcp
->data_offset
= 5;
726 tcp
->window
= swap16 (32792);
729 int ret
= net_proto_tcp_write (eth
, ip_dest
, tcp
, 0, 0);
734 net_proto_tcp_conn_del (conn
);
741 int net_proto_tcp_conn_estabilish_reply (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
743 if (!ip_old
|| !tcp_old
|| !conn
)
746 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
751 tcp
->port_source
= conn
->port_source
; // increase client port too
752 tcp
->port_dest
= conn
->port_dest
;
754 tcp
->seq
= tcp_old
->ack
;
755 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
758 tcp
->data_offset
= 5;
760 tcp
->window
= tcp_old
->window
+ swap16 (64);
763 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
766 conn
->seq
= tcp
->seq
;
767 conn
->ack
= tcp
->ack
;
768 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHED
;
771 DPRINT ("TCP -> fd %d connected to server succefully\n", conn
->fd
);
778 int net_proto_tcp_conn_disconnected (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
780 if (!ip_old
|| !tcp_old
|| !conn
)
783 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
)
784 return net_proto_tcp_conn_del (conn
);
786 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
791 tcp
->port_source
= conn
->port_source
; // increase client port too
792 tcp
->port_dest
= conn
->port_dest
;
794 tcp
->seq
= tcp_old
->ack
;
795 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
798 tcp
->data_offset
= 5;
800 tcp
->window
= tcp_old
->window
+ swap16 (64);
803 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
808 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
; //ret = net_proto_tcp_conn_del (conn);
815 int net_proto_tcp_conn_close (proto_tcp_conn_t
*conn
)
820 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
825 tcp
->port_source
= conn
->port_source
; // increase client port too
826 tcp
->port_dest
= conn
->port_dest
;
828 tcp
->seq
= conn
->seq
;
829 tcp
->ack
= conn
->ack
;
832 tcp
->data_offset
= 5;
834 tcp
->window
= swap16 (32832);
837 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
842 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
;
848 /* client wants to connect */
849 net_proto_tcp_conn_invite (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
)
854 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
859 tcp
->port_source
= conn
->port_source
;
860 tcp
->port_dest
= port
;
862 tcp
->seq
= proto_tcp_seq
++;
863 tcp
->ack
= seq
+ swap32 (1);
866 tcp
->data_offset
= 5;
868 tcp
->window
= swap16 (5816);
871 int ret
= net_proto_tcp_write (conn
->netif
, ip
, tcp
, 0, 0);
876 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
884 /* Create new TCP connection */
885 int net_proto_tcp_conn_add (fd_t
*fd
)
887 proto_tcp_conn_t
*conn
;
889 /* alloc and init context */
890 conn
= (proto_tcp_conn_t
*) kmalloc (sizeof (proto_tcp_conn_t
));
897 memset (conn
, 0, sizeof (proto_tcp_conn_t
));
907 conn
->next
= &proto_tcp_conn_list
;
908 conn
->prev
= proto_tcp_conn_list
.prev
;
909 conn
->prev
->next
= conn
;
910 conn
->next
->prev
= conn
;
915 /* Setup new connection */
916 int net_proto_tcp_conn_set (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
)
921 conn
->ip_source
= eth
->ip
;
922 conn
->ip_dest
= ip_dest
;
924 conn
->port_source
= port_source
;
925 conn
->port_dest
= port_dest
;
927 proto_tcp_seq
+= swap32 (1);
929 conn
->seq
= proto_tcp_seq
++;
932 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
943 /* Delete existing connection from list */
944 unsigned net_proto_tcp_conn_del (proto_tcp_conn_t
*conn
)
949 conn
->state
= PROTO_TCP_CONN_STATE_DISCONNECTED
;
956 conn
->next
->prev
= conn
->prev
;
957 conn
->prev
->next
= conn
->next
;
964 proto_tcp_conn_t
*net_proto_tcp_conn_check (net_ipv4 ip_source
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
, unsigned char *ret
)
967 proto_tcp_conn_t
*conn
= NULL
;
968 proto_tcp_conn_t
*conn_ret
= NULL
;
969 //printf ("-------------------------\n");
970 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
972 net_proto_ip_print (conn->ip_source);
974 net_proto_ip_print (ip_source);
976 net_proto_ip_print (conn->ip_dest);
978 net_proto_ip_print (ip_dest);
979 printf ("\nporty: %d / %d\n", swap16 (conn->port_source), swap16 (port_source));
980 printf ("porty2: %d / %d\n", swap16 (conn->port_dest), swap16 (port_dest));*/
982 if (conn
->ip_source
== ip_source
&& conn
->port_source
== port_source
) {
983 if (conn
->ip_dest
== ip_dest
&& conn
->port_dest
== port_dest
) {
995 if (!conn_ret
->bind
) {
998 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
1000 if (conn
->ip_source
== ip_source
&& conn
->port_source
== port_source
)
1009 proto_tcp_conn_t
*net_proto_tcp_conn_find (int fd
)
1011 proto_tcp_conn_t
*conn
= NULL
;
1012 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
1020 /* Create new TCP backlog stamp */
1021 int net_proto_tcp_backlog_add (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
)
1026 proto_tcp_backlog_t
*backlog
;
1028 /* alloc and init context */
1029 backlog
= (proto_tcp_backlog_t
*) kmalloc (sizeof (proto_tcp_backlog_t
));
1034 backlog
->conn
= conn
;
1036 backlog
->port
= port
;
1040 backlog
->next
= &proto_tcp_backlog_list
;
1041 backlog
->prev
= proto_tcp_backlog_list
.prev
;
1042 backlog
->prev
->next
= backlog
;
1043 backlog
->next
->prev
= backlog
;
1048 /* init of tcp protocol */
1049 unsigned init_net_proto_tcp ()
1051 proto_tcp_conn_list
.next
= &proto_tcp_conn_list
;
1052 proto_tcp_conn_list
.prev
= &proto_tcp_conn_list
;
1054 proto_tcp_backlog_list
.next
= &proto_tcp_backlog_list
;
1055 proto_tcp_backlog_list
.prev
= &proto_tcp_backlog_list
;
1057 proto_tcp_dup
= 0x0;
1058 proto_tcp_seq
= 0x1;