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>
32 #include <net/socket.h>
37 /* Mutex for socket function */
38 MUTEX_CREATE (mutex_tcp6_accept
);
39 MUTEX_CREATE (mutex_tcp6_read_cache
);
41 proto_tcp6_conn_t proto_tcp6_conn_list
;
42 proto_tcp6_backlog_t proto_tcp6_backlog_list
;
44 extern netif_t netif_list
;
46 static unsigned short proto_tcp6_dup
;
47 static unsigned proto_tcp6_seq
;
48 static proto_ipv6_t proto_ipv6_prealloc
;
49 static proto_tcp_t proto_tcp6_prealloc
;
50 static packet_t packet6_prealloc
;
53 proto_tcp6_conn_t
*net_proto_tcp6_conn_check (net_ipv6 ip_source
, net_port port_source
, net_ipv6 ip_dest
, net_port port_dest
, unsigned char *ret
);
54 int net_proto_tcp6_conn_add ();
55 int net_proto_tcp6_conn_set (proto_tcp6_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv6 ip_dest
, net_port port_dest
);
56 int net_proto_tcp6_conn_estabilish (proto_tcp6_conn_t
*conn
, netif_t
*eth
, net_ipv6 ip_dest
, net_port port_dest
);
57 int net_proto_tcp6_conn_estabilish_reply (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
);
58 int net_proto_tcp6_read_cache (proto_tcp6_conn_t
*conn
, char *data
, unsigned len
);
59 int net_proto_tcp6_read_ok (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
);
60 int net_proto_tcp6_write (netif_t
*eth
, net_ipv6 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
);
61 int net_proto_tcp6_write_data (proto_tcp6_conn_t
*conn
, char *data
, unsigned len
);
62 int net_proto_tcp6_write_data_ok (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
);
63 int net_proto_tcp6_conn_disconnected (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
);
64 int net_proto_tcp6_conn_close (proto_tcp6_conn_t
*conn
);
65 unsigned net_proto_tcp6_conn_del (proto_tcp6_conn_t
*conn
);
66 proto_tcp6_conn_t
*net_proto_tcp6_conn_find (int fd
);
67 int net_proto_tcp6_backlog_add (proto_tcp6_conn_t
*conn
, net_ipv6 ip
, net_port port
, unsigned seq
);
68 int net_proto_tcp6_conn_invite (proto_tcp6_conn_t
*conn
, net_ipv6 ip
, net_port port
, unsigned seq
);
71 * User-friendly socket functions
73 int net_proto_tcp6_socket (fd_t
*fd
)
75 return net_proto_tcp6_conn_add (fd
);
78 extern unsigned long timer_ticks
;
79 int net_proto_tcp6_connect (int fd
, sockaddr_in6
*addr
)
83 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
89 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
90 ret
= net_proto_tcp6_conn_estabilish (conn
, netif
, addr
->sin6_addr
, addr
->sin6_port
);
92 unsigned long stime
= timer_ticks
;
95 if (!(conn
->flags
& O_NONBLOCK
)) {
103 if ((stime
+3000) < timer_ticks
)
106 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHED
)
109 /* when connection cant be accepted succefully first time, try it again */
110 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHERROR
) {
111 ret
= net_proto_tcp6_conn_estabilish (conn
, netif
, addr
->sin6_addr
, addr
->sin6_port
);
112 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
116 /* non-blocking mode */
125 int net_proto_tcp6_send (int fd
, char *msg
, unsigned size
)
127 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
132 int ret
= net_proto_tcp6_write_data (conn
, msg
, size
);
135 unsigned long stime
= timer_ticks
;
138 if (!(conn
->flags
& O_NONBLOCK
)) {
139 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
143 if ((stime
+8000) < timer_ticks
)
147 /* non-blocking mode */
150 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
154 if ((stime
+1000) < timer_ticks
)
164 int net_proto_tcp6_recv (int fd
, char *msg
, unsigned size
)
166 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
173 //kprintf ("recv () - %d\n", fd);
176 if (!(conn
->flags
& O_NONBLOCK
)) {
177 unsigned long stime
= timer_ticks
;
179 while (!conn
->len
/* || conn->state != PROTO_TCP_CONN_STATE_READY*/) {
180 if ((stime
+10000) < timer_ticks
)
183 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
184 if (net_proto_tcp6_conn_del (conn
));
191 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
192 if (net_proto_tcp6_conn_del (conn
));
200 if ((conn
->len
-conn
->offset
) > size
) {
201 memcpy (msg
, conn
->data
+conn
->offset
, size
);
202 //printf ("msg: %d %d\n", conn->offset, size);
203 conn
->offset
+= size
;
207 ret
= conn
->len
-conn
->offset
;
209 memcpy (msg
, conn
->data
+conn
->offset
, conn
->len
-conn
->offset
);
210 //printf ("msg2: %d %d\n", conn->offset, size);
217 //kprintf ("recv () - %d -- DATA: %d\n", fd, ret);
222 int net_proto_tcp6_close (int fd
)
224 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
229 if (conn
->state
== PROTO_TCP_CONN_STATE_DISCONNECTED
)
232 int ret
= net_proto_tcp6_conn_close (conn
);
237 int net_proto_tcp6_fcntl (int fd
, int cmd
, long arg
)
239 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
255 int net_proto_tcp6_bind (int fd
, sockaddr_in6
*addr
, socklen_t len
)
257 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
263 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
264 net_proto_tcp6_conn_set (conn
, netif
, addr
->sin6_port
, 0, 0);
272 int net_proto_tcp6_listen (int fd
, int backlog
)
274 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
282 int net_proto_tcp6_accept (int fd
, sockaddr_in6
*addr
, socklen_t
*addrlen
)
284 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_find (fd
);
291 proto_tcp6_backlog_t
*backlog
= 0;
294 if (!(conn
->flags
& O_NONBLOCK
)) {
296 for (backlog
= proto_tcp6_backlog_list
.next
; backlog
!= &proto_tcp6_backlog_list
; backlog
= backlog
->next
) {
297 if (backlog
->conn
== conn
) {
306 /* non-blocking mode */
307 for (backlog
= proto_tcp6_backlog_list
.next
; backlog
!= &proto_tcp6_backlog_list
; backlog
= backlog
->next
) {
308 if (backlog
->conn
== conn
) {
315 //printf ("accept ()\n");
321 memcpy (ip
, backlog
->ip
, sizeof (net_ipv6
));
323 net_port port
= backlog
->port
;
324 unsigned seq
= backlog
->seq
;
326 int ret
= net_proto_tcp6_conn_invite (conn
, ip
, port
, seq
);
328 /* remove from queue accepted connection */
329 backlog
->next
->prev
= backlog
->prev
;
330 backlog
->prev
->next
= backlog
->next
;
337 fd_t
*fd_new
= fd_create (FD_SOCK
);
342 net_proto_tcp6_conn_add (fd_new
);
344 proto_tcp6_conn_t
*conn_new
= net_proto_tcp6_conn_find (fd_new
->id
);
349 net_proto_tcp6_conn_set (conn_new
, conn
->netif
, conn
->port_source
, conn
->netif
->ipv6
, port
);
351 memcpy (conn_new
->ip_dest
, ip
, sizeof (net_ipv6
));
353 memcpy (addr
->sin6_addr
, ip
, sizeof (net_ipv6
));
354 addr
->sin6_port
= port
;
355 addr
->sin6_family
= AF_INET6
;
361 * Hardcore code - syn, ack, psh, fin, etc :P
363 unsigned net_proto_tcp6_handler (packet_t
*packet
, proto_ipv6_t
*ip
, char *buf
, unsigned len
, unsigned flags
)
365 proto_tcp_t
*tcp
= (proto_tcp_t
*) buf
;
367 unsigned char ret
= 0;
369 /* First check ip address and ports, that we want this data */
370 proto_tcp6_conn_t
*conn
= net_proto_tcp6_conn_check (ip
->ip_dest
, tcp
->port_dest
, ip
->ip_source
, tcp
->port_source
, &ret
);
372 //printf ("hmm: %d - %d - %d\n", len, swap16 (tcp->port_dest), ret);
374 if (!conn
&& ret
== 0)
377 //printf ("tcp6->flags: 0x%x, ret: %d, conn: 0x%x, fd: %d\n", tcp->flags, ret, conn, conn->fd);
379 /* connection from client before accept () */
381 /* client want connect to our server */
382 if (tcp
->flags
== 0x02) {
383 mutex_lock (&mutex_tcp6_accept
);
385 unsigned ret
= net_proto_tcp6_backlog_add (conn
, ip
->ip_source
, tcp
->port_source
, tcp
->seq
);
387 mutex_unlock (&mutex_tcp6_accept
);
395 unsigned data_cache
= 0;
398 if (tcp
->flags
& 0x08) {
399 /* needed for calculate real offset from 4bit number */
400 unsigned offset
= tcp
->data_offset
* 4;
401 unsigned size
= len
- offset
;
403 //kprintf (">>>> %d : %d : %d\n", offset, size, len);
404 //mutex_lock (&mutex_tcp6_read_cache);
405 net_proto_tcp6_read_cache (conn
, buf
+offset
, size
);
406 //mutex_unlock (&mutex_tcp6_read_cache);
408 net_proto_tcp6_read_ok (conn
, ip
, tcp
, size
);
413 /* sended data was delivered succefully */
414 if (tcp
->flags
& 0x10) {
415 /* HACK: It is interesting, that no push flag, and there could be some data to read */
417 /* needed for calculate real offset from 4bit number */
418 unsigned offset
= tcp
->data_offset
* 4;
419 unsigned size
= len
- offset
;
421 /* there are data for read */
423 /* data was cached, so no need cache it again */
425 //kprintf (">>>>2 %d : %d : %d\n", offset, size, len);
426 mutex_lock (&mutex_tcp6_read_cache
);
427 net_proto_tcp6_read_cache (conn
, buf
+offset
, size
);
428 mutex_unlock (&mutex_tcp6_read_cache
);
430 net_proto_tcp6_read_ok (conn
, ip
, tcp
, size
);
433 /* when data are'nt available, lets normal work - acknowledgement */
434 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISH
) {
435 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHERROR
;
436 net_proto_tcp6_write_data_ok (conn
, ip
, tcp
);
438 net_proto_tcp6_write_data_ok (conn
, ip
, tcp
);
442 /* connection estabilish respond */
443 if (tcp
->flags
== 0x12) {
444 return net_proto_tcp6_conn_estabilish_reply (conn
, ip
, tcp
);
447 /* another side close connection */
448 if (tcp
->flags
& 0x01) {
449 DPRINT ("TCP -> fd %d connection closed by remote host\n", conn
->fd
);
450 net_proto_tcp6_conn_disconnected (conn
, ip
, tcp
); // FIXME: problem in server with hangind the whole program
453 /* another side close connection */
454 if (tcp
->flags
& 0x04) {
455 DPRINT ("TCP -> fd %d connection reseted by peer\n", conn
->fd
);
456 net_proto_tcp6_conn_disconnected (conn
, ip
, tcp
);
462 int net_proto_tcp6_read_cache (proto_tcp6_conn_t
*conn
, char *data
, unsigned len
)
464 if (!data
|| !conn
|| !len
)
468 conn
->data
= (char *) kmalloc (sizeof (char) * (len
+ 1));
470 memcpy (conn
->data
, data
, len
);
472 char *newdata
= (char *) kmalloc (sizeof (char) * (conn
->len
+ len
+ 1));
477 memcpy (newdata
, conn
->data
, conn
->len
);
478 memcpy (newdata
+conn
->len
, data
, len
);
482 conn
->data
= newdata
;
488 //kprintf ("DATA: %d - #'%s'#\n", len, data);
492 conn
->data
[conn
->len
] = '\0';
497 int net_proto_tcp6_read_ok (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
)
499 if (!ip_old
|| !tcp_old
|| !conn
)
502 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
507 tcp
->port_source
= conn
->port_source
; // increase client port too
508 tcp
->port_dest
= conn
->port_dest
;
510 tcp
->seq
= tcp_old
->ack
;
512 /* this small thing did bad work when e.g. 10 10 10 fe get to calculation,
513 it returns 10 10 10 08, no 10 10 11 08 */
514 unsigned seq
= swap32 (tcp_old
->seq
);
517 tcp
->ack
= swap32 (seq
);
520 tcp
->data_offset
= 5;
522 tcp
->window
= tcp_old
->window
+ swap16 (64);
525 int ret
= net_proto_tcp6_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
527 /*if (proto_tcp6_dup == tcp_old->checksum) {
528 printf ("Duplicated packet :)");
533 //printf ("read_ok: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
535 conn
->seq
= tcp
->ack
;
536 conn
->ack
= tcp
->seq
;
538 //printf ("read_ok2: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
540 proto_tcp6_dup
= tcp_old
->checksum
;
550 int net_proto_tcp6_write (netif_t
*eth
, net_ipv6 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
)
553 printf ("!eth || !tcp\n");
563 if (!tun6_addr_get ()) {
564 unsigned get
= ndp_cache_get (dest
, &mac_dest
);
567 ndp_send_nbrequest (eth
, dest
);
570 /* 200ms for waiting on NDP reply */
572 get
= ndp_cache_get (dest
, &mac_dest
);
577 /* TODO: make better waiting for NDP reply */
591 /* IPv6 tunnel stuff */
592 net_ipv4 tunnel
= tun6_addr_get ();
593 unsigned get
= arp_cache_get (tunnel
, &mac_dest
);
596 arp_send_request (eth
, tunnel
);
599 /* 100ms for waiting on ARP reply */
601 get
= arp_cache_get (tunnel
, &mac_dest
);
606 /* TODO: make better waiting for ARP reply */
622 packet_t
*packet
= &packet6_prealloc
;
625 printf ("!packet\n");
629 memcpy (&packet
->mac_source
, eth
->dev
->dev_addr
, 6);
630 memcpy (&packet
->mac_dest
, mac_dest
, 6);
631 packet
->type
= NET_PACKET_TYPE_IPV6
;
633 unsigned l
= (tcp
->data_offset
*4);
636 proto_ipv6_t
*ip
= &proto_ipv6_prealloc
;
643 /* there are some fixed values - yeah it is horrible */
647 ip
->pl_len
= swap16 (l
+len
);
648 ip
->nhead
= NET_PROTO_IP_TYPE_TCP6
;
650 memcpy (ip
->ip_source
, (void *) eth
->ipv6
, sizeof (net_ipv6
));
651 memcpy (ip
->ip_dest
, (void *) dest
, sizeof (net_ipv6
));
653 char *buf_tcp
= (char *) kmalloc ((len
+l
+1) * sizeof (char));
656 printf ("!buf_tcp\n");
660 memcpy (buf_tcp
, (char *) tcp
, l
);
663 memcpy (buf_tcp
+l
, data
, len
);
665 buf_tcp
[l
+len
] = '\0';
667 /* calculate checksum and put it to tcp header */
668 proto_tcp_t
*tcp_
= (proto_tcp_t
*) buf_tcp
;
672 tcp_
->checksum
= checksum16_ipv6 (eth
->ipv6
, dest
, buf_tcp
, l
+len
, NET_PROTO_IP_TYPE_TCP6
);
674 /* send tcp header+data to ip layer */
675 if (!tun6_addr_get ())
676 ret
= net_proto_ipv6_send (eth
, packet
, ip
, (char *) buf_tcp
, l
+len
);
678 ret
= net_proto_tun6_send (eth
, packet
, ip
, (char *) buf_tcp
, l
+len
);
685 int net_proto_tcp6_write_data (proto_tcp6_conn_t
*conn
, char *data
, unsigned len
)
687 if (!conn
|| !len
|| !data
)
690 proto_tcp_t
*tcp
= &proto_tcp6_prealloc
;
695 tcp
->port_source
= conn
->port_source
;
696 tcp
->port_dest
= conn
->port_dest
;
698 unsigned seq
= swap32 (proto_tcp6_seq
);
701 //tcp->ack = swap32 (seq);
703 proto_tcp6_seq
= swap32 (seq
);
706 tcp
->seq
= conn
->seq
;
707 tcp
->ack
= conn
->ack
;
709 tcp
->seq
= conn
->ack
;
710 tcp
->ack
= conn
->seq
;
715 //printf ("TCP -> seq: 0x%x | ack: 0x%x | proto_seq: 0x%x\n", tcp->seq, conn->ack, proto_tcp6_seq);
718 tcp
->data_offset
= 5;
720 tcp
->window
= swap16 (32768);
723 int ret
= net_proto_tcp6_write (conn
->netif
, conn
->ip_dest
, tcp
, data
, len
);
726 conn
->state
= PROTO_TCP_CONN_STATE_WAIT
;
731 int net_proto_tcp6_write_data_ok (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
)
733 if (!ip_old
|| !tcp_old
|| !conn
)
736 /* cross - because we change now sides :) */
737 conn
->seq
= tcp_old
->ack
;
738 conn
->ack
= tcp_old
->seq
;
740 //printf ("data_ok: seq: 0x%x | ack: 0x%x\n", tcp_old->ack, tcp_old->seq);
742 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
747 /* try connect to server */
748 int net_proto_tcp6_conn_estabilish (proto_tcp6_conn_t
*conn
, netif_t
*eth
, net_ipv6 ip_dest
, net_port port_dest
)
753 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
758 tcp
->port_source
= swap16 (netif_port_get ()); // increase client port too
759 tcp
->port_dest
= port_dest
;
761 /* setup new connection */
762 net_proto_tcp6_conn_set (conn
, eth
, tcp
->port_source
, ip_dest
, tcp
->port_dest
);
764 tcp
->seq
= conn
->seq
;
765 tcp
->ack
= conn
->ack
;
768 tcp
->data_offset
= 5;
770 tcp
->window
= swap16 (32792);
773 int ret
= net_proto_tcp6_write (eth
, ip_dest
, tcp
, 0, 0);
778 net_proto_tcp6_conn_del (conn
);
785 int net_proto_tcp6_conn_estabilish_reply (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
)
787 if (!ip_old
|| !tcp_old
|| !conn
)
790 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
795 tcp
->port_source
= conn
->port_source
; // increase client port too
796 tcp
->port_dest
= conn
->port_dest
;
798 tcp
->seq
= tcp_old
->ack
;
799 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
802 tcp
->data_offset
= 5;
804 tcp
->window
= tcp_old
->window
+ swap16 (64);
807 int ret
= net_proto_tcp6_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
810 conn
->seq
= tcp
->seq
;
811 conn
->ack
= tcp
->ack
;
812 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHED
;
815 DPRINT ("TCP -> fd %� connected to server succefully\n", conn
->fd
);
822 int net_proto_tcp6_conn_disconnected (proto_tcp6_conn_t
*conn
, proto_ipv6_t
*ip_old
, proto_tcp_t
*tcp_old
)
824 if (!ip_old
|| !tcp_old
|| !conn
)
827 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
)
828 return net_proto_tcp6_conn_del (conn
);
830 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
835 tcp
->port_source
= conn
->port_source
; // increase client port too
836 tcp
->port_dest
= conn
->port_dest
;
838 tcp
->seq
= tcp_old
->ack
;
839 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
842 tcp
->data_offset
= 5;
844 tcp
->window
= tcp_old
->window
+ swap16 (64);
847 int ret
= net_proto_tcp6_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
852 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
; //ret = net_proto_tcp6_conn_del (conn);
859 int net_proto_tcp6_conn_close (proto_tcp6_conn_t
*conn
)
861 return 0; /* FIXME: close () is faster then send () sometime :-B */
866 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
)
869 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
874 tcp
->port_source
= conn
->port_source
; // increase client port too
875 tcp
->port_dest
= conn
->port_dest
;
877 tcp
->seq
= conn
->seq
;
878 tcp
->ack
= conn
->ack
;
881 tcp
->data_offset
= 5;
883 tcp
->window
= swap16 (32832);
886 int ret
= net_proto_tcp6_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
891 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
;
897 /* client wants to connect */
898 net_proto_tcp6_conn_invite (proto_tcp6_conn_t
*conn
, net_ipv6 ip
, net_port port
, unsigned seq
)
903 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
908 tcp
->port_source
= conn
->port_source
;
909 tcp
->port_dest
= port
;
911 tcp
->seq
= proto_tcp6_seq
++;
912 tcp
->ack
= seq
+ swap32 (1);
915 tcp
->data_offset
= 5;
917 tcp
->window
= swap16 (5816);
920 int ret
= net_proto_tcp6_write (conn
->netif
, ip
, tcp
, 0, 0);
925 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
934 /* Create new TCP connection */
935 int net_proto_tcp6_conn_add (fd_t
*fd
)
937 proto_tcp6_conn_t
*conn
;
939 /* alloc and init context */
940 conn
= (proto_tcp6_conn_t
*) kmalloc (sizeof (proto_tcp6_conn_t
));
947 memset (conn
, 0, sizeof (proto_tcp6_conn_t
));
957 conn
->next
= &proto_tcp6_conn_list
;
958 conn
->prev
= proto_tcp6_conn_list
.prev
;
959 conn
->prev
->next
= conn
;
960 conn
->next
->prev
= conn
;
965 /* Setup new connection */
966 int net_proto_tcp6_conn_set (proto_tcp6_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv6 ip_dest
, net_port port_dest
)
971 memcpy (conn
->ip_source
, eth
->ipv6
, sizeof (net_ipv6
));
972 memcpy (conn
->ip_dest
, ip_dest
, sizeof (net_ipv6
));
974 conn
->port_source
= port_source
;
975 conn
->port_dest
= port_dest
;
977 proto_tcp6_seq
+= swap32 (1);
979 conn
->seq
= proto_tcp6_seq
++;
982 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
993 /* Delete existing connection from list */
994 unsigned net_proto_tcp6_conn_del (proto_tcp6_conn_t
*conn
)
999 conn
->state
= PROTO_TCP_CONN_STATE_DISCONNECTED
;
1006 conn
->next
->prev
= conn
->prev
;
1007 conn
->prev
->next
= conn
->next
;
1014 proto_tcp6_conn_t
*net_proto_tcp6_conn_check (net_ipv6 ip_source
, net_port port_source
, net_ipv6 ip_dest
, net_port port_dest
, unsigned char *ret
)
1017 proto_tcp6_conn_t
*conn
= NULL
;
1018 proto_tcp6_conn_t
*conn_ret
= NULL
;
1019 //printf ("-------------------------\n");
1020 for (conn
= proto_tcp6_conn_list
.next
; conn
!= &proto_tcp6_conn_list
; conn
= conn
->next
) {
1022 net_proto_ipv6_print (conn->ip_source);
1024 net_proto_ipv6_print (ip_source);
1026 net_proto_ipv6_print (conn->ip_dest);
1028 net_proto_ipv6_print (ip_dest);
1029 printf ("\nporty: %d / %d\n", swap16 (conn->port_source), swap16 (port_source));
1030 printf ("porty2: %d / %d\n", swap16 (conn->port_dest), swap16 (port_dest));*/
1032 if (net_proto_ipv6_cmp (conn
->ip_source
, ip_source
) && conn
->port_source
== port_source
) {
1033 if (net_proto_ipv6_cmp (conn
->ip_dest
, ip_dest
) && conn
->port_dest
== port_dest
) {
1045 if (!conn_ret
->bind
) {
1048 for (conn
= proto_tcp6_conn_list
.next
; conn
!= &proto_tcp6_conn_list
; conn
= conn
->next
) {
1050 if (net_proto_ipv6_cmp (conn
->ip_source
, ip_source
) && conn
->port_source
== port_source
)
1059 proto_tcp6_conn_t
*net_proto_tcp6_conn_find (int fd
)
1061 proto_tcp6_conn_t
*conn
= NULL
;
1062 for (conn
= proto_tcp6_conn_list
.next
; conn
!= &proto_tcp6_conn_list
; conn
= conn
->next
) {
1070 /* Create new TCP backlog stamp */
1071 int net_proto_tcp6_backlog_add (proto_tcp6_conn_t
*conn
, net_ipv6 ip
, net_port port
, unsigned seq
)
1076 proto_tcp6_backlog_t
*backlog
;
1078 /* alloc and init context */
1079 backlog
= (proto_tcp6_backlog_t
*) kmalloc (sizeof (proto_tcp6_backlog_t
));
1084 backlog
->conn
= conn
;
1085 memcpy (backlog
->ip
, ip
, sizeof (net_ipv6
));
1086 backlog
->port
= port
;
1090 backlog
->next
= &proto_tcp6_backlog_list
;
1091 backlog
->prev
= proto_tcp6_backlog_list
.prev
;
1092 backlog
->prev
->next
= backlog
;
1093 backlog
->next
->prev
= backlog
;
1098 /* init of tcp protocol */
1099 unsigned init_net_proto_tcp6 ()
1101 proto_tcp6_conn_list
.next
= &proto_tcp6_conn_list
;
1102 proto_tcp6_conn_list
.prev
= &proto_tcp6_conn_list
;
1104 proto_tcp6_backlog_list
.next
= &proto_tcp6_backlog_list
;
1105 proto_tcp6_backlog_list
.prev
= &proto_tcp6_backlog_list
;
1107 proto_tcp6_dup
= 0x0;
1108 proto_tcp6_seq
= 0x1;