ZDE button.c - source code cleanup; ZDE cursor.c - improvement of mouse flags; ZDE...
[ZeXOS.git] / kernel / core / net / socket.c
blob52a69382ab9a315cfd21333114addf30182a2c06
1 /*
2 * ZeX/OS
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/>.
22 #include <system.h>
23 #include <string.h>
24 #include <net/socket.h>
25 #include <dev.h>
26 #include <task.h>
27 #include <fd.h>
29 socket_t socket_list;
31 extern task_t *_curr_task;
33 socket_t *socket_getbyfd (int fd)
35 socket_t *socket;
36 for (socket = socket_list.next; socket != &socket_list; socket = socket->next) {
37 if (socket->fd == fd)
38 return socket;
41 return 0;
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;
50 sock->type = type;
51 sock->protocol = protocol;
53 switch (sock->family) {
54 case AF_UNSPEC:
55 return -1;
56 case AF_UNIX:
57 sock->fd = net_proto_unix_socket ();
58 break;
59 case AF_INET:
60 switch (sock->protocol) {
61 case IPPROTO_TCP:
62 sock->fd = net_proto_tcp_socket ();
63 break;
64 case IPPROTO_UDP:
65 sock->fd = net_proto_udp_socket ();
66 break;
68 break;
69 case AF_INET6:
70 switch (sock->protocol) {
71 case IPPROTO_TCP:
72 sock->fd = net_proto_tcp6_socket ();
73 break;
74 case IPPROTO_UDP:
75 sock->fd = net_proto_udp6_socket ();
76 break;
78 break;
79 case AF_RS232:
80 sock->fd = ips_socket ();
81 break;
84 /* add into list */
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);
92 if (!fd)
93 return 0;
95 proc_t *proc = proc_find (_curr_task);
97 /* when it is process */
98 if (proc) {
99 if (proc->task != _curr_task)
100 return;
102 fd->proc = proc;
103 } else {
104 /* it is kernel socket */
105 fd->proc = 0;
108 return sock->fd;
111 hostent *gethostbyname (char *hostname)
113 unsigned i = 0;
114 unsigned g = 0;
115 unsigned l = strlen (hostname);
117 /* TODO: make better checking, that it is ip addresss */
118 while (i < l) {
119 if (hostname[i] == '.')
120 g ++;
122 i ++;
125 unsigned target = 0;
127 /* it is dns address */
128 if (g != 3) {
129 target = dns_cache_get (hostname);
131 if (!target)
132 target = dns_send_request (hostname);
133 } else
134 target = net_proto_ip_convert (hostname);
136 if (!target)
137 return 0;
139 hostent *host = (hostent *) kmalloc (sizeof (hostent));
141 if (!host)
142 return 0;
144 memset (host, 0, sizeof (hostent));
146 /* 4bytes - unsigned - for ipv4 */
147 host->h_length = 4;
149 host->h_addr = (char *) kmalloc (sizeof (char) * host->h_length);
151 if (!host->h_addr) {
152 kfree (host);
153 return 0;
156 memcpy (host->h_addr, &target, host->h_length);
158 return host;
161 int connect (int fd, sockaddr *addr, socklen_t len)
163 DPRINT ("connect () -> socket: %d\n", fd);
164 socket_t *sock = socket_getbyfd (fd);
166 if (!sock)
167 return -1;
169 switch (sock->family) {
170 case AF_UNSPEC:
171 return -1;
172 case AF_UNIX:
173 return net_proto_unix_connect (fd, addr);
174 case AF_INET:
175 switch (sock->protocol) {
176 case IPPROTO_TCP:
177 return net_proto_tcp_connect (fd, (sockaddr_in *) addr);
178 case IPPROTO_UDP:
179 return net_proto_udp_connect (fd, addr);
181 break;
182 case AF_INET6:
183 switch (sock->protocol) {
184 case IPPROTO_TCP:
185 return net_proto_tcp6_connect (fd, (sockaddr_in *) addr);
186 case IPPROTO_UDP:
187 return net_proto_udp6_connect (fd, (sockaddr_in6 *) addr);
189 break;
190 case AF_RS232:
191 return ips_connect (fd, addr);
194 return 0;
197 int send (int fd, char *msg, size_t size, int flags)
199 socket_t *sock = socket_getbyfd (fd);
201 if (!sock)
202 return -1;
204 DPRINT ("send (%d) -> %s\n", fd, msg);
206 switch (sock->family) {
207 case AF_UNSPEC:
208 return -1;
209 case AF_UNIX:
210 return net_proto_unix_send (fd, msg, size);
211 case AF_INET:
212 switch (sock->protocol) {
213 case IPPROTO_TCP:
214 return net_proto_tcp_send (fd, msg, size);
215 case IPPROTO_UDP:
216 return net_proto_udp_send (fd, msg, size);
218 break;
219 case AF_INET6:
220 switch (sock->protocol) {
221 case IPPROTO_TCP:
222 return net_proto_tcp6_send (fd, msg, size);
223 case IPPROTO_UDP:
224 return net_proto_udp6_send (fd, msg, size);
226 break;
227 case AF_RS232:
228 return ips_send (fd, msg, size);
231 return 0;
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);
238 if (!sock)
239 return -1;
241 DPRINT ("sendto (%d) -> %s\n", fd, msg);
243 switch (sock->protocol) {
244 case IPPROTO_TCP:
245 switch (sock->family) {
246 case AF_UNSPEC:
247 return -1;
248 case AF_UNIX:
249 return -1;
250 case AF_INET:
251 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
252 case AF_INET6:
253 return -1; // net_proto_tcp6_sendto (fd, msg, len, to);
254 case AF_RS232:
255 return -1;
257 break;
258 case IPPROTO_UDP:
259 switch (sock->family) {
260 case AF_UNSPEC:
261 return -1;
262 case AF_UNIX:
263 return -1;
264 case AF_INET:
265 return net_proto_udp_sendto (fd, msg, len, (sockaddr_in *) to);
266 case AF_INET6:
267 return net_proto_udp6_sendto (fd, msg, len, (sockaddr_in6 *) to);
268 case AF_RS232:
269 return -1;
271 break;
274 return 0;
277 int recv (int fd, char *msg, size_t size, int flags)
279 socket_t *sock = socket_getbyfd (fd);
281 if (!sock)
282 return -1;
284 DPRINT ("recv (%d)\n", fd);
286 switch (sock->family) {
287 case AF_UNSPEC:
288 return -1;
289 case AF_UNIX:
290 return net_proto_unix_recv (fd, msg, size);
291 case AF_INET:
292 switch (sock->protocol) {
293 case IPPROTO_TCP:
294 return net_proto_tcp_recv (fd, msg, size);
295 case IPPROTO_UDP:
296 return net_proto_udp_recv (fd, msg, size);
298 break;
299 case AF_INET6:
300 switch (sock->protocol) {
301 case IPPROTO_TCP:
302 return net_proto_tcp6_recv (fd, msg, size);
303 case IPPROTO_UDP:
304 return net_proto_udp6_recv (fd, msg, size);
306 break;
307 case AF_RS232:
308 return ips_recv (fd, msg, size);
311 return -1;
314 int recvfrom (int fd, char *msg, size_t size, int flags, sockaddr *from, socklen_t fromlen)
316 socket_t *sock = socket_getbyfd (fd);
318 if (!sock)
319 return -1;
321 DPRINT ("recvfrom (%d)\n", fd);
323 switch (sock->protocol) {
324 case IPPROTO_TCP:
325 switch (sock->family) {
326 case AF_UNSPEC:
327 return -1;
328 case AF_UNIX:
329 return -1;
330 case AF_INET:
331 return -1; //net_proto_tcp_recvfrom (fd, msg, size, from);
332 case AF_INET6:
333 return -1; //net_proto_tcp6_recvfrom (fd, msg, size, from);
334 case AF_RS232:
335 return -1;
337 break;
338 case IPPROTO_UDP:
339 switch (sock->family) {
340 case AF_UNSPEC:
341 return -1;
342 case AF_UNIX:
343 return -1;
344 case AF_INET:
345 return net_proto_udp_recvfrom (fd, msg, size, (sockaddr_in *) from);
346 case AF_INET6:
347 return net_proto_udp6_recvfrom (fd, msg, size, (sockaddr_in6 *) from);
348 case AF_RS232:
349 return -1;
351 break;
354 return -1;
357 int bind (int fd, sockaddr *addr, socklen_t len)
359 socket_t *sock = socket_getbyfd (fd);
361 if (!sock)
362 return -1;
364 DPRINT ("bind (%d)\n", fd);
366 switch (sock->family) {
367 case AF_UNSPEC:
368 return -1;
369 case AF_UNIX:
370 return net_proto_unix_bind (fd, (sockaddr_in *) addr, len);
371 case AF_INET:
372 switch (sock->protocol) {
373 case IPPROTO_TCP:
374 return net_proto_tcp_bind (fd, (sockaddr_in *) addr, len);
375 case IPPROTO_UDP:
376 return net_proto_udp_bind (fd, (sockaddr_in *) addr, len);
378 break;
379 case AF_INET6:
380 switch (sock->protocol) {
381 case IPPROTO_TCP:
382 return net_proto_tcp6_bind (fd, (sockaddr_in6 *) addr, len);
383 case IPPROTO_UDP:
384 return net_proto_udp6_bind (fd, (sockaddr_in6 *) addr, len);
386 break;
387 case AF_RS232:
388 return ips_bind (fd, addr);
391 return -1;
394 int listen (int fd, int backlog)
396 socket_t *sock = socket_getbyfd (fd);
398 if (!sock)
399 return -1;
401 DPRINT ("listen (%d)\n", fd);
403 switch (sock->family) {
404 case AF_UNSPEC:
406 return -1;
407 case AF_UNIX:
408 return net_proto_unix_listen (fd, backlog);
409 case AF_INET:
410 return net_proto_tcp_listen (fd, backlog);
411 case AF_INET6:
412 return net_proto_tcp6_listen (fd, backlog);
413 case AF_RS232:
414 return ips_listen (fd, backlog);
417 return -1;
420 int accept (int fd, sockaddr *addr, socklen_t *addrlen)
422 socket_t *servsock = socket_getbyfd (fd);
424 if (!servsock)
425 return -1;
427 DPRINT ("accept (%d)\n", fd);
429 int client = 0;
431 switch (servsock->family) {
432 case AF_UNSPEC:
434 return -1;
435 case AF_UNIX:
436 client = net_proto_unix_accept (fd, (sockaddr_in *) addr, addrlen);
437 break;
438 case AF_INET:
439 client = net_proto_tcp_accept (fd, (sockaddr_in *) addr, addrlen);
440 break;
441 case AF_INET6:
442 client = net_proto_tcp6_accept (fd, (sockaddr_in6 *) addr, addrlen);
443 break;
444 case AF_RS232:
445 client = ips_accept (fd, addr, addrlen);
446 break;
449 if (client <= 0)
450 return client;
452 socket_t *sock;
454 /* alloc and init context */
455 sock = (socket_t *) kmalloc (sizeof (socket_t));
457 fd_count ++;
458 sock->fd = client;
459 sock->family = servsock->family;
460 sock->type = servsock->type;
461 sock->protocol = servsock->protocol;
463 /* add into list */
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;
479 return client;
482 int sclose (int fd)
484 socket_t *sock = socket_getbyfd (fd);
486 if (!sock)
487 return -1;
489 DPRINT ("close (%d)\n", fd);
491 switch (sock->family) {
492 case AF_UNSPEC:
493 return -1;
494 case AF_UNIX:
495 return net_proto_unix_close (fd);
496 case AF_INET:
497 switch (sock->protocol) {
498 case IPPROTO_TCP:
499 return net_proto_tcp_close (fd);
500 case IPPROTO_UDP:
501 return net_proto_udp_close (fd);
503 break;
504 case AF_INET6:
505 switch (sock->protocol) {
506 case IPPROTO_TCP:
507 return net_proto_tcp6_close (fd);
508 case IPPROTO_UDP:
509 return net_proto_udp6_close (fd);
511 break;
512 case AF_RS232:
513 return ips_close (fd);
516 return -1;
519 int sfcntl (int fd, int cmd, long arg)
521 socket_t *sock = socket_getbyfd (fd);
523 if (!sock)
524 return -1;
526 DPRINT ("fcntl (%d)\n", fd);
528 switch (sock->family) {
529 case AF_UNSPEC:
530 return -1;
531 case AF_UNIX:
532 return net_proto_unix_fcntl (fd, cmd, arg);
533 case AF_INET:
534 switch (sock->protocol) {
535 case IPPROTO_TCP:
536 return net_proto_tcp_fcntl (fd, cmd, arg);
537 case IPPROTO_UDP:
538 return net_proto_udp_fcntl (fd, cmd, arg);
540 break;
541 case AF_INET6:
542 switch (sock->protocol) {
543 case IPPROTO_TCP:
544 return net_proto_tcp6_fcntl (fd, cmd, arg);
545 case IPPROTO_UDP:
546 return net_proto_udp6_fcntl (fd, cmd, arg);
548 break;
549 case AF_RS232:
550 return ips_fcntl (fd);
553 return -1;
556 unsigned int init_socket ()
558 socket_list.next = &socket_list;
559 socket_list.prev = &socket_list;
561 fd_count = 3;
563 return 1;