3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
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/>.
24 #include <net/socket.h>
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
)
46 /* alloc and init context */
47 socket_t
*sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
49 sock
->family
= family
;
51 sock
->protocol
= protocol
;
53 switch (sock
->family
) {
57 sock
->fd
= net_proto_unix_socket ();
60 switch (sock
->protocol
) {
62 sock
->fd
= net_proto_tcp_socket ();
65 sock
->fd
= net_proto_udp_socket ();
70 switch (sock
->protocol
) {
72 sock
->fd
= net_proto_tcp6_socket ();
75 sock
->fd
= net_proto_udp6_socket ();
80 sock
->fd
= ips_socket ();
85 sock
->next
= &socket_list
;
86 sock
->prev
= socket_list
.prev
;
87 sock
->prev
->next
= sock
;
88 sock
->next
->prev
= sock
;
90 fd_t
*fd
= fd_create (sock
->fd
, FD_SOCK
);
95 proc_t
*proc
= proc_find (_curr_task
);
97 /* when it is process */
99 if (proc
->task
!= _curr_task
)
104 /* it is kernel socket */
111 hostent
*gethostbyname (char *hostname
)
115 unsigned l
= strlen (hostname
);
117 /* TODO: make better checking, that it is ip addresss */
119 if (hostname
[i
] == '.')
127 /* it is dns address */
129 target
= dns_cache_get (hostname
);
132 target
= dns_send_request (hostname
);
134 target
= net_proto_ip_convert (hostname
);
139 hostent
*host
= (hostent
*) kmalloc (sizeof (hostent
));
144 memset (host
, 0, sizeof (hostent
));
146 /* 4bytes - unsigned - for ipv4 */
149 host
->h_addr
= (char *) kmalloc (sizeof (char) * host
->h_length
);
156 memcpy (host
->h_addr
, &target
, host
->h_length
);
161 int connect (int fd
, sockaddr
*addr
, socklen_t len
)
163 DPRINT ("connect () -> socket: %d\n", fd
);
164 socket_t
*sock
= socket_getbyfd (fd
);
169 switch (sock
->family
) {
173 return net_proto_unix_connect (fd
, addr
);
175 switch (sock
->protocol
) {
177 return net_proto_tcp_connect (fd
, (sockaddr_in
*) addr
);
179 return net_proto_udp_connect (fd
, addr
);
183 switch (sock
->protocol
) {
185 return net_proto_tcp6_connect (fd
, (sockaddr_in
*) addr
);
187 return net_proto_udp6_connect (fd
, (sockaddr_in6
*) addr
);
191 return ips_connect (fd
, addr
);
197 int send (int fd
, char *msg
, size_t size
, int flags
)
199 socket_t
*sock
= socket_getbyfd (fd
);
204 DPRINT ("send (%d) -> %s\n", fd
, msg
);
206 switch (sock
->family
) {
210 return net_proto_unix_send (fd
, msg
, size
);
212 switch (sock
->protocol
) {
214 return net_proto_tcp_send (fd
, msg
, size
);
216 return net_proto_udp_send (fd
, msg
, size
);
220 switch (sock
->protocol
) {
222 return net_proto_tcp6_send (fd
, msg
, size
);
224 return net_proto_udp6_send (fd
, msg
, size
);
228 return ips_send (fd
, msg
, size
);
234 int sendto (int fd
, const void *msg
, size_t len
, int flags
, sockaddr
*to
, socklen_t tolen
)
236 socket_t
*sock
= socket_getbyfd (fd
);
241 DPRINT ("sendto (%d) -> %s\n", fd
, msg
);
243 switch (sock
->protocol
) {
245 switch (sock
->family
) {
251 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
253 return -1; // net_proto_tcp6_sendto (fd, msg, len, to);
259 switch (sock
->family
) {
265 return net_proto_udp_sendto (fd
, msg
, len
, (sockaddr_in
*) to
);
267 return net_proto_udp6_sendto (fd
, msg
, len
, (sockaddr_in6
*) to
);
277 int recv (int fd
, char *msg
, size_t size
, int flags
)
279 socket_t
*sock
= socket_getbyfd (fd
);
284 DPRINT ("recv (%d)\n", fd
);
286 switch (sock
->family
) {
290 return net_proto_unix_recv (fd
, msg
, size
);
292 switch (sock
->protocol
) {
294 return net_proto_tcp_recv (fd
, msg
, size
);
296 return net_proto_udp_recv (fd
, msg
, size
);
300 switch (sock
->protocol
) {
302 return net_proto_tcp6_recv (fd
, msg
, size
);
304 return net_proto_udp6_recv (fd
, msg
, size
);
308 return ips_recv (fd
, msg
, size
);
314 int recvfrom (int fd
, char *msg
, size_t size
, int flags
, sockaddr
*from
, socklen_t fromlen
)
316 socket_t
*sock
= socket_getbyfd (fd
);
321 DPRINT ("recvfrom (%d)\n", fd
);
323 switch (sock
->protocol
) {
325 switch (sock
->family
) {
331 return -1; //net_proto_tcp_recvfrom (fd, msg, size, from);
333 return -1; //net_proto_tcp6_recvfrom (fd, msg, size, from);
339 switch (sock
->family
) {
345 return net_proto_udp_recvfrom (fd
, msg
, size
, (sockaddr_in
*) from
);
347 return net_proto_udp6_recvfrom (fd
, msg
, size
, (sockaddr_in6
*) from
);
357 int bind (int fd
, sockaddr
*addr
, socklen_t len
)
359 socket_t
*sock
= socket_getbyfd (fd
);
364 DPRINT ("bind (%d)\n", fd
);
366 switch (sock
->family
) {
370 return net_proto_unix_bind (fd
, (sockaddr_in
*) addr
, len
);
372 switch (sock
->protocol
) {
374 return net_proto_tcp_bind (fd
, (sockaddr_in
*) addr
, len
);
376 return net_proto_udp_bind (fd
, (sockaddr_in
*) addr
, len
);
380 switch (sock
->protocol
) {
382 return net_proto_tcp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
384 return net_proto_udp6_bind (fd
, (sockaddr_in6
*) addr
, len
);
388 return ips_bind (fd
, addr
);
394 int listen (int fd
, int backlog
)
396 socket_t
*sock
= socket_getbyfd (fd
);
401 DPRINT ("listen (%d)\n", fd
);
403 switch (sock
->family
) {
408 return net_proto_unix_listen (fd
, backlog
);
410 return net_proto_tcp_listen (fd
, backlog
);
412 return net_proto_tcp6_listen (fd
, backlog
);
414 return ips_listen (fd
, backlog
);
420 int accept (int fd
, sockaddr
*addr
, socklen_t
*addrlen
)
422 socket_t
*servsock
= socket_getbyfd (fd
);
427 DPRINT ("accept (%d)\n", fd
);
431 switch (servsock
->family
) {
436 client
= net_proto_unix_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
439 client
= net_proto_tcp_accept (fd
, (sockaddr_in
*) addr
, addrlen
);
442 client
= net_proto_tcp6_accept (fd
, (sockaddr_in6
*) addr
, addrlen
);
445 client
= ips_accept (fd
, addr
, addrlen
);
454 /* alloc and init context */
455 sock
= (socket_t
*) kmalloc (sizeof (socket_t
));
459 sock
->family
= servsock
->family
;
460 sock
->type
= servsock
->type
;
461 sock
->protocol
= servsock
->protocol
;
464 sock
->next
= &socket_list
;
465 sock
->prev
= socket_list
.prev
;
466 sock
->prev
->next
= sock
;
467 sock
->next
->prev
= sock
;
469 fd_t
*fd_client
= (fd_t
*) kmalloc (sizeof (fd_t
));
471 fd_client
->flags
= FD_SOCK
;
472 fd_client
->id
= sock
->fd
;
474 fd_client
->next
= &fd_list
;
475 fd_client
->prev
= fd_list
.prev
;
476 fd_client
->prev
->next
= fd_client
;
477 fd_client
->next
->prev
= fd_client
;
484 socket_t
*sock
= socket_getbyfd (fd
);
489 DPRINT ("close (%d)\n", fd
);
491 switch (sock
->family
) {
495 return net_proto_unix_close (fd
);
497 switch (sock
->protocol
) {
499 return net_proto_tcp_close (fd
);
501 return net_proto_udp_close (fd
);
505 switch (sock
->protocol
) {
507 return net_proto_tcp6_close (fd
);
509 return net_proto_udp6_close (fd
);
513 return ips_close (fd
);
519 int sfcntl (int fd
, int cmd
, long arg
)
521 socket_t
*sock
= socket_getbyfd (fd
);
526 DPRINT ("fcntl (%d)\n", fd
);
528 switch (sock
->family
) {
532 return net_proto_unix_fcntl (fd
, cmd
, arg
);
534 switch (sock
->protocol
) {
536 return net_proto_tcp_fcntl (fd
, cmd
, arg
);
538 return net_proto_udp_fcntl (fd
, cmd
, arg
);
542 switch (sock
->protocol
) {
544 return net_proto_tcp6_fcntl (fd
, cmd
, arg
);
546 return net_proto_udp6_fcntl (fd
, cmd
, arg
);
550 return ips_fcntl (fd
);
556 unsigned int init_socket ()
558 socket_list
.next
= &socket_list
;
559 socket_list
.prev
= &socket_list
;