3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 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/>.
23 #include <net/socket.h>
30 extern unsigned int fd_count
;
31 extern task_t
*_curr_task
;
33 socket_t
*socket_getbyfd (int fd
)
36 for (socket
= socket_list
.next
; socket
!= &socket_list
; socket
= socket
->next
) {
44 int socket (int family
, int type
, int protocol
)
48 /* alloc and init context */
49 sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
51 sock
->fd
= fd_count
++;
52 sock
->family
= family
;
54 sock
->protocol
= protocol
;
56 switch (sock
->protocol
) {
58 switch (sock
->family
) {
65 sock
->fd
= net_proto_tcp_socket ();
68 sock
->fd
= net_proto_tcp6_socket ();
71 sock
->fd
= ips_socket ();
76 switch (sock
->family
) {
83 sock
->fd
= net_proto_udp_socket ();
86 sock
->fd
= net_proto_udp6_socket ();
95 sock
->next
= &socket_list
;
96 sock
->prev
= socket_list
.prev
;
97 sock
->prev
->next
= sock
;
98 sock
->next
->prev
= sock
;
100 fd_t
*fd
= (fd_t
*) kmalloc (sizeof (fd_t
));
105 proc_t
*proc
= proc_find (_curr_task
);
110 if (proc
->task
!= _curr_task
)
116 fd
->prev
= fd_list
.prev
;
123 hostent
*gethostbyname (char *hostname
)
127 unsigned l
= strlen (hostname
);
129 /* TODO: make better checking, that it is ip addresss */
131 if (hostname
[i
] == '.')
139 /* it is dns address */
141 target
= dns_cache_get (hostname
);
144 target
= dns_send_request (hostname
);
146 target
= net_proto_ip_convert (hostname
);
151 hostent
*host
= (hostent
*) kmalloc (sizeof (hostent
));
156 memset (host
, 0, sizeof (hostent
));
158 /* 4bytes - unsigned - for ipv4 */
161 host
->h_addr
= (char *) kmalloc (sizeof (char) * host
->h_length
);
168 memcpy (host
->h_addr
, &target
, host
->h_length
);
173 int connect (int fd
, sockaddr
*addr
, socklen_t len
)
175 DPRINT ("connect () -> socket: %d\n", fd
);
176 socket_t
*sock
= socket_getbyfd (fd
);
181 switch (sock
->protocol
) {
183 switch (sock
->family
) {
191 return net_proto_tcp_connect (fd
, (sockaddr_in
*) addr
);
193 return net_proto_tcp6_connect (fd
, (sockaddr_in6
*) addr
);
195 return ips_connect (fd
, addr
);
199 switch (sock
->family
) {
207 return net_proto_udp_connect (fd
, addr
);
209 return net_proto_udp6_connect (fd
, (sockaddr_in6
*) addr
);
220 int send (int fd
, char *msg
, size_t size
, int flags
)
222 socket_t
*sock
= socket_getbyfd (fd
);
227 DPRINT ("send (%d) -> %s\n", fd
, msg
);
229 switch (sock
->protocol
) {
231 switch (sock
->family
) {
239 return net_proto_tcp_send (fd
, msg
, size
);
241 return net_proto_tcp6_send (fd
, msg
, size
);
243 return ips_send (fd
, msg
, size
);
247 switch (sock
->family
) {
255 return net_proto_udp_send (fd
, msg
, size
);
257 return net_proto_udp6_send (fd
, msg
, size
);
268 int sendto (int fd
, const void *msg
, size_t len
, int flags
, sockaddr
*to
, socklen_t tolen
)
270 socket_t
*sock
= socket_getbyfd (fd
);
275 DPRINT ("sendto (%d) -> %s\n", fd
, msg
);
277 switch (sock
->protocol
) {
279 switch (sock
->family
) {
287 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
289 return -1; // net_proto_tcp6_sendto (fd, msg, len, to);
296 switch (sock
->family
) {
304 return net_proto_udp_sendto (fd
, msg
, len
, (sockaddr_in
*) to
);
306 return net_proto_udp6_sendto (fd
, msg
, len
, (sockaddr_in6
*) to
);
317 int recv (int fd
, char *msg
, size_t size
, int flags
)
319 socket_t
*sock
= socket_getbyfd (fd
);
324 DPRINT ("recv (%d)\n", fd
);
326 switch (sock
->protocol
) {
328 switch (sock
->family
) {
336 return net_proto_tcp_recv (fd
, msg
, size
);
338 return net_proto_tcp6_recv (fd
, msg
, size
);
340 return ips_recv (fd
, msg
, size
);
344 switch (sock
->family
) {
352 return net_proto_udp_recv (fd
, msg
, size
);
354 return net_proto_udp6_recv (fd
, msg
, size
);
365 int recvfrom (int fd
, char *msg
, size_t size
, int flags
, sockaddr
*from
, socklen_t fromlen
)
367 socket_t
*sock
= socket_getbyfd (fd
);
372 DPRINT ("recvfrom (%d)\n", fd
);
374 switch (sock
->protocol
) {
376 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);
393 switch (sock
->family
) {
401 return net_proto_udp_recvfrom (fd
, msg
, size
, (sockaddr_in
*) from
);
403 return net_proto_udp6_recvfrom (fd
, msg
, size
, (sockaddr_in6
*) from
);
414 int bind (int fd
, sockaddr
*addr
, socklen_t len
)
416 socket_t
*sock
= socket_getbyfd (fd
);
421 DPRINT ("bind (%d)\n", fd
);
423 switch (sock
->protocol
) {
425 switch (sock
->family
) {
433 return net_proto_tcp_bind (fd
, (sockaddr_in
*) addr
, len
);
435 return net_proto_tcp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
437 return ips_bind (fd
, addr
);
441 switch (sock
->family
) {
449 return net_proto_udp_bind (fd
, (sockaddr_in
*) addr
, len
);
451 return net_proto_udp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
461 int listen (int fd
, int backlog
)
463 socket_t
*sock
= socket_getbyfd (fd
);
468 DPRINT ("listen (%d)\n", fd
);
470 switch (sock
->family
) {
478 return net_proto_tcp_listen (fd
, backlog
);
480 return net_proto_tcp6_listen (fd
, backlog
);
482 return ips_listen (fd
, backlog
);
488 int accept (int fd
, sockaddr
*addr
, socklen_t
*addrlen
)
490 socket_t
*servsock
= socket_getbyfd (fd
);
495 DPRINT ("accept (%d)\n", fd
);
499 switch (servsock
->family
) {
507 client
= net_proto_tcp_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
510 client
= net_proto_tcp6_accept (fd
, (sockaddr_in6
*) addr
, addrlen
);
513 client
= ips_accept (fd
, addr
, addrlen
);
522 /* alloc and init context */
523 sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
527 sock
->family
= servsock
->family
;
528 sock
->type
= servsock
->type
;
529 sock
->protocol
= servsock
->protocol
;
532 sock
->next
= &socket_list
;
533 sock
->prev
= socket_list
.prev
;
534 sock
->prev
->next
= sock
;
535 sock
->next
->prev
= sock
;
537 fd_t
*fd_client
= (fd_t
*) kmalloc (sizeof (fd_t
));
539 fd_client
->flags
= FD_SOCK
;
540 fd_client
->id
= sock
->fd
;
542 fd_client
->next
= &fd_list
;
543 fd_client
->prev
= fd_list
.prev
;
544 fd_client
->prev
->next
= fd_client
;
545 fd_client
->next
->prev
= fd_client
;
552 socket_t
*sock
= socket_getbyfd (fd
);
557 DPRINT ("close (%d)\n", fd
);
559 switch (sock
->protocol
) {
561 switch (sock
->family
) {
569 return net_proto_tcp_close (fd
);
571 return net_proto_tcp6_close (fd
);
573 return ips_close (fd
);
577 switch (sock
->family
) {
585 return net_proto_udp_close (fd
);
587 return net_proto_udp6_close (fd
);
598 int sfcntl (int fd
, int cmd
, long arg
)
600 socket_t
*sock
= socket_getbyfd (fd
);
605 DPRINT ("fcntl (%d)\n", fd
);
607 switch (sock
->protocol
) {
609 switch (sock
->family
) {
617 return net_proto_tcp_fcntl (fd
, cmd
, arg
);
619 return net_proto_tcp6_fcntl (fd
, cmd
, arg
);
621 return ips_fcntl (fd
);
625 switch (sock
->family
) {
633 return net_proto_udp_fcntl (fd
, cmd
, arg
);
635 return net_proto_udp6_fcntl (fd
, cmd
, arg
);
645 unsigned int init_socket ()
647 socket_list
.next
= &socket_list
;
648 socket_list
.prev
= &socket_list
;