Kernel 0.5.9-r12; UDP protocol stuff support server with sendto
[ZeXOS.git] / kernel / core / net / socket.c
blob14d5969e71cfd73d850c543742ce6f93131896b6
1 /*
2 * ZeX/OS
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/>.
21 #include <system.h>
22 #include <string.h>
23 #include <net/socket.h>
24 #include <dev.h>
26 socket_t socket_list;
28 extern fd_t fd_list;
29 extern unsigned int fd_count;
31 socket_t *socket_getbyfd (int fd)
33 socket_t *socket;
34 for (socket = socket_list.next; socket != &socket_list; socket = socket->next) {
35 if (socket->fd == fd)
36 return socket;
39 return 0;
42 int socket (int family, int type, int protocol)
44 socket_t *sock;
46 /* alloc and init context */
47 sock = (socket_t *) kmalloc (sizeof (socket_t));
49 sock->fd = fd_count ++;
50 sock->family = family;
51 sock->type = type;
52 sock->protocol = protocol;
54 switch (sock->protocol) {
55 case IPPROTO_TCP:
56 switch (sock->family) {
57 case AF_UNSPEC:
58 return -1;
59 case AF_UNIX:
61 return -1;
62 case AF_INET:
63 sock->fd = net_proto_tcp_socket ();
64 break;
65 case AF_RS232:
66 sock->fd = ips_socket ();
67 break;
69 break;
70 case IPPROTO_UDP:
71 switch (sock->family) {
72 case AF_UNSPEC:
73 return -1;
74 case AF_UNIX:
76 return -1;
77 case AF_INET:
78 sock->fd = net_proto_udp_socket ();
79 break;
80 case AF_RS232:
81 return -1;
83 break;
86 /* add into list */
87 sock->next = &socket_list;
88 sock->prev = socket_list.prev;
89 sock->prev->next = sock;
90 sock->next->prev = sock;
92 fd_t *fd = (fd_t *) kmalloc (sizeof (fd_t));
94 fd->flags = FD_SOCK;
95 fd->id = sock->fd;
97 fd->next = &fd_list;
98 fd->prev = fd_list.prev;
99 fd->prev->next = fd;
100 fd->next->prev = fd;
102 return sock->fd;
105 hostent *gethostbyname (char *hostname)
107 unsigned i = 0;
108 unsigned g = 0;
109 unsigned l = strlen (hostname);
111 /* TODO: make better checking, that it is ip addresss */
112 while (i < l) {
113 if (hostname[i] == '.')
114 g ++;
116 i ++;
119 unsigned target = 0;
121 /* it is dns address */
122 if (g != 3) {
123 target = dns_cache_get (hostname);
125 if (!target)
126 target = dns_send_request (hostname);
127 } else
128 target = net_proto_ip_convert (hostname);
130 if (!target)
131 return 0;
133 hostent *host = (hostent *) kmalloc (sizeof (hostent));
135 if (!host)
136 return 0;
138 memset (host, 0, sizeof (hostent));
140 /* 4bytes - unsigned - for ipv4 */
141 host->h_length = 4;
143 host->h_addr = (char *) kmalloc (sizeof (char) * host->h_length);
145 if (!host->h_addr) {
146 kfree (host);
147 return 0;
150 memcpy (host->h_addr, &target, host->h_length);
152 return host;
155 int connect (int fd, sockaddr_in *addr, socklen_t len)
157 DPRINT ("connect () -> socket: %d\n", fd);
158 socket_t *sock = socket_getbyfd (fd);
160 if (!sock)
161 return -1;
163 switch (sock->protocol) {
164 case IPPROTO_TCP:
165 switch (sock->family) {
166 case AF_UNSPEC:
168 return -1;
169 case AF_UNIX:
171 return -1;
172 case AF_INET:
173 return net_proto_tcp_connect (fd, addr);
174 case AF_RS232:
175 return ips_connect (fd, addr);
177 break;
178 case IPPROTO_UDP:
179 switch (sock->family) {
180 case AF_UNSPEC:
182 return -1;
183 case AF_UNIX:
185 return -1;
186 case AF_INET:
187 return net_proto_udp_connect (fd, addr);
188 case AF_RS232:
190 return -1;
192 break;
195 return 1;
198 int send (int fd, char *msg, size_t size, int flags)
200 socket_t *sock = socket_getbyfd (fd);
202 if (!sock)
203 return -1;
205 DPRINT ("send (%d) -> %s\n", fd, msg);
207 switch (sock->protocol) {
208 case IPPROTO_TCP:
209 switch (sock->family) {
210 case AF_UNSPEC:
212 return -1;
213 case AF_UNIX:
215 return -1;
216 case AF_INET:
217 return net_proto_tcp_send (fd, msg, size);
218 case AF_RS232:
219 return ips_send (fd, msg, size);
221 break;
222 case IPPROTO_UDP:
223 switch (sock->family) {
224 case AF_UNSPEC:
226 return -1;
227 case AF_UNIX:
229 return -1;
230 case AF_INET:
231 return net_proto_udp_send (fd, msg, size);
232 case AF_RS232:
234 return -1;
236 break;
239 return 1;
242 int sendto (int fd, const void *msg, size_t len, int flags, sockaddr_in *to, socklen_t tolen)
244 socket_t *sock = socket_getbyfd (fd);
246 if (!sock)
247 return -1;
249 DPRINT ("sendto (%d) -> %s\n", fd, msg);
251 switch (sock->protocol) {
252 case IPPROTO_TCP:
253 switch (sock->family) {
254 case AF_UNSPEC:
256 return -1;
257 case AF_UNIX:
259 return -1;
260 case AF_INET:
261 return -1; // net_proto_tcp_sendto (fd, msg, len, to);
262 case AF_RS232:
264 return -1;
266 break;
267 case IPPROTO_UDP:
268 switch (sock->family) {
269 case AF_UNSPEC:
271 return -1;
272 case AF_UNIX:
274 return -1;
275 case AF_INET:
276 return net_proto_udp_sendto (fd, msg, len, to);
277 case AF_RS232:
279 return -1;
281 break;
284 return 1;
287 int recv (int fd, char *msg, size_t size, int flags)
289 socket_t *sock = socket_getbyfd (fd);
291 if (!sock)
292 return -1;
294 DPRINT ("recv (%d)\n", fd);
296 switch (sock->protocol) {
297 case IPPROTO_TCP:
298 switch (sock->family) {
299 case AF_UNSPEC:
301 return -1;
302 case AF_UNIX:
304 return -1;
305 case AF_INET:
306 return net_proto_tcp_recv (fd, msg, size);
307 case AF_RS232:
308 return ips_recv (fd, msg, size);
310 break;
311 case IPPROTO_UDP:
312 switch (sock->family) {
313 case AF_UNSPEC:
315 return -1;
316 case AF_UNIX:
318 return -1;
319 case AF_INET:
320 return net_proto_udp_recv (fd, msg, size);
321 case AF_RS232:
323 return -1;
325 break;
328 return 1;
331 int recvfrom (int fd, char *msg, size_t size, int flags, sockaddr_in *from, socklen_t fromlen)
333 socket_t *sock = socket_getbyfd (fd);
335 if (!sock)
336 return -1;
338 DPRINT ("recvfrom (%d)\n", fd);
340 switch (sock->protocol) {
341 case IPPROTO_TCP:
342 switch (sock->family) {
343 case AF_UNSPEC:
345 return -1;
346 case AF_UNIX:
348 return -1;
349 case AF_INET:
351 return -1; //net_proto_tcp_recvfrom (fd, msg, size, from);
352 case AF_RS232:
354 return -1;
356 break;
357 case IPPROTO_UDP:
358 switch (sock->family) {
359 case AF_UNSPEC:
361 return -1;
362 case AF_UNIX:
364 return -1;
365 case AF_INET:
366 return net_proto_udp_recvfrom (fd, msg, size, from);
367 case AF_RS232:
369 return -1;
371 break;
374 return 1;
377 int bind (int fd, sockaddr_in *addr, socklen_t len)
379 socket_t *sock = socket_getbyfd (fd);
381 if (!sock)
382 return -1;
384 DPRINT ("bind (%d)\n", fd);
386 switch (sock->protocol) {
387 case IPPROTO_TCP:
388 switch (sock->family) {
389 case AF_UNSPEC:
391 return -1;
392 case AF_UNIX:
394 return -1;
395 case AF_INET:
396 return net_proto_tcp_bind (fd, addr, len);
397 case AF_RS232:
398 return ips_bind (fd, addr);
400 break;
401 case IPPROTO_UDP:
402 switch (sock->family) {
403 case AF_UNSPEC:
405 return -1;
406 case AF_UNIX:
408 return -1;
409 case AF_INET:
410 return net_proto_udp_bind (fd, addr, len);
411 case AF_RS232:
412 return -1;
414 break;
417 return 1;
420 int listen (int fd, int backlog)
422 socket_t *sock = socket_getbyfd (fd);
424 if (!sock)
425 return -1;
427 DPRINT ("listen (%d)\n", fd);
429 switch (sock->family) {
430 case AF_UNSPEC:
432 return -1;
433 case AF_UNIX:
435 return -1;
436 case AF_INET:
437 return net_proto_tcp_listen (fd, backlog);
438 case AF_RS232:
439 return ips_listen (fd, backlog);
442 return 1;
445 int accept (int fd, sockaddr_in *addr, socklen_t *addrlen)
447 socket_t *servsock = socket_getbyfd (fd);
449 if (!servsock)
450 return -1;
452 DPRINT ("accept (%d)\n", fd);
454 int client = 0;
456 switch (servsock->family) {
457 case AF_UNSPEC:
459 return -1;
460 case AF_UNIX:
462 return -1;
463 case AF_INET:
464 client = net_proto_tcp_accept (fd, addr, addrlen);
465 break;
466 case AF_RS232:
467 client = ips_accept (fd, addr, addrlen);
468 break;
471 if (client <= 0)
472 return client;
474 socket_t *sock;
476 /* alloc and init context */
477 sock = (socket_t *) kmalloc (sizeof (socket_t));
479 fd_count ++;
480 sock->fd = client;
481 sock->family = servsock->family;
482 sock->type = servsock->type;
483 sock->protocol = servsock->protocol;
485 /* add into list */
486 sock->next = &socket_list;
487 sock->prev = socket_list.prev;
488 sock->prev->next = sock;
489 sock->next->prev = sock;
491 fd_t *fd_client = (fd_t *) kmalloc (sizeof (fd_t));
493 fd_client->flags = FD_SOCK;
494 fd_client->id = sock->fd;
496 fd_client->next = &fd_list;
497 fd_client->prev = fd_list.prev;
498 fd_client->prev->next = fd_client;
499 fd_client->next->prev = fd_client;
501 return client;
504 int sclose (int fd)
506 socket_t *sock = socket_getbyfd (fd);
508 if (!sock)
509 return -1;
511 DPRINT ("close (%d)\n", fd);
513 switch (sock->protocol) {
514 case IPPROTO_TCP:
515 switch (sock->family) {
516 case AF_UNSPEC:
518 return -1;
519 case AF_UNIX:
521 return -1;
522 case AF_INET:
523 return net_proto_tcp_close (fd);
524 case AF_RS232:
525 return ips_close (fd);
527 break;
528 case IPPROTO_UDP:
529 switch (sock->family) {
530 case AF_UNSPEC:
532 return -1;
533 case AF_UNIX:
535 return -1;
536 case AF_INET:
537 return net_proto_udp_close (fd);
538 case AF_RS232:
540 return -1;
542 break;
545 return 1;
548 int sfcntl (int fd, int cmd, long arg)
550 socket_t *sock = socket_getbyfd (fd);
552 if (!sock)
553 return -1;
555 DPRINT ("fcntl (%d)\n", fd);
557 switch (sock->family) {
558 case AF_UNSPEC:
560 return -1;
561 case AF_UNIX:
563 return -1;
564 case AF_INET:
565 return net_proto_tcp_fcntl (fd, cmd, arg);
566 case AF_RS232:
567 return ips_fcntl (fd);
571 unsigned int init_socket ()
573 socket_list.next = &socket_list;
574 socket_list.prev = &socket_list;
576 fd_count = 0;
578 return 1;