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)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <net/socket.h>
32 extern task_t
*_curr_task
;
34 socket_t
*socket_getbyfd (int fd
)
37 for (socket
= socket_list
.next
; socket
!= &socket_list
; socket
= socket
->next
) {
45 int socket (int family
, int type
, int protocol
)
47 /* alloc and init context */
48 socket_t
*sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
55 sock
->family
= family
;
57 sock
->protocol
= protocol
;
59 fd_t
*fd
= fd_create (FD_SOCK
);
68 switch (sock
->family
) {
72 net_proto_unix_socket (fd
);
75 switch (sock
->protocol
) {
77 net_proto_tcp_socket (fd
);
80 net_proto_udp_socket (fd
);
85 switch (sock
->protocol
) {
87 net_proto_tcp6_socket (fd
);
90 net_proto_udp6_socket (fd
);
95 sock
->fd
= ips_socket (fd
);
100 sock
->next
= &socket_list
;
101 sock
->prev
= socket_list
.prev
;
102 sock
->prev
->next
= sock
;
103 sock
->next
->prev
= sock
;
105 proc_t
*proc
= proc_find (_curr_task
);
107 /* when it is process */
109 if (proc
->task
!= _curr_task
)
114 /* it is kernel socket */
118 DPRINT (DBG_NET
| DBG_SOCKET
, "socket () -> socket: %d", sock
->fd
);
123 hostent
*gethostbyname (char *hostname
)
127 unsigned l
= strlen (hostname
);
129 /* TODO: make better checking, that it is IPv6 addresss */
131 if (hostname
[i
] == ':')
138 unsigned short targetv6
[8];
140 /* Is it an IPv6 address */
142 if (!net_proto_ipv6_convert (targetv6
, hostname
))
148 /* TODO: make better checking, that it is IPv4 addresss */
150 if (hostname
[i
] == '.')
157 /* it is dns address */
159 if (dns_cache_get (hostname
, &target
, 4) != 1) /* check for ipv4 address */
160 if (dns_send_request (hostname
, &target
, 4) != 1) {
162 if (dns_cache_get (hostname
, &targetv6
, 16) != 1) { /* check for ipv6 address */
163 if (dns_send_request (hostname
, &targetv6
, 16) != 1)
168 target
= net_proto_ip_convert (hostname
);
174 hostent
*host
= (hostent
*) kmalloc (sizeof (hostent
));
179 memset (host
, 0, sizeof (hostent
));
183 host
->h_length
= 16; /* IPv6 - 16 bytes */
185 host
->h_length
= 4; /* IPv4 - 4 bytes */
187 host
->h_addr
= (char *) kmalloc (sizeof (char) * host
->h_length
);
195 memcpy (host
->h_addr
, &targetv6
, host
->h_length
);
197 memcpy (host
->h_addr
, &target
, host
->h_length
);
202 int connect (int fd
, sockaddr
*addr
, socklen_t len
)
204 DPRINT (DBG_NET
| DBG_SOCKET
, "connect () -> socket: %d", fd
);
205 socket_t
*sock
= socket_getbyfd (fd
);
210 switch (sock
->family
) {
214 return net_proto_unix_connect (fd
, addr
);
216 switch (sock
->protocol
) {
218 return net_proto_tcp_connect (fd
, (sockaddr_in
*) addr
);
220 return net_proto_udp_connect (fd
, addr
);
224 switch (sock
->protocol
) {
226 return net_proto_tcp6_connect (fd
, (sockaddr_in
*) addr
);
228 return net_proto_udp6_connect (fd
, (sockaddr_in6
*) addr
);
232 return ips_connect (fd
, addr
);
238 int send (int fd
, char *msg
, size_t size
, int flags
)
240 socket_t
*sock
= socket_getbyfd (fd
);
245 DPRINT (DBG_NET
| DBG_SOCKET
, "send (%d) -> %s", fd
, msg
);
247 switch (sock
->family
) {
251 return net_proto_unix_send (fd
, msg
, size
);
253 switch (sock
->protocol
) {
255 return net_proto_tcp_send (fd
, msg
, size
);
257 return net_proto_udp_send (fd
, msg
, size
);
261 switch (sock
->protocol
) {
263 return net_proto_tcp6_send (fd
, msg
, size
);
265 return net_proto_udp6_send (fd
, msg
, size
);
269 return ips_send (fd
, msg
, size
);
275 int sendto (int fd
, const void *msg
, size_t len
, int flags
, sockaddr
*to
, socklen_t tolen
)
277 socket_t
*sock
= socket_getbyfd (fd
);
282 DPRINT (DBG_NET
| DBG_SOCKET
, "sendto (%d) -> %s", fd
, msg
);
284 switch (sock
->protocol
) {
286 switch (sock
->family
) {
292 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
294 return -1; // net_proto_tcp6_sendto (fd, msg, len, to);
300 switch (sock
->family
) {
306 return net_proto_udp_sendto (fd
, msg
, len
, (sockaddr_in
*) to
);
308 return net_proto_udp6_sendto (fd
, msg
, len
, (sockaddr_in6
*) to
);
318 int recv (int fd
, char *msg
, size_t size
, int flags
)
320 socket_t
*sock
= socket_getbyfd (fd
);
325 DPRINT (DBG_NET
| DBG_SOCKET
, "recv (%d)", fd
);
327 switch (sock
->family
) {
331 return net_proto_unix_recv (fd
, msg
, size
);
333 switch (sock
->protocol
) {
335 return net_proto_tcp_recv (fd
, msg
, size
);
337 return net_proto_udp_recv (fd
, msg
, size
);
341 switch (sock
->protocol
) {
343 return net_proto_tcp6_recv (fd
, msg
, size
);
345 return net_proto_udp6_recv (fd
, msg
, size
);
349 return ips_recv (fd
, msg
, size
);
355 int recvfrom (int fd
, char *msg
, size_t size
, int flags
, sockaddr
*from
, socklen_t fromlen
)
357 socket_t
*sock
= socket_getbyfd (fd
);
362 DPRINT (DBG_NET
| DBG_SOCKET
, "recvfrom (%d)", fd
);
364 switch (sock
->protocol
) {
366 switch (sock
->family
) {
372 return -1; //net_proto_tcp_recvfrom (fd, msg, size, from);
374 return -1; //net_proto_tcp6_recvfrom (fd, msg, size, from);
380 switch (sock
->family
) {
386 return net_proto_udp_recvfrom (fd
, msg
, size
, (sockaddr_in
*) from
);
388 return net_proto_udp6_recvfrom (fd
, msg
, size
, (sockaddr_in6
*) from
);
398 int bind (int fd
, sockaddr
*addr
, socklen_t len
)
400 socket_t
*sock
= socket_getbyfd (fd
);
405 DPRINT (DBG_NET
| DBG_SOCKET
, "bind (%d)", fd
);
407 switch (sock
->family
) {
411 return net_proto_unix_bind (fd
, (sockaddr_in
*) addr
, len
);
413 switch (sock
->protocol
) {
415 return net_proto_tcp_bind (fd
, (sockaddr_in
*) addr
, len
);
417 return net_proto_udp_bind (fd
, (sockaddr_in
*) addr
, len
);
421 switch (sock
->protocol
) {
423 return net_proto_tcp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
425 return net_proto_udp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
429 return ips_bind (fd
, addr
);
435 int listen (int fd
, int backlog
)
437 socket_t
*sock
= socket_getbyfd (fd
);
442 DPRINT (DBG_NET
| DBG_SOCKET
, "listen (%d)", fd
);
444 switch (sock
->family
) {
449 return net_proto_unix_listen (fd
, backlog
);
451 return net_proto_tcp_listen (fd
, backlog
);
453 return net_proto_tcp6_listen (fd
, backlog
);
455 return ips_listen (fd
, backlog
);
461 int accept (int fd
, sockaddr
*addr
, socklen_t
*addrlen
)
463 socket_t
*servsock
= socket_getbyfd (fd
);
468 //DPRINT (DBG_NET | DBG_SOCKET, "accept (%d)", fd);
472 switch (servsock
->family
) {
477 client
= net_proto_unix_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
480 client
= net_proto_tcp_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
483 client
= net_proto_tcp6_accept (fd
, (sockaddr_in6
*) addr
, addrlen
);
486 client
= ips_accept (fd
, addr
, addrlen
);
495 /* alloc and init context */
496 sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
499 sock
->family
= servsock
->family
;
500 sock
->type
= servsock
->type
;
501 sock
->protocol
= servsock
->protocol
;
504 sock
->next
= &socket_list
;
505 sock
->prev
= socket_list
.prev
;
506 sock
->prev
->next
= sock
;
507 sock
->next
->prev
= sock
;
514 socket_t
*sock
= socket_getbyfd (fd
);
519 DPRINT (DBG_NET
| DBG_SOCKET
, "close (%d)", fd
);
521 /* delete old socket from socket_list */
522 sock
->next
->prev
= sock
->prev
;
523 sock
->prev
->next
= sock
->next
;
525 int family
= sock
->family
;
526 int protocol
= sock
->protocol
;
534 return net_proto_unix_close (fd
);
538 return net_proto_tcp_close (fd
);
540 return net_proto_udp_close (fd
);
546 return net_proto_tcp6_close (fd
);
548 return net_proto_udp6_close (fd
);
552 return ips_close (fd
);
558 int sfcntl (int fd
, int cmd
, long arg
)
560 socket_t
*sock
= socket_getbyfd (fd
);
565 DPRINT (DBG_NET
| DBG_SOCKET
, "fcntl (%d)", fd
);
567 switch (sock
->family
) {
571 return net_proto_unix_fcntl (fd
, cmd
, arg
);
573 switch (sock
->protocol
) {
575 return net_proto_tcp_fcntl (fd
, cmd
, arg
);
577 return net_proto_udp_fcntl (fd
, cmd
, arg
);
581 switch (sock
->protocol
) {
583 return net_proto_tcp6_fcntl (fd
, cmd
, arg
);
585 return net_proto_udp6_fcntl (fd
, cmd
, arg
);
589 return ips_fcntl (fd
);
595 unsigned int init_socket ()
597 socket_list
.next
= &socket_list
;
598 socket_list
.prev
= &socket_list
;