3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <net/socket.h>
34 extern task_t
*_curr_task
;
36 socket_t
*socket_getbyfd (int fd
)
39 for (socket
= socket_list
.next
; socket
!= &socket_list
; socket
= socket
->next
) {
47 int socket (int family
, int type
, int protocol
)
49 /* alloc and init context */
50 socket_t
*sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
57 sock
->family
= family
;
59 sock
->protocol
= protocol
;
61 fd_t
*fd
= fd_create (FD_SOCK
);
72 switch (sock
->family
) {
76 ret
= net_proto_unix_socket (fd
);
79 switch (sock
->protocol
) {
81 ret
= net_proto_tcp_socket (fd
);
84 ret
= net_proto_udp_socket (fd
);
89 switch (sock
->protocol
) {
91 ret
= net_proto_tcp6_socket (fd
);
94 ret
= net_proto_udp6_socket (fd
);
99 ret
= ips_socket (fd
);
107 DPRINT (DBG_NET
| DBG_SOCKET
, "socket () -> %d : ERROR", sock
->fd
);
112 sock
->next
= &socket_list
;
113 sock
->prev
= socket_list
.prev
;
114 sock
->prev
->next
= sock
;
115 sock
->next
->prev
= sock
;
117 proc_t
*proc
= proc_find (_curr_task
);
119 /* when it is process */
121 if (proc
->task
!= _curr_task
)
126 /* it is kernel socket */
130 DPRINT (DBG_NET
| DBG_SOCKET
, "socket () -> socket: %d", sock
->fd
);
135 hostent
*gethostbyname (char *hostname
)
139 unsigned l
= strlen (hostname
);
141 /* TODO: make better checking, that it is IPv6 addresss */
143 if (hostname
[i
] == ':')
150 unsigned short targetv6
[8];
152 /* Is it an IPv6 address */
154 if (!net_proto_ipv6_convert (targetv6
, hostname
))
160 /* TODO: make better checking, that it is IPv4 addresss */
162 if (hostname
[i
] == '.')
169 /* it is dns address */
171 if (dns_cache_get (hostname
, &target
, 4) != 1) /* check for ipv4 address */
172 if (dns_send_request (hostname
, &target
, 4) != 1) {
174 if (dns_cache_get (hostname
, &targetv6
, 16) != 1) { /* check for ipv6 address */
175 if (dns_send_request (hostname
, &targetv6
, 16) != 1)
180 target
= net_proto_ip_convert (hostname
);
186 hostent
*host
= (hostent
*) kmalloc (sizeof (hostent
));
191 memset (host
, 0, sizeof (hostent
));
195 host
->h_length
= 16; /* IPv6 - 16 bytes */
197 host
->h_length
= 4; /* IPv4 - 4 bytes */
199 host
->h_addr
= (char *) kmalloc (sizeof (char) * host
->h_length
);
207 memcpy (host
->h_addr
, &targetv6
, host
->h_length
);
209 memcpy (host
->h_addr
, &target
, host
->h_length
);
214 int connect (int fd
, sockaddr
*addr
, socklen_t len
)
216 DPRINT (DBG_NET
| DBG_SOCKET
, "connect () -> socket: %d", fd
);
217 socket_t
*sock
= socket_getbyfd (fd
);
222 switch (sock
->family
) {
226 return net_proto_unix_connect (fd
, addr
);
228 switch (sock
->protocol
) {
230 return net_proto_tcp_connect (fd
, (sockaddr_in
*) addr
);
232 return net_proto_udp_connect (fd
, addr
);
236 switch (sock
->protocol
) {
238 return net_proto_tcp6_connect (fd
, (sockaddr_in
*) addr
);
240 return net_proto_udp6_connect (fd
, (sockaddr_in6
*) addr
);
244 return ips_connect (fd
, addr
);
250 int send (int fd
, char *msg
, size_t size
, int flags
)
252 socket_t
*sock
= socket_getbyfd (fd
);
257 DPRINT (DBG_NET
| DBG_SOCKET
, "send (%d) -> %s", fd
, msg
);
259 switch (sock
->family
) {
263 return net_proto_unix_send (fd
, msg
, size
);
265 switch (sock
->protocol
) {
267 return net_proto_tcp_send (fd
, msg
, size
);
269 return net_proto_udp_send (fd
, msg
, size
);
273 switch (sock
->protocol
) {
275 return net_proto_tcp6_send (fd
, msg
, size
);
277 return net_proto_udp6_send (fd
, msg
, size
);
281 return ips_send (fd
, msg
, size
);
287 int sendto (int fd
, const void *msg
, size_t len
, int flags
, sockaddr
*to
, socklen_t tolen
)
289 socket_t
*sock
= socket_getbyfd (fd
);
294 DPRINT (DBG_NET
| DBG_SOCKET
, "sendto (%d) -> %s", fd
, msg
);
296 switch (sock
->protocol
) {
298 switch (sock
->family
) {
304 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
306 return -1; // net_proto_tcp6_sendto (fd, msg, len, to);
312 switch (sock
->family
) {
318 return net_proto_udp_sendto (fd
, msg
, len
, (sockaddr_in
*) to
);
320 return net_proto_udp6_sendto (fd
, msg
, len
, (sockaddr_in6
*) to
);
330 int recv (int fd
, char *msg
, size_t size
, int flags
)
332 socket_t
*sock
= socket_getbyfd (fd
);
337 DPRINT (DBG_NET
| DBG_SOCKET
, "recv (%d)", fd
);
339 switch (sock
->family
) {
343 return net_proto_unix_recv (fd
, msg
, size
);
345 switch (sock
->protocol
) {
347 return net_proto_tcp_recv (fd
, msg
, size
);
349 return net_proto_udp_recv (fd
, msg
, size
);
353 switch (sock
->protocol
) {
355 return net_proto_tcp6_recv (fd
, msg
, size
);
357 return net_proto_udp6_recv (fd
, msg
, size
);
361 return ips_recv (fd
, msg
, size
);
367 int recvfrom (int fd
, char *msg
, size_t size
, int flags
, sockaddr
*from
, socklen_t fromlen
)
369 socket_t
*sock
= socket_getbyfd (fd
);
374 DPRINT (DBG_NET
| DBG_SOCKET
, "recvfrom (%d)", fd
);
376 switch (sock
->protocol
) {
378 switch (sock
->family
) {
384 return -1; //net_proto_tcp_recvfrom (fd, msg, size, from);
386 return -1; //net_proto_tcp6_recvfrom (fd, msg, size, from);
392 switch (sock
->family
) {
398 return net_proto_udp_recvfrom (fd
, msg
, size
, (sockaddr_in
*) from
);
400 return net_proto_udp6_recvfrom (fd
, msg
, size
, (sockaddr_in6
*) from
);
410 int bind (int fd
, sockaddr
*addr
, socklen_t len
)
412 socket_t
*sock
= socket_getbyfd (fd
);
417 DPRINT (DBG_NET
| DBG_SOCKET
, "bind (%d)", fd
);
419 switch (sock
->family
) {
423 return net_proto_unix_bind (fd
, (sockaddr_in
*) addr
, len
);
425 switch (sock
->protocol
) {
427 return net_proto_tcp_bind (fd
, (sockaddr_in
*) addr
, len
);
429 return net_proto_udp_bind (fd
, (sockaddr_in
*) addr
, len
);
433 switch (sock
->protocol
) {
435 return net_proto_tcp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
437 return net_proto_udp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
441 return ips_bind (fd
, addr
);
447 int listen (int fd
, int backlog
)
449 socket_t
*sock
= socket_getbyfd (fd
);
454 DPRINT (DBG_NET
| DBG_SOCKET
, "listen (%d)", fd
);
456 switch (sock
->family
) {
461 return net_proto_unix_listen (fd
, backlog
);
463 return net_proto_tcp_listen (fd
, backlog
);
465 return net_proto_tcp6_listen (fd
, backlog
);
467 return ips_listen (fd
, backlog
);
473 int accept (int fd
, sockaddr
*addr
, socklen_t
*addrlen
)
475 socket_t
*servsock
= socket_getbyfd (fd
);
480 //DPRINT (DBG_NET | DBG_SOCKET, "accept (%d)", fd);
484 switch (servsock
->family
) {
489 client
= net_proto_unix_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
492 client
= net_proto_tcp_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
495 client
= net_proto_tcp6_accept (fd
, (sockaddr_in6
*) addr
, addrlen
);
498 client
= ips_accept (fd
, addr
, addrlen
);
507 /* alloc and init context */
508 sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
514 sock
->family
= servsock
->family
;
515 sock
->type
= servsock
->type
;
516 sock
->protocol
= servsock
->protocol
;
519 sock
->next
= &socket_list
;
520 sock
->prev
= socket_list
.prev
;
521 sock
->prev
->next
= sock
;
522 sock
->next
->prev
= sock
;
529 socket_t
*sock
= socket_getbyfd (fd
);
534 DPRINT (DBG_NET
| DBG_SOCKET
, "close (%d)", fd
);
536 /* delete old socket from socket_list */
537 sock
->next
->prev
= sock
->prev
;
538 sock
->prev
->next
= sock
->next
;
540 int family
= sock
->family
;
541 int protocol
= sock
->protocol
;
549 return net_proto_unix_close (fd
);
553 return net_proto_tcp_close (fd
);
555 return net_proto_udp_close (fd
);
561 return net_proto_tcp6_close (fd
);
563 return net_proto_udp6_close (fd
);
567 return ips_close (fd
);
573 int sfcntl (int fd
, int cmd
, long arg
)
575 socket_t
*sock
= socket_getbyfd (fd
);
580 DPRINT (DBG_NET
| DBG_SOCKET
, "fcntl (%d)", fd
);
582 switch (sock
->family
) {
586 return net_proto_unix_fcntl (fd
, cmd
, arg
);
588 switch (sock
->protocol
) {
590 return net_proto_tcp_fcntl (fd
, cmd
, arg
);
592 return net_proto_udp_fcntl (fd
, cmd
, arg
);
596 switch (sock
->protocol
) {
598 return net_proto_tcp6_fcntl (fd
, cmd
, arg
);
600 return net_proto_udp6_fcntl (fd
, cmd
, arg
);
604 return ips_fcntl (fd
);
610 /* socket api select for specified socket */
611 int sselect (int readfd
, int writefd
, int exceptfd
)
622 socket_t
*sock
= socket_getbyfd (fd
);
627 switch (sock
->family
) {
631 return net_proto_unix_select (readfd, writefd, exceptfd);*/
633 switch (sock
->protocol
) {
635 return net_proto_tcp_select (readfd
, writefd
, exceptfd
);
637 return net_proto_udp_select (readfd
, writefd
, exceptfd
);
641 switch (sock
->protocol
) {
643 return net_proto_tcp6_select (readfd
, writefd
, exceptfd
);
645 return net_proto_udp6_select (readfd
, writefd
, exceptfd
);
649 return ips_select (readfd, writefd, exceptfd);*/
655 unsigned int init_socket ()
657 socket_list
.next
= &socket_list
;
658 socket_list
.prev
= &socket_list
;