From 62bd7c9b14d51eb6414a34e742401d1c59fedd2c Mon Sep 17 00:00:00 2001 From: Tomas 'ZeXx86' Jedrzejek Date: Tue, 30 Mar 2010 20:04:05 +0200 Subject: [PATCH] Fixed buffer overflow in mserver; fixed type of checkinfo () 2nd parameter; memory allocator kzmem was updated; memory allocator usermem was updated and improved; network stack was rewrited for preallocated buffers instead allocating new buffers all time - performance boost; small improvements and bug fixes in network stack - especially TCP protocol; implemented MTU support into network stack; small security improvements in scheduler; GMM and ZeXFS, ISOFS filesystems is enabled by default; added new sort of libc functions; fixed sscanf () libc function; port of DC++ hubsoft LamaHub --- apps/mserver/main.c | 2 +- kernel/arch/i386/paging.c | 5 +- kernel/core/init.c | 4 +- kernel/core/mm/kzmem.c | 33 +++++---- kernel/core/mm/usermem.c | 18 +++-- kernel/core/net/checksum.c | 18 ++--- kernel/core/net/ip.c | 12 ++-- kernel/core/net/packet.c | 7 +- kernel/core/net/socket.c | 4 +- kernel/core/net/tcp.c | 64 ++++++++++++----- kernel/core/net/tcp6.c | 49 +++++++++---- kernel/core/net/udp.c | 107 ++++++++++++++++++++-------- kernel/core/net/udp6.c | 54 +++++++------- kernel/core/sched.c | 14 ++-- kernel/core/smp.c | 28 ++++---- kernel/drivers/Kconfig | 6 +- kernel/include/net/ip.h | 1 - kernel/include/net/packet.h | 5 +- kernel/include/net/udp.h | 5 ++ kernel/include/paging.h | 4 +- kernel/lib/sys/select.c | 14 ++-- libc/Makefile | 6 +- libc/include/arpa/inet.h | 7 +- libc/include/stdlib.h | 3 + libc/include/string.h | 2 + libc/include/unistd.h | 1 + libc/socket/{htons.c => htonl.c} | 18 +++-- libc/socket/htons.c | 5 +- libc/socket/{inet_ntoa.c => inet_aton.c} | 16 ++--- libc/socket/inet_ntoa.c | 1 - libc/socket/{htons.c => ntohl.c} | 18 +++-- libc/socket/{htons.c => ntohs.c} | 8 +-- libc/stdio/dosscanf.c | 28 +++++--- libc/{socket/inet_ntoa.c => stdlib/atol.c} | 40 ++++++----- libc/{socket/inet_ntoa.c => stdlib/atoll.c} | 40 ++++++----- libc/string/memset.c | 13 ++-- libc/{socket/htons.c => string/strtok.c} | 33 ++++++--- 37 files changed, 440 insertions(+), 253 deletions(-) copy libc/socket/{htons.c => htonl.c} (72%) copy libc/socket/{inet_ntoa.c => inet_aton.c} (80%) copy libc/socket/{htons.c => ntohl.c} (72%) copy libc/socket/{htons.c => ntohs.c} (83%) copy libc/{socket/inet_ntoa.c => stdlib/atol.c} (54%) copy libc/{socket/inet_ntoa.c => stdlib/atoll.c} (54%) copy libc/{socket/htons.c => string/strtok.c} (63%) diff --git a/apps/mserver/main.c b/apps/mserver/main.c index 262dbfb..5297c91 100644 --- a/apps/mserver/main.c +++ b/apps/mserver/main.c @@ -120,7 +120,7 @@ int mserver_handle (client_t *c) return 0; char str[80]; - int r = recv (c->fd, str, 80, 0); + int r = recv (c->fd, str, 79, 0); if (r > 0) { str[r] = '\0'; diff --git a/kernel/arch/i386/paging.c b/kernel/arch/i386/paging.c index 9b86d5b..c288b34 100644 --- a/kernel/arch/i386/paging.c +++ b/kernel/arch/i386/paging.c @@ -3,6 +3,7 @@ * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +27,6 @@ #include #include -extern unsigned *code, *bss, *data, *end; - // A bitset of frames - used or free. static unsigned page_nframes; @@ -317,7 +316,7 @@ unsigned int init_paging () #ifdef CONFIG_MEM_PAGING // The size of physical memory. mem_end_page = mem_ext * 1024 * 1024; - + page_nframes = mem_end_page / 0x1000; #endif diff --git a/kernel/core/init.c b/kernel/core/init.c index 8594291..093c708 100644 --- a/kernel/core/init.c +++ b/kernel/core/init.c @@ -92,7 +92,7 @@ void oscmd (char *cmdline) } /* Eye-candy status */ -unsigned int checkinfo (char *msg, int ret) +unsigned int checkinfo (char *msg, unsigned int ret) { if (msg == NULL) return 2; @@ -153,7 +153,7 @@ int init (char *cmdline) _init (&init_errno, "Initialize errno"); /* Errno global variable */ _init (&init_env, "Initialize env vars"); /* Environment variables */ _init (&init_fd, "Initialize file desc"); /* File descriptors - stdin, stdout, .. */ - _init (&init_tasks, "Initialize tasks"); /* Thread and scheduler stuff */ + _init (&init_tasks, "Initialize tasks"); /* Thread and scheduler stuff */ _init (&init_vfs, "Initialize VFS"); /* Virtual filesystem */ _init (&init_fs, "Initialize fs"); /* Device filesystem */ _init (&init_partition, "Initialize parts"); /* Device partitions - hda0, hda1, .. */ diff --git a/kernel/core/mm/kzmem.c b/kernel/core/mm/kzmem.c index 67a776d..aa9f37e 100644 --- a/kernel/core/mm/kzmem.c +++ b/kernel/core/mm/kzmem.c @@ -60,7 +60,6 @@ void *kmalloc (size_t size) mutex_lock (&mutex_malloc); -DPRINT ("size: %d\n", size); unsigned malloc_len = sizeof (malloc_t); /* check malloc structure size */ unsigned need_alloc = 0; @@ -68,25 +67,25 @@ DPRINT ("size: %d\n", size); malloc_t *malloc = (malloc_t *) heap->first; - while (1) { + for (;;) { malloc = (malloc_t *) malloc->next; //DPRINT ("malloc: 0x%x\n", malloc); if (!malloc) { - DPRINT ("!malloc\n"); + DPRINT (DBG_MM | DBG_KMEM, "!malloc"); need_alloc = 1; break; } if (malloc->magic != KMEM_MALLOC_MAGIC) { - DPRINT ("malloc->magic != KMEM_MALLOC_MAGIC\n"); + DPRINT (DBG_MM | DBG_KMEM, "malloc->magic != KMEM_MALLOC_MAGIC"); need_alloc = 1; break; } if (malloc->state == KMEM_MALLOC_STATE_USED) { /* It's OK */ - //DPRINT ("malloc->state == KMEM_MALLOC_STATE_USED\n"); + //DPRINT ("DBG_MM | DBG_KMEM, malloc->state == KMEM_MALLOC_STATE_USED"); //need_alloc = 1; continue; } @@ -96,14 +95,14 @@ DPRINT ("size: %d\n", size); /* read next malloc structure, right behind free block */ malloc_t *next = (malloc_t *) malloc; - DPRINT ("malloc->state == KMEM_MALLOC_STATE_FREE\n"); + DPRINT (DBG_MM | DBG_KMEM, "malloc->state == KMEM_MALLOC_STATE_FREE"); while (1) { //kprintf ("hhhe\n"); next = (malloc_t *) next->next; if (next->magic != KMEM_MALLOC_MAGIC) { - DPRINT ("next->magic != KMEM_MALLOC_MAGIC\n"); + DPRINT (DBG_MM | DBG_KMEM, "next->magic != KMEM_MALLOC_MAGIC"); need_alloc = 1; break; } @@ -120,7 +119,7 @@ DPRINT ("size: %d\n", size); unsigned diff = (unsigned) ((void *) next - (void *) malloc); - DPRINT ("diff: %d\n", diff); + DPRINT (DBG_MM | DBG_KMEM, "diff: %d", diff); if (diff < size) continue; @@ -146,7 +145,7 @@ DPRINT ("size: %d\n", size); if ((unsigned) heap->curr > (unsigned) heap->last) heap->last = heap->curr; - DPRINT ("malloc: 0x%x\n", malloc); + DPRINT (DBG_MM | DBG_KMEM, "malloc: 0x%x", malloc); //kprintf ("kmalloc: 0x%x : %d\n", ((void *) malloc + malloc_len), size); @@ -164,7 +163,7 @@ void kfree (void *ptr) { if (!ptr) return; - + mutex_lock (&mutex_free); /* we need find malloc structure - it could be risk working with lower memory address */ @@ -194,15 +193,15 @@ void kfree (void *ptr) unsigned kmem_init () { - heap = (heap_t *) KMEM_HEAP_ADDR; + heap = (heap_t *) KMEM_HEAP_ADDR; - /* we rather clear heap structure */ - heap->addr = (void *) heap; - heap->first = (void *) ((void *) heap + sizeof (heap_t)); /* first malloc structure should be right behind heap structure */ - heap->last = heap->first; /* last malloc structure - it is first at init */ - heap->curr = heap->first; /* point to first malloc structure - well, it is clear and not used yet */ + /* we rather clear heap structure */ + heap->addr = (void *) heap; + heap->first = (void *) ((void *) heap + sizeof (heap_t)); /* first malloc structure should be right behind heap structure */ + heap->last = heap->first; /* last malloc structure - it is first at init */ + heap->curr = heap->first; /* point to first malloc structure - well, it is clear and not used yet */ - return 1; + return 1; } diff --git a/kernel/core/mm/usermem.c b/kernel/core/mm/usermem.c index 21683ec..fee8468 100644 --- a/kernel/core/mm/usermem.c +++ b/kernel/core/mm/usermem.c @@ -212,9 +212,17 @@ end: void *urealloc (proc_t *proc, void *ptr, size_t size) { - if (!ptr || !proc) + if (!proc) return 0; + if (!ptr) + return umalloc (proc, size); + + if (!size) { + ufree (proc, ptr); + return 0; + } + /* calculate size of process image (binary file) */ unsigned p = (unsigned) palign ((void *) (proc->end - proc->start)); @@ -228,14 +236,12 @@ void *urealloc (proc_t *proc, void *ptr, size_t size) } int s = (int) (malloc->next - ptr) + p; - - if (s >= size) { - ufree (proc, ptr); +printf ("s: %d : %d\n", s, size); + if (s >= size) return 0; - } char *ptr_new = umalloc (proc, size); - +printf ("s: ptr_new: 0x%x\n", ptr_new); if (!ptr_new) { ufree (proc, ptr); errno_set (ENOMEM); diff --git a/kernel/core/net/checksum.c b/kernel/core/net/checksum.c index 896f149..53b2216 100644 --- a/kernel/core/net/checksum.c +++ b/kernel/core/net/checksum.c @@ -1,6 +1,7 @@ /* * ZeX/OS * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +19,11 @@ #include #include +#include +#include +#include + +static char buf_prealloc[NET_PACKET_MTU + 64]; unsigned short checksum16_ones (unsigned sum, const void *_buf, int len) { @@ -72,7 +78,7 @@ typedef struct proto_tcp_pseudo_t { unsigned short checksum16_tcp (unsigned ip_source, unsigned ip_dest, char *buf, unsigned short len) { - char *buf_pseudo = (char *) kmalloc ((len+12) * sizeof (char)); + char *buf_pseudo = (char *) &buf_prealloc; if (!buf_pseudo) return 0; @@ -91,14 +97,12 @@ unsigned short checksum16_tcp (unsigned ip_source, unsigned ip_dest, char *buf, unsigned short ret = checksum16 (buf_pseudo, len+12); - kfree (buf_pseudo); - return ret; } unsigned short checksum16_udp (unsigned ip_source, unsigned ip_dest, char *buf, unsigned short len) { - char *buf_pseudo = (char *) kmalloc ((len+12) * sizeof (char)); + char *buf_pseudo = (char *) &buf_prealloc; if (!buf_pseudo) return 0; @@ -117,8 +121,6 @@ unsigned short checksum16_udp (unsigned ip_source, unsigned ip_dest, char *buf, unsigned short ret = checksum16 (buf_pseudo, len+12); - kfree (buf_pseudo); - return ret; } @@ -133,7 +135,7 @@ typedef struct proto_ipv6_pseudo_t { unsigned short checksum16_ipv6 (unsigned short ip_source[8], unsigned short ip_dest[8], char *buf, unsigned len, unsigned char proto) { - char *buf_pseudo = (char *) kmalloc (sizeof (proto_ipv6_pseudo_t) + len + 1); + char *buf_pseudo = (char *) &buf_prealloc; if (!buf_pseudo) return 0; @@ -157,7 +159,5 @@ unsigned short checksum16_ipv6 (unsigned short ip_source[8], unsigned short ip_d unsigned short ret = checksum16 (buf_pseudo, len+40); - kfree (buf_pseudo); - return ret; } diff --git a/kernel/core/net/ip.c b/kernel/core/net/ip.c index ed3c3f6..c06e356 100644 --- a/kernel/core/net/ip.c +++ b/kernel/core/net/ip.c @@ -28,6 +28,7 @@ #include #include +static char buf_ip_prealloc[NET_PACKET_MTU + sizeof (net_ipv4) + 1]; void net_proto_ip_print (net_ipv4 ip) { @@ -120,7 +121,12 @@ unsigned net_proto_ip_network (net_ipv4 ip) unsigned net_proto_ip_send (netif_t *netif, packet_t *packet, proto_ip_t *ip, char *buf, unsigned len) { - char *buf_ip = (char *) kmalloc ((len + 1 + sizeof (proto_ip_t))); + if (len +1 + sizeof (proto_ip_t) > NET_PACKET_MTU + sizeof (net_ipv4)) { + kprintf ("ERROR -> IP packet is too long (%d/%d Bytes)\n", len + sizeof (proto_ip_t), NET_PACKET_MTU + sizeof (net_ipv4)); + return 0; + } + + char *buf_ip = (char *) &buf_ip_prealloc; //(char *) kmalloc ((len + 1 + sizeof (proto_ip_t))); if (!buf_ip) return 0; @@ -134,12 +140,10 @@ unsigned net_proto_ip_send (netif_t *netif, packet_t *packet, proto_ip_t *ip, ch memcpy (buf_ip, (char *) ip, l); memcpy (buf_ip+l, buf, len); - buf_ip[l+len] = '\0'; - /* send packet */ unsigned ret = net_packet_send (netif, packet, buf_ip, l+len); - kfree (buf_ip); + //kfree (buf_ip); return ret; } diff --git a/kernel/core/net/packet.c b/kernel/core/net/packet.c index 269ac5b..828ae65 100644 --- a/kernel/core/net/packet.c +++ b/kernel/core/net/packet.c @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +35,7 @@ MUTEX_CREATE (mutex_packet); extern netif_t netif_list; extern unsigned long timer_ticks; -task_t *task_netcore = NULL; +static task_t *task_netcore = NULL; unsigned net_packet_send (netif_t *netif, packet_t *packet, char *buf, unsigned len) { @@ -45,13 +46,9 @@ unsigned net_packet_send (netif_t *netif, packet_t *packet, char *buf, unsigned return 0; } - //memset (netif->buf_tx, 0, 2048); - memcpy (netif->buf_tx, (char *) packet, 14); memcpy (netif->buf_tx+14, buf, len); - netif->buf_tx[14+len] = '\0'; - netif->dev->write ((char *) netif->buf_tx, 14+len); /* add transfered bytes to stats */ diff --git a/kernel/core/net/socket.c b/kernel/core/net/socket.c index 8c1316d..60614bc 100644 --- a/kernel/core/net/socket.c +++ b/kernel/core/net/socket.c @@ -633,8 +633,8 @@ int sselect (int readfd, int writefd, int exceptfd) switch (sock->protocol) { case IPPROTO_TCP: return net_proto_tcp_select (readfd, writefd, exceptfd); - //case IPPROTO_UDP: - // return net_proto_udp_select (readfd, writefd, exceptfd); + case IPPROTO_UDP: + return net_proto_udp_select (readfd, writefd, exceptfd); } break; case AF_INET6: diff --git a/kernel/core/net/tcp.c b/kernel/core/net/tcp.c index 5ddca1e..5b135b0 100644 --- a/kernel/core/net/tcp.c +++ b/kernel/core/net/tcp.c @@ -37,16 +37,17 @@ MUTEX_CREATE (mutex_tcp_accept); MUTEX_CREATE (mutex_tcp_read_cache); +extern netif_t netif_list; + proto_tcp_conn_t proto_tcp_conn_list; proto_tcp_backlog_t proto_tcp_backlog_list; -extern netif_t netif_list; - static unsigned short proto_tcp_dup; static unsigned proto_tcp_seq; static proto_ip_t proto_ip_prealloc; static proto_tcp_t proto_tcp_prealloc; static packet_t packet_prealloc; +static char buf_tcp_prealloc[NET_PACKET_MTU + sizeof (proto_tcp_t) + 1]; /* prototype */ proto_tcp_conn_t *net_proto_tcp_conn_check (net_ipv4 ip_source, net_port port_source, net_ipv4 ip_dest, net_port port_dest, unsigned char *ret); @@ -128,6 +129,23 @@ int net_proto_tcp_send (int fd, char *msg, unsigned size) if (!conn) return -1; + unsigned len = size; + + unsigned mtu_tcp = NET_PACKET_MTU - sizeof (proto_tcp_t) - sizeof (net_ipv4) - 16; + +check: + if (size > mtu_tcp) { + int r = net_proto_tcp_send (fd, msg, mtu_tcp); + + if (r <= 0) + return r; + + msg += mtu_tcp; + size -= mtu_tcp; + + goto check; + } + int ret = net_proto_tcp_write_data (conn, msg, size); if (ret) { @@ -146,19 +164,19 @@ int net_proto_tcp_send (int fd, char *msg, unsigned size) /* non-blocking mode */ /* TODO: ? */ - #ifdef TEST + //#ifdef TEST while (conn->state != PROTO_TCP_CONN_STATE_READY) { /* timeout 100ms */ if ((stime+100) < timer_ticks) - return size; + return 0; - printf (""); + schedule (); } - #endif + //#endif } } - return size; + return len; } int net_proto_tcp_recv (int fd, char *msg, unsigned size) @@ -329,7 +347,7 @@ int net_proto_tcp_accept (int fd, sockaddr_in *addr, socklen_t *addrlen) if (ret < 1) return ret; - + fd_t *fd_new = fd_create (FD_SOCK); if (!fd_new) @@ -349,6 +367,15 @@ int net_proto_tcp_accept (int fd, sockaddr_in *addr, socklen_t *addrlen) addr->sin_addr = ip; addr->sin_port = port; addr->sin_family = AF_INET; + + /* wait for ACK */ + unsigned long stime = timer_ticks; + while (conn_new->state != PROTO_TCP_CONN_STATE_READY) { + if ((stime+10) < timer_ticks) + return -1; + + schedule (); + } return fd_new->id; } @@ -444,7 +471,7 @@ unsigned net_proto_tcp_handler (packet_t *packet, proto_ip_t *ip, char *buf, uns data_cache = 1; } - /* sended data was delivered succefully */ + /* sended data was delivered succefully / ACK */ if (tcp->flags & 0x10) { /* HACK: It is interesting, that no push flag, and there could be some data to read */ @@ -651,7 +678,12 @@ int net_proto_tcp_write (netif_t *eth, net_ipv4 dest, proto_tcp_t *tcp, char *da /* calculate total length of packet (tcp/ip) */ ip->total_len = swap16 (l+sizeof (proto_tcp_t)+len); - char *buf_tcp = (char *) kmalloc ((len+l+1) * sizeof (char)); + if (len+l > NET_PACKET_MTU + sizeof (proto_tcp_t)) { + DPRINT (DBG_NET | DBG_SOCKET | DBG_TCP, "TCP -> data lenght is exceed: %d/%d bytes", len+l, NET_PACKET_MTU + sizeof (proto_tcp_t) + 1); + return 0; + } + + char *buf_tcp = (char *) &buf_tcp_prealloc; //(char *) kmalloc ((len+l+1) * sizeof (char)); if (!buf_tcp) return 0; @@ -661,7 +693,7 @@ int net_proto_tcp_write (netif_t *eth, net_ipv4 dest, proto_tcp_t *tcp, char *da if (len) memcpy (buf_tcp+l, data, len); - buf_tcp[l+len] = '\0'; +// buf_tcp[l+len] = '\0'; /* calculate checksum and put it to tcp header */ proto_tcp_t *tcp_ = (proto_tcp_t *) buf_tcp; @@ -671,7 +703,7 @@ int net_proto_tcp_write (netif_t *eth, net_ipv4 dest, proto_tcp_t *tcp, char *da /* send tcp header+data to ip layer */ unsigned ret = net_proto_ip_send (eth, packet, ip, (char *) buf_tcp, l+len); - kfree (buf_tcp); + //kfree (buf_tcp); return ret; } @@ -706,7 +738,7 @@ int net_proto_tcp_write_data (proto_tcp_conn_t *conn, char *data, unsigned len) conn->cross = 0; } -// printf ("TCP -> seq: 0x%x | ack: 0x%x | proto_seq: 0x%x\n", tcp->seq, conn->ack, proto_tcp_seq); +// printf ("TCP -> seq: 0x%x | ack: 0x%x | proto_seq: 0x%x\n", tcp->seq, tcp->ack, proto_tcp_seq); tcp->res = 0; tcp->data_offset = 5; @@ -731,7 +763,7 @@ int net_proto_tcp_write_data_ok (proto_tcp_conn_t *conn, proto_ip_t *ip_old, pro conn->seq = tcp_old->ack; conn->ack = tcp_old->seq; - //printf ("data_ok: seq: 0x%x | ack: 0x%x\n", tcp_old->ack, tcp_old->seq); +// printf ("data_ok: seq: 0x%x | ack: 0x%x\n", tcp_old->ack, tcp_old->seq); conn->state = PROTO_TCP_CONN_STATE_READY; @@ -804,10 +836,10 @@ int net_proto_tcp_conn_estabilish_reply (proto_tcp_conn_t *conn, proto_ip_t *ip_ conn->seq = tcp->seq; conn->ack = tcp->ack; conn->state = PROTO_TCP_CONN_STATE_ESTABILISHED; + + DPRINT (DBG_NET | DBG_SOCKET | DBG_TCP, "TCP -> fd %d connected to server succefully\n", conn->fd); } - DPRINT (DBG_NET | DBG_SOCKET | DBG_TCP, "TCP -> fd %d connected to server succefully\n", conn->fd); - kfree (tcp); return ret; diff --git a/kernel/core/net/tcp6.c b/kernel/core/net/tcp6.c index 481a706..ae6adc2 100644 --- a/kernel/core/net/tcp6.c +++ b/kernel/core/net/tcp6.c @@ -47,8 +47,9 @@ extern netif_t netif_list; static unsigned short proto_tcp6_dup; static unsigned proto_tcp6_seq; static proto_ipv6_t proto_ipv6_prealloc; -static proto_tcp_t proto_tcp6_prealloc; -static packet_t packet6_prealloc; +static proto_tcp_t proto_tcp_prealloc; +static packet_t packet_prealloc; +static char buf_tcp_prealloc[NET_PACKET_MTU + sizeof (proto_tcp_t) + 1]; /* prototype */ proto_tcp6_conn_t *net_proto_tcp6_conn_check (net_ipv6 ip_source, net_port port_source, net_ipv6 ip_dest, net_port port_dest, unsigned char *ret); @@ -130,6 +131,23 @@ int net_proto_tcp6_send (int fd, char *msg, unsigned size) if (!conn) return -1; + unsigned len = size; + + unsigned mtu_tcp = NET_PACKET_MTU - sizeof (proto_tcp_t) - sizeof (net_ipv6) - 16; + +check: + if (size > mtu_tcp) { + int r = net_proto_tcp_send (fd, msg, mtu_tcp); + + if (r <= 0) + return r; + + msg += mtu_tcp; + size -= mtu_tcp; + + goto check; + } + int ret = net_proto_tcp6_write_data (conn, msg, size); if (ret) { @@ -140,26 +158,26 @@ int net_proto_tcp6_send (int fd, char *msg, unsigned size) while (conn->state != PROTO_TCP_CONN_STATE_READY) { schedule (); - /* timeout for 8s */ - if ((stime+8000) < timer_ticks) + /* timeout for 350ms */ + if ((stime+350) < timer_ticks) return -1; } } else { /* non-blocking mode */ /* TODO: ? */ - #ifdef TEST + //#ifdef TEST while (conn->state != PROTO_TCP_CONN_STATE_READY) { schedule (); - /* timeout for 1s */ - if ((stime+1000) < timer_ticks) + /* timeout for 100ms */ + if ((stime+100) < timer_ticks) return -1; } - #endif + //#endif } } - return size; + return len; } int net_proto_tcp6_recv (int fd, char *msg, unsigned size) @@ -659,7 +677,7 @@ int net_proto_tcp6_write (netif_t *eth, net_ipv6 dest, proto_tcp_t *tcp, char *d } /* packet header */ - packet_t *packet = &packet6_prealloc; + packet_t *packet = &packet_prealloc; if (!packet) { printf ("!packet\n"); @@ -690,7 +708,12 @@ int net_proto_tcp6_write (netif_t *eth, net_ipv6 dest, proto_tcp_t *tcp, char *d memcpy (ip->ip_source, (void *) eth->ipv6, sizeof (net_ipv6)); memcpy (ip->ip_dest, (void *) dest, sizeof (net_ipv6)); - char *buf_tcp = (char *) kmalloc ((len+l+1) * sizeof (char)); + if (len+l > NET_PACKET_MTU + sizeof (proto_tcp_t)) { + DPRINT (DBG_NET | DBG_SOCKET | DBG_TCP, "TCP -> data lenght is exceed: %d/%d bytes", len+l, NET_PACKET_MTU + sizeof (proto_tcp_t) + 1); + return 0; + } + + char *buf_tcp = (char *) &buf_tcp_prealloc; if (!buf_tcp) { printf ("!buf_tcp\n"); @@ -717,8 +740,6 @@ int net_proto_tcp6_write (netif_t *eth, net_ipv6 dest, proto_tcp_t *tcp, char *d else ret = net_proto_tun6_send (eth, packet, ip, (char *) buf_tcp, l+len); - kfree (buf_tcp); - return ret; } @@ -727,7 +748,7 @@ int net_proto_tcp6_write_data (proto_tcp6_conn_t *conn, char *data, unsigned len if (!conn || !len || !data) return 0; - proto_tcp_t *tcp = &proto_tcp6_prealloc; + proto_tcp_t *tcp = &proto_tcp_prealloc; if (!tcp) return 0; diff --git a/kernel/core/net/udp.c b/kernel/core/net/udp.c index 15c0674..a864041 100644 --- a/kernel/core/net/udp.c +++ b/kernel/core/net/udp.c @@ -33,8 +33,14 @@ #include extern netif_t netif_list; + proto_udp_conn_t proto_udp_conn_list; +static proto_ip_t proto_ip_prealloc; +static proto_udp_t proto_udp_prealloc; +static packet_t packet_prealloc; +static char buf_udp_prealloc[NET_PACKET_MTU + sizeof (proto_udp_t) + 1]; + /* prototypes */ proto_udp_conn_t *net_proto_udp_conn_check (net_ipv4 ip_source, net_port port_source, net_ipv4 ip_dest, net_port port_dest, unsigned char *ret); int net_proto_udp_read_cache (proto_udp_conn_t *conn, char *data, unsigned len); @@ -88,6 +94,23 @@ int net_proto_udp_send (int fd, char *msg, unsigned size) if (!conn) return -1; + unsigned len = size; + + unsigned mtu_udp = NET_PACKET_MTU - sizeof (proto_udp_t) - sizeof (net_ipv4) - 16; + +check: + if (size > mtu_udp) { + int r = net_proto_udp_send (fd, msg, mtu_udp); + + if (r <= 0) + return r; + + msg += mtu_udp; + size -= mtu_udp; + + goto check; + } + int ret = net_proto_udp_write (conn, msg, size); if (ret) { @@ -101,7 +124,7 @@ int net_proto_udp_send (int fd, char *msg, unsigned size) } } - return size; + return len; } int net_proto_udp_sendto (int fd, char *msg, unsigned size, sockaddr_in *to) @@ -111,18 +134,25 @@ int net_proto_udp_sendto (int fd, char *msg, unsigned size, sockaddr_in *to) if (!conn) return -1; - //int ip = conn->ip_dest; + unsigned len = size; + + unsigned mtu_udp = NET_PACKET_MTU - sizeof (proto_udp_t) - sizeof (net_ipv4) - 16; - /*net_proto_ip_print (conn->ip_dest); - kprintf (" | "); - net_proto_ip_print (conn->ip_source);*/ +check: + if (size > mtu_udp) { + int r = net_proto_udp_sendto (fd, msg, mtu_udp, to); - //conn->ip_source = to->sin_addr; + if (r <= 0) + return r; + + msg += mtu_udp; + size -= mtu_udp; + + goto check; + } int ret = net_proto_udp_write (conn, msg, size); - //conn->ip_dest = ip; - if (ret) { /* blocking mode */ if (!(conn->flags & O_NONBLOCK)) { @@ -134,7 +164,7 @@ int net_proto_udp_sendto (int fd, char *msg, unsigned size, sockaddr_in *to) } } - return size; + return len; } extern unsigned long timer_ticks; @@ -322,8 +352,14 @@ int net_proto_udp_select (int readfd, int writefd, int exceptfd) if (!conn) return -1; + /* New incoming connection */ + if (conn->state == PROTO_UDP_CONN_STATE_NEW) { + conn->state = 0; + return 1; + } + /* Are some data available ? */ - if (conn->len) + if (conn->len > 0) return 1; return 0; @@ -339,10 +375,10 @@ unsigned net_proto_udp_handler (packet_t *packet, proto_ip_t *ip, char *buf, uns unsigned char ret; proto_udp_t *udp = (proto_udp_t *) buf; - /* First check ip address and ports, that we want this data */ + /* check ip address and ports first */ proto_udp_conn_t *conn = net_proto_udp_conn_check (ip->ip_dest, udp->port_dest, ip->ip_source, udp->port_source, &ret); - if (!conn && ret == 0) + if (!conn || ret == 0) return 1; if (ret == 1) @@ -351,8 +387,13 @@ unsigned net_proto_udp_handler (packet_t *packet, proto_ip_t *ip, char *buf, uns /* HACK: very ugly */ conn->port_dest = udp->port_source; - /* save data to buffer; +8 because udp packet is 8byte header and then data */ - int ret2 = net_proto_udp_read_cache (conn, buf+8, len-8); + unsigned short l = htons (udp->len); + + if (l < 1) + return 0; + + /* save data to buffer; +8 because udp packet contain 8byte header and than data */ + int ret2 = net_proto_udp_read_cache (conn, buf+8, l-8); if (ret2 < 1) return 0; @@ -415,7 +456,7 @@ int net_proto_udp_write (proto_udp_conn_t *conn, char *data, unsigned len) } /* packet header */ - packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t)); + packet_t *packet = (packet_t *) &packet_prealloc; if (!packet) return 0; @@ -425,7 +466,7 @@ int net_proto_udp_write (proto_udp_conn_t *conn, char *data, unsigned len) packet->type = NET_PACKET_TYPE_IPV4; /* ip layer */ - proto_ip_t *ip = (proto_ip_t *) kmalloc (sizeof (proto_ip_t)); + proto_ip_t *ip = (proto_ip_t *) &proto_ip_prealloc; if (!ip) return 0; @@ -443,25 +484,27 @@ int net_proto_udp_write (proto_udp_conn_t *conn, char *data, unsigned len) ip->ip_dest = conn->ip_dest; - proto_udp_t *udp = (proto_udp_t *) kmalloc (sizeof (proto_udp_t)); + proto_udp_t *udp = (proto_udp_t *) &proto_udp_prealloc; if (!udp) return 0; udp->port_source = conn->port_source; udp->port_dest = conn->port_dest; - udp->len = swap16 (8 + len); - udp->checksum = 0; - unsigned l = (ip->head_len * 4); /* calculate total length of packet (udp/ip) */ ip->total_len = swap16 (l + 8 + len); - char *buf_udp = (char *) kmalloc ((9 + len) * sizeof (char)); + if ((len + 8) > (NET_PACKET_MTU + sizeof (proto_udp_t) + 1)) { + DPRINT (DBG_NET | DBG_SOCKET | DBG_UDP, "UDP -> data lenght is exceed: %d/%d bytes", len+8, NET_PACKET_MTU + sizeof (proto_udp_t) + 1); + return 0; + } + + char *buf_udp = (char *) &buf_udp_prealloc; if (!buf_udp) return 0; @@ -479,11 +522,6 @@ int net_proto_udp_write (proto_udp_conn_t *conn, char *data, unsigned len) /* send udp header+data to ip layer */ unsigned ret = net_proto_ip_send (conn->netif, packet, ip, (char *) buf_udp, 8 + len); - kfree (buf_udp); - kfree (udp); - kfree (ip); - kfree (packet); - return ret; } @@ -531,6 +569,7 @@ int net_proto_udp_conn_set (proto_udp_conn_t *conn, netif_t *eth, net_port port_ conn->netif = eth; conn->bind = 0; + conn->state = 0; conn->len = 0; conn->data = 0; @@ -568,6 +607,12 @@ proto_udp_conn_t *net_proto_udp_conn_check (net_ipv4 ip_source, net_port port_so if (conn->ip_source == ip_source && conn->port_source == port_source) { if (conn->ip_dest == ip_dest) { *ret = 2; + + /*if (conn->bind) { + *ret = 1;printf ("OO11122\n"); + conn->state = PROTO_UDP_CONN_STATE_NEW; + }*/ + return conn; } @@ -587,15 +632,17 @@ proto_udp_conn_t *net_proto_udp_conn_check (net_ipv4 ip_source, net_port port_so } } } - - if (*ret == 1) - if (!conn_ret->bind) { + + if (*ret == 1) { + //if (!conn_ret->bind) { conn_ret = 0; for (conn = proto_udp_conn_list.next; conn != &proto_udp_conn_list; conn = conn->next) { if (conn->bind) { - if (conn->ip_source == ip_source && conn->port_source == port_source) + if (conn->ip_source == ip_source && conn->port_source == port_source) { conn_ret = conn; + conn->state = PROTO_UDP_CONN_STATE_NEW; + } } } } diff --git a/kernel/core/net/udp6.c b/kernel/core/net/udp6.c index 2ffd390..f935e47 100644 --- a/kernel/core/net/udp6.c +++ b/kernel/core/net/udp6.c @@ -32,10 +32,15 @@ #include #include - extern netif_t netif_list; + proto_udp6_conn_t proto_udp6_conn_list; +static proto_ipv6_t proto_ipv6_prealloc; +static proto_udp_t proto_udp_prealloc; +static packet_t packet_prealloc; +static char buf_udp_prealloc[NET_PACKET_MTU + sizeof (proto_udp_t) + 1]; + /* prototypes */ proto_udp6_conn_t *net_proto_udp6_conn_check (net_ipv6 ip_source, net_port port_source, net_ipv6 ip_dest, net_port port_dest, unsigned char *ret); int net_proto_udp6_read_cache (proto_udp6_conn_t *conn, char *data, unsigned len); @@ -112,18 +117,25 @@ int net_proto_udp6_sendto (int fd, char *msg, unsigned size, sockaddr_in6 *to) if (!conn) return -1; - //int ip = conn->ip_dest; + unsigned len = size; + + unsigned mtu_udp = NET_PACKET_MTU - sizeof (proto_udp_t) - sizeof (net_ipv6) - 16; - /*net_proto_ip_print (conn->ip_dest); - kprintf (" | "); - net_proto_ip_print (conn->ip_source);*/ +check: + if (size > mtu_udp) { + int r = net_proto_udp6_sendto (fd, msg, mtu_udp, to); - //conn->ip_source = to->sin6_addr; + if (r <= 0) + return r; + + msg += mtu_udp; + size -= mtu_udp; + + goto check; + } int ret = net_proto_udp6_write (conn, msg, size); - //conn->ip_dest = ip; - if (ret) { /* blocking mode */ if (!(conn->flags & O_NONBLOCK)) { @@ -419,7 +431,7 @@ int net_proto_udp6_write (proto_udp6_conn_t *conn, char *data, unsigned len) } /* packet header */ - packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t)); + packet_t *packet = (packet_t *) &packet_prealloc; if (!packet) return 0; @@ -429,7 +441,7 @@ int net_proto_udp6_write (proto_udp6_conn_t *conn, char *data, unsigned len) packet->type = NET_PACKET_TYPE_IPV6; /* ip layer */ - proto_ipv6_t *ip = (proto_ipv6_t *) kmalloc (sizeof (proto_ipv6_t)); + proto_ipv6_t *ip = (proto_ipv6_t *) &proto_ipv6_prealloc; if (!ip) return 0; @@ -445,23 +457,22 @@ int net_proto_udp6_write (proto_udp6_conn_t *conn, char *data, unsigned len) memcpy (ip->ip_dest, (void *) conn->ip_dest, sizeof (net_ipv6)); - proto_udp_t *udp = (proto_udp_t *) kmalloc (sizeof (proto_udp_t)); + proto_udp_t *udp = (proto_udp_t *) &proto_udp_prealloc; if (!udp) return 0; udp->port_source = conn->port_source; udp->port_dest = conn->port_dest; - udp->len = ip->pl_len; - udp->checksum = 0; - - - /* calculate total length of packet (udp/ip) */ - - - char *buf_udp = (char *) kmalloc ((9 + len) * sizeof (char)); + + if ((len + 8) > (NET_PACKET_MTU + sizeof (proto_udp_t) + 1)) { + DPRINT (DBG_NET | DBG_SOCKET | DBG_UDP, "UDP -> data lenght is exceed: %d/%d bytes", len+8, NET_PACKET_MTU + sizeof (proto_udp_t) + 1); + return 0; + } + + char *buf_udp = (char *) &buf_udp_prealloc; if (!buf_udp) return 0; @@ -483,11 +494,6 @@ int net_proto_udp6_write (proto_udp6_conn_t *conn, char *data, unsigned len) else ret = net_proto_tun6_send (conn->netif, packet, ip, (char *) buf_udp, 8 + len); - kfree (buf_udp); - kfree (udp); - kfree (ip); - kfree (packet); - return ret; } diff --git a/kernel/core/sched.c b/kernel/core/sched.c index f2f2eb2..b3ae7b8 100644 --- a/kernel/core/sched.c +++ b/kernel/core/sched.c @@ -130,28 +130,22 @@ task_t *task_create (char *name, unsigned entry, unsigned priority) task_t *task = (task_t *) kmalloc (sizeof (task_t)); /* out of memory ? */ - if (!task) { - DPRINT (DBG_SCHED, "task_create () - !task"); - task = (task_t *) kmalloc (sizeof (task_t)); - - if (!task) - return 0; - } + if (!task) + return 0; + /* kernel ? */ if (entry == NULL) { /* mark task #0 (idle task) runnable */ task->status = TS_RUNNABLE; task->priority = priority; - // add name of task + // add name of the task strcpy (task->name, name); task->spinlock = &sched_spinlock; task->id = task_id; #ifdef ARCH_i386 - task->page_cover = 0; - task->page_cover = (page_ent_t *) page_cover_create (); /* kernel covering by paging */ diff --git a/kernel/core/smp.c b/kernel/core/smp.c index af8364f..3a6a2b3 100644 --- a/kernel/core/smp.c +++ b/kernel/core/smp.c @@ -42,18 +42,20 @@ void smp_cpu_check () { unsigned cpu_cnt = 1; - char *str = (char *) kmalloc (sizeof (char) * (cpu_cnt * 256)); + /*char *str = (char *) kmalloc (sizeof (char) * (cpu_cnt * 256)); if (!str) return; + + str[0] = '\0';*/ - char strcpu[80]; + /*char strcpu[80]; char cpuarch[16]; smp_cpu_t *cpu; - for (cpu = smp_cpu_list.next; cpu != &smp_cpu_list; cpu = cpu->next) { - if (cpu->arch == SMP_ARCH_x86) + for (cpu = smp_cpu_list.next; cpu != &smp_cpu_list; cpu = cpu->next) {*/ + /*if (cpu->arch == SMP_ARCH_x86) strcpy (cpuarch, "x86"); else if (cpu->arch == SMP_ARCH_ARM) strcpy (cpuarch, "ARM"); @@ -63,7 +65,7 @@ void smp_cpu_check () sprintf (strcpu, "CPU %d (%s)\n\tarch: %s\n\tstate: %s\n\tfeatures: ", cpu_cnt, (cpu->flags == SMP_FLAGS_CPU_BS ) ? "BS" : "AP", cpuarch, (cpu->state == SMP_STATE_CPU_UP ) ? "running" : "down"); - strcat (str, strcpu); + strcpy (str, strcpu); smp_arch_x86 *arch_spec = cpu->arch_spec; @@ -133,16 +135,16 @@ void smp_cpu_check () r: strcat (str, "\n"); - cpu_cnt ++; - } - - vfs_list_add ("cpuinfo", VFS_FILEATTR_FILE | VFS_FILEATTR_READ | VFS_FILEATTR_SYSTEM, "/proc/"); + cpu_cnt ++;*/ + /*} +*/ + //vfs_list_add ("cpuinfo", VFS_FILEATTR_FILE | VFS_FILEATTR_READ | VFS_FILEATTR_SYSTEM, "/proc/"); - vfs_content_t content; - content.ptr = str; - content.len = strlen (str); + /*vfs_content_t content; + content.ptr = "prd"; + content.len = 3;*/ - vfs_mmap ("/proc/cpuinfo", 13, &content); + //vfs_mmap ("/proc/cpuinfo", 13, &content); } /* mostly x86 stuff */ diff --git a/kernel/drivers/Kconfig b/kernel/drivers/Kconfig index 8d8dc0f..f20de76 100644 --- a/kernel/drivers/Kconfig +++ b/kernel/drivers/Kconfig @@ -109,7 +109,7 @@ config DRV_VESA config DRV_GMM bool "Graphical Memory Management (EXPERIMENTAL)" - default n + default y help Enable the GMM extension @@ -139,7 +139,7 @@ config DRV_EXT2 config DRV_ZEXFS bool "ZEXFS filesystem driver (EXPERIMENTAL)" - default n + default y help Enable the ZEXFS filesystem driver for hard disk. @@ -151,7 +151,7 @@ config DRV_ZNFS config DRV_ISOFS bool "ISO 9660 filesystem driver" - default n + default y help Enable the ISO 9660 filesystem driver for hard disk and cdrom. diff --git a/kernel/include/net/ip.h b/kernel/include/net/ip.h index b19e2da..5ca9e31 100644 --- a/kernel/include/net/ip.h +++ b/kernel/include/net/ip.h @@ -27,7 +27,6 @@ typedef unsigned short net_ipv6[8]; #define NET_IPV4_TO_ADDR(a, b, c, d) \ (((net_ipv4)(d) << 24) | (((net_ipv4)(c) & 0xff) << 16) | (((net_ipv4)(b) & 0xff) << 8) | ((net_ipv4)(a) & 0xff)) - #define NET_PROTO_IP_TYPE_ICMP 0x1 #define NET_PROTO_IP_TYPE_ICMP6 0x3a #define NET_PROTO_IP_TYPE_TCP 0x6 diff --git a/kernel/include/net/packet.h b/kernel/include/net/packet.h index 67a16af..15e26f8 100644 --- a/kernel/include/net/packet.h +++ b/kernel/include/net/packet.h @@ -1,6 +1,7 @@ /* * ZeX/OS * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +17,12 @@ * along with this program. If not, see . */ + #ifndef _PACKET_H #define _PACKET_H +#define NET_PACKET_MTU 1500 + #define NET_PACKET_TYPE_IPV6 0xdd86 #define NET_PACKET_TYPE_IPV4 0x8 #define NET_PACKET_TYPE_STP 0x2600 @@ -30,7 +34,6 @@ typedef struct packet_t { unsigned short type; } packet_t; - extern unsigned net_packet_send (netif_t *netif, packet_t *packet, char *buf, unsigned len); extern unsigned init_packet (); diff --git a/kernel/include/net/udp.h b/kernel/include/net/udp.h index f76d1dc..c0d1042 100644 --- a/kernel/include/net/udp.h +++ b/kernel/include/net/udp.h @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +23,8 @@ #include +#define PROTO_UDP_CONN_STATE_NEW 0x1 + /* UDP connection structure */ typedef struct proto_udp_conn_context { struct proto_udp_conn_context *next, *prev; @@ -36,6 +39,8 @@ typedef struct proto_udp_conn_context { unsigned char bind; + unsigned char state; + unsigned short fd; netif_t *netif; diff --git a/kernel/include/paging.h b/kernel/include/paging.h index 2213c5b..453f1b6 100644 --- a/kernel/include/paging.h +++ b/kernel/include/paging.h @@ -48,6 +48,8 @@ #endif +#define __PACKED__ __attribute__ ((__packed__)) + /* Page structure */ typedef struct page_context { @@ -58,7 +60,7 @@ typedef struct page_context unsigned dirty : 1; unsigned unused : 7; unsigned frame : 20; -} page_t; +} __PACKED__ page_t ; typedef struct page_table_context { diff --git a/kernel/lib/sys/select.c b/kernel/lib/sys/select.c index 935c12c..46918b4 100644 --- a/kernel/lib/sys/select.c +++ b/kernel/lib/sys/select.c @@ -109,7 +109,13 @@ int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, cons efds = FD_SETSIZE; unsigned long stime = timer_ticks; - unsigned long ms = timeout->tv_usec / 1000 + timeout->tv_sec * 1000; // covert to milisecond precise + unsigned long ms; + + if (timeout) + ms = timeout->tv_usec / 1000 + timeout->tv_sec * 1000; // covert to milisecond precise + else + ms = 50000; + unsigned r; for (; (stime+ms) >= timer_ticks; ) { @@ -123,15 +129,15 @@ int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, cons _fd_clr (readfds->fd[r], readfds); continue; } - +//printf ("select0: %d\n", readfds->fd[r]); /* TODO: stdin, stdout */ if (fd->flags & FD_SOCK) { // socket select int ret = sselect (fd->id, 0, 0); - if (ret > 0) + if (ret > 0){//printf ("select0: %d - %d\n", readfds->fd[r], ret); goto ready; - + } continue; } diff --git a/libc/Makefile b/libc/Makefile index 3647d45..3200142 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -11,11 +11,11 @@ CCLIBC =$(CC) -g -Wall -W -O2 -nostdinc -fno-builtin -Wno-unused-parameter -I$(I STDIO =stdio/doprintf.o stdio/delay.o stdio/printf.o stdio/sprintf.o stdio/puts.o stdio/putch.o stdio/cls.o stdio/getch.o stdio/getkey.o stdio/gotoxy.o stdio/setcolor.o stdio/beep.o stdio/open.o stdio/close.o stdio/read.o stdio/write.o stdio/doscanf.o stdio/scanf.o stdio/getchar.o stdio/putchar.o stdio/fopen.o stdio/fclose.o stdio/fread.o stdio/fwrite.o stdio/fgetc.o stdio/fgets.o stdio/feof.o stdio/fileno.o stdio/fseek.o stdio/ftell.o stdio/fprintf.o stdio/fputc.o stdio/fdopen.o stdio/ferror.o stdio/fflush.o stdio/clearerr.o stdio/perror.o stdio/putc.o stdio/dosscanf.o stdio/sscanf.o stdio/fputs.o stdio/remove.o stdio/rename.o -STRING =string/memset.o string/memsetw.o string/memcpy.o string/memcmp.o string/memchr.o string/strlen.o string/strchr.o string/strcpy.o string/strncpy.o string/strcat.o string/strncat.o string/strcmp.o string/strstr.o string/strspn.o string/strdup.o string/strndup.o string/strpbrk.o string/strerror.o string/memmove.o +STRING =string/memset.o string/memsetw.o string/memcpy.o string/memcmp.o string/memchr.o string/strlen.o string/strchr.o string/strcpy.o string/strncpy.o string/strcat.o string/strncat.o string/strcmp.o string/strstr.o string/strspn.o string/strdup.o string/strndup.o string/strpbrk.o string/strerror.o string/memmove.o string/strtok.o STRINGS =strings/strcasecmp.o -STDLIB =stdlib/memory.o stdlib/exit.o stdlib/schedule.o stdlib/strtol.o stdlib/atoi.o stdlib/itoa.o stdlib/abort.o stdlib/abs.o stdlib/system.o stdlib/rand.o stdlib/random.o stdlib/getenv.o stdlib/strtoul.o stdlib/mkstemp.o stdlib/qsort.o +STDLIB =stdlib/memory.o stdlib/exit.o stdlib/schedule.o stdlib/strtol.o stdlib/atoi.o stdlib/itoa.o stdlib/abort.o stdlib/abs.o stdlib/system.o stdlib/rand.o stdlib/random.o stdlib/getenv.o stdlib/strtoul.o stdlib/mkstemp.o stdlib/qsort.o stdlib/atol.o stdlib/atoll.o UNISTD =unistd/sleep.o unistd/fcntl.o unistd/dup.o unistd/lseek.o unistd/unlink.o unistd/pipe.o unistd/getpid.o unistd/chdir.o unistd/getcwd.o unistd/access.o -SOCKET =socket/connect.o socket/socket.o socket/send.o socket/gethostbyname.o socket/htons.o socket/recv.o socket/bind.o socket/listen.o socket/accept.o socket/sendto.o socket/recvfrom.o socket/inet_ntop.o socket/inet_pton.o socket/inet_ntoa.o socket/setsockopt.o socket/inet_addr.o +SOCKET =socket/connect.o socket/socket.o socket/send.o socket/gethostbyname.o socket/htons.o socket/recv.o socket/bind.o socket/listen.o socket/accept.o socket/sendto.o socket/recvfrom.o socket/inet_ntop.o socket/inet_pton.o socket/inet_ntoa.o socket/setsockopt.o socket/inet_addr.o socket/htonl.o socket/ntohs.o socket/ntohl.o socket/inet_aton.o SIGNAL =signal/signal.o VFS =vfs/mount.o TIME =time/time.o time/localtime.o time/gettimeofday.o time/mktime.o diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h index 46a4cd8..5f53c01 100644 --- a/libc/include/arpa/inet.h +++ b/libc/include/arpa/inet.h @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,11 +26,15 @@ #include /* externs */ -extern int htons (int port); +extern unsigned short htons (unsigned short hostshort); +extern unsigned int htonl (unsigned int hostlong); +extern unsigned short ntohs (unsigned short netshort); +extern unsigned int ntohl (unsigned int netlong); extern const char *inet_ntop (int af, const void *src, char *dst, socklen_t cnt); extern int inet_pton (int af, const char *src, void *dst); extern char *inet_ntoa (struct in_addr in); extern in_addr_t inet_addr (const char *src); +extern int inet_aton (const char *cp, struct in_addr *inp); #endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 4e4303b..339ee91 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -3,6 +3,7 @@ * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,5 +49,7 @@ extern char *getenv (const char *name); extern unsigned long strtoul (const char *nptr, char **endptr, int base); extern int mkstemp (char *tmplate); extern void qsort (void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)); +extern long atol (const char *s); +extern long long atoll (const char *s); #endif diff --git a/libc/include/string.h b/libc/include/string.h index 34c0f5c..14ddeb9 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -3,6 +3,7 @@ * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,6 +47,7 @@ extern char *strndup (const char *s, size_t n); extern char *strerror (int errnum); extern void *memmove (void *dest, const void *src, size_t n); extern char *strrchr (const char *s, int c); +extern char *strtok (char *str, const char *delim); #endif diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 002024a..ec4fe5f 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -3,6 +3,7 @@ * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/libc/socket/htons.c b/libc/socket/htonl.c similarity index 72% copy from libc/socket/htons.c copy to libc/socket/htonl.c index 6daea16..333aa31 100644 --- a/libc/socket/htons.c +++ b/libc/socket/htonl.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,13 +20,21 @@ #include #include -#define htons_d(h) \ - ((((unsigned short)(h) & 0xff) << 8) | ((unsigned short)(h) >> 8)) +#define htonl_d(x) ({\ + unsigned _x = (x); \ + (((_x)>>24)&0xff)\ + |\ + (((_x)>>8)&0xff00)\ + |\ + (((_x)<<8)&0xff0000)\ + |\ + (((_x)<<24)&0xff000000);\ +}) -int htons (int port) +unsigned int htonl (unsigned int hostlong) { /* TODO */ - return htons_d (port); + return htonl_d (hostlong); } diff --git a/libc/socket/htons.c b/libc/socket/htons.c index 6daea16..d688e4e 100644 --- a/libc/socket/htons.c +++ b/libc/socket/htons.c @@ -1,6 +1,7 @@ /* * ZeX/OS * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,10 +24,10 @@ #define htons_d(h) \ ((((unsigned short)(h) & 0xff) << 8) | ((unsigned short)(h) >> 8)) -int htons (int port) +unsigned short htons (unsigned short hostshort) { /* TODO */ - return htons_d (port); + return htons_d (hostshort); } diff --git a/libc/socket/inet_ntoa.c b/libc/socket/inet_aton.c similarity index 80% copy from libc/socket/inet_ntoa.c copy to libc/socket/inet_aton.c index 7d1afdf..b4303ae 100644 --- a/libc/socket/inet_ntoa.c +++ b/libc/socket/inet_aton.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,19 +22,19 @@ #include #include -static char tmp_addr[16]; - -char *inet_ntoa (struct in_addr in) +int inet_aton (const char *cp, struct in_addr *inp) { - unsigned *ip = (unsigned *) ∈ + unsigned *ip = (unsigned *) inp; + if (!*ip) + return 0; + unsigned char a = (unsigned char) *ip; unsigned char b = (unsigned char) (*ip >> 8); unsigned char c = (unsigned char) (*ip >> 16); unsigned char d = (unsigned char) (*ip >> 24); - sprintf (tmp_addr, "%d.%d.%d.%d", a, b, c, d); + sprintf ((char *) cp, "%d.%d.%d.%d", a, b, c, d); - return tmp_addr; + return 1; } - diff --git a/libc/socket/inet_ntoa.c b/libc/socket/inet_ntoa.c index 7d1afdf..baa1600 100644 --- a/libc/socket/inet_ntoa.c +++ b/libc/socket/inet_ntoa.c @@ -37,4 +37,3 @@ char *inet_ntoa (struct in_addr in) return tmp_addr; } - diff --git a/libc/socket/htons.c b/libc/socket/ntohl.c similarity index 72% copy from libc/socket/htons.c copy to libc/socket/ntohl.c index 6daea16..941232c 100644 --- a/libc/socket/htons.c +++ b/libc/socket/ntohl.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,13 +20,21 @@ #include #include -#define htons_d(h) \ - ((((unsigned short)(h) & 0xff) << 8) | ((unsigned short)(h) >> 8)) +#define ntohl_d(x) ({\ + unsigned _x = (x); \ + (((_x)>>24)&0xff)\ + |\ + (((_x)>>8)&0xff00)\ + |\ + (((_x)<<8)&0xff0000)\ + |\ + (((_x)<<24)&0xff000000);\ +}) -int htons (int port) +unsigned short ntohl (unsigned short netlong) { /* TODO */ - return htons_d (port); + return ntohl_d (netlong); } diff --git a/libc/socket/htons.c b/libc/socket/ntohs.c similarity index 83% copy from libc/socket/htons.c copy to libc/socket/ntohs.c index 6daea16..4774f8f 100644 --- a/libc/socket/htons.c +++ b/libc/socket/ntohs.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,13 +20,13 @@ #include #include -#define htons_d(h) \ +#define ntohs_d(h) \ ((((unsigned short)(h) & 0xff) << 8) | ((unsigned short)(h) >> 8)) -int htons (int port) +unsigned short ntohs (unsigned short netshort) { /* TODO */ - return htons_d (port); + return ntohs_d (netshort); } diff --git a/libc/stdio/dosscanf.c b/libc/stdio/dosscanf.c index f07bc9c..b8ebb70 100644 --- a/libc/stdio/dosscanf.c +++ b/libc/stdio/dosscanf.c @@ -71,13 +71,13 @@ int vsscanf (const char *str, const char *fmt, va_list args) int *num = 0; float *fp = 0; unsigned char *buf = 0; - + unsigned i = 0; + unsigned s_len = strlen (str); char *s = (char *) malloc (sizeof (char) * s_len); if (!s) { errno = ENOMEM; - errno_update (); return 0; } @@ -101,8 +101,10 @@ int vsscanf (const char *str, const char *fmt, va_list args) if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u') { num = va_arg (args, int *); - if (scanf_getint (s, num)) + if (scanf_getint (s, num)) { count ++; + i += strlen (s+i)+1; + } continue; } @@ -110,8 +112,10 @@ int vsscanf (const char *str, const char *fmt, va_list args) if (*fmt == 'x' || *fmt == 'X') { num = va_arg (args, int *); - if (scanf_gethex (s, num)) + if (scanf_gethex (s+i, num)){ count ++; + i += strlen (s+i)+1; + } continue; } @@ -119,8 +123,10 @@ int vsscanf (const char *str, const char *fmt, va_list args) if (*fmt == 'c') { buf = va_arg (args, unsigned char *); - if (scanf_getchar (s, buf)) + if (scanf_getchar (s+i, buf)) { count ++; + i += strlen (s+i)+1; + } continue; } @@ -128,8 +134,10 @@ int vsscanf (const char *str, const char *fmt, va_list args) if (*fmt == 'f') { fp = va_arg (args, float *); - if (scanf_getfloat (s, fp)) + if (scanf_getfloat (s+i, fp)) { count ++; + i += strlen (s+i)+1; + } continue; } @@ -137,16 +145,16 @@ int vsscanf (const char *str, const char *fmt, va_list args) if (*fmt == 's') { buf = va_arg (args, unsigned char *); - if (scanf_getstring (s, buf)) + if (scanf_getstring (s+i, buf)) { count ++; - + i += strlen (s+i)+1; + } + continue; } continue; } - - count ++; } free (s); diff --git a/libc/socket/inet_ntoa.c b/libc/stdlib/atol.c similarity index 54% copy from libc/socket/inet_ntoa.c copy to libc/stdlib/atol.c index 7d1afdf..6e988a8 100644 --- a/libc/socket/inet_ntoa.c +++ b/libc/stdlib/atol.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,25 +16,31 @@ * along with this program. If not, see . */ +long atol (const char *s) +{ + char **endptr = (char **) &s; + int base = 10; -#include -#include -#include -#include + int nDigit; + long acc = 0; -static char tmp_addr[16]; + while((nDigit = *s) != 0) + { + // Convert to digit + nDigit -= '0'; + if(nDigit > 9) + nDigit -= ('A' - '9' - 1); + if(nDigit > base - 1) + break; -char *inet_ntoa (struct in_addr in) -{ - unsigned *ip = (unsigned *) ∈ + // Move the value to the next rank and add the digit + acc *= base; + acc += nDigit; + s ++; + } - unsigned char a = (unsigned char) *ip; - unsigned char b = (unsigned char) (*ip >> 8); - unsigned char c = (unsigned char) (*ip >> 16); - unsigned char d = (unsigned char) (*ip >> 24); - - sprintf (tmp_addr, "%d.%d.%d.%d", a, b, c, d); + if(endptr != 0) + *endptr = (char *) s; - return tmp_addr; + return acc; } - diff --git a/libc/socket/inet_ntoa.c b/libc/stdlib/atoll.c similarity index 54% copy from libc/socket/inet_ntoa.c copy to libc/stdlib/atoll.c index 7d1afdf..952ff91 100644 --- a/libc/socket/inet_ntoa.c +++ b/libc/stdlib/atoll.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,25 +16,31 @@ * along with this program. If not, see . */ +long long atoll (const char *s) +{ + char **endptr = (char **) &s; + int base = 10; -#include -#include -#include -#include + int nDigit; + long long acc = 0; -static char tmp_addr[16]; + while((nDigit = *s) != 0) + { + // Convert to digit + nDigit -= '0'; + if(nDigit > 9) + nDigit -= ('A' - '9' - 1); + if(nDigit > base - 1) + break; -char *inet_ntoa (struct in_addr in) -{ - unsigned *ip = (unsigned *) ∈ + // Move the value to the next rank and add the digit + acc *= base; + acc += nDigit; + s ++; + } - unsigned char a = (unsigned char) *ip; - unsigned char b = (unsigned char) (*ip >> 8); - unsigned char c = (unsigned char) (*ip >> 16); - unsigned char d = (unsigned char) (*ip >> 24); - - sprintf (tmp_addr, "%d.%d.%d.%d", a, b, c, d); + if(endptr != 0) + *endptr = (char *) s; - return tmp_addr; + return acc; } - diff --git a/libc/string/memset.c b/libc/string/memset.c index 91468ba..c1062df 100644 --- a/libc/string/memset.c +++ b/libc/string/memset.c @@ -1,6 +1,7 @@ /* * ZeX/OS * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,14 +20,14 @@ #include <_size_t.h> -void *memset(void *dst_ptr, int val, size_t count) +void *memset (void *dst_ptr, int val, size_t count) { - char *dst = (char *)dst_ptr; + char *dst = (char *) dst_ptr; - for(; count != 0; count--) - { - *dst = (char)val; - dst++; + for (; count != 0; count --) { + *dst = (char) val; + dst ++; } + return dst_ptr; } diff --git a/libc/socket/htons.c b/libc/string/strtok.c similarity index 63% copy from libc/socket/htons.c copy to libc/string/strtok.c index 6daea16..31e3069 100644 --- a/libc/socket/htons.c +++ b/libc/string/strtok.c @@ -1,6 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) + * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,32 @@ #include -#include -#define htons_d(h) \ - ((((unsigned short)(h) & 0xff) << 8) | ((unsigned short)(h) >> 8)) +static char *_strtok_tmp = 0; -int htons (int port) +char *strtok (char *str, const char *delim) { - /* TODO */ + char *b; + char *send; - return htons_d (port); -} + b = str ? str : _strtok_tmp; + + if (!b) + return NULL; + + b += strspn (b, delim); + + if (*b == '\0') { + _strtok_tmp = 0; + return 0; + } + send = strpbrk (b, delim); + + if (send && *send != '\0') + *send ++ = '\0'; + + _strtok_tmp = send; + + return b; +} -- 2.11.4.GIT