Free (GPLv2) TCP/IP stack developed by TASS Belgium

Fork of PicoTCP by Daniele Lacamera

Files at this revision

API Documentation at this revision

Comitter:
daniele
Date:
Sun Jun 16 20:19:33 2013 +0000
Parent:
27:26c168f5aa97
Child:
29:1a47b7151851
Commit message:
Updated from masterbranch

Changed in this revision

EthernetInterface/EthernetInterface.cpp Show diff for this revision Revisions of this file
EthernetInterface/EthernetInterface.h Show diff for this revision Revisions of this file
Socket/Endpoint.cpp Show diff for this revision Revisions of this file
Socket/Endpoint.h Show diff for this revision Revisions of this file
Socket/Socket.cpp Show diff for this revision Revisions of this file
Socket/Socket.h Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.cpp Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.h Show diff for this revision Revisions of this file
Socket/TCPSocketServer.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketServer.h Show diff for this revision Revisions of this file
Socket/UDPSocket.cpp Show diff for this revision Revisions of this file
Socket/UDPSocket.h Show diff for this revision Revisions of this file
Socket/bsd/proxy_endpoint.h Show diff for this revision Revisions of this file
Socket/bsd/stack_endpoint.cpp Show diff for this revision Revisions of this file
Socket/bsd/wrapper.h Show diff for this revision Revisions of this file
include/PicoCondition.h Show diff for this revision Revisions of this file
include/arch/pico_mbed.h Show diff for this revision Revisions of this file
include/heap.h Show diff for this revision Revisions of this file
include/pico_addressing.h Show diff for this revision Revisions of this file
include/pico_arp.h Show diff for this revision Revisions of this file
include/pico_config.h Show diff for this revision Revisions of this file
include/pico_constants.h Show diff for this revision Revisions of this file
include/pico_device.h Show diff for this revision Revisions of this file
include/pico_eth.h Show diff for this revision Revisions of this file
include/pico_frame.h Show diff for this revision Revisions of this file
include/pico_module_eth.h Show diff for this revision Revisions of this file
include/pico_protocol.h Show diff for this revision Revisions of this file
include/pico_queue.h Show diff for this revision Revisions of this file
include/pico_socket.h Show diff for this revision Revisions of this file
include/pico_stack.h Show diff for this revision Revisions of this file
include/pico_tree.h Show diff for this revision Revisions of this file
modules/pico_dev_loop.c Show diff for this revision Revisions of this file
modules/pico_dev_loop.h Show diff for this revision Revisions of this file
modules/pico_dev_mbed.cpp Show diff for this revision Revisions of this file
modules/pico_dev_mbed.h Show diff for this revision Revisions of this file
modules/pico_dhcp_client.c Show diff for this revision Revisions of this file
modules/pico_dhcp_client.h Show diff for this revision Revisions of this file
modules/pico_dhcp_common.c Show diff for this revision Revisions of this file
modules/pico_dhcp_common.h Show diff for this revision Revisions of this file
modules/pico_dhcp_server.c Show diff for this revision Revisions of this file
modules/pico_dhcp_server.h Show diff for this revision Revisions of this file
modules/pico_dns_client.c Show diff for this revision Revisions of this file
modules/pico_dns_client.h Show diff for this revision Revisions of this file
modules/pico_http_client.c Show diff for this revision Revisions of this file
modules/pico_http_client.h Show diff for this revision Revisions of this file
modules/pico_http_server.c Show diff for this revision Revisions of this file
modules/pico_http_server.h Show diff for this revision Revisions of this file
modules/pico_http_util.c Show diff for this revision Revisions of this file
modules/pico_http_util.h Show diff for this revision Revisions of this file
modules/pico_icmp4.c Show diff for this revision Revisions of this file
modules/pico_icmp4.h Show diff for this revision Revisions of this file
modules/pico_igmp.c Show diff for this revision Revisions of this file
modules/pico_igmp.h Show diff for this revision Revisions of this file
modules/pico_ipfilter.c Show diff for this revision Revisions of this file
modules/pico_ipfilter.h Show diff for this revision Revisions of this file
modules/pico_ipv4.c Show diff for this revision Revisions of this file
modules/pico_ipv4.h Show diff for this revision Revisions of this file
modules/pico_ipv6.h Show diff for this revision Revisions of this file
modules/pico_mbed.cpp Show diff for this revision Revisions of this file
modules/pico_nat.c Show diff for this revision Revisions of this file
modules/pico_nat.h Show diff for this revision Revisions of this file
modules/pico_simple_http.c Show diff for this revision Revisions of this file
modules/pico_simple_http.h Show diff for this revision Revisions of this file
modules/pico_tcp.c Show diff for this revision Revisions of this file
modules/pico_tcp.h Show diff for this revision Revisions of this file
modules/pico_udp.c Show diff for this revision Revisions of this file
modules/pico_udp.h Show diff for this revision Revisions of this file
stack/pico_arp.c Show diff for this revision Revisions of this file
stack/pico_device.c Show diff for this revision Revisions of this file
stack/pico_frame.c Show diff for this revision Revisions of this file
stack/pico_protocol.c Show diff for this revision Revisions of this file
stack/pico_socket.c Show diff for this revision Revisions of this file
stack/pico_stack.c Show diff for this revision Revisions of this file
stack/pico_tree.c Show diff for this revision Revisions of this file
--- a/EthernetInterface/EthernetInterface.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "EthernetInterface.h"
-#include "Queue.h"
-#include "wrapper.h"
-#include "proxy_endpoint.h"
-#include "pico_dev_mbed_emac.h"
-#include "mbed.h"
-#include "PicoCondition.h"
-extern "C"{
-#include "pico_stack.h"
-#include "pico_config.h"
-#include "cmsis_os.h"
-#include "pico_dhcp_client.h"
-#include "pico_dns_client.h"
-
-void (*linkCb)(uint32_t link) = NULL;
-}
-
-//DigitalOutput led(LED3);
-/* TCP/IP and Network Interface Initialisation */
-static struct pico_device *lpc_eth;
-
-static uint32_t dhcp_xid = 0;
-static PicoCondition dhcp_mx;
-static int dhcp_retval = -1;
-
-static char mac_addr[19];
-static char ip_addr[17] = "\0";
-static char gw_addr[17] = "\0";
-static bool use_dhcp = false;
-static bool is_initialized = false;
-
-static void dhcp_cb(void *cli, int code)
-{
-    void *id = NULL;
-    struct pico_ip4 address, gateway, zero = {};
-    printf("DHCP callback : %d\n",code);
-    if (PICO_DHCP_SUCCESS != code)
-        goto fail;
-        
-    id = pico_dhcp_get_identifier(dhcp_xid);
-    if (!id)
-        goto fail;
-    address = pico_dhcp_get_address(id);
-    gateway = pico_dhcp_get_gateway(id);
-    //if (address) ? // still needed
-    pico_ipv4_to_string(ip_addr, address.addr);
-    printf("IP assigned : %s\n",ip_addr);
-    
-    if (gateway.addr != 0) {
-        pico_ipv4_to_string(gw_addr, gateway.addr);
-        printf("Default gateway assigned : %s\n",gw_addr);
-        pico_ipv4_route_add(zero, zero, gateway, 1, NULL);
-    }
-    printf("Unlocking\n");
-    dhcp_mx.unlock();
-    dhcp_retval = 0;
-    printf("Returning\n");
-    return;
-    
-fail:
-    printf("DHCP request failed!\n");
-    dhcp_retval = -1;
-    dhcp_mx.unlock();
-}
-
-static void init_eth(void) 
-{
-   if (!is_initialized) {
-        pico_stack_init();
-        picotcp_init();
-        lpc_eth = pico_emac_create("mbed0");
-        is_initialized = true;
-        pico_dns_client_init();
-    }
-    if (lpc_eth) {
-        snprintf(mac_addr, 19, "%02X:%02X:%02X:%02X:%02X:%02X", lpc_eth->eth->mac.addr[0], lpc_eth->eth->mac.addr[1], 
-            lpc_eth->eth->mac.addr[2], lpc_eth->eth->mac.addr[3], lpc_eth->eth->mac.addr[4], lpc_eth->eth->mac.addr[5]);
-    }
-    printf("Lpc init : %x\n",lpc_eth);
-}
-
-int EthernetInterface::init() 
-{
-    init_eth();    
-    /* use dhcp to retrieve address and gateway. */
-    use_dhcp = true;
-    return 0; 
-}
-
-int EthernetInterface::init(const char* ip, const char* mask, const char* gateway) {
-    pico_ip4 pico_addr, pico_netmask, pico_gw = {0}, zero = {0};
-    
-    init_eth();
-    
-    use_dhcp = false;
-    strcpy(ip_addr, ip);
-    
-    pico_string_to_ipv4(ip, &pico_addr.addr);
-    pico_string_to_ipv4(mask, &pico_netmask.addr);
-    if (gateway) {
-        pico_string_to_ipv4(ip, &pico_gw.addr);
-    }
-    pico_ipv4_link_add(lpc_eth, pico_addr, pico_netmask);
-    
-    if (pico_gw.addr)
-        pico_ipv4_route_add(zero, zero, pico_gw, 1, NULL);
-    
-    return 0;
-}
-
-int EthernetInterface::connect(unsigned int timeout_ms) {
-    //dhcp_mx.lock(); do we still need this ?
-    if (use_dhcp) {
-        if (pico_dhcp_initiate_negotiation(lpc_eth, &dhcp_cb, &dhcp_xid) < 0)
-            return -1;
-      
-        dhcp_mx.lock(timeout_ms); // wait for a sign
-        printf("dhcp wake up!\n");
-        return dhcp_retval;
-        
-    } else {
-        return 0;
-    }
-}
-
-int EthernetInterface::disconnect() {
-    if (use_dhcp) {
-    } 
-    pico_device_destroy(lpc_eth);
-    lpc_eth = NULL;
-    return 0;
-}
-
-char* EthernetInterface::getMACAddress() {
-    return mac_addr;
-}
-
-char* EthernetInterface::getIPAddress() {
-    return ip_addr;
-}
-
-int EthernetInterface::registerLinkStatus(void (*cb)(uint32_t linkStatus))
-{
-    ::linkCb = cb;
-    return 0;
-}
-
-int EthernetInterface::setDnsServer(const char * name)
-{
-    struct pico_ip4 addr;
-    pico_string_to_ipv4(name,&addr.addr);
-    return pico_dns_client_nameserver(&addr,PICO_DNS_NS_ADD);
-}
--- a/EthernetInterface/EthernetInterface.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- 
-#ifndef ETHERNETINTERFACE_H_
-#define ETHERNETINTERFACE_H_
-
-#if !defined(TARGET_LPC1768)
-#error The Ethernet Interface library is supported only on the mbed NXP LPC1768
-#endif
-
-#include "rtos.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    extern void (*linkCb)(uint32_t link);
-#ifdef __cplusplus    
-}
-#endif
- /** Interface using Ethernet to connect to an IP-based network
- *
- */
-class EthernetInterface {
-public:
-  /** Initialize the interface with DHCP.
-  * Initialize the interface and configure it to use DHCP (no connection at this point).
-  * \return 0 on success, a negative number on failure
-  */
-  static int init(); //With DHCP
-
-  /** Initialize the interface with a static IP address.
-  * Initialize the interface and configure it with the following static configuration (no connection at this point).
-  * \param ip the IP address to use
-  * \param mask the IP address mask
-  * \param gateway the gateway to use
-  * \return 0 on success, a negative number on failure
-  */
-  static int init(const char* ip, const char* mask, const char* gateway);
-
-  /** Connect
-  * Bring the interface up, start DHCP if needed.
-  * \param   timeout_ms  timeout in ms (default: (10)s).
-  * \return 0 on success, a negative number on failure
-  */
-  static int connect(unsigned int timeout_ms=15000);
-  
-  /** Disconnect
-  * Bring the interface down
-  * \return 0 on success, a negative number on failure
-  */
-  static int disconnect();
-  
-  /** Get the MAC address of your Ethernet interface
-   * \return a pointer to a string containing the MAC address
-   */
-  static char* getMACAddress();
-  
-  /** Get the IP address of your Ethernet interface
-   * \return a pointer to a string containing the IP address
-   */
-  static char* getIPAddress();
-  
-  
-  /** Register a callback to tell the status of the link.
-   * \return 0 if callback was registered.
-   */
-  static int registerLinkStatus(void (*cb)(uint32_t linkStatus));
-  
-  
-  /** Register a callback to tell the status of the link.
-   * \return 0 if callback was registered.
-   */
-  static int setDnsServer(const char *);
-  
-};
-
-#include "TCPSocketConnection.h"
-#include "TCPSocketServer.h"
-
-#include "Endpoint.h"
-#include "UDPSocket.h"
-
-#endif /* ETHERNETINTERFACE_H_ */
--- a/Socket/Endpoint.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "Socket/Socket.h"
-#include "Socket/Endpoint.h"
-#include "wrapper.h"
-#include "proxy_endpoint.h"
-
-extern "C"
-{
-#include "pico_ipv4.h"
-}
-#include <cstring>
-#include <cstdio>
-
-Endpoint::Endpoint()  {
-    reset_address();
-}
-Endpoint::~Endpoint() {}
-
-void Endpoint::reset_address(void) {
-    memset(&_remoteHost,0,sizeof(_remoteHost));
-}
-
-#include "stdio.h"
-
-int Endpoint::set_address(const char* host, const int port) {
-    _remoteHost.sin_port = short_be(port);
-    pico_string_to_ipv4(host,&_remoteHost.sin_addr.s_addr);
-    memcpy(_ipAddress,host, strlen(host)+1);
-    return 0;
-}
-
-char* Endpoint::get_address() {
-    return _ipAddress;
-}
-
-int   Endpoint::get_port() {
-    return short_be(_remoteHost.sin_port);
-}
--- a/Socket/Endpoint.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef ENDPOINT_H
-#define ENDPOINT_H
-
-class UDPSocket;
-
-/**
-IP Endpoint (address, port)
-*/
-class Endpoint {
-    friend class UDPSocket;
-
-public:
-    /** IP Endpoint (address, port)
-     */
-    Endpoint(void);
-    
-    ~Endpoint(void);
-    
-    /** Reset the address of this endpoint
-     */
-    void reset_address(void);
-    
-    /** Set the address of this endpoint
-    \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
-    \param port The endpoint port
-    \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
-     */
-    int  set_address(const char* host, const int port);
-    
-    /** Get the IP address of this endpoint
-    \return The IP address of this endpoint.
-     */
-    char* get_address(void);
-    
-    /** Get the port of this endpoint
-    \return The port of this endpoint
-     */
-    int get_port(void);
-
-protected:
-    char _ipAddress[17];
-    struct sockaddr_in _remoteHost;
-
-};
-
-#endif
--- a/Socket/Socket.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "Socket/Socket.h"
-#include "wrapper.h"
-#include "proxy_endpoint.h"
-#include <cstring>
-
-using std::memset;
-
-Socket::Socket() : _ep(NULL), _blocking(true)
-{
-    //set_blocking(true,1500); // ?
-}
-
-void Socket::set_blocking(bool blocking, unsigned int timeout) {
-    _blocking = blocking;
-    _timeout = timeout;
-}
-
-int Socket::init_socket(int type) {
-    if (_ep != NULL)
-    {
-        printf("Sock open already...\n");
-        return -1;
-    }
-    struct stack_endpoint *ep  = picotcp_socket(AF_INET, type, 0);
-    if (!ep)
-    {
-        printf("Error opening socket...\n");
-        return -1;
-    }
-    _ep = ep;
-    return 0;
-}
-
-int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) {
-    return picotcp_setsockopt(_ep, optname, (void *)optval);
-}
-
-int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) {
-    return picotcp_getsockopt(_ep, optname, optval);
-}
-
-int Socket::select(struct timeval *timeout, bool read, bool write) {
-    return picotcp_select(_ep, timeout, read, write);
-}
-
-int Socket::wait_readable(TimeInterval& timeout) {
-    return (select(&timeout._time, true, false) == 0 ? -1 : 0);
-}
-
-int Socket::wait_writable(TimeInterval& timeout) {
-    return (select(&timeout._time, false, true) == 0 ? -1 : 0);
-}
-
-int Socket::close() {
-    if (_ep == NULL)
-        return -1;
-    picotcp_close(_ep);
-    return 0;
-}
-
-Socket::~Socket() {
-    if(_ep)
-    picotcp_close(_ep);
-}
-
-TimeInterval::TimeInterval(unsigned int ms) {
-    _time.tv_sec = ms / 1000;
-    _time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
-}
--- a/Socket/Socket.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SOCKET_H_
-#define SOCKET_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    #include "pico_dns_client.h"
-#ifdef __cplusplus
-}
-#endif
-
-#include "wrapper.h"
-#include "proxy_endpoint.h"
-
-class TimeInterval;
-
-/** Socket file descriptor and select wrapper
-  */
-class Socket {
-public:
-    /** Socket
-     */
-    Socket();
-    
-    /** Set blocking or non-blocking mode of the socket and a timeout on
-        blocking socket operations
-    \param blocking  true for blocking mode, false for non-blocking mode.
-    \param timeout   timeout in ms [Default: (1500)ms].
-    */
-    void set_blocking(bool blocking, unsigned int timeout=1500);
-    
-    /** Set socket options
-    \param level     stack level (see: lwip/sockets.h)
-    \param optname   option ID
-    \param optval    option value
-    \param socklen_t length of the option value
-    \return 0 on success, -1 on failure
-    */
-    int set_option(int level, int optname, const void *optval, socklen_t optlen);
-    
-    /** Get socket options
-        \param level     stack level (see: lwip/sockets.h)
-        \param optname   option ID
-        \param optval    buffer pointer where to write the option value
-        \param socklen_t length of the option value
-        \return 0 on success, -1 on failure
-        */
-    int get_option(int level, int optname, void *optval, socklen_t *optlen);
-    
-    /** Close the socket file descriptor
-     */
-    int close();
-    
-    ~Socket();
-    
-protected:
-    struct stack_endpoint *_ep;
-    int init_socket(int type);
-    
-    int wait_readable(TimeInterval& timeout);
-    int wait_writable(TimeInterval& timeout);
-    
-    bool _blocking;
-    unsigned int _timeout;
-    
-private:
-    int select(struct timeval *timeout, bool read, bool write);
-};
-
-/** Time interval class used to specify timeouts
- */
-class TimeInterval {
-    friend class Socket;
-
-public:
-    /** Time Interval
-     \param ms time interval expressed in milliseconds
-      */
-    TimeInterval(unsigned int ms);
-    
-private:
-    struct timeval _time;
-    struct stack_endpoint * _ep;
-};
-
- 
-inline struct hostent *gethostbyname(const char *name) {
-  return picotcp_gethostbyname(name);
-   
-}
-/* DNS 
-inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) {
-  return picotcp_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
-}*/
-#endif /* SOCKET_H_ */
--- a/Socket/TCPSocketConnection.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "TCPSocketConnection.h"
-#include "wrapper.h"
-#include <cstring>
-
-using std::memset;
-using std::memcpy;
-
-TCPSocketConnection::TCPSocketConnection() :
-        _is_connected(false) {
-}
-
-int TCPSocketConnection::connect(const char* host, const int port) {
-    if (init_socket(SOCK_STREAM) < 0)
-    {
-        printf("init_socket\n");
-        return -1;
-    }
-    
-    if (set_address(host, port) != 0)
-    {
-        printf("set_address\n");
-        return -1;
-    }
-    
-    if (picotcp_connect(_ep, (struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
-        close();
-        return -1;
-    }
-    _is_connected = true;
-    
-    return 0;
-}
-
-bool TCPSocketConnection::is_connected(void) {
-    return _is_connected;
-}
-
-int TCPSocketConnection::send(char* data, int length) {
-    int ret;
-    if ((_ep < 0) || !_is_connected)
-        return -1;
-    
-    if (!_blocking) {
-        TimeInterval timeout(_timeout);
-        if (wait_writable(timeout) != 0)
-        {
-            printf("Failed\n");
-            return -1;
-        }
-    }
-    ret = picotcp_write(_ep, data, length);
-    if (ret < length) {
-        _ep->revents &= (~PICO_SOCK_EV_WR);
-        printf("Short write\n");
-    }
-    return ret;
-}
-
-// -1 if unsuccessful, else number of bytes written
-int TCPSocketConnection::send_all(char* data, int length) {
-    int ret;
-    if ((_ep < 0) || !_is_connected)
-        return -1;
-        
-    if (!_blocking) {
-       TimeInterval timeout(_timeout);
-       // Wait for socket to be writeable
-       if (wait_writable(timeout) != 0) {
-           return 0;
-        }
-    }
-    ret = picotcp_write(_ep, data, length);
-    if (ret < length) {
-        _ep->revents &= (~PICO_SOCK_EV_WR);
-        //printf("Short write\n");
-    }
-    return ret;
-}
-
-int TCPSocketConnection::receive(char* data, int length) {
-    int ret;
-    if ((_ep < 0) || !_is_connected)
-        return -1;
-    
-    if (!_blocking) {
-        TimeInterval timeout(_timeout);
-        if (wait_readable(timeout) != 0)
-        {
-            printf("Failed receiving\n");
-            return -1;
-        }
-    }
-    ret = picotcp_read(_ep, data, length);
-    if (ret < length) {
-        _ep->revents &= (~PICO_SOCK_EV_RD);
-        //printf("Short read\n");
-    }
-    return ret;
-}
-
-// -1 if unsuccessful, else number of bytes received
-int TCPSocketConnection::receive_all(char* data, int length) {
-    return receive(data, length);
-}
--- a/Socket/TCPSocketConnection.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef TCPSOCKET_H
-#define TCPSOCKET_H
-
-#include "Socket/Socket.h"
-#include "Socket/Endpoint.h"
-
-/**
-TCP socket connection
-*/
-class TCPSocketConnection : public Socket, public Endpoint {
-    friend class TCPSocketServer;
-    
-public:
-    /** TCP socket connection
-    */
-    TCPSocketConnection();
-    
-    /** Connects this TCP socket to the server
-    \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
-    \param port The host's port to connect to.
-    \return 0 on success, -1 on failure.
-    */
-    int connect(const char* host, const int port);
-    
-    /** Check if the socket is connected
-    \return true if connected, false otherwise.
-    */
-    bool is_connected(void);
-    
-    /** Send data to the remote host.
-    \param data The buffer to send to the host.
-    \param length The length of the buffer to send.
-    \return the number of written bytes on success (>=0) or -1 on failure
-     */
-    int send(char* data, int length);
-    
-    /** Send all the data to the remote host.
-    \param data The buffer to send to the host.
-    \param length The length of the buffer to send.
-    \return the number of written bytes on success (>=0) or -1 on failure
-    */
-    int send_all(char* data, int length);
-    
-    /** Receive data from the remote host.
-    \param data The buffer in which to store the data received from the host.
-    \param length The maximum length of the buffer.
-    \return the number of received bytes on success (>=0) or -1 on failure
-     */
-    int receive(char* data, int length);
-    
-    /** Receive all the data from the remote host.
-    \param data The buffer in which to store the data received from the host.
-    \param length The maximum length of the buffer.
-    \return the number of received bytes on success (>=0) or -1 on failure
-    */
-    int receive_all(char* data, int length);
-
-private:
-    bool _is_connected;
-
-};
-
-#endif
--- a/Socket/TCPSocketServer.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ b/Socket/TCPSocketServer.cpp	Sun Jun 16 20:19:33 2013 +0000
@@ -70,6 +70,7 @@
 }
 
 int TCPSocketServer::accept(TCPSocketConnection& connection) {
+    char *address;
     if (_ep < 0)
         return -1;
     
@@ -87,5 +88,8 @@
     }
     connection.set_blocking(true,1500);
     connection._is_connected = true;
+    address = (char *)malloc(80);
+    pico_ipv4_to_string(address, connection._remoteHost.sin_addr.s_addr);
+    connection.set_address(address, connection._remoteHost.sin_port);
     return 0;
 }
--- a/Socket/TCPSocketServer.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef TCPSOCKETSERVER_H
-#define TCPSOCKETSERVER_H
-
-#include "Socket/Socket.h"
-#include "wrapper.h"
-#include "TCPSocketConnection.h"
-
-/** TCP Server.
-  */
-class TCPSocketServer : public Socket {
-  public:
-    /** Instantiate a TCP Server.
-    */
-    TCPSocketServer();
-    
-    /** Bind a socket to a specific port.
-    \param port The port to listen for incoming connections on.
-    \return 0 on success, -1 on failure.
-    */
-    int bind(int port);
-    
-    /** Start listening for incoming connections.
-    \param backlog number of pending connections that can be queued up at any
-                   one time [Default: 1].
-    \return 0 on success, -1 on failure.
-    */
-    int listen(int backlog=1);
-    
-    /** Accept a new connection.
-    \param connection A TCPSocketConnection instance that will handle the incoming connection.
-    \return 0 on success, -1 on failure.
-    */
-    int accept(TCPSocketConnection& connection);
-};
-
-#endif
--- a/Socket/UDPSocket.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "Socket/UDPSocket.h"
-#include "wrapper.h"
-#include "proxy_endpoint.h"
-
-#include <cstring>
-
-using std::memset;
-
-UDPSocket::UDPSocket() {
-}
-
-int UDPSocket::init(void) {
-    return init_socket(SOCK_DGRAM);
-}
-
-// Server initialization
-int UDPSocket::bind(int port) {
-    if (init_socket(SOCK_DGRAM) < 0)
-        return -1;
-    
-    struct sockaddr_in localHost; 
-    std::memset(&localHost, 0, sizeof(localHost));
-    
-    localHost.sin_family = AF_INET;
-    localHost.sin_port = short_be(port);
-    localHost.sin_addr.s_addr = INADDR_ANY;
-    
-    if (picotcp_bind(_ep, (struct sockaddr *) &localHost, (socklen_t)sizeof(localHost)) < 0) {
-        close();
-        return -1;
-    }
-    
-    return 0;
-}
-
-int UDPSocket::join_multicast_group(EthernetInterface& eth, const char* address) {
-    
-    return picotcp_join_multicast(_ep,address,eth.getIPAddress());
-}
-
-int UDPSocket::set_broadcasting(void) {
-    int option = 1;
-    return set_option(SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
-}
-
-// -1 if unsuccessful, else number of bytes written
-int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) {
-    if (_ep < 0)
-    {
-        printf("Error on socket descriptor \n");
-        return -1;
-    }
-    
-    /* This is not needed for our udp sock ?
-    if (_blocking) {
-        TimeInterval timeout(_timeout);
-        if (wait_writable(timeout) != 0)
-            return 0;
-    }*/
-    
-    return picotcp_sendto(_ep, packet, length, (struct sockaddr *) &remote._remoteHost, sizeof(remote._remoteHost));
-}
-
-// -1 if unsuccessful, else number of bytes received
-int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) {
-    if (_ep < 0)
-        return -1;
-    
-    if (!_blocking) {
-        TimeInterval timeout(_timeout);
-        if (wait_readable(timeout) != 0)
-            return 0;
-    }
-    //remote.reset_address(); why is this needed ?
-    socklen_t remoteHostLen = sizeof(remote._remoteHost);
-    return picotcp_recvfrom(_ep, buffer, length, (struct sockaddr*) &remote._remoteHost, &remoteHostLen);
-}
--- a/Socket/UDPSocket.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/* 
- *
- * PicoTCP Socket interface for mbed.
- * Copyright (C) 2013 TASS Belgium NV
- * 
- * Released under GPL v2
- *
- * Other licensing models might apply at the sole discretion of the copyright holders.
- *
- *
- * This software is based on the mbed.org EthernetInterface implementation:
- * Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef UDPSOCKET_H
-#define UDPSOCKET_H
-
-#include "Socket/Socket.h"
-#include "Socket/Endpoint.h"
-#include "EthernetInterface.h"
-#include <cstdint>
-
-/**
-UDP Socket
-*/
-class UDPSocket : public Socket {
-
-public:
-    /** Instantiate an UDP Socket.
-    */
-    UDPSocket();
-    
-    /** Init the UDP Client Socket without binding it to any specific port
-    \return 0 on success, -1 on failure.
-    */
-    int init(void);
-    
-    /** Bind a UDP Server Socket to a specific port
-    \param port The port to listen for incoming connections on
-    \return 0 on success, -1 on failure.
-    */
-    int bind(int port);
-    
-    /** Join the multicast group at the given address
-    \param address  The address of the multicast group
-    \return 0 on success, -1 on failure.
-    */
-    int join_multicast_group(EthernetInterface& eth, const char* address);
-    
-    /** Set the socket in broadcasting mode
-    \return 0 on success, -1 on failure.
-    */
-    int set_broadcasting(void);
-    
-    /** Send a packet to a remote endpoint
-    \param remote   The remote endpoint
-    \param packet   The packet to be sent
-    \param length   The length of the packet to be sent
-    \return the number of written bytes on success (>=0) or -1 on failure
-    */
-    int sendTo(Endpoint &remote, char *packet, int length);
-    
-    /** Receive a packet from a remote endpoint
-    \param remote   The remote endpoint
-    \param buffer   The buffer for storing the incoming packet data. If a packet
-           is too long to fit in the supplied buffer, excess bytes are discarded
-    \param length   The length of the buffer
-    \return the number of received bytes on success (>=0) or -1 on failure
-    */
-    int receiveFrom(Endpoint &remote, char *buffer, int length);
-};
-
-#endif
--- a/Socket/bsd/proxy_endpoint.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2013 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Daniele Lacamera <daniele.lacamera@tass.be>
-*********************************************************************/
-
-#ifndef __PICOTCP_BSD_LAYER
-#define __PICOTCP_BSD_LAYER
-
-extern "C"  {
-#include "pico_stack.h"
-#include "pico_tree.h"
-#include "pico_dns_client.h"
-#include "pico_socket.h"
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-#include "pico_config.h"
-#include "pico_ipv4.h"
-#include "pico_device.h"
-};
-#include "mbed.h"
-#include "rtos.h"
-#include "Queue.h"
-#include "PicoCondition.h"
-
-struct sockaddr;
-
-struct ip_addr_s {
-    uint32_t s_addr;
-};
-
-typedef struct ip_addr_s ip_addr_t;
-
-struct sockaddr_in 
-{
-    ip_addr_t sin_addr;
-    uint16_t sin_family;
-    uint16_t sin_port;
-};
-
-struct timeval {
-    uint32_t tv_sec;
-    uint32_t tv_usec;
-};
-
-/* Description of data base entry for a single host.  */
-struct hostent
-{
-  char *h_name;     /* Official name of host.  */
-  char **h_aliases;   /* Alias list.  */
-  int h_addrtype;   /* Host address type.  */
-  int h_length;     /* Length of address.  */
-  char **h_addr_list;   /* List of addresses from name server.  */
-# define  h_addr  h_addr_list[0] /* Address, for backward compatibility.*/
-};
-
-#ifndef PF_INET
-#define PF_INET     2
-#define PF_INET6    10
-#define AF_INET     PF_INET
-#define AF_INET6    PF_INET6
-
-#define SOCK_STREAM 1
-#define SOCK_DGRAM  2
-
-#define SOL_SOCKET 1
-#define SO_BROADCAST  6
-
-#define INADDR_ANY 0u
-
-#endif
-
-enum socket_state_e {
-    SOCK_OPEN,
-    SOCK_BOUND,
-    SOCK_LISTEN,
-    SOCK_CONNECTED,
-    SOCK_CLOSED
-};
-
-typedef int socklen_t;
-
-void picotcp_init(void);
-
-struct stack_endpoint * picotcp_socket(uint16_t net, uint16_t proto, uint16_t flags);
-int picotcp_state(struct stack_endpoint *);
-int picotcp_bind(struct stack_endpoint *, struct sockaddr *local_addr, socklen_t len);
-
-int picotcp_listen(struct stack_endpoint *, int queue);
-int picotcp_connect(struct stack_endpoint *, struct sockaddr *srv_addr, socklen_t len);
-struct stack_endpoint * picotcp_accept(struct stack_endpoint *, struct sockaddr *orig, socklen_t *);
-int picotcp_select(struct stack_endpoint *, struct timeval *timeout, int read, int write);
-
-int picotcp_send(struct stack_endpoint *,void * buff, int len, int flags);
-int picotcp_recv(struct stack_endpoint *,void * buff, int len, int flags);
-int picotcp_sendto(struct stack_endpoint *,void * buff, int len, struct sockaddr*,socklen_t);
-int picotcp_recvfrom(struct stack_endpoint *,void * buff, int len, struct sockaddr *, socklen_t *);
-int picotcp_read(struct stack_endpoint *,void *buf, int len);
-int picotcp_write(struct stack_endpoint *,void *buf, int len);
-int picotcp_setsockopt(struct stack_endpoint *, int option, void *value);
-int picotcp_getsockopt(struct stack_endpoint *, int option, void *value);
-struct hostent * picotcp_gethostbyname(const char *url);
-char * picotcp_gethostbyaddr(const char *ip);
-int picotcp_close(struct stack_endpoint *);
-// set blocking
-int picotcp_setblocking(struct stack_endpoint *,int blocking);
-int picotcp_join_multicast(struct stack_endpoint *,const char* address,const char* local);
-
-int picotcp_async_interrupt(void *);
-
-
-#endif
--- a/Socket/bsd/stack_endpoint.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-#include "wrapper.h"
-#include "rtos.h"
-#include "cmsis_os.h"
-#include "mbed.h"
-#include "Socket.h"
-#include "Mutex.h"
-
-//#define ptsock_dbg printf
-#define ptsock_dbg(...)
-
-int in_the_stack = 0;
-Mutex *PicoTcpLock;
-Queue<void,10> *PicoTcpEvents;
-
-static struct stack_endpoint *ep_accepting;
-static Thread * serverThread = NULL;
-
-#define pt_proxy_dbg(...) 
-
-/* Testing ng blocking mechanism */
-
-/* 
- * backend of select function, used in blocking (like picotcp_read()...) 
- * calls. Sleeps on the message queue 
- * 
- *
- * WARNING: PicoTcpLock (big stack lock) must be acquired before entering this.
- */
-
-static inline int __critical_select(struct stack_endpoint *ep, uint32_t time)
-{
-  int retval = 0;
-  uint16_t ev = ep->revents;
-  uint32_t in_time = PICO_TIME_MS();
-  
-  PicoTcpLock->unlock();
-  while ((ep->events & ep->revents) == 0) {
-    ep->queue->get(time);
-    if ((time != osWaitForever) && (PICO_TIME_MS() > in_time + time)) {
-        printf("TIMEOUT in critical select... (ev:%04x rev:%04x \n", ep->events, ep->revents);
-        PicoTcpLock->lock();
-        return 0;
-    }
-  }
-  PicoTcpLock->lock();
-  return 1;
-}
-
-static void wakeup(uint16_t ev, struct pico_socket *s)
-{
-  struct stack_endpoint *ep = (struct stack_endpoint *)s->priv;
-  if (!ep) {
-    if (ep_accepting != NULL) {
-        printf("Delivering %02x to accepting socket...\n", ev);
-        ep = ep_accepting;
-    } else {
-        printf("WAKEUP: socket not found! ev=%04x\n", ev);
-        return;
-    }
-  }
-  ep->revents |= ev;
-
-  if ((ev & PICO_SOCK_EV_CLOSE) || (ev & PICO_SOCK_EV_FIN)) {
-    ep->connected = 0;
-  }
-  if ((ev & PICO_SOCK_EV_CONN) || (ev & PICO_SOCK_EV_RD)) {
-      ep->connected = 1;
-  }
-  ep->queue->put((void *)0);
-}
-
-
-struct stack_endpoint *picotcp_socket(uint16_t net, uint16_t proto, uint16_t timeout)
-{
-  struct stack_endpoint *ep = (struct stack_endpoint *)pico_zalloc(sizeof(struct stack_endpoint));
-  uint16_t p_net = ((net == AF_INET6)?PICO_PROTO_IPV6:PICO_PROTO_IPV4);
-  uint16_t p_proto = ((proto == SOCK_DGRAM)?PICO_PROTO_UDP:PICO_PROTO_TCP);
-  PicoTcpLock->lock();
-  ep->s = pico_socket_open( p_net, p_proto, &wakeup );
-  if (ep->s == NULL) {
-    delete(ep->queue);
-    pico_free(ep);
-    ep = NULL;
-    printf("Error opening socket!\n");
-  } else {
-    ep->s->priv = ep;
-    printf("Added socket (open)\n");
-    ep->queue = new Queue<void,1>();
-  }
-  PicoTcpLock->unlock();
-  return ep;
-}
-
-
-int picotcp_state(struct stack_endpoint *ep)
-{
-/* TODO: return one of:
-    SOCK_OPEN,
-    SOCK_BOUND,
-    SOCK_LISTEN,
-    SOCK_CONNECTED,
-    SOCK_CLOSED
-*/
-    return ep->state;
-}
-
-int picotcp_bind(struct stack_endpoint *ep, struct sockaddr *_local_addr, socklen_t len)
-{
-  int ret;
-  struct sockaddr_in *local_addr;
-  local_addr = (struct sockaddr_in *)_local_addr;
-  
-  PicoTcpLock->lock();
-  ret = pico_socket_bind(ep->s, (struct pico_ip4 *)(&local_addr->sin_addr.s_addr), &local_addr->sin_port);
-  PicoTcpLock->unlock();
-  return ret;
-}
-
-int picotcp_listen(struct stack_endpoint *ep, int queue)
-{
-  int ret;
-  PicoTcpLock->lock();
-  ret = pico_socket_listen(ep->s, queue);
-  ep_accepting = (struct stack_endpoint *) pico_zalloc(sizeof(struct stack_endpoint));
-  ep_accepting->queue = new Queue<void,1>();
-  if (!ep_accepting)
-    ret = -1;
-  PicoTcpLock->unlock();
-  return ret;
-}
-
-int picotcp_connect(struct stack_endpoint *ep, struct sockaddr *_srv_addr, socklen_t len)
-{
-  int retval;
-  struct sockaddr_in *srv_addr;
-  srv_addr = (struct sockaddr_in *)_srv_addr;
-  PicoTcpLock->lock();
-  pico_socket_connect(ep->s, (struct pico_ip4 *)(&srv_addr->sin_addr.s_addr), srv_addr->sin_port);
-  ep->events = PICO_SOCK_EV_CONN | PICO_SOCK_EV_ERR;
-  __critical_select(ep, osWaitForever);
-  if ((ep->revents & PICO_SOCK_EV_CONN) && ep->connected) {
-    ep->revents &= (~PICO_SOCK_EV_CONN);
-    ep->revents |= PICO_SOCK_EV_WR;
-    ptsock_dbg("Established. sock state: %x\n", ep->s->state);
-    retval = 0;
-  } else {
-    retval = -1;
-  }
-  PicoTcpLock->unlock();
-  return retval;
-}
-
-struct stack_endpoint *picotcp_accept(struct stack_endpoint *ep, struct sockaddr *_cli_addr, socklen_t *len)
-{
-  int retval;
-  struct stack_endpoint *aep = ep_accepting;
-  struct sockaddr_in *cli_addr = (struct sockaddr_in *)_cli_addr;
-  ep_accepting = (struct stack_endpoint *) pico_zalloc(sizeof(struct stack_endpoint));
-  if (ep_accepting)
-    ep_accepting->queue = new Queue<void,1>();
-  
-  
-  if (!aep)
-    return aep;
-  
-  PicoTcpLock->lock();
-  ep->events = PICO_SOCK_EV_CONN | PICO_SOCK_EV_ERR;
-  __critical_select(ep, osWaitForever);
-  if (ep->revents & PICO_SOCK_EV_CONN) {
-    printf("Calling Accept\n");
-    aep->s = pico_socket_accept(ep->s, (struct pico_ip4 *)(&cli_addr->sin_addr.s_addr), &cli_addr->sin_port);
-    printf("Accept returned\n");
-    aep->s->priv = aep;
-    ep->revents &= (~PICO_SOCK_EV_CONN);
-    aep->revents |= PICO_SOCK_EV_WR;
-    printf("Added socket (accept)\n");
-    
-    *len = sizeof(struct sockaddr_in);
-    ptsock_dbg("Established. sock state: %x\n", aep->s->state);
-  } else {
-    pico_free(aep);
-    aep = NULL;
-  }
-  PicoTcpLock->unlock();
-  return aep;
-}
-
-int picotcp_select(struct stack_endpoint *ep, struct timeval *timeout, int read, int write)
-{
-  int ret;
-  ep->timeout |= timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
-  ep->events = PICO_SOCK_EV_ERR;
-  ep->events |= PICO_SOCK_EV_FIN;
-  ep->events |= PICO_SOCK_EV_CLOSE;
-  ep->events |= PICO_SOCK_EV_CONN;
-  if (read) {
-    ep->events |= PICO_SOCK_EV_RD;
-  }
-  if (write)
-    ep->events |= PICO_SOCK_EV_WR;
-  ret = __critical_select(ep, ep->timeout);
-  return ret;
-}
-
-int picotcp_send(struct stack_endpoint *ep,void * buff, int len, int flags)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_recv(struct stack_endpoint *ep,void * buff, int len, int flags)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_sendto(struct stack_endpoint *ep,void * buff, int len, struct sockaddr *a, socklen_t l)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_recvfrom(struct stack_endpoint *ep,void * buff, int len, struct sockaddr *a, socklen_t *l)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_read(struct stack_endpoint *ep,void *buf, int len)
-{
-  int retval = 0;
-  int tot_len = 0;
-  if (!buf || (len <= 0))
-     return  0;
-  PicoTcpLock->lock();
-  while (tot_len < len) {
-    retval = pico_socket_read(ep->s, ((uint8_t *)buf) + tot_len ,  len - tot_len);
-    if (retval == 0) {
-        if (tot_len < len)
-            ep->revents &= ~PICO_SOCK_EV_RD;
-        break;
-    }
-    if (retval < 0) {
-       tot_len = -1;
-       break;
-    }
-    tot_len += retval;
-  }
-  PicoTcpLock->unlock();
-  return tot_len;
-}
-
-int picotcp_write(struct stack_endpoint *ep,void *buf, int len)
-{
-  int retval = 0;
-  int tot_len = 0;
-  if (!buf || (len <= 0))
-     return  0;
-  PicoTcpLock->lock();
-  while (tot_len < len) {
-    retval = pico_socket_write(ep->s, ((uint8_t *)buf) + tot_len ,  len - tot_len);
-    retval = pico_socket_read(ep->s, ((uint8_t *)buf) + tot_len ,  len - tot_len);
-    if (retval == 0) {
-        if (tot_len < len)
-            ep->revents &= ~PICO_SOCK_EV_RD;
-        break;
-    }
-    if (retval < 0) {
-       tot_len = -1;
-       break;
-    }
-    tot_len += retval;
-    
-  }
-  PicoTcpLock->unlock();
-  picotcp_async_interrupt(NULL);
-  return tot_len; 
-}
-
-
-int picotcp_setsockopt(struct stack_endpoint *ep, int option, void *value)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_getsockopt(struct stack_endpoint *ep, int option, void *value)
-{
-  /* TODO */
-  return -1;
-}
-
-int picotcp_close(struct stack_endpoint *ep)
-{
-  PicoTcpLock->lock();
-  pico_socket_close(ep->s);
-  ep->s->priv = NULL;
-  printf("Socket closed!\n");
-  delete(ep->queue);
-  pico_free(ep);
-  PicoTcpLock->unlock();
-}
-
-int picotcp_join_multicast(struct stack_endpoint *ep,const char* address,const char* local)
-{
-  /* TODO */
-  return -1;
-}
-
-
-
-void pico_wrapper_loop(const void * arg)
-{
-  (void)arg;
-  int ret = 0;
-  struct pico_device *dev;
-  while(1) {
-    
-    osEvent evt = PicoTcpEvents->get(2);
-    
-    if (evt.status == osEventMessage) {
-        dev = (struct pico_device *)evt.value.p;
-    } else {
-        dev = NULL;
-    }
-    
-    if (dev && dev->dsr){ 
-      PicoTcpLock->lock();
-      dev->dsr(dev, 200);
-      pico_stack_tick();
-      PicoTcpLock->unlock();
-    } else {
-      if (PicoTcpLock->trylock()) {
-        pico_stack_tick();
-        PicoTcpLock->unlock();
-      }
-    }
-  }
-}
-
-void picotcp_start(void)
-{
-  if (serverThread == NULL) {
-    PicoTcpLock = new Mutex();
-    PicoTcpEvents = new Queue<void,10>();
-    printf (" *** PicoTCP initialized *** \n");
-    serverThread = new Thread(pico_wrapper_loop);
-    serverThread->set_priority(osPriorityIdle);
-  }
-}
-
-void picotcp_init(void)
-{
-  picotcp_start(); 
-}
-
-int picotcp_async_interrupt(void *arg)
-{
-    PicoTcpEvents->put(arg);
-}
--- a/Socket/bsd/wrapper.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#ifndef ____WRAPPER_H
-#define ____WRAPPER_H
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-#include "pico_ipv4.h"
-#include "pico_ipv6.h"
-#include "pico_stack.h"
-#include "pico_socket.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#include "mbed.h"
-#include "rtos.h"
-
-struct stack_endpoint {
-  uint16_t sock_fd;
-  struct pico_socket *s;
-  int connected;
-  int events;
-  int revents;
-  Queue<void,1> *queue;//receive queue of 1 element of type 
-  uint32_t timeout; // this is used for timeout sockets
-  int state; // for pico_state
-};
-
-void picotcp_start(void);
-struct stack_endpoint *pico_get_socket(uint16_t sockfd);
-#endif
--- a/include/PicoCondition.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#ifndef __PICOMUTEX__
-#define __PICOMUTEX__
-/*
-* Cross-Threading Mutex Class
-*/
-
-#include "mbed.h"
-#include "rtos.h"
-#include "Queue.h"
-
-class PicoCondition
-{
-    private:
-        Queue <int,1> * queue;
-    public:
-        PicoCondition()
-        {
-            queue = new Queue<int,1>();
-        }
-        
-        ~PicoCondition()
-        {
-            if(queue)
-            {
-                delete queue;
-                queue = NULL;
-            }
-        }
-        
-        bool unlock(uint32_t millisec=0,int * ptr=NULL)
-        {
-            osStatus status;
-            status = queue->put(ptr, millisec);
-            return (status == osEventMessage || status == osOK);
-        }
-        
-        bool lock(uint32_t millisec=osWaitForever)
-        {
-            osEvent event = queue->get(millisec);
-            return (event.status == osEventMessage || event.status == osOK);
-        }
-};
-
-
-#endif
\ No newline at end of file
--- a/include/arch/pico_mbed.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-Do not redistribute without a written permission by the Copyright
-holders.
-
-File: pico_mbed.h
-Author: Toon Peters
-*********************************************************************/
-
-#ifndef PICO_SUPPORT_MBED
-#define PICO_SUPPORT_MBED
-#include <stdio.h>
-
-//#include "mbed.h"
-//#include "serial_api.h"
-
-/*
-Debug needs initialization:
-* void serial_init       (serial_t *obj, PinName tx, PinName rx);
-* void serial_baud       (serial_t *obj, int baudrate);
-* void serial_format     (serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
-*/
-
-#define dbg(...) 
-#define pico_zalloc(x) calloc(x, 1)
-#define pico_free(x) free(x)
-
-#ifdef MEMORY_MEASURE // in case, comment out the two defines above me.
-extern uint32_t max_mem;
-extern uint32_t cur_mem;
-
-static inline void * pico_zalloc(int x)
-{
-    uint32_t *ptr;
-    if ((cur_mem + x )> (10 * 1024))
-        return NULL;
-        
-    ptr = (uint32_t *)calloc(x + 4, 1);
-    *ptr = (uint32_t)x;
-    cur_mem += x;
-    if (cur_mem > max_mem) {
-        max_mem = cur_mem;
-        printf("max mem: %lu\n", max_mem);
-    }
-    return (void*)(ptr + 1);
-}
-
-static inline void pico_free(void *x)
-{
-    uint32_t *ptr = (uint32_t*)(((uint8_t *)x) - 4);
-    cur_mem -= *ptr;
-    free(ptr);
-}
-#endif
-
-#define PICO_SUPPORT_MUTEX
-extern void *pico_mutex_init(void);
-extern void pico_mutex_lock(void*);
-extern void pico_mutex_unlock(void*);
-
-
-extern uint32_t os_time;
-
-static inline unsigned long PICO_TIME(void)
-{
-  return (unsigned long)os_time / 1000;
-}
-
-static inline unsigned long PICO_TIME_MS(void)
-{
-  return (unsigned long)os_time;
-}
-
-static inline void PICO_IDLE(void)
-{
-  // TODO needs implementation
-}
-/*
-static inline void PICO_DEBUG(const char * formatter, ... )
-{
-  char buffer[256];
-  char *ptr;
-  va_list args;
-  va_start(args, formatter);
-  vsnprintf(buffer, 256, formatter, args);
-  ptr = buffer;
-  while(*ptr != '\0')
-    serial_putc(serial_t *obj, (int) (*(ptr++)));
-  va_end(args);
-  //TODO implement serial_t
-}*/
-
-#endif
--- a/include/heap.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-
-#define DECLARE_HEAP(type, orderby) \
-struct heap_##type {   \
-  uint32_t size;       \
-  uint32_t n;       \
-  type *top;        \
-}; \
-typedef struct heap_##type heap_##type; \
-static inline int heap_insert(struct heap_##type *heap, type *el) \
-{ \
-  int i; \
-  type * newTop; \
-  if (++heap->n >= heap->size) {                                                \
-    newTop = pico_zalloc((heap->n + 1) * sizeof(type)); \
-    if(!newTop) \
-      return -1; \
-    if (heap->top)  {\
-      memcpy(newTop,heap->top,heap->n*sizeof(type)); \
-      pico_free(heap->top); \
-    } \
-    heap->top = newTop;                \
-    heap->size++;                                                                \
-  }                                                                              \
-  if (heap->n == 1) {                                                          \
-    memcpy(&heap->top[1], el, sizeof(type));                                    \
-    return 0;                                                                    \
-  }                                                                              \
-  for (i = heap->n; ((i > 1) && (heap->top[i / 2].orderby > el->orderby)); i /= 2) {          \
-    memcpy(&heap->top[i], &heap->top[i / 2], sizeof(type));                        \
-  }              \
-  memcpy(&heap->top[i], el, sizeof(type));                                      \
-  return 0;                                                                       \
-} \
-static inline int heap_peek(struct heap_##type *heap, type *first) \
-{ \
-  type *last;              \
-  int i, child;          \
-  if(heap->n == 0) {      \
-    return -1;             \
-  }                      \
-  memcpy(first, &heap->top[1], sizeof(type));      \
-  last = &heap->top[heap->n--];                  \
-  for(i = 1; (i * 2) <= heap->n; i = child) {      \
-    child = 2 * i;                                \
-    if ((child != heap->n) &&                     \
-        (heap->top[child + 1]).orderby             \
-        < (heap->top[child]).orderby)            \
-        child++;                                \
-    if (last->orderby >                         \
-        heap->top[child].orderby)                \
-        memcpy(&heap->top[i], &heap->top[child],\
-                sizeof(type));                    \
-    else                                        \
-        break;                                    \
-  }                                              \
-  memcpy(&heap->top[i], last, sizeof(type));      \
-  return 0;                                      \
-} \
-static inline type *heap_first(heap_##type *heap)  \
-{ \
-  if (heap->n == 0)      \
-    return NULL;        \
-  return &heap->top[1];  \
-} \
-static inline heap_##type *heap_init(void) \
-{ \
-  heap_##type *p = (heap_##type *)pico_zalloc(sizeof(heap_##type));  \
-  return p;      \
-} \
-static inline void heap_destroy(heap_##type *h) \
-{ \
-  pico_free(h->top);   \
-  pico_free(h);       \
-} \
-
-
--- a/include/pico_addressing.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_ADDRESSING
-#define _INCLUDE_PICO_ADDRESSING
-#include <stdint.h>
-
-
-struct pico_ip4
-{
-  uint32_t addr;
-};
-#define PICO_SIZE_IP4 4
-
-
-struct pico_ip6
-{
-  uint8_t addr[16];
-};
-#define PICO_SIZE_IP6 16
-
-struct pico_eth
-{
-  uint8_t addr[6];
-  uint8_t padding[2];
-};
-#define PICO_SIZE_ETH 6
-
-extern const uint8_t PICO_ETHADDR_ALL[];
-
-
-struct pico_trans
-{
-  uint16_t sport;
-  uint16_t dport;
-
-};
-#define PICO_SIZE_TRANS 8
-
-
-/* Here are some protocols. */
-#define PICO_PROTO_IPV4   0
-#define PICO_PROTO_ICMP4  1
-#define PICO_PROTO_IGMP  2
-#define PICO_PROTO_TCP    6
-#define PICO_PROTO_UDP    17
-#define PICO_PROTO_IPV6   41
-#define PICO_PROTO_ICMP6  58
-
-#endif
--- a/include/pico_arp.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_ARP
-#define _INCLUDE_PICO_ARP
-#include "pico_eth.h"
-#include "pico_device.h"
-
-int pico_arp_receive(struct pico_frame *);
-
-
-struct pico_eth *pico_arp_get(struct pico_frame *f);
-int pico_arp_query(struct pico_device *dev, struct pico_ip4 *dst);
-
-#define PICO_ARP_STATUS_REACHABLE 0x00
-#define PICO_ARP_STATUS_PERMANENT 0x01
-#define PICO_ARP_STATUS_STALE     0x02
-
-
-struct pico_eth *pico_arp_lookup(struct pico_ip4 *dst);
-struct pico_ip4 *pico_arp_reverse_lookup(struct pico_eth *dst);
-int pico_arp_create_entry(uint8_t* hwaddr, struct pico_ip4 ipv4, struct pico_device* dev);
-#endif
--- a/include/pico_config.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_CONFIG
-#define _INCLUDE_PICO_CONFIG
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pico_constants.h"
-
-
-#define MBED
-//#define PICO_SUPPORT_CRC
-#define PICO_SUPPORT_DEVLOOP
-#define PICO_SUPPORT_DHCPC
-#define PICO_SUPPORT_DHCPD
-#define PICO_SUPPORT_DNS_CLIENT
-#define PICO_SUPPORT_HTTP_CLIENT
-#define PICO_SUPPORT_HTTP
-#define PICO_SUPPORT_HTTP_SERVER
-#define PICO_SUPPORT_ICMP4
-#define PICO_SUPPORT_PING
-#define PICO_SUPPORT_IGMP2
-//#define PICO_SUPPORT_IPFILTER
-//#define PICO_SUPPORT_IPFRAG
-#define PICO_SUPPORT_IPV4
-#define PICO_SUPPORT_MCAST
-#define PICO_SUPPORT_NAT
-#define PICO_SUPPORT_TCP
-#define PICO_SUPPORT_UDP
-# include "arch/pico_mbed.h"
-#endif
--- a/include/pico_constants.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_CONST
-#define _INCLUDE_PICO_CONST
-/* Included from pico_config.h */
-/** Endian-dependant constants **/
-
-extern volatile unsigned long pico_tick;
-
-#ifdef PICO_BIGENDIAN
-
-# define PICO_IDETH_IPV4 0x0800
-# define PICO_IDETH_ARP 0x0806
-# define PICO_IDETH_IPV6 0x86DD
-
-# define PICO_ARP_REQUEST 0x0001
-# define PICO_ARP_REPLY   0x0002
-# define PICO_ARP_HTYPE_ETH 0x0001
-
-#define short_be(x) (x)
-#define long_be(x) (x)
-
-static inline uint16_t short_from(void *_p)
-{
-  unsigned char *p = (unsigned char *)_p;
-  uint16_t r, p0, p1;
-  p0 = p[0];
-  p1 = p[1];
-  r = (p0 << 8) + p1;
-  return r;
-}
-
-static inline uint32_t long_from(void *_p)
-{
-  unsigned char *p = (unsigned char *)_p;
-  uint32_t r, p0, p1, p2, p3;
-  p0 = p[0];
-  p1 = p[1];
-  p2 = p[2];
-  p3 = p[3];
-  r = (p0 << 24) + (p1 << 16) + (p2 << 8) + p3;
-  return r;
-}
-
-#else
-
-static inline uint16_t short_from(void *_p)
-{
-  unsigned char *p = (unsigned char *)_p;
-  uint16_t r, p0, p1;
-  p0 = p[0];
-  p1 = p[1];
-  r = (p1 << 8) + p0;
-  return r;
-}
-
-static inline uint32_t long_from(void *_p)
-{
-  unsigned char *p = (unsigned char *)_p;
-  uint32_t r, p0, p1, p2, p3;
-  p0 = p[0];
-  p1 = p[1];
-  p2 = p[2];
-  p3 = p[3];
-  r = (p3 << 24) + (p2 << 16) + (p1 << 8) + p0;
-  return r;
-}
-
-
-# define PICO_IDETH_IPV4 0x0008
-# define PICO_IDETH_ARP 0x0608
-# define PICO_IDETH_IPV6 0xDD86
-
-# define PICO_ARP_REQUEST 0x0100
-# define PICO_ARP_REPLY   0x0200
-# define PICO_ARP_HTYPE_ETH 0x0100
-
-static inline uint16_t short_be(uint16_t le)
-{
-  return ((le & 0xFF) << 8) | ((le >> 8) & 0xFF);
-}
-
-static inline uint32_t long_be(uint32_t le)
-{
-  uint8_t *b = (uint8_t *)&le;
-  uint32_t be = 0;
-  uint32_t b0, b1, b2;
-  b0 = b[0];
-  b1 = b[1];
-  b2 = b[2];
-  be = b[3] + (b2 << 8) + (b1 << 16) + (b0 << 24);
-  return be;
-}
-#endif
-
-
-/* Add well-known host numbers here. (bigendian constants only beyond this point) */
-#define PICO_IP4_ANY (0x00000000U)
-#define PICO_IP4_BCAST (0xffffffffU)
-
-/* defined in modules/pico_ipv6.c */
-#ifdef PICO_SUPPORT_IPV6
-extern const uint8_t PICO_IPV6_ANY[PICO_SIZE_IP6];
-#endif
-
-static inline uint32_t pico_hash(char *name)
-{
-  unsigned long hash = 5381;
-  int c;
-  while ((c = *name++))
-    hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-  return hash;
-}
-
-/* Debug */
-//#define PICO_SUPPORT_DEBUG_MEMORY
-//#define PICO_SUPPORT_DEBUG_TOOLS
-#endif
--- a/include/pico_device.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_DEVICE 
-#define _INCLUDE_PICO_DEVICE 
-#include "pico_queue.h"
-#include "pico_frame.h"
-#include "pico_addressing.h"
-#include "pico_tree.h"
-#define MAX_DEVICE_NAME 16
-
-
-struct pico_ethdev {
-  struct pico_eth mac;
-};
-
-struct pico_device {
-  char name[MAX_DEVICE_NAME];
-  uint32_t hash;
-  uint32_t overhead;
-  struct pico_ethdev *eth; /* Null if non-ethernet */
-  struct pico_queue *q_in;
-  struct pico_queue *q_out;
-  int (*send)(struct pico_device *self, void *buf, int len); /* Send function. Return 0 if busy */
-  int (*poll)(struct pico_device *self, int loop_score);
-  void(*destroy)(struct pico_device *self);
-  int (*dsr)(struct pico_device *self, int loop_score);
-  int __serving_interrupt;
-};
-
-int pico_device_init(struct pico_device *dev, char *name, uint8_t *mac);
-void pico_device_destroy(struct pico_device *dev);
-int pico_devices_loop(int loop_score, int direction);
-struct pico_device* pico_get_device(char* name);
-int pico_device_broadcast(struct pico_frame * f);
-
-#endif
--- a/include/pico_eth.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_ETH
-#define _INCLUDE_PICO_ETH
-#include "pico_addressing.h"
-#include "pico_ipv4.h"
-#include "pico_ipv6.h"
-
-
-struct __attribute__((packed)) pico_eth_hdr {
-  uint8_t   daddr[6];
-  uint8_t   saddr[6];
-  uint16_t  proto;
-};
-
-#define PICO_SIZE_ETHHDR 14
-
-#endif
--- a/include/pico_frame.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_FRAME
-#define _INCLUDE_PICO_FRAME
-#include "pico_config.h"
-
-
-#define PICO_FRAME_FLAG_BCAST   (0x01)
-#define PICO_FRAME_FLAG_SACKED  (0x80)
-#define IS_BCAST(f) ((f->flags & PICO_FRAME_FLAG_BCAST) == PICO_FRAME_FLAG_BCAST)
-
-
-struct pico_socket;
-
-
-struct pico_frame {
-
-  /* Connector for queues */
-  struct pico_frame *next;
-
-  /* Start of the whole buffer, total frame length. */
-  unsigned char *buffer;
-  uint32_t      buffer_len;
-
-  /* For outgoing packets: this is the meaningful buffer. */
-  unsigned char *start;
-  uint32_t      len;
-
-  /* Pointer to usage counter */
-  uint32_t *usage_count;
-
-  /* Pointer to protocol headers */
-  uint8_t *datalink_hdr;
-
-  uint8_t *net_hdr;
-  int net_len;
-  uint8_t *transport_hdr;
-  int transport_len;
-  uint8_t *app_hdr;
-  int app_len;
-
-  /* Pointer to the phisical device this packet belongs to.
-   * Should be valid in both routing directions
-   */
-  struct pico_device *dev;
-
-  unsigned long timestamp;
-
-  /* Failures due to bad datalink addressing. */
-  uint16_t failure_count;
-
-  /* Protocol over IP */
-  uint8_t  proto;
-
-  /* PICO_FRAME_FLAG_* */
-  uint8_t flags;
-
-  /* Pointer to payload */
-  unsigned char *payload;
-  int payload_len;
-
-#ifdef PICO_SUPPORT_IPFRAG
-  /* Payload fragmentation info (big endian)*/
-  uint16_t frag;
-#endif
-
-  /* Pointer to socket */
-  struct pico_socket *sock;
-
-  /* Pointer to transport info, used to store remote UDP duple (IP + port) */
-  void *info;
-
-  /*Priority. "best-effort" priority, the default value is 0. Priority can be in between -10 and +10*/
-  int8_t priority;
-};
-
-/** frame alloc/dealloc/copy **/
-void pico_frame_discard(struct pico_frame *f);
-struct pico_frame *pico_frame_copy(struct pico_frame *f);
-struct pico_frame *pico_frame_deepcopy(struct pico_frame *f);
-struct pico_frame *pico_frame_alloc(int size);
-uint16_t pico_checksum(void *inbuf, int len);
-uint16_t pico_dualbuffer_checksum(void *b1, int len1, void *b2, int len2);
-
-static inline int pico_is_digit(char c)
-{
-  if (c < '0' || c > '9')
-    return 0;
-  return 1;
-}
-
-#endif
--- a/include/pico_module_eth.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _PICO_MODULE_IPV4_H
-#define _PICO_MODULE_IPV4_H
-
-struct pico_arp_entry {
-  struct eth dest;
-#ifdef PICO_CONFIG_IPV4
-  struct ipv4 addr_ipv4;
-#endif
-  RB_ENTRY(pico_arp_entry) node;
-};
-
-/* Configured device */
-struct pico_eth_link {
-  struct pico_device *dev;
-  struct eth address;
-  struct eth netmask;
-  RB_ENTRY(pico_eth_link) node;
-};
-
-#ifndef IS_MODULE_ETH
-# define _mod extern
-#else
-# define _mod
-#endif
-_mod struct pico_module pico_module_eth;
-#undef _mod
-
-#endif
--- a/include/pico_protocol.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_PROTOCOL 
-#define _INCLUDE_PICO_PROTOCOL 
-#include <stdint.h>
-#include "pico_queue.h"
-
-#define PICO_LOOP_DIR_IN   1
-#define PICO_LOOP_DIR_OUT  2
-
-enum pico_layer {
-  PICO_LAYER_DATALINK = 2,  /* Ethernet only. */
-  PICO_LAYER_NETWORK = 3,   /* IPv4, IPv6, ARP. Arp is there because it communicates with L2 */
-  PICO_LAYER_TRANSPORT = 4, /* UDP, TCP, ICMP */
-  PICO_LAYER_SOCKET = 5     /* Socket management */
-};
-
-enum pico_err_e {
-  PICO_ERR_NOERR = 0,
-  PICO_ERR_EPERM,
-  PICO_ERR_ENOENT,
-  /* ... */
-  PICO_ERR_EINTR = 4,
-  PICO_ERR_EIO,
-  PICO_ERR_ENXIO, 
-  /* ... */
-  PICO_ERR_EAGAIN = 11,
-  PICO_ERR_ENOMEM,
-  PICO_ERR_EACCESS,
-  PICO_ERR_EFAULT,
-  /* ... */
-  PICO_ERR_EBUSY = 16,
-  PICO_ERR_EEXIST = 17,
-  /* ... */
-  PICO_ERR_EINVAL = 22,
-  /* ... */
-  PICO_ERR_EPROTO = 71,
-  PICO_ERR_ENOPROTOOPT = 92,
-  PICO_ERR_EPROTONOSUPPORT = 93,
-
-  /* ... */
-  PICO_ERR_EADDRINUSE = 98,
-  PICO_ERR_EADDRNOTAVAIL,
-  PICO_ERR_ENETUNREACH,
-
-  /* ... */
-  PICO_ERR_ECONNRESET = 104,
-
-  /* ... */
-  PICO_ERR_EISCONN = 106,
-  PICO_ERR_ENOTCONN,
-  PICO_ERR_ESHUTDOWN,
-  /* ... */
-  PICO_ERR_ETIMEDOUT = 110,
-  PICO_ERR_ECONNREFUSED = 111,
-  PICO_ERR_EHOSTDOWN,
-  PICO_ERR_EHOSTUNREACH,
-  /* ... */
-  PICO_ERR_EOPNOTSUPP = 122,
-
-};
-
-typedef enum pico_err_e pico_err_t;
-extern volatile pico_err_t pico_err;
-
-#define IS_IPV6(f) ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x60)
-#define IS_IPV4(f) ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x40)
-
-#define MAX_PROTOCOL_NAME 16
-
-struct pico_protocol {
-  char name[MAX_PROTOCOL_NAME];
-  uint32_t hash;
-  enum pico_layer layer;
-  int proto_number;
-  struct pico_queue *q_in;
-  struct pico_queue *q_out;
-  struct pico_frame *(*alloc)(struct pico_protocol *self, int size); /* Frame allocation. */
-  int (*push) (struct pico_protocol *self, struct pico_frame *p);    /* Push function, for active outgoing pkts from above */
-  int (*process_out)(struct pico_protocol *self, struct pico_frame *p); /* Send loop. */
-  int (*process_in)(struct pico_protocol *self, struct pico_frame *p); /* Recv loop. */
-};
-
-int pico_protocols_loop(int loop_score);
-void pico_protocol_init(struct pico_protocol *p);
-
-int pico_protocol_datalink_loop(int loop_score, int direction);
-int pico_protocol_network_loop(int loop_score, int direction);
-int pico_protocol_transport_loop(int loop_score, int direction);
-int pico_protocol_socket_loop(int loop_score, int direction);
-
-#endif
--- a/include/pico_queue.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_QUEUE
-#define _INCLUDE_PICO_QUEUE
-#include <stdint.h>
-#include "pico_config.h"
-#include "pico_frame.h"
-
-#define Q_LIMIT 0
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-struct pico_queue {
-  uint32_t frames;
-  uint32_t size;
-  uint32_t max_frames;
-  uint32_t max_size;
-  struct pico_frame *head;
-  struct pico_frame *tail;
-#ifdef PICO_SUPPORT_MUTEX
-  void * mutex;
-#endif
-  uint8_t shared;
-};
-
-#ifdef PICO_SUPPORT_MUTEX
-#define LOCK(x) {\
-  if (x == NULL) \
-    x = pico_mutex_init(); \
-  pico_mutex_lock(x); \
-}
-#define UNLOCK(x) pico_mutex_unlock(x);
-
-#else 
-#define LOCK(x) do{}while(0)
-#define UNLOCK(x) do{}while(0)
-#endif
-
-#ifdef PICO_SUPPORT_DEBUG_TOOLS
-static void debug_q(struct pico_queue *q)
-{
-  struct pico_frame *p = q->head;
-  dbg("%d: ", q->frames);
-  while(p) {
-    dbg("(%p)-->", p);
-    p = p->next;
-  }
-  dbg("X\n");
-}
-
-#else
-
-#define debug_q(x) do{}while(0)
-#endif
-
-static inline int pico_enqueue(struct pico_queue *q, struct pico_frame *p)
-{
-  if ((q->max_frames) && (q->max_frames <= q->frames))
-    return -1;
-    
-  if ((Q_LIMIT) && (Q_LIMIT < p->buffer_len + q->size))
-    return -1;
-    
-  if ((q->max_size) && (q->max_size < (p->buffer_len + q->size)))
-    return -1;
-
-  if (q->shared)
-    LOCK(q->mutex);
-
-  p->next = NULL;
-  if (!q->head) {
-    q->head = p;
-    q->tail = p;
-    q->size = 0;
-    q->frames = 0;
-  } else {
-    q->tail->next = p;
-    q->tail = p;
-  }
-  q->size += p->buffer_len;
-  q->frames++;
-  debug_q(q);
-
-  if (q->shared)
-    UNLOCK(q->mutex);
-  return q->size;
-}
-
-static inline struct pico_frame *pico_dequeue(struct pico_queue *q)
-{
-  struct pico_frame *p = q->head;
-  if (q->frames < 1)
-    return NULL;
-  if (q->shared)
-    LOCK(q->mutex);
-
-  q->head = p->next;
-  q->frames--;
-  q->size -= p->buffer_len;
-  if (q->head == NULL)
-    q->tail = NULL;
-  debug_q(q);
-  p->next = NULL;
-  if (q->shared)
-    UNLOCK(q->mutex);
-  return p;
-}
-
-static inline struct pico_frame *pico_queue_peek(struct pico_queue *q)
-{
-  struct pico_frame *p = q->head;
-  if (q->frames < 1)
-    return NULL;
-  debug_q(q);
-  return p;
-}
-
-static inline void pico_queue_empty(struct pico_queue *q)
-{
-  struct pico_frame *p = pico_dequeue(q);
-  while(p) {
-    pico_free(p);
-    p = pico_dequeue(q);
-  }
-}
-
-static inline void pico_queue_protect(struct pico_queue *q)
-{
-  q->shared = 1;
-}
-
-#endif
--- a/include/pico_socket.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_SOCKET
-#define _INCLUDE_PICO_SOCKET
-#include "pico_queue.h"
-#include "pico_addressing.h"
-#include "pico_config.h"
-#include "pico_protocol.h"
-
-//#define PICO_DEFAULT_SOCKETQ (128 * 1024)
-#define PICO_DEFAULT_SOCKETQ (4 * 1024)
-
-#define PICO_SHUT_RD   1
-#define PICO_SHUT_WR   2
-#define PICO_SHUT_RDWR 3
-
-
-struct pico_socket {
-  struct pico_protocol *proto;
-  struct pico_protocol *net;
-
-  union {
-    struct pico_ip4 ip4;
-    struct pico_ip6 ip6;
-  } local_addr;
-
-  union {
-    struct pico_ip4 ip4;
-    struct pico_ip6 ip6;
-  } remote_addr;
-
-  uint16_t local_port;
-  uint16_t remote_port;
-
-  struct pico_queue q_in;
-  struct pico_queue q_out;
-
-  void (*wakeup)(uint16_t ev, struct pico_socket *s);
-
-
-#ifdef PICO_SUPPORT_TCP
-  /* For the TCP backlog queue */
-  struct pico_socket *backlog;
-  struct pico_socket *next;
-  struct pico_socket *parent;
-  int max_backlog;
-#endif
-#ifdef PICO_SUPPORT_MCAST
-  struct pico_tree *MCASTListen;
-#endif
-  uint16_t ev_pending;
-
-  struct pico_device *dev;
-
-  /* Private field. */
-  int id;
-  uint16_t state;
-  uint16_t opt_flags;
-  void *priv;
-};
-
-struct pico_remote_duple {
-  union {
-    struct pico_ip4 ip4;
-    struct pico_ip6 ip6;
-  } remote_addr;
-
-  uint16_t remote_port;
-};
-
-
-/* request struct for multicast socket opt */
-struct pico_ip_mreq {
-  struct pico_ip4 mcast_group_addr;
-  struct pico_ip4 mcast_link_addr;
-};
-
-struct pico_ip_mreq_source {
-  struct pico_ip4 mcast_group_addr;
-  struct pico_ip4 mcast_source_addr;
-  struct pico_ip4 mcast_link_addr;
-};
-
-#define PICO_SOCKET_STATE_UNDEFINED       0x0000
-#define PICO_SOCKET_STATE_SHUT_LOCAL      0x0001
-#define PICO_SOCKET_STATE_SHUT_REMOTE     0x0002
-#define PICO_SOCKET_STATE_BOUND           0x0004
-#define PICO_SOCKET_STATE_CONNECTED       0x0008
-#define PICO_SOCKET_STATE_CLOSING         0x0010
-#define PICO_SOCKET_STATE_CLOSED          0x0020
-
-# define PICO_SOCKET_STATE_TCP                0xFF00
-# define PICO_SOCKET_STATE_TCP_UNDEF          0x00FF
-# define PICO_SOCKET_STATE_TCP_CLOSED         0x0100
-# define PICO_SOCKET_STATE_TCP_LISTEN         0x0200
-# define PICO_SOCKET_STATE_TCP_SYN_SENT       0x0300
-# define PICO_SOCKET_STATE_TCP_SYN_RECV       0x0400
-# define PICO_SOCKET_STATE_TCP_ESTABLISHED    0x0500
-# define PICO_SOCKET_STATE_TCP_CLOSE_WAIT     0x0600
-# define PICO_SOCKET_STATE_TCP_LAST_ACK       0x0700
-# define PICO_SOCKET_STATE_TCP_FIN_WAIT1      0x0800
-# define PICO_SOCKET_STATE_TCP_FIN_WAIT2      0x0900
-# define PICO_SOCKET_STATE_TCP_CLOSING        0x0a00
-# define PICO_SOCKET_STATE_TCP_TIME_WAIT      0x0b00
-# define PICO_SOCKET_STATE_TCP_ARRAYSIZ       0x0c
-
-# define PICO_TCP_NODELAY                     1
-
-# define PICO_SOCKET_OPT_TCPNODELAY           0x0000
-
-# define PICO_IP_MULTICAST_EXCLUDE            0
-# define PICO_IP_MULTICAST_INCLUDE            1
-# define PICO_IP_MULTICAST_IF                 32
-# define PICO_IP_MULTICAST_TTL                33
-# define PICO_IP_MULTICAST_LOOP               34
-# define PICO_IP_ADD_MEMBERSHIP               35
-# define PICO_IP_DROP_MEMBERSHIP              36
-# define PICO_IP_UNBLOCK_SOURCE               37
-# define PICO_IP_BLOCK_SOURCE                 38
-# define PICO_IP_ADD_SOURCE_MEMBERSHIP        39
-# define PICO_IP_DROP_SOURCE_MEMBERSHIP       40
-
-# define PICO_SOCKET_OPT_MULTICAST_LOOP       1
-
-# define PICO_IP_DEFAULT_MULTICAST_TTL        1
-# define PICO_IP_DEFAULT_MULTICAST_LOOP       1
-
-#define PICO_SOCKET_SHUTDOWN_WRITE 0x01
-#define PICO_SOCKET_SHUTDOWN_READ  0x02
-#define TCPSTATE(s) ((s)->state & PICO_SOCKET_STATE_TCP)
-
-#define PICO_SOCK_EV_RD 1
-#define PICO_SOCK_EV_WR 2
-#define PICO_SOCK_EV_CONN 4
-#define PICO_SOCK_EV_CLOSE 8
-#define PICO_SOCK_EV_FIN 0x10
-#define PICO_SOCK_EV_ERR 0x80
-
-
-struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s));
-
-int pico_socket_read(struct pico_socket *s, void *buf, int len);
-int pico_socket_write(struct pico_socket *s, void *buf, int len);
-
-int pico_socket_sendto(struct pico_socket *s, void *buf, int len, void *dst, uint16_t remote_port);
-int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *local_port);
-
-int pico_socket_send(struct pico_socket *s, void *buf, int len);
-int pico_socket_recv(struct pico_socket *s, void *buf, int len);
-
-int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port);
-int pico_socket_connect(struct pico_socket *s, void *srv_addr, uint16_t remote_port);
-int pico_socket_listen(struct pico_socket *s, int backlog);
-struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, uint16_t *port);
-int pico_socket_del(struct pico_socket *s);
-
-int pico_socket_setoption(struct pico_socket *s, int option, void *value);
-int pico_socket_getoption(struct pico_socket *s, int option, void *value);
-
-int pico_socket_shutdown(struct pico_socket *s, int mode);
-int pico_socket_close(struct pico_socket *s);
-
-struct pico_frame *pico_socket_frame_alloc(struct pico_socket *s, int len);
-
-#ifdef PICO_SUPPORT_IPV4
-# define is_sock_ipv4(x) (x->net == &pico_proto_ipv4)
-#else
-# define is_sock_ipv4(x) (0)
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-# define is_sock_ipv6(x) (x->net == &pico_proto_ipv6)
-#else
-# define is_sock_ipv6(x) (0)
-#endif
-
-#ifdef PICO_SUPPORT_UDP
-# define is_sock_udp(x) (x->net == &pico_proto_udp)
-#else
-# define is_sock_udp(x) (0)
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-# define is_sock_tcp(x) (x->net == &pico_proto_tcp)
-#else
-# define is_sock_tcp(x) (0)
-#endif
-
-/* Interface towards transport protocol */
-int pico_transport_process_in(struct pico_protocol *self, struct pico_frame *f);
-struct pico_socket *pico_socket_clone(struct pico_socket *facsimile);
-int pico_socket_add(struct pico_socket *s);
-int pico_transport_error(struct pico_frame *f, uint8_t proto, int code);
-
-/* Socket loop */
-int pico_sockets_loop(int loop_score);
-
-/* Port check */
-int pico_is_port_free(uint16_t proto, uint16_t port, void *addr, void *net);
-
-
-#endif
--- a/include/pico_stack.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_STACK
-#define _INCLUDE_PICO_STACK
-#include "pico_config.h"
-#include "pico_frame.h"
-
-#define PICO_MAX_TIMERS 20
-
-/* ===== RECEIVING FUNCTIONS (from dev up to socket) ===== */
-
-/* TRANSPORT LEVEL */
-/* interface towards network */
-int pico_transport_receive(struct pico_frame *f, uint8_t proto);
-
-/* NETWORK LEVEL */
-/* interface towards ethernet */
-int pico_network_receive(struct pico_frame *f);
-
-/* The pico_ethernet_receive() function is used by 
- * those devices supporting ETH in order to push packets up 
- * into the stack. 
- */
-/* DATALINK LEVEL */
-int pico_ethernet_receive(struct pico_frame *f);
-
-/* LOWEST LEVEL: interface towards devices. */
-/* Device driver will call this function which returns immediately.
- * Incoming packet will be processed later on in the dev loop.
- */
-int pico_stack_recv(struct pico_device *dev, uint8_t *buffer, int len);
-
-
-/* ===== SENDIING FUNCTIONS (from socket down to dev) ===== */
-
-int pico_transport_send(struct pico_frame *f);
-int pico_network_send(struct pico_frame *f);
-int pico_ethernet_send(struct pico_frame *f);
-int pico_sendto_dev(struct pico_frame *f);
-
-/* ----- Initialization ----- */
-void pico_stack_init(void);
-
-/* ----- Loop Function. ----- */
-void pico_stack_tick(void);
-void pico_stack_loop(void);
-
-/* ---- Notifications for stack errors */
-int pico_notify_socket_unreachable(struct pico_frame *f);
-int pico_notify_proto_unreachable(struct pico_frame *f);
-int pico_notify_dest_unreachable(struct pico_frame *f);
-int pico_notify_ttl_expired(struct pico_frame *f);
-
-/* Various. */
-int pico_source_is_local(struct pico_frame *f);
-int pico_destination_is_local(struct pico_frame *f);
-void pico_store_network_origin(void *src, struct pico_frame *f);
-void pico_timer_add(unsigned long expire, void (*timer)(unsigned long, void *), void *arg);
-uint32_t pico_rand(void);
-void pico_rand_feed(uint32_t feed);
-
-#endif
--- a/include/pico_tree.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#ifndef __PICO_RBTREE_H__
-#define __PICO_RBTREE_H__
-
-#include <stdint.h>
-#include "pico_config.h"
-
-// This is used to declare a new tree, leaf root by default
-#define PICO_TREE_DECLARE(name,compareFunction) \
-    struct pico_tree name =\
-    { \
-        &LEAF, \
-        compareFunction \
-    }
-
-struct pico_tree_node
-{
-  void* keyValue; // generic key
-  struct pico_tree_node* parent;
-  struct pico_tree_node* leftChild;
-  struct pico_tree_node* rightChild;
-  uint8_t color;
-};
-
-struct pico_tree
-{
-    struct pico_tree_node * root; // root of the tree
-
-    // this function directly provides the keys as parameters not the nodes.
-  int (*compare)(void* keyA, void* keyB);
-};
-
-extern struct pico_tree_node LEAF; // generic leaf node
-/*
- * Manipulation functions
- */
-void * pico_tree_insert(struct pico_tree * tree, void * key);
-void * pico_tree_delete(struct pico_tree * tree, void * key);
-void * pico_tree_findKey(struct pico_tree * tree, void * key);
-void     pico_tree_drop(struct pico_tree * tree);
-int     pico_tree_empty(struct pico_tree * tree);
-struct pico_tree_node * pico_tree_findNode(struct pico_tree * tree, void * key);
-
-void * pico_tree_first(struct pico_tree * tree);
-void * pico_tree_last(struct pico_tree * tree);
-/*
- * Traverse functions
- */
-struct pico_tree_node * pico_tree_lastNode(struct pico_tree_node * node);
-struct pico_tree_node * pico_tree_firstNode(struct pico_tree_node * node);
-struct pico_tree_node * pico_tree_next(struct pico_tree_node * node);
-struct pico_tree_node * pico_tree_prev(struct pico_tree_node * node);
-
-/*
- * For each macros
- */
-
-#define pico_tree_foreach(idx,tree) \
-        for ((idx) = pico_tree_firstNode((tree)->root); \
-             (idx) != &LEAF; \
-             (idx) = pico_tree_next(idx))
-
-#define pico_tree_foreach_reverse(idx,tree) \
-        for ((idx) = pico_tree_lastNode((tree)->root); \
-             (idx) != &LEAF; \
-             (idx) = pico_tree_prev(idx))
-
-#define pico_tree_foreach_safe(idx,tree,idx2) \
-        for ((idx) = pico_tree_firstNode((tree)->root);    \
-             ((idx) != &LEAF) && ((idx2) = pico_tree_next(idx), 1); \
-              (idx) = (idx2))
-
-#define pico_tree_foreach_reverse_safe(idx,tree,idx2) \
-        for ((idx) = pico_tree_lastNode((tree)->root); \
-                ((idx) != &LEAF) && ((idx2) = pico_tree_prev(idx), 1); \
-                 (idx) = (idx2))
-
-#endif
--- a/modules/pico_dev_loop.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_device.h"
-#include "pico_dev_loop.h"
-#include "pico_stack.h"
-
-
-#define LOOP_MTU 1500
-static uint8_t l_buf[LOOP_MTU];
-static int l_bufsize = 0;
-
-
-static int pico_loop_send(struct pico_device *dev, void *buf, int len)
-{
-  if (len > LOOP_MTU)
-    return 0;
-
-  if (l_bufsize == 0) {
-    memcpy(l_buf, buf, len);
-    l_bufsize+=len;
-    return len;
-  }
-  return 0;
-}
-
-static int pico_loop_poll(struct pico_device *dev, int loop_score)
-{
-  if (loop_score <= 0)
-    return 0;
-
-  if (l_bufsize > 0) {
-    pico_stack_recv(dev, l_buf, l_bufsize);
-    l_bufsize = 0;
-    loop_score--;
-  }
-  return loop_score;
-}
-
-/* Public interface: create/destroy. */
-
-void pico_loop_destroy(struct pico_device *dev)
-{
-}
-
-struct pico_device *pico_loop_create(void)
-{
-  struct pico_device *loop = pico_zalloc(sizeof(struct pico_device));
-  if (!loop)
-    return NULL;
-
-  if( 0 != pico_device_init((struct pico_device *)loop, "loop", NULL)) {
-    dbg ("Loop init failed.\n");
-    pico_loop_destroy((struct pico_device *)loop);
-    return NULL;
-  }
-  loop->send = pico_loop_send;
-  loop->poll = pico_loop_poll;
-  loop->destroy = pico_loop_destroy;
-  dbg("Device %s created.\n", loop->name);
-  return (struct pico_device *)loop;
-}
-
--- a/modules/pico_dev_loop.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_LOOP
-#define _INCLUDE_PICO_LOOP
-#include "pico_config.h"
-#include "pico_device.h"
-
-void pico_loop_destroy(struct pico_device *loop);
-struct pico_device *pico_loop_create(void);
-
-#endif
-
--- a/modules/pico_dev_mbed.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-Do not redistribute without a written permission by the Copyright
-holders.
-
-Authors: Toon Peters, Maxime Vincent
-*********************************************************************/
-#include "mbed.h"
-extern "C" {
-#include "pico_device.h"
-#include "pico_dev_mbed.h"
-#include "pico_stack.h"
-#include "ethernet_api.h"
-}
-
-struct pico_device_mbed {
-  struct pico_device dev;
-  int bytes_left_in_frame;
-};
-
-#define ETH_MTU 1514
-uint8_t buf[ETH_MTU];
-
-Serial pc(p9, p10, "Serial port"); // tx, rx
-
-extern "C" {
-
-static int pico_mbed_send(struct pico_device *dev, void *buf, int len)
-{
-  int ret, sent;
-  struct pico_device_mbed *mb = (struct pico_device_mbed *) dev;
-
-  if (len > ETH_MTU)
-    return -1;
-
-  /* Write buf content to dev and return amount written */
-  ret = ethernet_write((const char *)buf, len);
-  sent = ethernet_send();
-
-  pc.printf("ETH> sent %d bytes\r\n",ret);
-  if (len != ret || sent != ret)
-    return -1;
-  else
-    return ret;
-}
-
-static int pico_mbed_poll(struct pico_device *dev, int loop_score)
-{
-  int len;
-  struct pico_device_mbed *mb = (struct pico_device_mbed *) dev;
-  
-  while(loop_score > 0)
-  {
-    /* check for new frame(s) */
-    len = (int) ethernet_receive();
-    
-    /* return if no frame has arrived */
-    if (!len)
-      return loop_score;
-  
-    /* read and process frame */
-    len = ethernet_read((char*)buf, ETH_MTU);
-    pc.printf("ETH> recv %d bytes: %x:%x\r\n", len, buf[0],buf[1]);
-    pico_stack_recv(dev, buf, len);
-    loop_score--;
-  }
-  return loop_score;
-}
-
-/* Public interface: create/destroy. */
-void pico_mbed_destroy(struct pico_device *dev)
-{
-  ethernet_free();
-  pico_device_destroy(dev);
-}
-
-struct pico_device *pico_mbed_create(char *name)
-{
-  std::uint8_t mac[PICO_SIZE_ETH];
-  struct pico_device_mbed *mb = (struct pico_device_mbed*) pico_zalloc(sizeof(struct pico_device_mbed));
-
-  if (!mb)
-    return NULL;
-
-  ethernet_address((char *)mac);
-  pc.printf("ETH> Set MAC address to: %x:%x:%x:%x:%x:%x\r\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
-
-  if(0 != pico_device_init((struct pico_device *)mb, name, mac)) {
-    pc.printf ("ETH> Loop init failed.\n");
-    //pico_loop_destroy(mb);
-    return NULL;
-  }
-
-  mb->dev.send = pico_mbed_send;
-  mb->dev.poll = pico_mbed_poll;
-  mb->dev.destroy = pico_mbed_destroy;
-  mb->bytes_left_in_frame = 0;
-
-  if(0 != ethernet_init()) {
-    pc.printf("ETH> Failed to initialize hardware.\r\n");
-    pico_device_destroy((struct pico_device *)mb);
-    return NULL;
-  }
-
-  // future work: make the mac address configurable
-
-  pc.printf("ETH> Device %s created.\r\n", mb->dev.name);
-
-  return (struct pico_device *)mb;
-}
-
-void pico_mbed_get_address(char *mac)
-{
-  ethernet_address(mac);
-}
-
-}
\ No newline at end of file
--- a/modules/pico_dev_mbed.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-Do not redistribute without a written permission by the Copyright
-holders.
-
-File: pico_dev_mbed.h
-Author: Toon Peters
-*********************************************************************/
-
-#ifndef PICO_DEV_MBED_H
-#define    PICO_DEV_MBED_H
-
-#include "pico_config.h"
-#include "pico_device.h"
-
-void pico_mbed_destroy(struct pico_device *vde);
-struct pico_device *pico_mbed_create(char *name);
-
-#endif    /* PICO_DEV_MBED_H */
-
--- a/modules/pico_dhcp_client.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,732 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Frederik Van Slycken, Kristof Roelants
-*********************************************************************/
-
-#include "pico_dhcp_client.h"
-#include "pico_stack.h"
-#include "pico_config.h"
-#include "pico_device.h"
-#include "pico_ipv4.h"
-#include "pico_socket.h"
-
-#ifdef PICO_SUPPORT_DHCPC
-
-/***********
- * structs *
- ***********/
-
-static uint8_t dhcp_client_mutex = 1; /* to serialize client negotations if multiple devices */
-
-struct dhcp_timer_param{
-    uint16_t type;
-    struct pico_dhcp_client_cookie* cli;
-    int valid;
-};
-
-struct pico_dhcp_client_cookie
-{
-    uint32_t xid;
-  uint32_t *xid_user;
-    struct pico_ip4 address;
-    struct pico_ip4 netmask;
-    struct pico_ip4 gateway;
-    struct pico_ip4 nameserver;
-    struct pico_ip4 server_id;
-    uint32_t lease_time;
-    uint32_t T1;
-    uint32_t T2;
-    struct pico_socket* socket;
-    int connected;
-    struct pico_device* device;
-    unsigned long start_time;
-    int attempt;
-    enum dhcp_negotiation_state state;
-    void (*cb)(void* cli, int code);
-    struct dhcp_timer_param* timer_param_1;
-    struct dhcp_timer_param* timer_param_2;
-    struct dhcp_timer_param* timer_param_lease;
-    struct dhcp_timer_param* timer_param_retransmit;
-    int link_added;
-};
-
-static int dhcp_cookies_cmp(void *ka, void *kb)
-{
-  struct pico_dhcp_client_cookie *a = ka, *b = kb;
-  if (a->xid < b->xid)
-    return -1; 
-  else if (a->xid > b->xid)
-    return 1;
-  else
-    return 0;
-} 
-PICO_TREE_DECLARE(DHCPCookies, dhcp_cookies_cmp);
-
-/*************************
- * function declarations *
- *************************/
-static void pico_dhcp_state_machine(int type, struct pico_dhcp_client_cookie* cli, uint8_t* data, int len);
-static void pico_dhcp_reinitiate_negotiation(unsigned long now, void *arg);
-
-//cb
-static void pico_dhcp_wakeup(uint16_t ev, struct pico_socket *s);
-static void dhcp_timer_cb(unsigned long tick, void* param);
-
-//util
-static void pico_dhcp_retry(struct pico_dhcp_client_cookie *client);
-static int dhclient_send(struct pico_dhcp_client_cookie *cli, uint8_t msg_type);
-static int pico_dhcp_verify_and_identify_type(uint8_t* data, int len, struct pico_dhcp_client_cookie *cli);
-static int init_cookie(struct pico_dhcp_client_cookie* cli);
-static struct pico_dhcp_client_cookie* get_cookie_by_xid(uint32_t xid);
-static uint32_t get_xid(uint8_t* data);
-
-//fsm functions
-static int recv_offer(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-static int recv_ack(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-static int renew(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-static int reset(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-static int retransmit(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-
-//fsm implementation
-static void pico_dhcp_state_machine(int type, struct pico_dhcp_client_cookie* cli, uint8_t* data, int len);
-
-/***************
- * entry point *
- ***************/
-
-static uint32_t pico_dhcp_execute_init(struct pico_dhcp_client_cookie *cli)
-{
-  if (!dhcp_client_mutex) {
-    pico_timer_add(3000, pico_dhcp_reinitiate_negotiation, cli);
-    return 0;
-  }
-  dhcp_client_mutex--;
-
-    if (init_cookie(cli) < 0)
-    return -1;
-
-  dbg("DHCPC: cookie with xid %u\n", cli->xid);
-  
-  if (pico_tree_insert(&DHCPCookies, cli)) {
-    pico_err = PICO_ERR_EAGAIN;
-        if(cli->cb != NULL) {
-            cli->cb(cli, PICO_DHCP_ERROR);
-    }
-    pico_free(cli);
-    return -1; /* Element key already exists */
-  }
-
-    if (dhclient_send(cli, PICO_DHCP_MSG_DISCOVER) < 0)
-    return -1;
-
-    return 0;
-}
-
-/* returns a pointer to the client cookie. The user should pass this pointer every time he calls a dhcp-function. This is so that we can (one day) support dhcp on multiple interfaces */
-int pico_dhcp_initiate_negotiation(struct pico_device *device, void (*callback)(void *cli, int code), uint32_t *xid)
-{
-    struct pico_dhcp_client_cookie *cli;
-  
-    if(!device || !callback || !xid){
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-    }
-  cli = pico_zalloc(sizeof(struct pico_dhcp_client_cookie));
-    if(!cli){
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-    }
-
-  cli->device = device;
-  cli->cb = callback;
-  cli->xid_user = xid;
-  *(cli->xid_user) = 0;
-
-  return pico_dhcp_execute_init(cli);
-}
-
-static void pico_dhcp_reinitiate_negotiation(unsigned long now, void *arg)
-{
-  struct pico_dhcp_client_cookie *cli = (struct pico_dhcp_client_cookie *) arg;
-
-  pico_dhcp_execute_init(cli);
-
-  return;
-}
-
-/********************
- * access functions *
- ********************/
-
-struct pico_ip4 pico_dhcp_get_address(void* cli)
-{
-    return ((struct pico_dhcp_client_cookie*)cli)->address;
-}
-
-struct pico_ip4 pico_dhcp_get_gateway(void* cli)
-{
-    return ((struct pico_dhcp_client_cookie*)cli)->gateway;
-}
-
-struct pico_ip4 pico_dhcp_get_nameserver(void* cli)
-{
-    return ((struct pico_dhcp_client_cookie*)cli)->nameserver;
-}
-
-/*************
- * callbacks *
- *************/
-
-static void pico_dhcp_wakeup(uint16_t ev, struct pico_socket *s)
-{
-    uint8_t buf[DHCPC_DATAGRAM_SIZE];
-    int r=0;
-    uint32_t peer;
-    uint16_t port;
-    int type;
-
-    struct pico_dhcp_client_cookie *cli;
-    dbg("DHCPC: called dhcp_wakeup\n");
-    if (ev == PICO_SOCK_EV_RD) {
-        do {
-            r = pico_socket_recvfrom(s, buf, DHCPC_DATAGRAM_SIZE, &peer, &port);
-            cli = get_cookie_by_xid(get_xid(buf));
-            if(cli == NULL)
-                return;
-            if (r > 0 && port == PICO_DHCPD_PORT) {
-                type = pico_dhcp_verify_and_identify_type(buf, r, cli);
-                pico_dhcp_state_machine(type, cli, buf, r);
-            }
-        } while(r>0);
-    }
-}
-
-static void dhcp_timer_cb(unsigned long tick, void* param)
-{
-    struct dhcp_timer_param* param2 = (struct dhcp_timer_param*) param;
-    if(param2->valid == 1){
-        //dbg("called timer cb on active timer type %d\n",param2->type);
-        pico_dhcp_state_machine(param2->type, param2->cli, NULL, 0);
-    }
-    if(param2->cli->timer_param_1 == param){
-        param2->cli->timer_param_1 = NULL;
-    }
-    if(param2->cli->timer_param_2 == param){
-        param2->cli->timer_param_2 = NULL;
-    }
-    if(param2->cli->timer_param_lease == param){
-        param2->cli->timer_param_lease = NULL;
-    }
-    if(param2->cli->timer_param_retransmit == param){
-        param2->cli->timer_param_retransmit = NULL;
-    }
-
-    pico_free(param);
-
-}
-/*****************
- * fsm functions *
- *****************/
-
-static int recv_offer(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len)
-{
-    struct pico_dhcphdr *dhdr = (struct pico_dhcphdr *) data;
-    uint8_t *nextopt, opt_data[20], opt_type;
-    int opt_len = 20;
-    uint8_t msg_type = 0xFF;
-    int T1_set = 0;
-    int T2_set = 0;
-
-    cli->address.addr = dhdr->yiaddr;
-
-    opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len, &nextopt);
-    while (opt_type != PICO_DHCPOPT_END) {
-        if (opt_type == PICO_DHCPOPT_MSGTYPE)
-            msg_type = opt_data[0];
-        if ((opt_type == PICO_DHCPOPT_LEASETIME) && (opt_len == 4)){
-            memcpy(&cli->lease_time, opt_data, 4);
-            cli->lease_time = long_be(cli->lease_time);
-        }
-        if ((opt_type == PICO_DHCPOPT_RENEWALTIME) && (opt_len == 4)){
-            memcpy(&cli->T1, opt_data, 4);
-            cli->T1 = long_be(cli->T1);
-            T1_set =1;
-        }
-        if ((opt_type == PICO_DHCPOPT_REBINDINGTIME) && (opt_len == 4)){
-            memcpy(&cli->T2, opt_data, 4);
-            cli->T2 = long_be(cli->T2);
-            T2_set =1;
-        }
-        if ((opt_type == PICO_DHCPOPT_ROUTER) && (opt_len == 4)) //XXX assuming only one router will be advertised...
-            memcpy(&cli->gateway.addr, opt_data, 4);
-        if ((opt_type == PICO_DHCPOPT_DNS) && (opt_len == 4))
-            memcpy(&cli->nameserver.addr, opt_data, 4);
-        if ((opt_type == PICO_DHCPOPT_NETMASK) && (opt_len == 4))
-            memcpy(&cli->netmask.addr, opt_data, 4);
-        if ((opt_type == PICO_DHCPOPT_SERVERID) && (opt_len == 4))
-            memcpy(&cli->server_id.addr, opt_data, 4);
-        if (opt_type == PICO_DHCPOPT_OPTIONOVERLOAD)
-            dbg("DHCPC: WARNING: option overload present (not processed)");
-
-        opt_len = 20;
-        opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len, &nextopt);
-    }
-
-    /* default values for T1 and T2 if necessary */
-    if(T1_set != 1)
-        cli->T1 = cli->lease_time >> 1;
-    if(T2_set != 1)
-        cli->T2 = (cli->lease_time * 875) / 1000;
-
-
-
-    if ((msg_type != PICO_DHCP_MSG_OFFER) || !cli->lease_time || !cli->netmask.addr || !cli->server_id.addr )
-        return 0;
-
-
-    dhclient_send(cli, PICO_DHCP_MSG_REQUEST);
-    cli->state = DHCPSTATE_REQUEST;
-    return 1;
-}
-
-static int recv_ack(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len)
-{
-    struct pico_ip4 address = {0};
-
-    if(cli->link_added == 0){
-    /* close the socket bound on address 0.0.0.0 */
-    pico_socket_close(cli->socket);
-    cli->socket = NULL;
-        pico_ipv4_link_del(cli->device, address);
-        pico_ipv4_link_add(cli->device, cli->address, cli->netmask);
-        cli->link_added = 1;
-    }
-    cli->state = DHCPSTATE_BOUND;
-
-    dbg("DHCPC: T1: %d\n",cli->T1);
-    dbg("DHCPC: T2: %d\n",cli->T2);
-    dbg("DHCPC: lease time: %d\n",cli->lease_time);
-
-    if(cli->timer_param_1)
-        cli->timer_param_1->valid = 0;
-    if(cli->timer_param_2)
-        cli->timer_param_2->valid = 0;
-    if(cli->timer_param_lease)
-        cli->timer_param_lease->valid = 0;
-    if(cli->timer_param_retransmit)
-        cli->timer_param_retransmit->valid = 0;
-
-
-    cli->timer_param_1 = pico_zalloc(sizeof(struct dhcp_timer_param));
-    if(!cli->timer_param_1){
-        if(cli->cb != NULL){
-      pico_err = PICO_ERR_ENOMEM;
-            cli->cb(cli, PICO_DHCP_ERROR);
-        }
-        return 0;
-    }
-    cli->timer_param_2 = pico_zalloc(sizeof(struct dhcp_timer_param));
-    if(!cli->timer_param_2){
-        if(cli->cb != NULL){
-      pico_err = PICO_ERR_ENOMEM;
-            cli->cb(cli, PICO_DHCP_ERROR);
-        }
-        return 0;
-    }
-    cli->timer_param_lease = pico_zalloc(sizeof(struct dhcp_timer_param));
-    if(!cli->timer_param_lease){
-        if(cli->cb != NULL){
-      pico_err = PICO_ERR_ENOMEM;
-            cli->cb(cli, PICO_DHCP_ERROR);
-        }
-        return 0;
-    }
-    cli->timer_param_1->valid = 1;
-    cli->timer_param_2->valid = 1;
-    cli->timer_param_lease->valid = 1;
-
-    cli->timer_param_1->cli = cli;
-    cli->timer_param_2->cli = cli;
-    cli->timer_param_lease->cli = cli;
-
-    cli->timer_param_1->type = PICO_DHCP_EVENT_T1;
-    cli->timer_param_2->type = PICO_DHCP_EVENT_T2;
-    cli->timer_param_lease->type = PICO_DHCP_EVENT_LEASE;
-    //add timer
-    pico_timer_add(cli->T1*1000, dhcp_timer_cb, cli->timer_param_1);
-    pico_timer_add(cli->T2*1000, dhcp_timer_cb, cli->timer_param_2);
-    pico_timer_add(cli->lease_time*1000, dhcp_timer_cb, cli->timer_param_lease);
-
-  *(cli->xid_user) = cli->xid;
-    if(cli->cb != NULL)
-        cli->cb(cli, PICO_DHCP_SUCCESS);
-    else
-        dbg("DHCPC: no callback\n");
-
-  dhcp_client_mutex++;
-    cli->state = DHCPSTATE_BOUND;
-    return 0;
-}
-
-static int renew(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len)
-{
-    uint16_t port = PICO_DHCP_CLIENT_PORT;
-
-  /* open and bind to currently acquired address */
-  if (cli->socket)
-    return -1;
-
-  cli->socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcp_wakeup);
-  if (!cli->socket) {
-    dbg("DHCPC: error opening socket on renew: %s\n", strerror(pico_err));
-    if(cli->cb != NULL)
-      cli->cb(cli, PICO_DHCP_ERROR);
-    return -1;
-  }
-  if (pico_socket_bind(cli->socket, &cli->address, &port) != 0){
-    dbg("DHCPC: error binding socket on renew: %s\n", strerror(pico_err));
-    pico_socket_close(cli->socket);
-    if(cli->cb != NULL)
-      cli->cb(cli, PICO_DHCP_ERROR);
-    return -1;
-  }
-    cli->state = DHCPSTATE_RENEWING;
-    dhclient_send(cli, PICO_DHCP_MSG_REQUEST);
-
-    return 0;
-}
-
-static int reset(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len)
-{
-    if(cli->cb != NULL)
-        cli->cb(cli, PICO_DHCP_RESET);
-    //reset pretty much everything
-
-    if(cli->timer_param_1)
-        cli->timer_param_1->valid = 0;
-    if(cli->timer_param_2)
-        cli->timer_param_2->valid = 0;
-    if(cli->timer_param_lease)
-        cli->timer_param_lease->valid = 0;
-    if(cli->timer_param_retransmit)
-        cli->timer_param_retransmit->valid = 0;
-
-    pico_socket_close(cli->socket);
-    pico_ipv4_link_del(cli->device, cli->address);
-
-    //initiate negotiations again
-    init_cookie(cli);
-    pico_dhcp_retry(cli);
-    dhclient_send(cli, PICO_DHCP_MSG_DISCOVER);
-
-    return 0;
-
-}
-
-static int retransmit(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len)
-{
-    pico_dhcp_retry(cli);
-
-    if(cli->state == DHCPSTATE_DISCOVER)
-        dhclient_send(cli, PICO_DHCP_MSG_DISCOVER);
-    else if(cli->state == DHCPSTATE_RENEWING)
-        dhclient_send(cli, PICO_DHCP_MSG_REQUEST);
-    else
-        dbg("DHCPC: WARNING: should not get here in state %d!\n", cli->state);
-
-    return 0;
-
-}
-
-/**********************
- * fsm implementation *
- **********************/
-
-struct dhcp_action_entry {
-    uint16_t tcpstate;
-    int (*offer)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-    int (*ack)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-    int (*nak)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-    int (*timer1)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-    int (*timer_lease)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-    int (*timer_retransmit)(struct pico_dhcp_client_cookie *cli, uint8_t *data, int len);
-};
-
-static struct dhcp_action_entry dhcp_fsm[] = {
-        /* State             offer       ack       nak     timer1  timer_lease timer_retransmit*/
-    { DHCPSTATE_DISCOVER,  recv_offer, NULL,     NULL,   NULL,   reset,      retransmit},
-    { DHCPSTATE_OFFER,     NULL,       NULL,     NULL,   NULL,   reset,      NULL},
-    { DHCPSTATE_REQUEST,   NULL,       recv_ack, reset,  NULL,   reset,      retransmit},
-    { DHCPSTATE_BOUND,     NULL,       NULL,     reset,  renew,  reset,      NULL},
-    { DHCPSTATE_RENEWING,  NULL,       recv_ack, reset,  NULL,   reset,      retransmit},
-};
-
-
-static void pico_dhcp_state_machine(int type, struct pico_dhcp_client_cookie* cli, uint8_t* data, int len)
-{
-    dbg("DHCPC: received incoming event of type %d\n", type);
-    switch(type){
-        case PICO_DHCP_MSG_OFFER:
-            if(dhcp_fsm[cli->state].offer != NULL)
-                dhcp_fsm[cli->state].offer(cli, data, len);
-            break;
-        case PICO_DHCP_MSG_ACK:
-            if(dhcp_fsm[cli->state].ack != NULL){
-                dhcp_fsm[cli->state].ack(cli, data, len);
-            }
-            break;
-        case PICO_DHCP_MSG_NAK:
-            if(dhcp_fsm[cli->state].nak!= NULL){
-                dhcp_fsm[cli->state].nak(cli, data, len);
-            }
-            break;
-        case PICO_DHCP_EVENT_T1:
-            if(dhcp_fsm[cli->state].timer1!= NULL){
-                dhcp_fsm[cli->state].timer1(cli, NULL, 0);
-            }
-            break;
-        case PICO_DHCP_EVENT_LEASE:
-            if(dhcp_fsm[cli->state].timer_lease!= NULL){
-                dhcp_fsm[cli->state].timer_lease(cli, NULL, 0);
-            }
-            break;
-        case PICO_DHCP_EVENT_RETRANSMIT:
-            if(dhcp_fsm[cli->state].timer_retransmit!= NULL){
-                dhcp_fsm[cli->state].timer_retransmit(cli, NULL, 0);
-            }
-            break;
-        default:
-            dbg("DHCPC: event not supported yet!!\n");
-            break;
-    }
-}
-
-
-/*********************
- * utility functions *
- *********************/
-
-static void pico_dhcp_retry(struct pico_dhcp_client_cookie *cli)
-{
-    const int MAX_RETRY = 3;
-    uint32_t new_xid;
-    if (++cli->attempt > MAX_RETRY) {
-        cli->start_time = pico_tick;
-        cli->attempt = 0;
-         new_xid = pico_rand();
-        while(get_cookie_by_xid(new_xid) != NULL){
-            new_xid = pico_rand();
-        }
-        cli->xid = new_xid;
-        cli->state = DHCPSTATE_DISCOVER;
-    }
-}
-
-static int dhclient_send(struct pico_dhcp_client_cookie *cli, uint8_t msg_type)
-{
-    uint8_t buf_out[DHCPC_DATAGRAM_SIZE] = {0};
-    struct pico_dhcphdr *dh_out = (struct pico_dhcphdr *) buf_out;
-    int sent = 0;
-    int i = 0;
-    struct pico_ip4 destination;
-    uint16_t port = PICO_DHCPD_PORT;
-    if(cli->state == DHCPSTATE_BOUND || cli->state == DHCPSTATE_RENEWING){
-        destination.addr = cli->server_id.addr;
-    }else{
-        destination.addr = long_be(0xFFFFFFFF);
-    }
-
-    if(cli->device->eth == NULL){
-        pico_err = PICO_ERR_EOPNOTSUPP;
-        if(cli->cb != NULL){
-            cli->cb(cli, PICO_DHCP_ERROR);
-        }
-        return -1;
-    }
-    memcpy(dh_out->hwaddr, &cli->device->eth->mac, PICO_HLEN_ETHER);
-    dh_out->op = PICO_DHCP_OP_REQUEST;
-    dh_out->htype = PICO_HTYPE_ETHER;
-    dh_out->hlen = PICO_HLEN_ETHER;
-    dh_out->xid = cli->xid;
-    dh_out->secs = (msg_type == PICO_DHCP_MSG_REQUEST)?0:short_be((pico_tick - cli->start_time)/1000);
-    dh_out->dhcp_magic = PICO_DHCPD_MAGIC_COOKIE;
-  if (cli->state == DHCPSTATE_RENEWING)
-    dh_out->ciaddr = cli->address.addr;
-
-    /* Option: msg type, len 1 */
-    dh_out->options[i++] = PICO_DHCPOPT_MSGTYPE;
-    dh_out->options[i++] = 1;
-    dh_out->options[i++] = msg_type;
-
-    if (msg_type == PICO_DHCP_MSG_REQUEST) {
-        dh_out->options[i++] = PICO_DHCPOPT_REQIP;
-        dh_out->options[i++] = 4;
-        dh_out->options[i++] = (long_be(cli->address.addr) & 0xFF000000) >> 24;
-        dh_out->options[i++] = (long_be(cli->address.addr) & 0xFF0000) >> 16;
-        dh_out->options[i++] = (long_be(cli->address.addr) & 0xFF00) >> 8;
-        dh_out->options[i++] = (long_be(cli->address.addr) & 0xFF);
-        dh_out->options[i++] = PICO_DHCPOPT_SERVERID;
-        dh_out->options[i++] = 4;
-        dh_out->options[i++] = (long_be(cli->server_id.addr) & 0xFF000000) >> 24;
-        dh_out->options[i++] = (long_be(cli->server_id.addr) & 0xFF0000) >> 16;
-        dh_out->options[i++] = (long_be(cli->server_id.addr) & 0xFF00) >> 8;
-        dh_out->options[i++] = (long_be(cli->server_id.addr) & 0xFF);
-    }
-
-    /* Option: req list, len 4 */
-    dh_out->options[i++] = PICO_DHCPOPT_PARMLIST;
-    dh_out->options[i++] = 7;
-    dh_out->options[i++] = PICO_DHCPOPT_NETMASK;
-    dh_out->options[i++] = PICO_DHCPOPT_BCAST;
-    dh_out->options[i++] = PICO_DHCPOPT_TIME;
-    dh_out->options[i++] = PICO_DHCPOPT_ROUTER;
-    dh_out->options[i++] = PICO_DHCPOPT_HOSTNAME;
-    dh_out->options[i++] = PICO_DHCPOPT_RENEWALTIME;
-    dh_out->options[i++] = PICO_DHCPOPT_REBINDINGTIME;
-
-    /* Option : max message size */
-    if( msg_type == PICO_DHCP_MSG_REQUEST || msg_type == PICO_DHCP_MSG_DISCOVER){
-        uint16_t dds = DHCPC_DATAGRAM_SIZE;
-        dh_out->options[i++] = PICO_DHCPOPT_MAXMSGSIZE;
-        dh_out->options[i++] = 2;
-        dh_out->options[i++] = (dds & 0xFF00) >> 8;
-        dh_out->options[i++] = (dds & 0xFF);
-    }
-
-
-
-    dh_out->options[i] = PICO_DHCPOPT_END;
-    sent = pico_socket_sendto(cli->socket, buf_out, DHCPC_DATAGRAM_SIZE, &destination, port);
-    if (sent < 0) {
-        dbg("DHCPC: sendto failed: %s\n", strerror(pico_err));
-        if(cli->cb != NULL)
-            cli->cb(cli, PICO_DHCP_ERROR);
-    }
-
-
-    //resend-timer :
-    if(cli->timer_param_retransmit != NULL)
-        cli->timer_param_retransmit->valid=0;
-
-    cli->timer_param_retransmit = pico_zalloc(sizeof(struct dhcp_timer_param));
-    if(!cli->timer_param_retransmit){
-        if(cli->cb != NULL)
-      pico_err = PICO_ERR_ENOMEM;
-            cli->cb(cli, PICO_DHCP_ERROR);
-        return -1;
-    }
-    cli->timer_param_retransmit->valid = 1;
-    cli->timer_param_retransmit->cli = cli;
-    cli->timer_param_retransmit->type = PICO_DHCP_EVENT_RETRANSMIT;
-    pico_timer_add(4000, dhcp_timer_cb, cli->timer_param_retransmit);
-
-  return 0;
-}
-
-//identifies type & does some preprocessing : checking if everything is valid
-static int pico_dhcp_verify_and_identify_type(uint8_t* data, int len, struct pico_dhcp_client_cookie *cli)
-{
-    struct pico_dhcphdr *dhdr = (struct pico_dhcphdr *) data;
-    uint8_t *nextopt, opt_data[20], opt_type;
-    int opt_len = 20;
-
-    if (dhdr->xid != cli->xid)
-        return 0;
-
-    if (!is_options_valid(dhdr->options, len - sizeof(struct pico_dhcphdr)))
-        return 0;
-
-    if( dhdr->dhcp_magic != PICO_DHCPD_MAGIC_COOKIE)
-        return 0;
-
-    opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len, &nextopt);
-    while (opt_type != PICO_DHCPOPT_END) {
-        /* parse interesting options here */
-        if (opt_type == PICO_DHCPOPT_MSGTYPE) {
-            return *opt_data;
-        }
-        opt_len = 20;
-        opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len, &nextopt);
-    }
-    return 0;
-
-}
-
-static int init_cookie(struct pico_dhcp_client_cookie* cli)
-{
-  uint8_t n = 3;
-    uint16_t port = PICO_DHCP_CLIENT_PORT;
-    struct pico_ip4 address, netmask;
-
-    address.addr = long_be(0x00000000);
-    netmask.addr = long_be(0x00000000);
-
-    cli->state = DHCPSTATE_DISCOVER;
-    cli->start_time = pico_tick;
-    cli->attempt = 0;
-
-    cli->socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcp_wakeup);
-    if (!cli->socket) {
-        dbg("DHCPC: error opening socket: %s\n", strerror(pico_err));
-        if(cli->cb != NULL)
-            cli->cb(cli, PICO_DHCP_ERROR);
-        return -1;
-    }
-    if (pico_socket_bind(cli->socket, &address, &port) != 0){
-        dbg("DHCPC: error binding socket: %s\n", strerror(pico_err));
-    pico_socket_close(cli->socket);
-        if(cli->cb != NULL)
-            cli->cb(cli, PICO_DHCP_ERROR);
-        return -1;
-    }
-    cli->socket->dev = cli->device;
-
-    if(pico_ipv4_link_add(cli->device, address, netmask) != 0){
-    dbg("DHCPC: error adding link: %s\n", strerror(pico_err));
-        if(cli->cb != NULL)
-            cli->cb(cli, PICO_DHCP_ERROR);
-        return -1;
-    }
-
-  /* attempt to generate a correct xid 3 times, then fail */
-  do {
-      cli->xid = pico_rand();
-  } while (!cli->xid && --n);
-  if (!cli->xid) {
-        if(cli->cb != NULL)
-            cli->cb(cli, PICO_DHCP_ERROR);
-    return -1;
-  }
-
-  return 0;
-}
-
-static struct pico_dhcp_client_cookie *get_cookie_by_xid(uint32_t xid)
-{
-    struct pico_dhcp_client_cookie test = { }, *cookie = NULL;
-
-  if (!xid)
-    return NULL;
-
-  test.xid = xid;
-  cookie = pico_tree_findKey(&DHCPCookies, &test);
-  if (!cookie)
-    return NULL;
-  else
-    return cookie;
-}
-
-void *pico_dhcp_get_identifier(uint32_t xid)
-{
-  return (void *) get_cookie_by_xid(xid);
-}
-
-static uint32_t get_xid(uint8_t* data)
-{
-    struct pico_dhcphdr *dhdr = (struct pico_dhcphdr *) data;
-    return dhdr->xid;
-}
-
-#endif
--- a/modules/pico_dhcp_client.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_DHCP_CLIENT
-#define _INCLUDE_PICO_DHCP_CLIENT
-
-
-#include "pico_dhcp_common.h"
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-
-
-int pico_dhcp_initiate_negotiation(struct pico_device *device, void (*callback)(void* cli, int code), uint32_t *xid);
-void pico_dhcp_process_incoming_message(uint8_t *data, int len);
-void *pico_dhcp_get_identifier(uint32_t xid);
-struct pico_ip4 pico_dhcp_get_address(void *cli);
-struct pico_ip4 pico_dhcp_get_gateway(void *cli);
-struct pico_ip4 pico_dhcp_get_nameserver(void* cli);
-
-/* possible codes for the callback */
-#define PICO_DHCP_SUCCESS 0
-#define PICO_DHCP_ERROR   1
-#define PICO_DHCP_RESET   2
-
-/* DHCP EVENT TYPE 
- * these come after the message types, used for the state machine*/
-#define PICO_DHCP_EVENT_T1                   9
-#define PICO_DHCP_EVENT_T2                   10
-#define PICO_DHCP_EVENT_LEASE                11
-#define PICO_DHCP_EVENT_RETRANSMIT           12
-
-#endif
--- a/modules/pico_dhcp_common.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Frederik Van Slycken
-*********************************************************************/
-
-#include "pico_config.h"
-#include "pico_stack.h"
-#include "pico_dhcp_common.h"
-
-#if defined (PICO_SUPPORT_DHCPC) || defined (PICO_SUPPORT_DHCPD)
-//this function should only be used after you checked if the options are valid! otherwise it could read from bad memory!
-uint8_t dhcp_get_next_option(uint8_t *begin, uint8_t *data, int *len, uint8_t **nextopt)
-{
-    uint8_t *p;
-    uint8_t type;
-    uint8_t opt_len;
-
-    if (!begin)
-        p = *nextopt;
-    else
-        p = begin;
-
-    type = *p;
-    *nextopt = ++p;
-    if ((type == PICO_DHCPOPT_END) || (type == PICO_DHCPOPT_PAD)) {
-        memset(data, 0, *len);
-        len = 0;
-        return type;
-    }
-    opt_len = *p;
-    p++;
-    if (*len > opt_len)
-        *len = opt_len;
-    memcpy(data, p, *len);
-    *nextopt = p + opt_len;
-    return type;
-}
-
-int is_options_valid(uint8_t *opt_buffer, int len)
-{
-    uint8_t *p = opt_buffer;
-    while (len > 0) {
-        if (*p == PICO_DHCPOPT_END)
-            return 1;
-        else if (*p == PICO_DHCPOPT_PAD) {
-            p++;
-            len--;
-        } else {
-            uint8_t opt_len;
-            p++;
-            len--;
-            if(len > 0) {
-                opt_len = *p;
-                p += opt_len + 1;
-                len -= opt_len;
-            }else
-                return 0;
-        }
-    }
-    return 0;
-}
-
-#endif
--- a/modules/pico_dhcp_common.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_DHCP_COMMON
-#define _INCLUDE_PICO_DHCP_COMMON
-
-
-#include <stdint.h>
-
-//minimum size is 576, cfr RFC
-#define DHCPC_DATAGRAM_SIZE 576
-#define DHCPD_DATAGRAM_SIZE 576
-
-
-#define PICO_DHCPD_PORT (short_be(67))
-#define PICO_DHCP_CLIENT_PORT (short_be(68))
-
-#define PICO_DHCP_OP_REQUEST 1
-#define PICO_DHCP_OP_REPLY   2
-
-#define PICO_HTYPE_ETHER 1
-#define PICO_HLEN_ETHER  6
-
-#define PICO_DHCPD_MAGIC_COOKIE (long_be(0x63825363))
-
-/* DHCP OPTIONS, RFC2132 */
-#define PICO_DHCPOPT_PAD                     0x00
-#define PICO_DHCPOPT_NETMASK                 0x01
-#define PICO_DHCPOPT_TIME                    0x02
-#define PICO_DHCPOPT_ROUTER                  0x03
-#define PICO_DHCPOPT_DNS                     0x06
-#define PICO_DHCPOPT_HOSTNAME                0x0c
-#define PICO_DHCPOPT_DOMAINNAME              0x0f
-#define PICO_DHCPOPT_MTU                     0x1a
-#define PICO_DHCPOPT_BCAST                   0x1c
-#define PICO_DHCPOPT_NETBIOSNS               0x2c
-#define PICO_DHCPOPT_NETBIOSSCOPE            0x2f
-
-#define PICO_DHCPOPT_REQIP                   0x32
-#define PICO_DHCPOPT_LEASETIME               0x33
-#define PICO_DHCPOPT_OPTIONOVERLOAD          0x34
-#define PICO_DHCPOPT_MSGTYPE                 0x35
-#define PICO_DHCPOPT_SERVERID                0x36
-#define PICO_DHCPOPT_PARMLIST                0x37
-#define PICO_DHCPOPT_MAXMSGSIZE              0x39
-#define PICO_DHCPOPT_RENEWALTIME             0x3a
-#define PICO_DHCPOPT_REBINDINGTIME           0x3b
-#define PICO_DHCPOPT_DOMAINSEARCH            0x77
-#define PICO_DHCPOPT_STATICROUTE             0x79
-#define PICO_DHCPOPT_END                     0xFF
-
-/* DHCP MESSAGE TYPE */
-#define PICO_DHCP_MSG_DISCOVER               1
-#define PICO_DHCP_MSG_OFFER                  2
-#define PICO_DHCP_MSG_REQUEST                3
-#define PICO_DHCP_MSG_DECLINE                4
-#define PICO_DHCP_MSG_ACK                    5
-#define PICO_DHCP_MSG_NAK                    6
-#define PICO_DHCP_MSG_RELEASE                7
-#define PICO_DHCP_MSG_INFORM                 8
-
-
-enum dhcp_negotiation_state {
-        DHCPSTATE_DISCOVER = 0,
-        DHCPSTATE_OFFER,
-        DHCPSTATE_REQUEST,
-        DHCPSTATE_BOUND,
-        DHCPSTATE_RENEWING
-};
-
-
-struct __attribute__((packed)) pico_dhcphdr
-{
-    uint8_t op;
-    uint8_t htype;
-    uint8_t hlen;
-    uint8_t hops; //zero
-    uint32_t xid; //store this in the request
-    uint16_t secs; // ignore
-    uint16_t flags;
-    uint32_t ciaddr; // client address - if asking for renewal
-    uint32_t yiaddr; // your address (client)
-    uint32_t siaddr; // dhcp offered address
-    uint32_t giaddr; // relay agent, bootp.
-    uint8_t hwaddr[6];
-    uint8_t hwaddr_padding[10];
-    char    hostname[64];
-    char    bootp_filename[128];
-    uint32_t dhcp_magic;
-    uint8_t options[0];
-};
-
-
-//common functions for client and server
-
-uint8_t dhcp_get_next_option(uint8_t *begin, uint8_t *data, int *len, uint8_t **nextopt);
-int is_options_valid(uint8_t *opt_buffer, int len); 
-#endif
--- a/modules/pico_dhcp_server.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-
-Authors: Frederik Van Slycken, Kristof Roelants
-*********************************************************************/
-
-#ifdef PICO_SUPPORT_DHCPD
-
-#include "pico_dhcp_server.h"
-#include "pico_stack.h"
-#include "pico_config.h"
-#include "pico_addressing.h"
-#include "pico_socket.h"
-#include "pico_arp.h"
-#include <stdlib.h>
-
-# define dhcpd_dbg(...) do{}while(0)
-//# define dhcpd_dbg dbg
-
-#define dhcpd_make_offer(x) dhcpd_make_reply(x, PICO_DHCP_MSG_OFFER)
-#define dhcpd_make_ack(x) dhcpd_make_reply(x, PICO_DHCP_MSG_ACK)
-#define ip_inrange(x) ((long_be(x) >= long_be(dn->settings->pool_start)) && (long_be(x) <= long_be(dn->settings->pool_end)))
-
-static int dhcp_settings_cmp(void *ka, void *kb)
-{
-  struct pico_dhcpd_settings *a = ka, *b = kb;
-  if (a->dev < b->dev)
-    return -1; 
-  else if (a->dev > b->dev)
-    return 1;
-  else
-    return 0;
-} 
-PICO_TREE_DECLARE(DHCPSettings, dhcp_settings_cmp);
-
-static int dhcp_negotiations_cmp(void *ka, void *kb)
-{
-  struct pico_dhcp_negotiation *a = ka, *b = kb;
-  if (a->xid < b->xid)
-    return -1; 
-  else if (a->xid > b->xid)
-    return 1;
-  else
-    return 0;
-} 
-PICO_TREE_DECLARE(DHCPNegotiations, dhcp_negotiations_cmp);
-
-static struct pico_dhcp_negotiation *get_negotiation_by_xid(uint32_t xid)
-{
-  struct pico_dhcp_negotiation test = { }, *neg = NULL;
-
-  test.xid = xid;
-  neg = pico_tree_findKey(&DHCPNegotiations, &test);
-  if (!neg)
-    return NULL;
-  else
-    return neg;
-}
-
-static void dhcpd_make_reply(struct pico_dhcp_negotiation *dn, uint8_t reply_type)
-{
-  uint8_t buf_out[DHCPD_DATAGRAM_SIZE] = {0};
-  struct pico_dhcphdr *dh_out = (struct pico_dhcphdr *) buf_out;
-  struct pico_ip4 destination = { };
-  uint32_t bcast = dn->settings->my_ip.addr | ~(dn->settings->netmask.addr);
-  uint32_t dns_server = OPENDNS;
-  uint16_t port = PICO_DHCP_CLIENT_PORT;
-  int sent = 0;
-
-  memcpy(dh_out->hwaddr, dn->eth.addr, PICO_HLEN_ETHER);
-  dh_out->op = PICO_DHCP_OP_REPLY;
-  dh_out->htype = PICO_HTYPE_ETHER;
-  dh_out->hlen = PICO_HLEN_ETHER;
-  dh_out->xid = dn->xid;
-  dh_out->yiaddr = dn->ipv4.addr;
-  dh_out->siaddr = dn->settings->my_ip.addr;
-  dh_out->dhcp_magic = PICO_DHCPD_MAGIC_COOKIE;
-
-  /* Option: msg type, len 1 */
-  dh_out->options[0] = PICO_DHCPOPT_MSGTYPE;
-  dh_out->options[1] = 1;
-  dh_out->options[2] = reply_type;
-
-  /* Option: server id, len 4 */
-  dh_out->options[3] = PICO_DHCPOPT_SERVERID;
-  dh_out->options[4] = 4;
-  memcpy(dh_out->options + 5, &dn->settings->my_ip.addr, 4);
-
-  /* Option: Lease time, len 4 */
-  dh_out->options[9] = PICO_DHCPOPT_LEASETIME;
-  dh_out->options[10] = 4;
-  memcpy(dh_out->options + 11, &dn->settings->lease_time, 4);
-
-  /* Option: Netmask, len 4 */
-  dh_out->options[15] = PICO_DHCPOPT_NETMASK;
-  dh_out->options[16] = 4;
-  memcpy(dh_out->options + 17, &dn->settings->netmask.addr, 4);
-
-  /* Option: Router, len 4 */
-  dh_out->options[21] = PICO_DHCPOPT_ROUTER;
-  dh_out->options[22] = 4;
-  memcpy(dh_out->options + 23, &dn->settings->my_ip.addr, 4);
-
-  /* Option: Broadcast, len 4 */
-  dh_out->options[27] = PICO_DHCPOPT_BCAST;
-  dh_out->options[28] = 4;
-  memcpy(dh_out->options + 29, &bcast, 4);
-
-  /* Option: DNS, len 4 */
-  dh_out->options[33] = PICO_DHCPOPT_DNS;
-  dh_out->options[34] = 4;
-  memcpy(dh_out->options + 35, &dns_server, 4);
-
-  dh_out->options[40] = PICO_DHCPOPT_END;
-
-  destination.addr = dh_out->yiaddr;
-
-  sent = pico_socket_sendto(dn->settings->s, buf_out, DHCPD_DATAGRAM_SIZE, &destination, port);
-  if (sent < 0) {
-    dhcpd_dbg("DHCPD: sendto failed with code %d!\n", pico_err);
-  }
-}
-
-static void dhcp_recv(struct pico_socket *s, uint8_t *buffer, int len)
-{
-  struct pico_dhcphdr *dhdr = (struct pico_dhcphdr *) buffer;
-  struct pico_dhcp_negotiation *dn = get_negotiation_by_xid(dhdr->xid);
-  struct pico_ip4* ipv4 = NULL;
-  struct pico_dhcpd_settings test, *settings = NULL;
-  uint8_t *nextopt, opt_data[20], opt_type;
-  int opt_len = 20;
-
-  if (!is_options_valid(dhdr->options, len - sizeof(struct pico_dhcphdr))) {
-    dhcpd_dbg("DHCPD WARNING: invalid options in dhcp message\n");
-    return;
-  }
-
-  if (!dn) {
-    dn = pico_zalloc(sizeof(struct pico_dhcp_negotiation));
-    if (!dn) {
-      pico_err = PICO_ERR_ENOMEM;
-      return;
-    }
-    dn->xid = dhdr->xid;
-    dn->state = DHCPSTATE_DISCOVER;
-    memcpy(dn->eth.addr, dhdr->hwaddr, PICO_HLEN_ETHER);
-
-    test.dev = pico_ipv4_link_find(&s->local_addr.ip4);
-    settings = pico_tree_findKey(&DHCPSettings, &test);
-    if (settings) {
-      dn->settings = settings;
-    } else {
-      dhcpd_dbg("DHCPD WARNING: received DHCP message on unconfigured link %s\n", test.dev->name);
-      pico_free(dn);
-      return;
-    }
-
-    ipv4 = pico_arp_reverse_lookup(&dn->eth);
-    if (!ipv4) {
-      dn->ipv4.addr = settings->pool_next;
-      pico_arp_create_entry(dn->eth.addr, dn->ipv4, settings->dev);
-      settings->pool_next = long_be(long_be(settings->pool_next) + 1);
-    } else {
-      dn->ipv4.addr = ipv4->addr;
-    }
-
-    if (pico_tree_insert(&DHCPNegotiations, dn)) {
-      dhcpd_dbg("DHCPD WARNING: tried creating new negotation for existing xid %u\n", dn->xid);
-      pico_free(dn);
-      return; /* Element key already exists */
-    }
-  }
- 
-  if (!ip_inrange(dn->ipv4.addr))
-    return;
-
-  opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len, &nextopt);
-  while (opt_type != PICO_DHCPOPT_END) {
-    /* parse interesting options here */
-    if (opt_type == PICO_DHCPOPT_MSGTYPE) {
-      /* server simple state machine */
-      uint8_t msg_type = opt_data[0];
-      if (msg_type == PICO_DHCP_MSG_DISCOVER) {
-        dhcpd_make_offer(dn);
-        dn->state = DHCPSTATE_OFFER;
-        return;
-      } else if ((msg_type == PICO_DHCP_MSG_REQUEST)&&( dn->state == DHCPSTATE_OFFER)) {
-        dhcpd_make_ack(dn);
-        dn->state = DHCPSTATE_BOUND;
-        return;
-      }
-    }
-    opt_len = 20;
-    opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len, &nextopt);
-  }
-}
-
-static void pico_dhcpd_wakeup(uint16_t ev, struct pico_socket *s)
-{
-  uint8_t buf[DHCPD_DATAGRAM_SIZE] = { };
-  int r = 0;
-  uint32_t peer = 0;
-  uint16_t port = 0;
-
-  dhcpd_dbg("DHCPD: called dhcpd_wakeup\n");
-  if (ev == PICO_SOCK_EV_RD) {
-    do {
-      r = pico_socket_recvfrom(s, buf, DHCPD_DATAGRAM_SIZE, &peer, &port);
-      if (r > 0 && port == PICO_DHCP_CLIENT_PORT) {
-        dhcp_recv(s, buf, r);
-      }
-    } while(r>0);
-  }
-}
-
-int pico_dhcp_server_initiate(struct pico_dhcpd_settings *setting)
-{
-  struct pico_dhcpd_settings *settings = NULL;
-  struct pico_ipv4_link *link = NULL;
-  uint16_t port = PICO_DHCPD_PORT;
-
-  if (!setting) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if (!setting->my_ip.addr) {
-    pico_err = PICO_ERR_EINVAL;
-    dhcpd_dbg("DHCPD: IP address of interface was not supplied\n");
-    return -1;
-  }
-
-  link = pico_ipv4_link_get(&setting->my_ip);
-  if (!link) {
-    pico_err = PICO_ERR_EINVAL;
-    dhcpd_dbg("DHCPD: no link with IP %X found\n", setting->my_ip.addr);
-    return -1;
-  }
-
-  settings = pico_zalloc(sizeof(struct pico_dhcpd_settings));
-  if (!settings) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  memcpy(settings, setting, sizeof(struct pico_dhcpd_settings));
-
-  settings->dev = link->dev;
-  dhcpd_dbg("DHCPD: configuring DHCP server for link %s\n", link->dev->name);
-  settings->my_ip.addr = link->address.addr;
-  dhcpd_dbg("DHCPD: using server addr %X\n", long_be(settings->my_ip.addr));
-  settings->netmask.addr = link->netmask.addr;
-  dhcpd_dbg("DHCPD: using netmask %X\n", long_be(settings->netmask.addr));
-
-  /* default values if not provided */
-  if (settings->pool_start == 0)
-    settings->pool_start = (settings->my_ip.addr & settings->netmask.addr) | POOL_START;
-  dhcpd_dbg("DHCPD: using pool_start %X\n", long_be(settings->pool_start));
-  if (settings->pool_end == 0)
-    settings->pool_end = (settings->my_ip.addr & settings->netmask.addr) | POOL_END;
-  dhcpd_dbg("DHCPD: using pool_end %x\n", long_be(settings->pool_end));
-  if (settings->lease_time == 0)
-    settings->lease_time = LEASE_TIME;
-  dhcpd_dbg("DHCPD: using lease time %x\n", long_be(settings->lease_time));
-  settings->pool_next = settings->pool_start;
-
-  settings->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcpd_wakeup);
-  if (!settings->s) {
-    dhcpd_dbg("DHCP: could not open client socket\n");
-    pico_free(settings);
-    return -1;
-  }
-  if (pico_socket_bind(settings->s, &settings->my_ip, &port) != 0) {
-    dhcpd_dbg("DHCP: could not bind server socket (%s)\n", strerror(pico_err));
-    pico_free(settings);
-    return -1;
-  }
-  
-  if (pico_tree_insert(&DHCPSettings, settings)) {
-    dhcpd_dbg("DHCPD ERROR: link %s already configured\n", link->dev->name);
-    pico_err = PICO_ERR_EINVAL;
-    pico_free(settings);
-    return -1; /* Element key already exists */
-  }
-  dhcpd_dbg("DHCPD: configured DHCP server for link %s\n", link->dev->name);
-
-  return 0;
-}
-#endif /* PICO_SUPPORT_DHCP */
--- a/modules/pico_dhcp_server.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_DHCP_SERVER
-#define _INCLUDE_PICO_DHCP_SERVER
-
-#include "pico_dhcp_common.h"
-#include "pico_addressing.h"
-
-/* default configuration */ 
-#define OPENDNS (long_be(0xd043dede)) /* OpenDNS DNS server 208.67.222.222 */
-#define POOL_START long_be(0x00000064)
-#define POOL_END long_be(0x000000fe)
-#define LEASE_TIME long_be(0x00000078)
-
-struct pico_dhcpd_settings
-{
-  struct pico_device *dev;
-  struct pico_socket *s;
-  struct pico_ip4 my_ip;
-  struct pico_ip4 netmask;
-  uint32_t pool_start;
-  uint32_t pool_next;
-  uint32_t pool_end;
-  uint32_t lease_time;
-  uint8_t flags; /* unused atm */
-};
-
-struct pico_dhcp_negotiation {
-  struct pico_dhcpd_settings *settings;
-  struct pico_ip4 ipv4;
-  struct pico_eth eth;
-  enum dhcp_negotiation_state state;
-  uint32_t xid;
-  uint32_t assigned_address;
-};
-
-/* required settings field: IP address of the interface to serve, only IPs of this network will be served. */
-int pico_dhcp_server_initiate(struct pico_dhcpd_settings *setting);
-
-#endif /* _INCLUDE_PICO_DHCP_SERVER */
--- a/modules/pico_dns_client.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,767 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-  
-Authors: Kristof Roelants
-*********************************************************************/
-#include "pico_config.h"
-#include "pico_stack.h"
-#include "pico_addressing.h"
-#include "pico_socket.h"
-#include "pico_ipv4.h"
-#include "pico_dns_client.h"
-#include "pico_tree.h"
-
-#ifdef PICO_SUPPORT_DNS_CLIENT
-
-#define dns_dbg(...) do{}while(0)
-//#define dns_dbg dbg
-
-/* DNS response length */
-#define PICO_DNS_MAX_RESPONSE_LEN 256
-
-/* DNS client retransmission time (msec) + frequency */
-#define PICO_DNS_CLIENT_RETRANS 4000
-#define PICO_DNS_CLIENT_MAX_RETRANS 3
-
-/* Default nameservers */
-#define PICO_DNS_NS_GOOGLE "8.8.8.8"
-
-/* Nameserver port */
-#define PICO_DNS_NS_PORT 53
-
-/* FLAG values */
-#define PICO_DNS_QR_QUERY 0
-#define PICO_DNS_QR_RESPONSE 1
-#define PICO_DNS_OPCODE_QUERY 0
-#define PICO_DNS_OPCODE_IQUERY 1
-#define PICO_DNS_OPCODE_STATUS 2
-#define PICO_DNS_AA_NO_AUTHORITY 0
-#define PICO_DNS_AA_IS_AUTHORITY 1
-#define PICO_DNS_TC_NO_TRUNCATION 0
-#define PICO_DNS_TC_IS_TRUNCATED 1
-#define PICO_DNS_RD_NO_DESIRE 0
-#define PICO_DNS_RD_IS_DESIRED 1
-#define PICO_DNS_RA_NO_SUPPORT 0
-#define PICO_DNS_RA_IS_SUPPORTED 1
-#define PICO_DNS_RCODE_NO_ERROR 0
-#define PICO_DNS_RCODE_EFORMAT 1
-#define PICO_DNS_RCODE_ESERVER 2
-#define PICO_DNS_RCODE_ENAME 3
-#define PICO_DNS_RCODE_ENOIMP 4
-#define PICO_DNS_RCODE_EREFUSED 5
-
-/* QTYPE values */
-#define PICO_DNS_TYPE_A 1
-#define PICO_DNS_TYPE_PTR 12
-
-/* QCLASS values */
-#define PICO_DNS_CLASS_IN 1
-
-/* Compression values */
-#define PICO_DNS_LABEL 0
-#define PICO_DNS_POINTER 3
-
-/* TTL values */
-#define PICO_DNS_MAX_TTL 604800 /* one week */
-
-/* Header flags */
-#define FLAG_QR(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x1 << 15)) | (x << 15)) 
-#define FLAG_OPCODE(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0xF << 11)) | (x << 11)) 
-#define FLAG_AA(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x1 << 10)) | (x << 10)) 
-#define FLAG_TC(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x1 << 9)) | (x << 9)) 
-#define FLAG_RD(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x1 << 8)) | (x << 8)) 
-#define FLAG_RA(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x1 << 7)) | (x << 7)) 
-#define FLAG_Z(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0x7 << 4)) | (x << 4)) 
-#define FLAG_RCODE(hdr, x) ((hdr)->flags = ((hdr)->flags & ~(0xF)) | x) 
-
-#define GET_FLAG_QR(hdr) ((((hdr)->flags) & (1 << 15)) != 0) 
-#define GET_FLAG_OPCODE(hdr) ((((hdr)->flags) & (0xF << 11)) >> 11) 
-#define GET_FLAG_AA(hdr) ((((hdr)->flags) & (1 << 10)) != 0) 
-#define GET_FLAG_TC(hdr) ((((hdr)->flags) & (1 << 9)) != 0) 
-#define GET_FLAG_RD(hdr) ((((hdr)->flags) & (1 << 8)) != 0) 
-#define GET_FLAG_RA(hdr) ((((hdr)->flags) & (1 << 7)) != 0) 
-#define GET_FLAG_Z(hdr) ((((hdr)->flags) & (0x7 << 4)) >> 4) 
-#define GET_FLAG_RCODE(hdr) (((hdr)->flags) & (0x0F)) 
-
-/* RFC 1025 section 4. MESSAGES */
-struct __attribute__((packed)) dns_message_hdr
-{
-  uint16_t id;
-  uint16_t flags;
-  uint16_t qdcount;
-  uint16_t ancount;
-  uint16_t nscount;
-  uint16_t arcount;
-};
-
-struct __attribute__((packed)) dns_query_suffix
-{
-  /* NAME - domain name to which this resource record pertains */
-  uint16_t qtype;
-  uint16_t qclass;
-};
-
-struct __attribute__((packed)) dns_answer_suffix
-{
-  /* NAME - domain name to which this resource record pertains */
-  uint16_t qtype;
-  uint16_t qclass;
-  uint32_t ttl;
-  uint16_t rdlength;
-  /* RDATA - variable length string of octets that describes the resource */
-};
-
-struct pico_dns_ns
-{
-  struct pico_ip4 ns; /* Nameserver */
-};
-
-static int dns_ns_cmp(void *ka, void *kb)
-{
-    struct pico_dns_ns *a = ka, *b = kb;
-  if (a->ns.addr < b->ns.addr)
-    return -1; 
-  else if (a->ns.addr > b->ns.addr)
-    return 1;
-  else
-    return 0;
-} 
-    
-PICO_TREE_DECLARE(NSTable,dns_ns_cmp);
-
-int pico_dns_client_nameserver(struct pico_ip4 *ns, uint8_t flag)
-{
-  struct pico_dns_ns test, *key = NULL;
-
-  if (!ns) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  switch (flag)
-  {
-    case PICO_DNS_NS_ADD:
-      key = pico_zalloc(sizeof(struct pico_dns_ns));
-      if (!key) {
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-      }
-      key->ns = *ns;
-
-      if(pico_tree_insert(&NSTable,key)){
-        dns_dbg("DNS WARNING: nameserver %08X already added\n",ns->addr);
-        pico_err = PICO_ERR_EINVAL;
-        pico_free(key);
-        return -1; /* Element key already exists */
-      }
-      dns_dbg("DNS: nameserver %08X added\n", ns->addr);
-      /* If default NS found, remove it */
-      pico_string_to_ipv4(PICO_DNS_NS_GOOGLE, &test.ns.addr);
-      if (ns->addr != test.ns.addr) {
-
-          key = pico_tree_findKey(&NSTable,&test);
-        if (key) {
-            if(pico_tree_delete(&NSTable,key)) {
-            dns_dbg("DNS: default nameserver %08X removed\n", test.ns.addr);
-            pico_free(key);
-          } else {
-            pico_err = PICO_ERR_EAGAIN;
-            return -1;
-          }
-        }
-      }
-      break;
-
-    case PICO_DNS_NS_DEL:
-      test.ns = *ns;
-
-      key = pico_tree_findKey(&NSTable,&test);
-      if (!key) {
-        dns_dbg("DNS WARNING: nameserver %08X not found\n", ns->addr);
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-      }
-      /* RB_REMOVE returns pointer to removed element, NULL to indicate error */
-
-            if(pico_tree_delete(&NSTable,key)) {
-        dns_dbg("DNS: nameserver %08X removed\n",key->ns.addr);
-        pico_free(key);
-      } else {
-        pico_err = PICO_ERR_EAGAIN;
-        return -1;
-      }
-      /* If no NS left, add default NS */
-      if(pico_tree_first(&NSTable) == NULL){
-        dns_dbg("DNS: add default nameserver\n");
-        return pico_dns_client_init();
-      }
-      break;
-
-    default:
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-  }
-  return 0;
-}
-
-int pico_dns_client_init()
-{
-  struct pico_ip4 default_ns;
-  if (pico_string_to_ipv4(PICO_DNS_NS_GOOGLE, &default_ns.addr) != 0) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  return pico_dns_client_nameserver(&default_ns, PICO_DNS_NS_ADD);
-}
-
-struct pico_dns_key
-{
-  char *q_hdr;
-  uint16_t len;
-  uint16_t id;
-  uint16_t qtype;
-  uint16_t qclass;
-  uint8_t retrans;
-  struct pico_dns_ns q_ns;
-  struct pico_socket *s;
-  void (*callback)(char *, void *);
-  void *arg;
-};
-
-static int dns_cmp(void *ka, void *kb)
-{
-    struct pico_dns_key *a = ka,*b = kb;
-  if (a->id < b->id)
-    return -1; 
-  else if (a->id > b->id)
-    return 1;
-  else
-    return 0;
-} 
-    
-PICO_TREE_DECLARE(DNSTable,dns_cmp);
-
-static int pico_dns_client_strlen(const char *url)
-{
-  uint16_t len = 0;
-  int p;
-
-  if (!url)
-    return -1;
-
-  while ((p = *url++) != 0) {
-    len++;
-  }
-  return len;
-}
-
-/* Replace '.' by the label length */
-static int pico_dns_client_label(char *ptr)
-{
-  char *l;
-  uint8_t lbl_len = 0;
-  int p;
-
-  if (!ptr)
-    return -1;
-
-  l = ptr++;
-  while ((p = *ptr++) != 0){
-    if (p == '.') {
-      *l = lbl_len;
-      l = ptr - 1;
-      lbl_len = 0;
-    } else {
-      lbl_len++;
-    }
-  }
-  *l = lbl_len;
-  return 0;
-}
-
-/* Replace the label length by '.' */
-static int pico_dns_client_reverse_label(char *ptr)
-{
-  char *l;
-  int p;
-
-  if(!ptr)
-    return -1;
-
-  l = ptr;
-  while ((p = *ptr++) != 0){
-    ptr += p;
-    *l = '.';
-    l = ptr;
-  }
-  return 0;
-}
-
-/* Seek the end of a string */
-static char *pico_dns_client_seek(char *ptr)
-{
-  int p;
-
-  if (!ptr)
-    return NULL;
-
-  while ((p = *ptr++) != 0);
-
-  return ptr++;
-}
-
-static inline void pico_dns_client_construct_hdr(struct dns_message_hdr *hdr, uint16_t id)
-{
-  hdr->id = short_be(id);
-  FLAG_QR(hdr, PICO_DNS_QR_QUERY); 
-  FLAG_OPCODE(hdr, PICO_DNS_OPCODE_QUERY); 
-  FLAG_AA(hdr, PICO_DNS_AA_NO_AUTHORITY); 
-  FLAG_TC(hdr, PICO_DNS_TC_NO_TRUNCATION); 
-  FLAG_RD(hdr, PICO_DNS_RD_IS_DESIRED); 
-  FLAG_RA(hdr, PICO_DNS_RA_NO_SUPPORT); 
-  FLAG_Z(hdr, 0); 
-  FLAG_RCODE(hdr, PICO_DNS_RCODE_NO_ERROR); 
-  hdr->flags = short_be(hdr->flags);
-  hdr->qdcount = short_be(1);
-  hdr->ancount = short_be(0);
-  hdr->nscount = short_be(0);
-  hdr->arcount = short_be(0);
-}
-
-static inline void pico_dns_client_hdr_ntoh(struct dns_message_hdr *hdr)
-{
-  hdr->id = short_be(hdr->id);
-  hdr->flags = short_be(hdr->flags);
-  hdr->qdcount = short_be(hdr->qdcount);
-  hdr->ancount = short_be(hdr->ancount);
-  hdr->nscount = short_be(hdr->nscount);
-  hdr->arcount = short_be(hdr->arcount);
-}
-
-
-static int pico_dns_client_mirror(char *ptr)
-{
-  unsigned char buf[4] = {0};
-  char *m;
-  int cnt = 0;
-  int p, i;
-
-  if (!ptr)
-    return -1;
-
-  m = ptr;
-  while ((p = *ptr++) != 0)
-  {
-    if (pico_is_digit(p)) {
-      buf[cnt] = (10 * buf[cnt]) + (p - '0');
-    } else if (p == '.') {
-        cnt++;
-    } else {
-      return -1;
-    }
-  }
-
-  /* Handle short notation */
-  if(cnt == 1){
-    buf[3] = buf[1];
-    buf[1] = 0;
-    buf[2] = 0;
-  }else if (cnt == 2){
-    buf[3] = buf[2];
-    buf[2] = 0;
-  }else if(cnt != 3){
-    /* String could not be parsed, return error */
-    return -1;
-  }
-
-  ptr = m;
-  for(i = 3; i >= 0; i--)
-  {
-    if(buf[i] > 99){
-      *ptr++ = '0' + (buf[i] / 100);
-      *ptr++ = '0' + ((buf[i] % 100) / 10);
-      *ptr++ = '0' + ((buf[i] % 100) % 10);
-    }else if(buf[i] > 9){
-      *ptr++ = '0' + (buf[i] / 10);
-      *ptr++ = '0' + (buf[i] % 10);
-    }else{
-      *ptr++ = '0' + buf[i];
-    }
-    if(i > 0)
-      *ptr++ = '.';
-  }
-
-  return 0;
-}
-
-static struct pico_dns_key *pico_dns_client_idcheck(uint16_t id)
-{
-  struct pico_dns_key test;
-
-  test.id = id;
-  return pico_tree_findKey(&DNSTable,&test);
-}
-
-static void pico_dns_client_callback(uint16_t ev, struct pico_socket *s);
-
-static int pico_dns_client_send(struct pico_dns_key *key)
-{
-  struct pico_socket *s;
-  int w = 0;
-
-  dns_dbg("DNS: sending query to %08X\n", key->q_ns.ns.addr);
-  s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dns_client_callback);
-  if (!s)
-    return -1; 
-  key->s = s;
-  if (pico_socket_connect(s, &key->q_ns.ns, short_be(PICO_DNS_NS_PORT)) != 0)
-    return -1;
-  w = pico_socket_send(s, key->q_hdr, key->len);
-  if (w <= 0)
-    return -1;
-
-  return 0;
-}
-
-static void pico_dns_client_retransmission(unsigned long now, void *arg)
-{
-  struct pico_dns_key *key = (struct pico_dns_key *)arg;
-  struct pico_dns_ns *q_ns = NULL;
-
-  if (!key->retrans) {
-    dns_dbg("DNS: no retransmission!\n");
-    pico_free(key->q_hdr);
-
-    if(pico_tree_delete(&DNSTable,key))
-      pico_free(key);
-  }
-  else if (key->retrans <= PICO_DNS_CLIENT_MAX_RETRANS) {
-    key->retrans++;
-    dns_dbg("DNS: retransmission! (%u attempts)\n", key->retrans);
-        // ugly hack
-    q_ns = pico_tree_next(pico_tree_findNode(&NSTable,&key->q_ns))->keyValue;
-    if (q_ns)
-      key->q_ns = *q_ns; 
-    else
-        key->q_ns = *((struct pico_dns_ns *)pico_tree_first(&NSTable));
-    pico_dns_client_send(key);
-    pico_timer_add(PICO_DNS_CLIENT_RETRANS, pico_dns_client_retransmission, key);
-  } else {
-    dns_dbg("DNS ERROR: no reply from nameservers! (%u attempts)\n", key->retrans);
-    pico_socket_close(key->s);
-    pico_err = PICO_ERR_EIO;
-    key->callback(NULL, key->arg);
-    pico_free(key->q_hdr);
-    /* RB_REMOVE returns pointer to removed element, NULL to indicate error */
-
-    if(pico_tree_delete(&DNSTable,key))
-      pico_free(key);
-  }
-}
-
-static void pico_dns_client_callback(uint16_t ev, struct pico_socket *s)
-{
-  char *q_qname, *q_suf, *a_hdr, *a_qname, *a_suf, *a_rdata;
-  struct dns_message_hdr *hdr;
-  struct dns_query_suffix query_suf;
-  struct dns_answer_suffix answer_suf;
-  struct pico_dns_key test, *key;
-  char *answer;
-  char dns_answer[PICO_DNS_MAX_RESPONSE_LEN] = {0};
-  uint8_t valid_suffix = 0;
-  uint16_t compression = 0;
-  int i = 0, r = 0;
-
-  if (ev & PICO_SOCK_EV_RD) {
-    r = pico_socket_read(s, dns_answer, PICO_DNS_MAX_RESPONSE_LEN);
-    pico_socket_close(s);
-    if (r == PICO_DNS_MAX_RESPONSE_LEN || r < (int)sizeof(struct dns_message_hdr)) {
-      dns_dbg("DNS ERROR: received incorrect number(%d) of bytes\n", r);
-      return;
-    }
-
-    /* Check header validity */
-    a_hdr = dns_answer;
-    hdr = (struct dns_message_hdr *) a_hdr;
-    pico_dns_client_hdr_ntoh(hdr);
-    if (GET_FLAG_QR(hdr) != PICO_DNS_QR_RESPONSE || GET_FLAG_OPCODE(hdr) != PICO_DNS_OPCODE_QUERY 
-        || GET_FLAG_TC(hdr) == PICO_DNS_TC_IS_TRUNCATED || GET_FLAG_RCODE(hdr) != PICO_DNS_RCODE_NO_ERROR) {
-      dns_dbg("DNS ERROR: OPCODE %d | TC %d | RCODE %d\n", GET_FLAG_OPCODE(hdr), GET_FLAG_TC(hdr), GET_FLAG_RCODE(hdr));
-      return;
-    }
-
-    if (hdr->ancount < 1 || r < (int)(sizeof(struct dns_message_hdr) + hdr->qdcount * sizeof(struct dns_query_suffix)
-            + hdr->ancount * sizeof(struct dns_answer_suffix))) {
-      dns_dbg("DNS ERROR: ancount < 1 OR received number(%d) of bytes too low\n", r);
-      return;
-    }
-
-    /* Find DNS key */
-    test.id = hdr->id;
-
-    key = pico_tree_findKey(&DNSTable,&test);
-    if (!key) {
-      dns_dbg("DNS WARNING: key with id %u not found\n", hdr->id);
-      return;
-    }
-    key->retrans = 0;
-
-    /* Check query suffix validity */
-    q_qname = a_hdr + sizeof(struct dns_message_hdr);
-    q_suf = pico_dns_client_seek(q_qname);
-    query_suf = *(struct dns_query_suffix *) q_suf;
-    if (short_be(query_suf.qtype) != key->qtype || short_be(query_suf.qclass) != key->qclass) {
-      dns_dbg("DNS ERROR: received qtype (%u) or qclass (%u) incorrect\n", short_be(query_suf.qtype), short_be(query_suf.qclass));
-      return;
-    }
-
-    /* Seek answer suffix */
-    a_qname = q_suf + sizeof(struct dns_query_suffix);
-    a_suf = a_qname;
-    while(i++ < hdr->ancount) {
-      uint16_t comp_h = short_from(a_suf);
-      compression = short_be(comp_h);
-      switch (compression >> 14)
-      {
-        case PICO_DNS_POINTER:
-          while (compression >> 14 == PICO_DNS_POINTER) {
-            dns_dbg("DNS: pointer\n");
-            a_suf += sizeof(uint16_t);
-            comp_h = short_from(a_suf);
-            compression = short_be(comp_h);
-          }
-          break;
-
-        case PICO_DNS_LABEL:
-          dns_dbg("DNS: label\n");
-          a_suf = pico_dns_client_seek(a_qname);
-          break;
-
-        default:
-          dns_dbg("DNS ERROR: incorrect compression (%u) value\n", compression);
-          return;
-      }
-
-      /* Check answer suffix validity */
-      answer_suf = *(struct dns_answer_suffix *)a_suf;
-      if (short_be(answer_suf.qtype) != key->qtype || short_be(answer_suf.qclass) != key->qclass) {
-        dns_dbg("DNS WARNING: received qtype (%u) or qclass (%u) incorrect\n", short_be(answer_suf.qtype), short_be(answer_suf.qclass));
-        a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength);
-        continue;
-      }
-
-      if (short_be(answer_suf.ttl) > PICO_DNS_MAX_TTL) {
-        dns_dbg("DNS WARNING: received TTL (%u) > MAX (%u)\n", short_be(answer_suf.ttl), PICO_DNS_MAX_TTL);
-        a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength);
-        continue;
-      }
-
-      valid_suffix = 1;
-      break;
-    }
-
-    if (!valid_suffix) {
-       dns_dbg("DNS ERROR: invalid dns answer suffix\n");
-       return;
-    }
-
-    a_rdata = a_suf + sizeof(struct dns_answer_suffix);
-    if (key->qtype == PICO_DNS_TYPE_A) {
-      uint32_t ip_h = long_from(a_rdata);
-      dns_dbg("DNS: length %u | ip %08X\n", short_be(answer_suf.rdlength), long_be(ip_h));
-      answer = pico_zalloc(16);
-      pico_ipv4_to_string(answer, ip_h);
-      key->callback(answer, key->arg);
-    } else if (key->qtype == PICO_DNS_TYPE_PTR) {
-      pico_dns_client_reverse_label((char *) a_rdata);
-      dns_dbg("DNS: length %u | name %s\n", short_be(answer_suf.rdlength), (char *)a_rdata + 1);
-      answer = pico_zalloc(answer_suf.rdlength - 1);
-      memcpy(answer, (char *)a_rdata + 1, short_be(answer_suf.rdlength) - 1);
-      key->callback(answer, key->arg);
-    } else {
-      dns_dbg("DNS ERROR: incorrect qtype (%u)\n", key->qtype);
-      return;
-    }
-  }
-
-  if (ev == PICO_SOCK_EV_ERR) {
-    dns_dbg("DNS: socket error received\n");
-  }
-}
-
-int pico_dns_client_getaddr(const char *url, void (*callback)(char *, void *), void *arg)
-{
-  char *q_hdr, *q_qname, *q_suf;
-  struct dns_message_hdr *hdr;
-  struct dns_query_suffix query_suf;
-  struct pico_dns_key *key;
-  uint16_t url_len = 0;
-  uint16_t id = 0;
-
-  if (!url || !callback) {
-    dns_dbg("DNS ERROR: NULL parameters\n");
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  url_len = pico_dns_client_strlen(url);
-  /* 2 extra bytes for url_len to account for 2 extra label length octets */
-  q_hdr = pico_zalloc(sizeof(struct dns_message_hdr) + (1 + url_len + 1) + sizeof(struct dns_query_suffix));
-  if (!q_hdr) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  q_qname = q_hdr + sizeof(struct dns_message_hdr);
-  q_suf = q_qname + (1 + url_len + 1);
-
-  /* Construct query header */
-  hdr = (struct dns_message_hdr *) q_hdr;
-  do {
-    id = (uint16_t) (pico_rand() & 0xFFFFU);
-    dns_dbg("DNS: generated id %u\n", id);
-  } while (pico_dns_client_idcheck(id));
-  pico_dns_client_construct_hdr(hdr, id);
-  /* Add and manipulate domain name */
-  memcpy(q_qname + 1, url, url_len + 1);
-  pico_dns_client_label(q_qname);
-  /* Add type and class of query */
-  query_suf.qtype = short_be(PICO_DNS_TYPE_A);
-  query_suf.qclass = short_be(PICO_DNS_CLASS_IN);
-  memcpy(q_suf, &query_suf, sizeof(struct dns_query_suffix));
-  /* Create RB entry */
-  key = pico_zalloc(sizeof(struct pico_dns_key));
-  if (!key) {
-    pico_free(q_hdr);
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  key->q_hdr = q_hdr;
-  key->len = sizeof(struct dns_message_hdr) + (1 + url_len + 1) + sizeof(struct dns_query_suffix);
-  key->id = id;
-  key->qtype = PICO_DNS_TYPE_A;
-  key->qclass = PICO_DNS_CLASS_IN;
-  key->retrans = 1;
-
-  key->q_ns = *((struct pico_dns_ns *)pico_tree_first(&NSTable));
-  key->s = NULL;
-  key->callback = callback;
-  key->arg = arg;
-  /* Send query */
-  if (pico_dns_client_send(key) < 0) {
-    pico_free(q_hdr);
-    if (key->s)
-      pico_socket_close(key->s);
-    pico_free(key);
-    pico_err = PICO_ERR_EAGAIN;
-    return -1;
-  }
-  /* Insert RB entry */
-
-  if(pico_tree_insert(&DNSTable,key)) {
-    pico_free(q_hdr);
-    pico_free(key);
-    pico_err = PICO_ERR_EAGAIN;
-    return -1; /* Element key already exists */
-  }
-
-  pico_timer_add(PICO_DNS_CLIENT_RETRANS, pico_dns_client_retransmission, key);
-  return 0;
-}
-
-int pico_dns_client_getname(const char *ip, void (*callback)(char *, void *), void *arg)
-{
-  char *q_hdr, *q_qname, *q_suf;
-  struct dns_message_hdr *hdr;
-  struct dns_query_suffix query_suf;
-  struct pico_dns_key *key;
-  uint16_t ip_len = 0;
-  uint16_t arpa_len = 0;
-  uint16_t id = 0;
-
-  if (!ip || !callback) {
-    dns_dbg("DNS ERROR: NULL parameters\n");
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  ip_len = pico_dns_client_strlen(ip);
-  arpa_len = pico_dns_client_strlen(".in-addr.arpa");
-  /* 2 extra bytes for ip_len and arpa_len to account for 2 extra length octets */
-  q_hdr = pico_zalloc(sizeof(struct dns_message_hdr) + (1 + ip_len + arpa_len + 1) + sizeof(struct dns_query_suffix));
-  if (!q_hdr) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  q_qname = q_hdr + sizeof(struct dns_message_hdr);
-  q_suf = q_qname + (1 + ip_len + arpa_len + 1);
-
-  /* Construct query header */
-  hdr = (struct dns_message_hdr *)q_hdr;
-  do {
-    id = (uint16_t) (pico_rand() & 0xFFFFU);
-    dns_dbg("DNS: generated id %u\n", id);
-  } while (pico_dns_client_idcheck(id));
-  pico_dns_client_construct_hdr(hdr, id);
-  /* Add and manipulate domain name */
-  memcpy(q_qname + 1, ip, ip_len + 1);
-  pico_dns_client_mirror(q_qname + 1);
-  memcpy(q_qname + 1 + ip_len, ".in-addr.arpa", arpa_len);
-  pico_dns_client_label(q_qname);
-  /* Add type and class of query */
-  query_suf.qtype = short_be(PICO_DNS_TYPE_PTR);
-  query_suf.qclass = short_be(PICO_DNS_CLASS_IN);
-  memcpy(q_suf, &query_suf, sizeof(struct dns_query_suffix));
-  /* Create RB entry */
-  key = pico_zalloc(sizeof(struct pico_dns_key));
-  if (!key) {
-    pico_free(q_hdr);
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  key->q_hdr = q_hdr;
-  key->len = sizeof(struct dns_message_hdr) + (1 + ip_len + arpa_len + 1) + sizeof(struct dns_query_suffix);
-  key->id = id;
-  key->qtype = PICO_DNS_TYPE_PTR;
-  key->qclass = PICO_DNS_CLASS_IN;
-  key->retrans = 1;
-  key->q_ns = *((struct pico_dns_ns *)pico_tree_first(&NSTable));
-  key->s = NULL;
-  key->callback = callback;
-  key->arg = arg;
-  /* Send query */
-  if (pico_dns_client_send(key) < 0) {
-    pico_free(q_hdr);
-    if (key->s)
-      pico_socket_close(key->s);
-    pico_free(key);
-    pico_err = PICO_ERR_EAGAIN;
-    return -1;
-  }
-  /* Insert RB entry */
-
-  if(pico_tree_insert(&DNSTable,key)) {
-    pico_free(q_hdr);
-    pico_free(key);
-    pico_err = PICO_ERR_EAGAIN;
-    return -1; /* Element key already exists */
-  }
-
-  pico_timer_add(PICO_DNS_CLIENT_RETRANS, pico_dns_client_retransmission, key);
-  return 0;
-}
-
-#ifdef PICO_DNS_CLIENT_MAIN
-int main(int argc, char *argv[])
-{
-  dns_dbg(">>>>> DNS GET ADDR\n");
-  pico_dns_client_getaddr("www.google.be");
-  dns_dbg(">>>>> DNS GET NAME\n");
-  pico_dns_client_getname("173.194.67.94");
-
-  return 0;
-}
-#endif /* PICO_DNS_CLIENT_MAIN */
-#endif /* PICO_SUPPORT_DNS_CLIENT */
--- a/modules/pico_dns_client.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-  
-Authors: Kristof Roelants
-*********************************************************************/
-#include <stdint.h>
-#ifndef _INCLUDE_PICO_DNS_CLIENT
-#define _INCLUDE_PICO_DNS_CLIENT
-
-#define PICO_DNS_NS_DEL 0
-#define PICO_DNS_NS_ADD 1
-
-int pico_dns_client_init();
-/* flag is PICO_DNS_NS_DEL or PICO_DNS_NS_ADD */
-int pico_dns_client_nameserver(struct pico_ip4 *ns, uint8_t flag);
-int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg);
-int pico_dns_client_getname(const char *ip, void (*callback)(char *url, void *arg), void *arg);
-
-#endif /* _INCLUDE_PICO_DNS_CLIENT */
--- a/modules/pico_http_client.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,701 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-#include <string.h>
-#include <stdint.h>
-#include "pico_tree.h"
-#include "pico_config.h"
-#include "pico_socket.h"
-#include "pico_tcp.h"
-#include "pico_dns_client.h"
-#include "pico_http_client.h"
-#include "pico_ipv4.h"
-#include "pico_stack.h"
-
-/*
- * This is the size of the following header
- *
- * GET <resource> HTTP/1.1<CRLF>
- * Host: <host>:<port><CRLF>
- * User-Agent: picoTCP<CRLF>
- * Connection: close<CRLF>
- * <CRLF>
- *
- * where <resource>,<host> and <port> will be added later.
- */
-
-#ifdef PICO_SUPPORT_HTTP_CLIENT
-
-#define HTTP_GET_BASIC_SIZE   63u
-#define HTTP_HEADER_LINE_SIZE 50u
-#define RESPONSE_INDEX                9u
-
-#define HTTP_CHUNK_ERROR    0xFFFFFFFFu
-
-#ifdef dbg
-    #undef dbg
-    #define dbg(...) do{}while(0);
-#endif
-
-#define consumeChar(c)                             (pico_socket_read(client->sck,&c,1u))
-#define isLocation(line)                         (memcmp(line,"Location",8u) == 0)
-#define isContentLength(line)             (memcmp(line,"Content-Length",14u) == 0u)
-#define isTransferEncoding(line)        (memcmp(line,"Transfer-Encoding",17u) == 0u)
-#define isChunked(line)                            (memcmp(line," chunked",8u) == 0u)
-#define isNotHTTPv1(line)                        (memcmp(line,"HTTP/1.",7u))
-#define is_hex_digit(x) ( ('0' <= x && x <= '9') || ('a' <= x && x <= 'f') )
-#define hex_digit_to_dec(x) ( ('0' <= x && x <= '9') ? x-'0' : ( ('a' <= x && x <= 'f') ? x-'a' + 10 : -1) )
-
-struct pico_http_client
-{
-    uint16_t connectionID;
-    uint8_t state;
-    struct pico_socket * sck;
-    void (*wakeup)(uint16_t ev, uint16_t conn);
-    struct pico_ip4 ip;
-    struct pico_http_uri * uriKey;
-    struct pico_http_header * header;
-};
-
-// HTTP Client internal states
-#define HTTP_READING_HEADER      0
-#define HTTP_READING_BODY                 1
-#define HTTP_READING_CHUNK_VALUE 2
-#define HTTP_READING_CHUNK_TRAIL 3
-
-
-static int compareClients(void * ka, void * kb)
-{
-    return ((struct pico_http_client *)ka)->connectionID - ((struct pico_http_client *)kb)->connectionID;
-}
-
-PICO_TREE_DECLARE(pico_client_list,compareClients);
-
-// Local functions
-int parseHeaderFromServer(struct pico_http_client * client, struct pico_http_header * header);
-int readChunkLine(struct pico_http_client * client);
-
-void tcpCallback(uint16_t ev, struct pico_socket *s)
-{
-
-    struct pico_http_client * client = NULL;
-    struct pico_tree_node * index;
-
-    // find httpClient
-    pico_tree_foreach(index,&pico_client_list)
-    {
-        if( ((struct pico_http_client *)index->keyValue)->sck == s )
-        {
-            client = (struct pico_http_client *)index->keyValue;
-            break;
-        }
-    }
-
-    if(!client)
-    {
-        dbg("Client not found...Something went wrong !\n");
-        return;
-    }
-
-    if(ev & PICO_SOCK_EV_CONN)
-        client->wakeup(EV_HTTP_CON,client->connectionID);
-
-    if(ev & PICO_SOCK_EV_RD)
-    {
-
-        // read the header, if not read
-        if(client->state == HTTP_READING_HEADER)
-        {
-            // wait for header
-            client->header = pico_zalloc(sizeof(struct pico_http_header));
-            if(!client->header)
-            {
-                pico_err = PICO_ERR_ENOMEM;
-                return;
-            }
-
-            // wait for header
-            if(parseHeaderFromServer(client,client->header) < 0)
-            {
-                client->wakeup(EV_HTTP_ERROR,client->connectionID);
-            }
-            else
-            {
-                // call wakeup
-                if(client->header->responseCode != HTTP_CONTINUE)
-                {
-                    client->wakeup(
-                            client->header->responseCode == HTTP_OK ?
-                            EV_HTTP_REQ | EV_HTTP_BODY : // data comes for sure only when 200 is received
-                            EV_HTTP_REQ
-                            ,client->connectionID);
-                }
-            }
-        }
-        else
-        {
-            // just let the user know that data has arrived, if chunked data comes, will be treated in the
-            // read api.
-            client->wakeup(EV_HTTP_BODY,client->connectionID);
-        }
-    }
-
-    if(ev & PICO_SOCK_EV_ERR)
-    {
-        client->wakeup(EV_HTTP_ERROR,client->connectionID);
-    }
-
-    if( (ev & PICO_SOCK_EV_CLOSE) || (ev & PICO_SOCK_EV_FIN) )
-    {
-        client->wakeup(EV_HTTP_CLOSE,client->connectionID);
-    }
-
-}
-
-// used for getting a response from DNS servers
-static void dnsCallback(char *ip, void * ptr)
-{
-    struct pico_http_client * client = (struct pico_http_client *)ptr;
-
-    if(!client)
-    {
-        dbg("Who made the request ?!\n");
-        return;
-    }
-
-    if(ip)
-    {
-        client->wakeup(EV_HTTP_DNS,client->connectionID);
-
-        // add the ip address to the client, and start a tcp connection socket
-        pico_string_to_ipv4(ip,&client->ip.addr);
-        pico_free(ip);
-        client->sck = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &tcpCallback);
-        if(!client->sck)
-        {
-            client->wakeup(EV_HTTP_ERROR,client->connectionID);
-            return;
-        }
-
-        if(pico_socket_connect(client->sck,&client->ip,short_be(client->uriKey->port)) < 0)
-        {
-            client->wakeup(EV_HTTP_ERROR,client->connectionID);
-            return;
-        }
-
-    }
-    else
-    {
-        // wakeup client and let know error occured
-        client->wakeup(EV_HTTP_ERROR,client->connectionID);
-
-        // close the client (free used heap)
-        pico_http_client_close(client->connectionID);
-    }
-}
-
-/*
- * API used for opening a new HTTP Client.
- *
- * The accepted uri's are [http://]hostname[:port]/resource
- * no relative uri's are accepted.
- *
- * The function returns a connection ID >= 0 if successful
- * -1 if an error occured.
- */
-int pico_http_client_open(char * uri, void (*wakeup)(uint16_t ev, uint16_t conn))
-{
-    struct pico_http_client * client;
-
-    if(!wakeup)
-    {
-        pico_err = PICO_ERR_EINVAL;
-        return HTTP_RETURN_ERROR;
-    }
-
-    client = pico_zalloc(sizeof(struct pico_http_client));
-    if(!client)
-    {
-        // memory error
-        pico_err = PICO_ERR_ENOMEM;
-        return HTTP_RETURN_ERROR;
-    }
-
-    client->wakeup = wakeup;
-    client->connectionID = (uint16_t)pico_rand() & 0x7FFFu; // negative values mean error, still not good generation
-
-    client->uriKey = pico_zalloc(sizeof(struct pico_http_uri));
-
-    if(!client->uriKey)
-    {
-        pico_err = PICO_ERR_ENOMEM;
-        pico_free(client);
-        return HTTP_RETURN_ERROR;
-    }
-
-    pico_processURI(uri,client->uriKey);
-
-    if(pico_tree_insert(&pico_client_list,client))
-    {
-        // already in
-        pico_err = PICO_ERR_EEXIST;
-        pico_free(client->uriKey);
-        pico_free(client);
-        return HTTP_RETURN_ERROR;
-    }
-
-    // dns query
-    dbg("Querying : %s \n",client->uriKey->host);
-    pico_dns_client_getaddr(client->uriKey->host, dnsCallback,client);
-
-    // return the connection ID
-    return client->connectionID;
-}
-
-/*
- * API for sending a header to the client.
- *
- * if hdr == HTTP_HEADER_RAW , then the parameter header
- * is sent as it is to client.
- *
- * if hdr == HTTP_HEADER_DEFAULT, then the parameter header
- * is ignored and the library will build the response header
- * based on the uri passed when opening the client.
- *
- */
-int pico_http_client_sendHeader(uint16_t conn, char * header, int hdr)
-{
-    struct pico_http_client search = {.connectionID = conn};
-    struct pico_http_client * http = pico_tree_findKey(&pico_client_list,&search);
-    int length ;
-    if(!http)
-    {
-        dbg("Client not found !\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    // the api gives the possibility to the user to build the GET header
-    // based on the uri passed when opening the client, less headache for the user
-    if(hdr == HTTP_HEADER_DEFAULT)
-    {
-        header = pico_http_client_buildHeader(http->uriKey);
-
-        if(!header)
-        {
-            pico_err = PICO_ERR_ENOMEM;
-            return HTTP_RETURN_ERROR;
-        }
-    }
-
-    length = pico_socket_write(http->sck,(void *)header,strlen(header)+1);
-
-    if(hdr == HTTP_HEADER_DEFAULT)
-        pico_free(header);
-
-    return length;
-}
-
-/*
- * API for reading received data.
- *
- * This api hides from the user if the transfer-encoding
- * was chunked or a full length was provided, in case of
- * a chunked transfer encoding will "de-chunk" the data
- * and pass it to the user.
- */
-int pico_http_client_readData(uint16_t conn, char * data, uint16_t size)
-{
-    struct pico_http_client dummy = {.connectionID = conn};
-    struct pico_http_client * client = pico_tree_findKey(&pico_client_list,&dummy);
-
-    if(!client)
-    {
-        dbg("Wrong connection id !\n");
-        pico_err = PICO_ERR_EINVAL;
-        return HTTP_RETURN_ERROR;
-    }
-
-    // for the moment just read the data, do not care if it's chunked or not
-    if(client->header->transferCoding == HTTP_TRANSFER_FULL)
-        return pico_socket_read(client->sck,(void *)data,size);
-    else
-    {
-        int lenRead = 0;
-
-        // read the chunk line
-        if(readChunkLine(client) == HTTP_RETURN_ERROR)
-        {
-            dbg("Probably the chunk is malformed or parsed wrong...\n");
-            client->wakeup(EV_HTTP_ERROR,client->connectionID);
-            return HTTP_RETURN_ERROR;
-        }
-
-        // nothing to read, no use to try
-        if(client->state != HTTP_READING_BODY)
-        {
-            pico_err = PICO_ERR_EAGAIN;
-            return HTTP_RETURN_OK;
-        }
-
-        // check if we need more than one chunk
-        if(size >= client->header->contentLengthOrChunk)
-        {
-            // read the rest of the chunk, if chunk is done, proceed to the next chunk
-            while(lenRead <= size)
-            {
-                int tmpLenRead = 0;
-
-                if(client->state == HTTP_READING_BODY)
-                {
-
-                    // if needed truncate the data
-                    tmpLenRead = pico_socket_read(client->sck,data + lenRead,
-                    client->header->contentLengthOrChunk < size-lenRead ? client->header->contentLengthOrChunk : size-lenRead);
-
-                    if(tmpLenRead > 0)
-                    {
-                        client->header->contentLengthOrChunk -= tmpLenRead;
-                    }
-                    else if(tmpLenRead < 0)
-                    {
-                        // error on reading
-                        dbg(">>> Error returned pico_socket_read\n");
-                        pico_err = PICO_ERR_EBUSY;
-                        // return how much data was read until now
-                        return lenRead;
-                    }
-                }
-
-                lenRead += tmpLenRead;
-                if(readChunkLine(client) == HTTP_RETURN_ERROR)
-                {
-                    dbg("Probably the chunk is malformed or parsed wrong...\n");
-                    client->wakeup(EV_HTTP_ERROR,client->connectionID);
-                    return HTTP_RETURN_ERROR;
-                }
-
-                if(client->state != HTTP_READING_BODY || !tmpLenRead)  break;
-
-            }
-        }
-        else
-        {
-            // read the data from the chunk
-            lenRead = pico_socket_read(client->sck,(void *)data,size);
-
-            if(lenRead)
-                client->header->contentLengthOrChunk -= lenRead;
-        }
-
-        return lenRead;
-    }
-}
-
-/*
- * API for reading received data.
- *
- * Reads out the header struct received from server.
- */
-struct pico_http_header * pico_http_client_readHeader(uint16_t conn)
-{
-    struct pico_http_client dummy = {.connectionID = conn};
-    struct pico_http_client * client = pico_tree_findKey(&pico_client_list,&dummy);
-
-    if(client)
-    {
-        return client->header;
-    }
-    else
-    {
-        // not found
-        dbg("Wrong connection id !\n");
-        pico_err = PICO_ERR_EINVAL;
-        return NULL;
-    }
-}
-
-/*
- * API for reading received data.
- *
- * Reads out the uri struct after was processed.
- */
-struct pico_http_uri * pico_http_client_readUriData(uint16_t conn)
-{
-    struct pico_http_client dummy = {.connectionID = conn};
-    struct pico_http_client * client = pico_tree_findKey(&pico_client_list,&dummy);
-    //
-    if(client)
-        return client->uriKey;
-    else
-    {
-        // not found
-        dbg("Wrong connection id !\n");
-        pico_err = PICO_ERR_EINVAL;
-        return NULL;
-    }
-}
-
-/*
- * API for reading received data.
- *
- * Close the client.
- */
-int pico_http_client_close(uint16_t conn)
-{
-    struct pico_http_client * toBeRemoved = NULL;
-    struct pico_http_client dummy = {};
-    dummy.connectionID = conn;
-
-    dbg("Closing the client...\n");
-    toBeRemoved = pico_tree_delete(&pico_client_list,&dummy);
-    if(!toBeRemoved)
-    {
-        dbg("Warning ! Element not found ...");
-        return HTTP_RETURN_ERROR;
-    }
-
-    // close socket
-    if(toBeRemoved->sck)
-    pico_socket_close(toBeRemoved->sck);
-
-
-    if(toBeRemoved->header)
-    {
-        // free space used
-            if(toBeRemoved->header->location)
-                pico_free(toBeRemoved->header->location);
-
-        pico_free(toBeRemoved->header);
-    }
-
-    if(toBeRemoved->uriKey)
-    {
-        if(toBeRemoved->uriKey->host)
-            pico_free(toBeRemoved->uriKey->host);
-
-        if(toBeRemoved->uriKey->resource)
-            pico_free(toBeRemoved->uriKey->resource);
-        pico_free(toBeRemoved->uriKey);
-    }
-    pico_free(toBeRemoved);
-
-    return 0;
-}
-
-/*
- * API for reading received data.
- *
- * Builds a GET header based on the fields on the uri.
- */
-char * pico_http_client_buildHeader(const struct pico_http_uri * uriData)
-{
-    char * header;
-    char port[6u]; // 6 = max length of a uint16 + \0
-
-    uint16_t headerSize = HTTP_GET_BASIC_SIZE;
-
-    if(!uriData->host || !uriData->resource || !uriData->port)
-    {
-        pico_err = PICO_ERR_EINVAL;
-        return NULL;
-    }
-
-    //
-    headerSize += strlen(uriData->host) + strlen(uriData->resource) + pico_itoa(uriData->port,port) + 4u; // 3 = size(CRLF + \0)
-    header = pico_zalloc(headerSize);
-
-    if(!header)
-    {
-        // not enought memory
-        pico_err = PICO_ERR_ENOMEM;
-        return NULL;
-    }
-
-    // build the actual header
-    strcpy(header,"GET ");
-    strcat(header,uriData->resource);
-    strcat(header," HTTP/1.1\r\n");
-    strcat(header,"Host: ");
-    strcat(header,uriData->host);
-    strcat(header,":");
-    strcat(header,port);
-    strcat(header,"\r\n");
-    strcat(header,"User-Agent: picoTCP\r\nConnection: close\r\n\r\n"); //?
-
-    return header;
-}
-
-int parseHeaderFromServer(struct pico_http_client * client, struct pico_http_header * header)
-{
-    char line[HTTP_HEADER_LINE_SIZE];
-    char c;
-    int index = 0;
-
-    // read the first line of the header
-    while(consumeChar(c)>0 && c!='\r')
-    {
-        if(index < HTTP_HEADER_LINE_SIZE) // truncate if too long
-            line[index++] = c;
-    }
-
-    consumeChar(c); // consume \n
-
-    // check the integrity of the response
-    // make sure we have enough characters to include the response code
-    // make sure the server response starts with HTTP/1.
-    if(index < RESPONSE_INDEX+2 || isNotHTTPv1(line))
-    {
-        // wrong format of the the response
-        pico_err = PICO_ERR_EINVAL;
-        return HTTP_RETURN_ERROR;
-    }
-
-    // extract response code
-    header->responseCode = (line[RESPONSE_INDEX] - '0') * 100u +
-                                                 (line[RESPONSE_INDEX+1] - '0') * 10u +
-                                                 (line[RESPONSE_INDEX+2] - '0');
-
-
-    if(header->responseCode/100u > 5u)
-    {
-        // invalid response type
-        header->responseCode = 0;
-        return HTTP_RETURN_ERROR;
-    }
-
-    dbg("Server response : %d \n",header->responseCode);
-
-    // parse the rest of the header
-    while(consumeChar(c)>0)
-    {
-        if(c==':')
-        {
-            // check for interesting fields
-
-            // Location:
-            if(isLocation(line))
-            {
-                index = 0;
-                while(consumeChar(c)>0 && c!='\r')
-                {
-                    line[index++] = c;
-                }
-
-                // allocate space for the field
-                header->location = pico_zalloc(index+1u);
-                if(!header->location)
-                {
-                    pico_err = PICO_ERR_ENOMEM;
-                    return HTTP_RETURN_ERROR;
-                }
-
-                memcpy(header->location,line,index);
-
-            }// Content-Length:
-            else if(isContentLength(line))
-            {
-                header->contentLengthOrChunk = 0u;
-                header->transferCoding = HTTP_TRANSFER_FULL;
-                // consume the first space
-                consumeChar(c);
-                while(consumeChar(c)>0 && c!='\r')
-                {
-                    header->contentLengthOrChunk = header->contentLengthOrChunk*10u + (c-'0');
-                }
-
-            }// Transfer-Encoding: chunked
-            else if(isTransferEncoding(line))
-            {
-                index = 0;
-                while(consumeChar(c)>0 && c!='\r')
-                {
-                    line[index++] = c;
-                }
-
-                if(isChunked(line))
-                {
-                    header->contentLengthOrChunk = 0u;
-                    header->transferCoding = HTTP_TRANSFER_CHUNKED;
-                }
-
-            }// just ignore the line
-            else
-            {
-                while(consumeChar(c)>0 && c!='\r');
-            }
-
-            // consume the next one
-            consumeChar(c);
-            // reset the index
-            index = 0u;
-        }
-        else if(c=='\r' && !index)
-        {
-                // consume the \n
-                consumeChar(c);
-                break;
-        }
-        else
-        {
-            line[index++] = c;
-        }
-    }
-
-    if(header->transferCoding == HTTP_TRANSFER_CHUNKED)
-    {
-        // read the first chunk
-        header->contentLengthOrChunk = 0;
-
-        client->state = HTTP_READING_CHUNK_VALUE;
-        readChunkLine(client);
-
-    }
-    else
-        client->state = HTTP_READING_BODY;
-
-    dbg("End of header\n");
-    return HTTP_RETURN_OK;
-
-}
-
-// an async read of the chunk part, since in theory a chunk can be split in 2 packets
-int readChunkLine(struct pico_http_client * client)
-{
-    char c = 0;
-
-    if(client->header->contentLengthOrChunk==0 && client->state == HTTP_READING_BODY)
-    {
-        client->state = HTTP_READING_CHUNK_VALUE;
-    }
-
-    if(client->state == HTTP_READING_CHUNK_VALUE)
-    {
-        while(consumeChar(c)>0 && c!='\r' && c!=';')
-        {
-            if(is_hex_digit(c))
-                client->header->contentLengthOrChunk = (client->header->contentLengthOrChunk << 4u) + hex_digit_to_dec(c);
-            else
-            {
-                pico_err = PICO_ERR_EINVAL;
-                // something went wrong
-                return HTTP_RETURN_ERROR;
-            }
-        }
-
-        if(c=='\r' || c==';') client->state = HTTP_READING_CHUNK_TRAIL;
-    }
-
-    if(client->state == HTTP_READING_CHUNK_TRAIL)
-    {
-
-        while(consumeChar(c)>0 && c!='\n');
-
-        if(c=='\n') client->state = HTTP_READING_BODY;
-    }
-
-    return HTTP_RETURN_OK;
-}
-#endif
--- a/modules/pico_http_client.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-
-#ifndef PICO_HTTP_CLIENT_H_
-#define PICO_HTTP_CLIENT_H_
-
-#include "pico_http_util.h"
-
-/*
- * Transfer encodings
- */
-#define HTTP_TRANSFER_CHUNKED  1u
-#define HTTP_TRANSFER_FULL         0u
-
-/*
- * Parameters for the send header function
- */
-#define HTTP_HEADER_RAW                    0u
-#define HTTP_HEADER_DEFAULT            1u
-
-/*
- * Data types
- */
-
-struct pico_http_header
-{
-    uint16_t responseCode;                     // http response
-    char * location;                                     // if redirect is reported
-    uint32_t contentLengthOrChunk;    // size of the message
-    uint8_t transferCoding;                   // chunked or full
-
-};
-
-int pico_http_client_open(char * uri, void (*wakeup)(uint16_t ev, uint16_t conn));
-int pico_http_client_sendHeader(uint16_t conn, char * header, int hdr);
-
-struct pico_http_header * pico_http_client_readHeader(uint16_t conn);
-struct pico_http_uri * pico_http_client_readUriData(uint16_t conn);
-char * pico_http_client_buildHeader(const struct pico_http_uri * uriData);
-
-int pico_http_client_readData(uint16_t conn, char * data, uint16_t size);
-int pico_http_client_close(uint16_t conn);
-
-#endif /* PICO_HTTP_CLIENT_H_ */
--- a/modules/pico_http_server.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,636 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#include "pico_stack.h"
-#include "pico_http_server.h"
-#include "pico_tcp.h"
-#include "pico_tree.h"
-#include "pico_socket.h"
-
-#ifdef PICO_SUPPORT_HTTP_SERVER
-
-#define BACKLOG                              10
-
-#define HTTP_SERVER_CLOSED         0
-#define HTTP_SERVER_LISTEN         1
-
-#define HTTP_HEADER_MAX_LINE     256u
-
-#define consumeChar(c) (pico_socket_read(client->sck,&c,1u))
-
-static char returnOkHeader[] =
-"HTTP/1.1 200 OK\r\n\
-Host: localhost\r\n\
-Transfer-Encoding: chunked\r\n\
-Connection: close\r\n\
-\r\n";
-
-static char returnFailHeader[] =
-"HTTP/1.1 404 Not Found\r\n\
-Host: localhost\r\n\
-Connection: close\r\n\
-\r\n\
-<html><body>The resource you requested cannot be found !</body></html>";
-
-static char errorHeader[] =
-"HTTP/1.1 400 Bad Request\r\n\
-Host: localhost\r\n\
-Connection: close\r\n\
-\r\n\
-<html><body>There was a problem with your request !</body></html>";
-
-struct httpServer
-{
-    uint16_t state;
-    struct pico_socket * sck;
-    uint16_t port;
-    void (*wakeup)(uint16_t ev, uint16_t param);
-    uint8_t accepted;
-};
-
-struct httpClient
-{
-    uint16_t connectionID;
-    struct pico_socket * sck;
-    void * buffer;
-    uint16_t bufferSize;
-    uint16_t bufferSent;
-    char * resource;
-    uint16_t state;
-};
-
-/* Local states for clients */
-#define HTTP_WAIT_HDR                0
-#define HTTP_WAIT_EOF_HDR        1
-#define HTTP_EOF_HDR                2
-#define HTTP_WAIT_RESPONSE  3
-#define HTTP_WAIT_DATA            4
-#define HTTP_SENDING_DATA        5
-#define HTTP_ERROR                    6
-#define HTTP_CLOSED                    7
-
-static struct httpServer server = {};
-
-/*
- * Private functions
- */
-static int parseRequest(struct httpClient * client);
-static int readRemainingHeader(struct httpClient * client);
-static void sendData(struct httpClient * client);
-static inline int readData(struct httpClient * client); // used only in a place
-static inline struct httpClient * findClient(uint16_t conn);
-
-static int compareClients(void * ka, void * kb)
-{
-    return ((struct httpClient *)ka)->connectionID - ((struct httpClient *)kb)->connectionID;
-}
-
-PICO_TREE_DECLARE(pico_http_clients,compareClients);
-
-void httpServerCbk(uint16_t ev, struct pico_socket *s)
-{
-    struct pico_tree_node * index;
-    struct httpClient * client = NULL;
-  uint8_t serverEvent = FALSE;
-
-  // determine the client for the socket
-  if( s == server.sck)
-  {
-        serverEvent = TRUE;
-  }
-  else
-  {
-        pico_tree_foreach(index,&pico_http_clients)
-        {
-            client = index->keyValue;
-            if(client->sck == s) break;
-            client = NULL;
-        }
-  }
-
-    if(!client && !serverEvent)
-    {
-        return;
-    }
-
-    if (ev & PICO_SOCK_EV_RD)
-    {
-
-        if(readData(client) == HTTP_RETURN_ERROR)
-        {
-            // send out error
-            client->state = HTTP_ERROR;
-            pico_socket_write(client->sck,errorHeader,sizeof(errorHeader)-1);
-            server.wakeup(EV_HTTP_ERROR,client->connectionID);
-        }
-    }
-
-    if(ev & PICO_SOCK_EV_WR)
-    {
-        if(client->state == HTTP_SENDING_DATA)
-        {
-            sendData(client);
-        }
-    }
-
-    if(ev & PICO_SOCK_EV_CONN)
-    {
-        server.accepted = FALSE;
-        server.wakeup(EV_HTTP_CON,HTTP_SERVER_ID);
-        if(!server.accepted)
-        {
-            pico_socket_close(s); // reject socket
-        }
-    }
-
-    if( (ev & PICO_SOCK_EV_CLOSE) || (ev & PICO_SOCK_EV_FIN) )
-    {
-        server.wakeup(EV_HTTP_CLOSE,(serverEvent ? HTTP_SERVER_ID : client->connectionID));
-    }
-
-    if(ev & PICO_SOCK_EV_ERR)
-    {
-        server.wakeup(EV_HTTP_ERROR,(serverEvent ? HTTP_SERVER_ID : client->connectionID));
-    }
-}
-
-/*
- * API for starting the server. If 0 is passed as a port, the port 80
- * will be used.
- */
-int pico_http_server_start(uint16_t port, void (*wakeup)(uint16_t ev, uint16_t conn))
-{
-    struct pico_ip4 anything = {};
-
-    server.port = port ? short_be(port) : short_be(80u);
-
-    if(!wakeup)
-    {
-        pico_err = PICO_ERR_EINVAL;
-        return HTTP_RETURN_ERROR;
-    }
-
-    server.sck = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &httpServerCbk);
-
-    if(!server.sck)
-    {
-        pico_err = PICO_ERR_EFAULT;
-        return HTTP_RETURN_ERROR;
-    }
-
-    if(pico_socket_bind(server.sck , &anything, &server.port)!=0)
-    {
-        pico_err = PICO_ERR_EADDRNOTAVAIL;
-        return HTTP_RETURN_ERROR;
-    }
-
-    if (pico_socket_listen(server.sck, BACKLOG) != 0)
-    {
-        pico_err = PICO_ERR_EADDRINUSE;
-        return HTTP_RETURN_ERROR;
-    }
-    server.wakeup = wakeup;
-    server.state = HTTP_SERVER_LISTEN;
-    return HTTP_RETURN_OK;
-}
-
-/*
- * API for accepting new connections. This function should be
- * called when the event EV_HTTP_CON is triggered, if not called
- * when noticed the connection will be considered rejected and the
- * socket will be dropped.
- *
- * Returns the ID of the new connection or a negative value if error.
- */
-int pico_http_server_accept(void)
-{
-  struct pico_ip4 orig;
-  struct httpClient * client;
-  uint16_t port;
-
-  client = pico_zalloc(sizeof(struct httpClient));
-  if(!client)
-  {
-        pico_err = PICO_ERR_ENOMEM;
-      return HTTP_RETURN_ERROR;
-  }
-
-    client->sck = pico_socket_accept(server.sck,&orig,&port);
-
-    if(!client->sck)
-    {
-        pico_err = PICO_ERR_ENOMEM;
-        pico_free(client);
-        return HTTP_RETURN_ERROR;
-    }
-
-    server.accepted = TRUE;
-    // buffer used for async sending
-    client->state = HTTP_WAIT_HDR;
-    client->buffer = NULL;
-    client->bufferSize = 0;
-    client->connectionID = pico_rand() & 0x7FFF;
-
-    //add element to the tree, if duplicate because the rand
-    //regenerate
-    while(pico_tree_insert(&pico_http_clients,client)!=NULL)
-        client->connectionID = pico_rand() & 0x7FFF;
-
-    return client->connectionID;
-}
-
-/*
- * Function used for getting the resource asked by the
- * client. It is useful after the request header (EV_HTTP_REQ)
- * from client was received, otherwise NULL is returned.
- */
-char * pico_http_getResource(uint16_t conn)
-{
-    struct httpClient * client = findClient(conn);
-
-    if(!client)
-        return NULL;
-    else
-        return client->resource;
-}
-
-/*
- * After the resource was asked by the client (EV_HTTP_REQ)
- * before doing anything else, the server has to let know
- * the client if the resource can be provided or not.
- *
- * This is controlled via the code parameter which can
- * have two values :
- *
- * HTTP_RESOURCE_FOUND or HTTP_RESOURCE_NOT_FOUND
- *
- * If a resource is reported not found the 404 header will be sent and the connection
- * will be closed , otherwise the 200 header is sent and the user should
- * immediately submit data.
- *
- */
-int pico_http_respond(uint16_t conn, uint16_t code)
-{
-    struct httpClient * client = findClient(conn);
-
-    if(!client)
-    {
-        dbg("Client not found !\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    if(client->state == HTTP_WAIT_RESPONSE)
-    {
-        if(code == HTTP_RESOURCE_FOUND)
-        {
-            client->state = HTTP_WAIT_DATA;
-            return pico_socket_write(client->sck,returnOkHeader,sizeof(returnOkHeader)-1);//remove \0
-        }
-        else
-        {
-            int length;
-
-            length = pico_socket_write(client->sck,returnFailHeader,sizeof(returnFailHeader)-1);//remove \0
-            pico_socket_close(client->sck);
-            client->state = HTTP_CLOSED;
-            return length;
-
-        }
-    }
-    else
-    {
-        dbg("Bad state for the client \n");
-        return HTTP_RETURN_ERROR;
-    }
-
-}
-
-/*
- * API used to submit data to the client.
- * Server sends data only using Transfer-Encoding: chunked.
- *
- * With this function the user will submit a data chunk to
- * be sent.
- * The function will send the chunk size in hex and the rest will
- * be sent using WR event from sockets.
- * After each transmision EV_HTTP_PROGRESS is called and at the
- * end of the chunk EV_HTTP_SENT is called.
- *
- * To let the client know this is the last chunk, the user
- * should pass a NULL buffer.
- */
-int pico_http_submitData(uint16_t conn, void * buffer, int len)
-{
-
-    struct httpClient * client = findClient(conn);
-    char chunkStr[10];
-    int chunkCount;
-
-    if(client->state != HTTP_WAIT_DATA)
-    {
-        dbg("Client is in a different state than accepted\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    if(client->buffer)
-    {
-        dbg("Already a buffer submited\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    if(!client)
-    {
-        dbg("Wrong connection ID\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    if(!buffer)
-    {
-        len = 0;
-    }
-
-    if(len > 0)
-    {
-        client->buffer = pico_zalloc(len);
-        if(!client->buffer)
-        {
-            pico_err = PICO_ERR_ENOMEM;
-            return HTTP_RETURN_ERROR;
-        }
-        // taking over the buffer
-        memcpy(client->buffer,buffer,len);
-    }
-    else
-        client->buffer = NULL;
-
-
-    client->bufferSize = len;
-    client->bufferSent = 0;
-
-    // create the chunk size and send it
-    if(len > 0)
-    {
-        client->state = HTTP_SENDING_DATA;
-        chunkCount = pico_itoaHex(client->bufferSize,chunkStr);
-        chunkStr[chunkCount++] = '\r';
-        chunkStr[chunkCount++] = '\n';
-        pico_socket_write(client->sck,chunkStr,chunkCount);
-    }
-    else if(len == 0)
-    {
-        dbg("->\n");
-        // end of transmision
-        pico_socket_write(client->sck,"0\r\n\r\n",5u);
-        // nothing left, close the client
-        pico_socket_close(client->sck);
-        client->state = HTTP_CLOSED;
-    }
-
-    return HTTP_RETURN_OK;
-}
-
-/*
- * When EV_HTTP_PROGRESS is triggered you can use this
- * function to check the state of the chunk.
- */
-
-int pico_http_getProgress(uint16_t conn, uint16_t * sent, uint16_t *total)
-{
-    struct httpClient * client = findClient(conn);
-
-    if(!client)
-    {
-        dbg("Wrong connection id !\n");
-        return HTTP_RETURN_ERROR;
-    }
-
-    *sent = client->bufferSent;
-    *total = client->bufferSize;
-
-    return HTTP_RETURN_OK;
-}
-
-/*
- * This API can be used to close either a client
- * or the server ( if you pass HTTP_SERVER_ID as a connection ID).
- */
-int pico_http_close(uint16_t conn)
-{
-    // close the server
-    if(conn == HTTP_SERVER_ID)
-    {
-        if(server.state == HTTP_SERVER_LISTEN)
-        {
-            struct pico_tree_node * index, * tmp;
-            // close the server
-            pico_socket_close(server.sck);
-            server.sck = NULL;
-
-            // destroy the tree
-            pico_tree_foreach_safe(index,&pico_http_clients,tmp)
-            {
-                struct httpClient * client = index->keyValue;
-
-                if(client->resource)
-                    pico_free(client->resource);
-
-                pico_socket_close(client->sck);
-                pico_tree_delete(&pico_http_clients,client);
-            }
-
-            server.state = HTTP_SERVER_CLOSED;
-            return HTTP_RETURN_OK;
-        }
-        else // nothing to close
-            return HTTP_RETURN_ERROR;
-    } // close a connection in this case
-    else
-    {
-
-        struct httpClient * client = findClient(conn);
-
-        if(!client)
-        {
-            dbg("Client not found..\n");
-            return HTTP_RETURN_ERROR;
-        }
-
-        pico_tree_delete(&pico_http_clients,client);
-
-        if(client->resource)
-            pico_free(client->resource);
-
-        if(client->buffer)
-            pico_free(client->buffer);
-
-        if(client->state != HTTP_CLOSED || !client->sck)
-            pico_socket_close(client->sck);
-
-        pico_free(client);
-        return HTTP_RETURN_OK;
-    }
-}
-
-// check the integrity of the request
-int parseRequest(struct httpClient * client)
-{
-    char c;
-    //read first line
-    consumeChar(c);
-    if(c == 'G')
-    { // possible GET
-
-        char line[HTTP_HEADER_MAX_LINE];
-        int index = 0;
-
-        line[index] = c;
-
-        // consume the full line
-        while(consumeChar(c)>0) // read char by char only the first line
-        {
-            line[++index] = c;
-            if(c == '\n')
-                break;
-
-                if(index >= HTTP_HEADER_MAX_LINE)
-            {
-                dbg("Size exceeded \n");
-                return HTTP_RETURN_ERROR;
-            }
-        }
-
-        // extract the function and the resource
-        if(memcmp(line,"GET",3u) || line[3u]!=' ' || index < 10u || line[index] !='\n')
-        {
-            dbg("Wrong command or wrong ending\n");
-            return HTTP_RETURN_ERROR;
-        }
-
-        // start reading the resource
-        index = 4u; // go after ' '
-        while(line[index]!=' ')
-        {
-            if(line[index]=='\n') // no terminator ' '
-            {
-                dbg("No terminator...\n");
-                return HTTP_RETURN_ERROR;
-            }
-
-            index++;
-        }
-
-        client->resource = pico_zalloc(index - 3u);// allocate without the GET in front + 1 which is \0
-
-        if(!client)
-        {
-            pico_err = PICO_ERR_ENOMEM;
-            return HTTP_RETURN_ERROR;
-        }
-
-        // copy the resource
-        memcpy(client->resource,line+4u,index-4u);// copy without the \0 which was already set by pico_zalloc
-
-        client->state = HTTP_WAIT_EOF_HDR;
-        return HTTP_RETURN_OK;
-
-    }
-
-    return HTTP_RETURN_ERROR;
-}
-
-
-
-int readRemainingHeader(struct httpClient * client)
-{
-    char line[100];
-    int count = 0;
-    int len;
-
-    while( (len = pico_socket_read(client->sck,line,100u)) > 0)
-    {
-        char c;
-        int index = 0;
-        // parse the response
-        while(index < len)
-        {
-            c = line[index++];
-            if(c!='\r' && c!='\n')
-                count++;
-            if(c=='\n')
-            {
-                if(!count)
-                {
-                    client->state = HTTP_EOF_HDR;
-                    dbg("End of header !\n");
-                    break;
-                }
-                count = 0;
-
-            }
-        }
-    }
-
-    return HTTP_RETURN_OK;
-}
-
-void sendData(struct httpClient * client)
-{
-    int length;
-    while( client->bufferSent < client->bufferSize &&
-    (length = pico_socket_write(client->sck,client->buffer+client->bufferSent,client->bufferSize-client->bufferSent)) > 0 )
-    {
-        client->bufferSent += length;
-        server.wakeup(EV_HTTP_PROGRESS,client->connectionID);
-    }
-
-    if(client->bufferSent == client->bufferSize && client->bufferSize)
-    {
-        //send chunk trail
-        if(pico_socket_write(client->sck,"\r\n",2) > 0)
-        {
-            client->state = HTTP_WAIT_DATA;
-            //free the buffer
-            pico_free(client->buffer);
-            client->buffer = NULL;
-            server.wakeup(EV_HTTP_SENT,client->connectionID);
-        }
-    }
-
-}
-
-int readData(struct httpClient * client)
-{
-    if(client->state == HTTP_WAIT_HDR)
-    {
-        if(parseRequest(client)<0 || readRemainingHeader(client)<0)
-        {
-            return HTTP_RETURN_ERROR;
-        }
-    } // continue with this in case the header comes line by line not a big chunk
-    else if(client->state == HTTP_WAIT_EOF_HDR)
-    {
-        if(readRemainingHeader(client)<0 )
-            return HTTP_RETURN_ERROR;
-    }
-
-    if(client->state == HTTP_EOF_HDR)
-    {
-        client->state = HTTP_WAIT_RESPONSE;
-        pico_socket_shutdown(client->sck,PICO_SHUT_RD);
-        server.wakeup(EV_HTTP_REQ,client->connectionID);
-    }
-
-    return HTTP_RETURN_OK;
-}
-
-struct httpClient * findClient(uint16_t conn)
-{
-    struct httpClient dummy = {.connectionID = conn};
-
-    return pico_tree_findKey(&pico_http_clients,&dummy);
-}
-#endif
--- a/modules/pico_http_server.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#ifndef PICO_HTTP_SERVER_H_
-#define PICO_HTTP_SERVER_H_
-
-#include <stdint.h>
-#include "pico_http_util.h"
-
-// Response codes
-#define HTTP_RESOURCE_FOUND                0
-#define HTTP_RESOURCE_NOT_FOUND        1
-
-// Generic id for the server
-#define HTTP_SERVER_ID                    0
-
-/*
- * Server functions
- */
-int pico_http_server_start(uint16_t port, void (*wakeup)(uint16_t ev, uint16_t conn));
-int pico_http_server_accept(void);
-
-/*
- * Client functions
- */
-char * pico_http_getResource(uint16_t conn);
-int      pico_http_getProgress(uint16_t conn, uint16_t * sent, uint16_t *total);
-
-/*
- * Handshake and data functions
- */
-int      pico_http_respond(uint16_t conn, uint16_t code);
-int      pico_http_submitData(uint16_t conn, void * buffer, int len);
-int      pico_http_close(uint16_t conn);
-
-#endif /* PICO_HTTP_SERVER_H_ */
--- a/modules/pico_http_util.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#include <stdint.h>
-#include "pico_config.h"
-#include "pico_stack.h"
-#include "pico_protocol.h"
-#include "pico_http_util.h"
-
-#define TRUE    1
-#define FALSE 0
-
-#define HTTP_PROTO_TOK        "http://"
-#define HTTP_PROTO_LEN        7u
-
-#if defined PICO_SUPPORT_HTTP_CLIENT || defined PICO_SUPPORT_HTTP_SERVER
-
-int pico_itoaHex(uint16_t port, char * ptr)
-{
-    int size = 0;
-    int index;
-
-    // transform to from number to string [ in backwards ]
-    while(port)
-    {
-        ptr[size] = ((port & 0xF) < 10) ? ((port & 0xF) + '0') : ((port & 0xF) - 10 + 'a');
-        port = port>>4u; //divide by 16
-        size++;
-    }
-
-    // invert positions
-    for(index=0 ;index < size>>1u ;index++)
-    {
-        char c = ptr[index];
-        ptr[index] = ptr[size-index-1];
-        ptr[size-index-1] = c;
-    }
-    ptr[size] = '\0';
-    return size;
-}
-
-int pico_itoa(uint16_t port, char * ptr)
-{
-    int size = 0;
-    int index;
-
-    // transform to from number to string [ in backwards ]
-    while(port)
-    {
-        ptr[size] = port%10 + '0';
-        port = port/10;
-        size++;
-    }
-
-    // invert positions
-    for(index=0 ;index < size>>1u ;index++)
-    {
-        char c = ptr[index];
-        ptr[index] = ptr[size-index-1];
-        ptr[size-index-1] = c;
-    }
-    ptr[size] = '\0';
-    return size;
-}
-
-
-int pico_processURI(const char * uri, struct pico_http_uri * urikey)
-{
-
-    uint16_t lastIndex = 0, index;
-
-    if(!uri || !urikey || uri[0] == '/')
-    {
-        pico_err = PICO_ERR_EINVAL;
-        goto error;
-    }
-
-    // detect protocol => search for  "://"
-    if(memcmp(uri,HTTP_PROTO_TOK,HTTP_PROTO_LEN) == 0) // could be optimized
-    { // protocol identified, it is http
-        urikey->protoHttp = TRUE;
-        lastIndex = HTTP_PROTO_LEN;
-    }
-    else
-    {
-        if(strstr(uri,"://")) // different protocol specified
-        {
-            urikey->protoHttp = FALSE;
-            goto error;
-        }
-        // no protocol specified, assuming by default it's http
-        urikey->protoHttp = TRUE;
-    }
-
-    // detect hostname
-    index = lastIndex;
-    while(uri[index] && uri[index]!='/' && uri[index]!=':') index++;
-
-    if(index == lastIndex)
-    {
-        // wrong format
-        urikey->host = urikey->resource = NULL;
-        urikey->port = urikey->protoHttp = 0u;
-
-        goto error;
-    }
-    else
-    {
-        // extract host
-        urikey->host = (char *)pico_zalloc(index-lastIndex+1);
-
-        if(!urikey->host)
-        {
-            // no memory
-            goto error;
-        }
-        memcpy(urikey->host,uri+lastIndex,index-lastIndex);
-    }
-
-    if(!uri[index])
-    {
-        // nothing specified
-        urikey->port = 80u;
-        urikey->resource = pico_zalloc(2u);
-        urikey->resource[0] = '/';
-        return HTTP_RETURN_OK;
-    }
-    else if(uri[index] == '/')
-    {
-        urikey->port = 80u;
-    }
-    else if(uri[index] == ':')
-    {
-        urikey->port = 0u;
-        index++;
-        while(uri[index] && uri[index]!='/')
-        {
-            // should check if every component is a digit
-            urikey->port = urikey->port*10 + (uri[index] - '0');
-            index++;
-        }
-    }
-
-  // extract resource
-    if(!uri[index])
-    {
-        urikey->resource = pico_zalloc(2u);
-        urikey->resource[0] = '/';
-    }
-    else
-    {
-        lastIndex = index;
-        while(uri[index] && uri[index]!='?' && uri[index]!='&' && uri[index]!='#') index++;
-        urikey->resource = (char *)pico_zalloc(index-lastIndex+1);
-
-        if(!urikey->resource)
-        {
-            // no memory
-            pico_err = PICO_ERR_ENOMEM;
-            goto error;
-        }
-
-        memcpy(urikey->resource,uri+lastIndex,index-lastIndex);
-    }
-
-    return HTTP_RETURN_OK;
-
-    error :
-    if(urikey->resource)
-    {
-        pico_free(urikey->resource);
-        urikey->resource = NULL;
-    }
-    if(urikey->host)
-    {
-        pico_free(urikey->host);
-        urikey->host = NULL;
-    }
-
-    return HTTP_RETURN_ERROR;
-}
-#endif
--- a/modules/pico_http_util.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#ifndef PICO_HTTP_UTIL_H_
-#define PICO_HTTP_UTIL_H_
-
-/* Informational reponses */
-#define HTTP_CONTINUE                         100u
-#define HTTP_SWITCHING_PROTOCOLS  101u
-#define HTTP_PROCESSING                      102u
-
-/* Success */
-#define HTTP_OK                                        200u
-#define HTTP_CREATED                            201u
-#define HTTP_ACCEPTED                            202u
-#define HTTP_NON_AUTH_INFO                203u
-#define HTTP_NO_CONTENT                        204u
-#define HTTP_RESET_CONTENT                205u
-#define HTTP_PARTIAL_CONTENT            206u
-#define HTTP_MULTI_STATUS                    207u
-#define HTTP_ALREADY_REPORTED            208u
-#define HTTP_LOW_SPACE                        250u
-#define HTTP_IM_SPACE                            226u
-
-/* Redirection */
-#define HTTP_MULTI_CHOICE                    300u
-#define HTTP_MOVED_PERMANENT            301u
-#define HTTP_FOUND                                302u
-#define HTTP_SEE_OTHER                        303u
-#define HTTP_NOT_MODIFIED                    304u
-#define HTTP_USE_PROXY                        305u
-#define HTTP_SWITCH_PROXY                    306u
-#define HTTP_TEMP_REDIRECT                307u
-#define HTTP_PERM_REDIRECT                308u
-
-/* Client error */
-#define HTTP_BAD_REQUEST                    400u
-#define HTTP_UNAUTH                                401u
-#define HTTP_PAYMENT_REQ                    402u
-#define HTTP_FORBIDDEN                        403u
-#define HTTP_NOT_FOUND                        404u
-#define HTTP_METH_NOT_ALLOWED            405u
-#define HTTP_NOT_ACCEPTABLE                406u
-#define HTTP_PROXY_AUTH_REQ                407u
-#define HTTP_REQ_TIMEOUT                    408u
-#define HTTP_CONFLICT                            409u
-#define HTTP_GONE                                    410u
-#define HTTP_LEN_REQ                            411u
-#define HTTP_PRECONDITION_FAIL        412u
-#define HTTP_REQ_ENT_LARGE                413u
-#define HTTP_URI_TOO_LONG                    414u
-#define HTTP_UNSUPORTED_MEDIA            415u
-#define HTTP_REQ_RANGE_NOK                416u
-#define HTTP_EXPECT_FAILED                417u
-#define HTTP_TEAPOT                                418u
-#define HTTP_UNPROC_ENTITY                422u
-#define HTTP_LOCKED                                423u
-#define HTTP_METHOD_FAIL                    424u
-#define HTTP_UNORDERED                        425u
-#define HTTP_UPGRADE_REQ                    426u
-#define HTTP_PRECOND_REQ                    428u
-#define HTTP_TOO_MANY_REQ                    429u
-#define HTTP_HEDER_FIELD_LARGE        431u
-
-/* Server error */
-#define HTTP_INTERNAL_SERVER_ERR    500u
-#define HTTP_NOT_IMPLEMENTED            501u
-#define HTTP_BAD_GATEWAY                    502u
-#define HTTP_SERVICE_UNAVAILABLE    503u
-#define HTTP_GATEWAY_TIMEOUT            504u
-#define HTTP_NOT_SUPPORTED                505u
-#define HTTP_SERV_LOW_STORAGE            507u
-#define HTTP_LOOP_DETECTED                508u
-#define HTTP_NOT_EXTENDED                    510u
-#define HTTP_NETWORK_AUTH                    511u
-#define HTTP_PERMISSION_DENIED        550u
-
-/* Returns used  */
-#define HTTP_RETURN_ERROR    -1
-#define HTTP_RETURN_OK                0
-
-/* List of events - shared between client and server */
-#define EV_HTTP_CON            1u
-#define EV_HTTP_REQ       2u
-#define EV_HTTP_PROGRESS  4u
-#define EV_HTTP_SENT          8u
-#define EV_HTTP_CLOSE     16u
-#define EV_HTTP_ERROR     32u
-#define EV_HTTP_BODY            64u
-#define EV_HTTP_DNS                128u
-
-#ifndef TRUE
-    #define TRUE    1
-#endif
-
-#ifndef FALSE
-    #define FALSE 0
-#endif
-
-struct pico_http_uri
-{
-    uint8_t protoHttp; // is the protocol Http ?
-    char * host;             // hostname
-    uint16_t port;         // port if specified
-    char * resource;     // resource , ignoring the other possible parameters
-};
-
-// used for chunks
-int pico_itoaHex(uint16_t port, char * ptr);
-int pico_itoa(uint16_t port, char * ptr);
-int pico_processURI(const char * uri, struct pico_http_uri * urikey);
-
-#endif /* PICO_HTTP_UTIL_H_ */
--- a/modules/pico_icmp4.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_icmp4.h"
-#include "pico_config.h"
-#include "pico_ipv4.h"
-#include "pico_eth.h"
-#include "pico_device.h"
-#include "pico_stack.h"
-#include "pico_tree.h"
-
-/* Queues */
-static struct pico_queue icmp_in = {};
-static struct pico_queue icmp_out = {};
-
-
-/* Functions */
-
-static int pico_icmp4_checksum(struct pico_frame *f)
-{
-  struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
-  if (!hdr) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_checksum(hdr, f->transport_len));
-  return 0;
-}
-
-#ifdef PICO_SUPPORT_PING
-static void ping_recv_reply(struct pico_frame *f);
-#endif
-
-static int pico_icmp4_process_in(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
-  if (hdr->type == PICO_ICMP_ECHO) {
-    hdr->type = PICO_ICMP_ECHOREPLY;
-    /* Ugly, but the best way to get ICMP data size here. */
-    f->transport_len = f->buffer_len - PICO_SIZE_IP4HDR;
-    if (f->dev->eth)
-      f->transport_len -= PICO_SIZE_ETHHDR;
-    pico_icmp4_checksum(f);
-    f->net_hdr = f->transport_hdr - PICO_SIZE_IP4HDR;
-    f->start = f->net_hdr;
-    f->len = f->buffer_len;
-    if (f->dev->eth)
-      f->len -= PICO_SIZE_ETHHDR;
-    pico_ipv4_rebound(f);
-  } else if (hdr->type == PICO_ICMP_UNREACH) {
-    f->net_hdr = f->transport_hdr + PICO_ICMPHDR_UN_SIZE;
-    pico_ipv4_unreachable(f, hdr->code);
-  } else if (hdr->type == PICO_ICMP_ECHOREPLY) {
-#ifdef PICO_SUPPORT_PING
-    ping_recv_reply(f);
-#endif
-    pico_frame_discard(f);
-  } else {
-    pico_frame_discard(f);
-  }
-  return 0;
-}
-
-static int pico_icmp4_process_out(struct pico_protocol *self, struct pico_frame *f)
-{
-  dbg("Called %s\n", __FUNCTION__);
-  return 0;
-}
-
-/* Interface: protocol definition */
-struct pico_protocol pico_proto_icmp4 = {
-  .name = "icmp4",
-  .proto_number = PICO_PROTO_ICMP4,
-  .layer = PICO_LAYER_TRANSPORT,
-  .process_in = pico_icmp4_process_in,
-  .process_out = pico_icmp4_process_out,
-  .q_in = &icmp_in,
-  .q_out = &icmp_out,
-};
-
-static int pico_icmp4_notify(struct pico_frame *f, uint8_t type, uint8_t code)
-{
-  struct pico_frame *reply;
-  struct pico_icmp4_hdr *hdr;
-  struct pico_ipv4_hdr *info;
-  if (f == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  reply = pico_proto_ipv4.alloc(&pico_proto_ipv4, 8 + sizeof(struct pico_ipv4_hdr) + PICO_ICMPHDR_UN_SIZE);
-  info = (struct pico_ipv4_hdr*)(f->net_hdr);
-  hdr = (struct pico_icmp4_hdr *) reply->transport_hdr;
-  hdr->type = type;
-  hdr->code = code;
-  hdr->hun.ih_pmtu.ipm_nmtu = short_be(1500);
-  hdr->hun.ih_pmtu.ipm_void = 0;
-  reply->transport_len = 8 + sizeof(struct pico_ipv4_hdr) +  PICO_ICMPHDR_UN_SIZE;
-  reply->payload = reply->transport_hdr + PICO_ICMPHDR_UN_SIZE;
-  memcpy(reply->payload, f->net_hdr, 8 + sizeof(struct pico_ipv4_hdr));
-  pico_icmp4_checksum(reply);
-  pico_ipv4_frame_push(reply, &info->src, PICO_PROTO_ICMP4);
-  return 0;
-}
-
-int pico_icmp4_port_unreachable(struct pico_frame *f)
-{
-  /*Parameter check executed in pico_icmp4_notify*/
-  return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_PORT);
-}
-
-int pico_icmp4_proto_unreachable(struct pico_frame *f)
-{
-  /*Parameter check executed in pico_icmp4_notify*/
-  return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_PROTOCOL);
-}
-
-int pico_icmp4_dest_unreachable(struct pico_frame *f)
-{
-  /*Parameter check executed in pico_icmp4_notify*/
-  return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_HOST);
-}
-
-int pico_icmp4_ttl_expired(struct pico_frame *f)
-{
-  /*Parameter check executed in pico_icmp4_notify*/
-  return pico_icmp4_notify(f, PICO_ICMP_TIME_EXCEEDED, PICO_ICMP_TIMXCEED_INTRANS);
-}
-
-
-int pico_icmp4_packet_filtered(struct pico_frame *f)
-{
-  /*Parameter check executed in pico_icmp4_notify*/
-  /*Packet Filtered: type 3, code 13 (Communication Administratively Prohibited)*/
-  return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_FILTER_PROHIB);
-}
-
-
-/***********************/
-/* Ping implementation */
-/***********************/
-/***********************/
-/***********************/
-/***********************/
-
-
-#ifdef PICO_SUPPORT_PING
-
-
-struct pico_icmp4_ping_cookie
-{
-  struct pico_ip4 dst;
-  uint16_t err;
-  uint16_t id;
-  uint16_t seq;
-  uint16_t size;
-  int count;
-  unsigned long timestamp;
-  int interval;
-  int timeout;
-  void (*cb)(struct pico_icmp4_stats*);
-
-};
-
-static int cookie_compare(void *ka, void *kb)
-{
-    struct pico_icmp4_ping_cookie *a = ka, *b = kb;
-  if (a->id < b->id)
-    return -1;
-  if (a->id > b->id)
-    return 1;
-  return (a->seq - b->seq);
-}
-
-PICO_TREE_DECLARE(Pings,cookie_compare);
-
-static int pico_icmp4_send_echo(struct pico_icmp4_ping_cookie *cookie)
-{
-  struct pico_frame *echo = pico_proto_ipv4.alloc(&pico_proto_ipv4, PICO_ICMPHDR_UN_SIZE + cookie->size);
-  struct pico_icmp4_hdr *hdr;
-
-  hdr = (struct pico_icmp4_hdr *) echo->transport_hdr;
-
-  hdr->type = PICO_ICMP_ECHO;
-  hdr->code = 0;
-  hdr->hun.ih_idseq.idseq_id = short_be(cookie->id);
-  hdr->hun.ih_idseq.idseq_seq = short_be(cookie->seq);
-  echo->transport_len = PICO_ICMPHDR_UN_SIZE + cookie->size;
-  echo->payload = echo->transport_hdr + PICO_ICMPHDR_UN_SIZE;
-  echo->payload_len = cookie->size;
-  /* XXX: Fill payload */
-  pico_icmp4_checksum(echo);
-  pico_ipv4_frame_push(echo, &cookie->dst, PICO_PROTO_ICMP4);
-  return 0;
-}
-
-
-static void ping_timeout(unsigned long now, void *arg)
-{
-  struct pico_icmp4_ping_cookie *cookie = (struct pico_icmp4_ping_cookie *)arg;
-  if(pico_tree_findKey(&Pings,cookie)){
-    if (cookie->err == PICO_PING_ERR_PENDING) {
-      struct pico_icmp4_stats stats;
-      stats.dst = cookie->dst;
-      stats.seq = cookie->seq;
-      stats.time = 0;
-      stats.size = cookie->size;
-      stats.err = PICO_PING_ERR_TIMEOUT;
-      dbg(" ---- Ping timeout!!!\n");
-      cookie->cb(&stats);
-    }
-
-    pico_tree_delete(&Pings,cookie);
-    pico_free(cookie);
-  }
-}
-
-static void next_ping(unsigned long now, void *arg);
-static inline void send_ping(struct pico_icmp4_ping_cookie *cookie)
-{
-  pico_icmp4_send_echo(cookie);
-  cookie->timestamp = pico_tick;
-  pico_timer_add(cookie->timeout, ping_timeout, cookie);
-  if (cookie->seq < cookie->count)
-    pico_timer_add(cookie->interval, next_ping, cookie);
-}
-
-static void next_ping(unsigned long now, void *arg)
-{
-  struct pico_icmp4_ping_cookie *newcookie, *cookie = (struct pico_icmp4_ping_cookie *)arg;
-
-    if(pico_tree_findKey(&Pings,cookie)){
-    if (cookie->seq < cookie->count) {
-      newcookie = pico_zalloc(sizeof(struct pico_icmp4_ping_cookie));
-      if (!newcookie)
-        return;
-      memcpy(newcookie, cookie, sizeof(struct pico_icmp4_ping_cookie));
-      newcookie->seq++;
-
-        pico_tree_insert(&Pings,newcookie);
-      send_ping(newcookie);
-    }
-  }
-}
-
-
-static void ping_recv_reply(struct pico_frame *f)
-{
-  struct pico_icmp4_ping_cookie test, *cookie;
-  struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
-  test.id  = short_be(hdr->hun.ih_idseq.idseq_id );
-  test.seq = short_be(hdr->hun.ih_idseq.idseq_seq);
-
-  cookie = pico_tree_findKey(&Pings, &test);
-  if (cookie) {
-    struct pico_icmp4_stats stats;
-    cookie->err = PICO_PING_ERR_REPLIED;
-    stats.dst = cookie->dst;
-    stats.seq = cookie->seq;
-    stats.size = cookie->size;
-    stats.time = pico_tick - cookie->timestamp;
-    stats.err = cookie->err;
-    stats.ttl = ((struct pico_ipv4_hdr *)f->net_hdr)->ttl;
-        if(cookie->cb != NULL)
-        cookie->cb(&stats);
-  } else {
-    dbg("Reply for seq=%d, not found.\n", test.seq);
-  }
-}
-
-int pico_icmp4_ping(char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp4_stats *))
-{
-  static uint16_t next_id = 0x91c0;
-  struct pico_icmp4_ping_cookie *cookie;
-
-  if((dst == NULL) || (interval == 0) || (timeout == 0) || (count == 0)){
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  cookie = pico_zalloc(sizeof(struct pico_icmp4_ping_cookie));
-  if (!cookie) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-
-  if (pico_string_to_ipv4(dst, &cookie->dst.addr) < 0) {
-    pico_err = PICO_ERR_EINVAL;
-    pico_free(cookie);
-    return -1;
-  }
-  cookie->seq = 1;
-  cookie->id = next_id++;
-  cookie->err = PICO_PING_ERR_PENDING;
-  cookie->size = size;
-  cookie->interval = interval;
-  cookie->timeout = timeout;
-  cookie->cb = cb;
-  cookie->count = count;
-
-  pico_tree_insert(&Pings,cookie);
-  send_ping(cookie);
-
-  return 0;
-
-}
-
-#endif
--- a/modules/pico_icmp4.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_ICMP4
-#define _INCLUDE_PICO_ICMP4
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-
-extern struct pico_protocol pico_proto_icmp4;
-
-struct __attribute__((packed)) pico_icmp4_hdr {
-  uint8_t type;
-  uint8_t code;
-  uint16_t crc;
-
-  /* hun */
-  union {
-    uint8_t ih_pptr;
-    struct pico_ip4 ih_gwaddr;
-    struct {
-      uint16_t idseq_id;
-      uint16_t idseq_seq;
-    } ih_idseq;
-    uint32_t ih_void;
-    struct {
-      uint16_t ipm_void;
-      uint16_t ipm_nmtu;
-    } ih_pmtu;
-    struct {
-      uint8_t rta_numgw;
-      uint8_t rta_wpa;
-      uint16_t rta_lifetime;
-    } ih_rta;
-  } hun;
-
-  /* dun */
-  union {
-    struct {
-      uint32_t ts_otime;
-      uint32_t ts_rtime;
-      uint32_t ts_ttime;
-    } id_ts;
-    struct {
-      uint32_t ip_options;
-      uint32_t ip_data_hi;
-      uint32_t ip_data_lo;
-    } id_ip;
-    struct {
-      uint32_t ira_addr;
-      uint32_t ira_pref;
-    } id_ra;
-    uint32_t id_mask;
-    uint8_t  id_data[1];
-  } dun;
-};
-
-#define PICO_ICMPHDR_DRY_SIZE  4
-#define PICO_ICMPHDR_UN_SIZE  8
-
-#define PICO_ICMP_ECHOREPLY    0 
-#define PICO_ICMP_DEST_UNREACH 3 
-#define PICO_ICMP_SOURCE_QUENCH  4
-#define PICO_ICMP_REDIRECT   5
-#define PICO_ICMP_ECHO   8
-#define PICO_ICMP_TIME_EXCEEDED  11
-#define PICO_ICMP_PARAMETERPROB  12
-#define PICO_ICMP_TIMESTAMP    13
-#define PICO_ICMP_TIMESTAMPREPLY 14
-#define PICO_ICMP_INFO_REQUEST 15
-#define PICO_ICMP_INFO_REPLY   16
-#define PICO_ICMP_ADDRESS    17
-#define PICO_ICMP_ADDRESSREPLY 18
-
-
-#define  PICO_ICMP_UNREACH    3  
-#define  PICO_ICMP_SOURCEQUENCH  4  
-#define  PICO_ICMP_ROUTERADVERT  9  
-#define  PICO_ICMP_ROUTERSOLICIT  10  
-#define  PICO_ICMP_TIMXCEED    11  
-#define  PICO_ICMP_PARAMPROB    12  
-#define  PICO_ICMP_TSTAMP    13  
-#define  PICO_ICMP_TSTAMPREPLY  14  
-#define  PICO_ICMP_IREQ    15  
-#define  PICO_ICMP_IREQREPLY    16    
-#define  PICO_ICMP_MASKREQ    17    
-#define  PICO_ICMP_MASKREPLY    18    
-
-#define  PICO_ICMP_MAXTYPE    18
-
-
-#define  PICO_ICMP_UNREACH_NET          0  
-#define  PICO_ICMP_UNREACH_HOST          1  
-#define  PICO_ICMP_UNREACH_PROTOCOL          2  
-#define  PICO_ICMP_UNREACH_PORT          3  
-#define  PICO_ICMP_UNREACH_NEEDFRAG          4  
-#define  PICO_ICMP_UNREACH_SRCFAIL          5  
-#define  PICO_ICMP_UNREACH_NET_UNKNOWN        6  
-#define  PICO_ICMP_UNREACH_HOST_UNKNOWN       7  
-#define  PICO_ICMP_UNREACH_ISOLATED          8  
-#define  PICO_ICMP_UNREACH_NET_PROHIB          9  
-#define  PICO_ICMP_UNREACH_HOST_PROHIB        10  
-#define  PICO_ICMP_UNREACH_TOSNET          11  
-#define  PICO_ICMP_UNREACH_TOSHOST          12  
-#define  PICO_ICMP_UNREACH_FILTER_PROHIB      13  
-#define  PICO_ICMP_UNREACH_HOST_PRECEDENCE    14  
-#define  PICO_ICMP_UNREACH_PRECEDENCE_CUTOFF  15  
-
-
-#define  PICO_ICMP_REDIRECT_NET  0    
-#define  PICO_ICMP_REDIRECT_HOST  1    
-#define  PICO_ICMP_REDIRECT_TOSNET  2    
-#define  PICO_ICMP_REDIRECT_TOSHOST  3    
-
-
-#define  PICO_ICMP_TIMXCEED_INTRANS  0    
-#define  PICO_ICMP_TIMXCEED_REASS  1    
-
-
-#define  PICO_ICMP_PARAMPROB_OPTABSENT 1    
-
-#define PICO_SIZE_ICMP4HDR ((sizeof(struct pico_icmp4_hdr)))
-
-struct pico_icmp4_stats
-{
-  struct pico_ip4 dst;
-  unsigned long size;
-  unsigned long seq;
-  unsigned long time;
-  unsigned long ttl;
-  int err;
-};
-
-int pico_icmp4_port_unreachable(struct pico_frame *f);
-int pico_icmp4_proto_unreachable(struct pico_frame *f);
-int pico_icmp4_dest_unreachable(struct pico_frame *f);
-int pico_icmp4_ttl_expired(struct pico_frame *f);
-int pico_icmp4_packet_filtered(struct pico_frame *f);
-
-int pico_icmp4_ping(char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp4_stats *));
-#define PICO_PING_ERR_REPLIED 0
-#define PICO_PING_ERR_TIMEOUT 1
-#define PICO_PING_ERR_UNREACH 2
-#define PICO_PING_ERR_PENDING 0xFFFF
-
-#endif
--- a/modules/pico_igmp.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1120 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-RFC 1112, 2236, 3376, 3569, 3678, 4607
-
-Authors: Kristof Roelants (IGMPv3), Simon Maes, Brecht Van Cauwenberghe 
-*********************************************************************/
-
-#include "pico_stack.h"
-#include "pico_ipv4.h"
-#include "pico_igmp.h"
-#include "pico_config.h"
-#include "pico_eth.h"
-#include "pico_addressing.h"
-#include "pico_frame.h"
-#include "pico_tree.h"
-#include "pico_device.h"
-#include "pico_socket.h"
-
-#define igmp_dbg(...) do{}while(0)
-//#define igmp_dbg dbg
-
-/* membership states */
-#define IGMP_STATE_NON_MEMBER             (0x0)
-#define IGMP_STATE_DELAYING_MEMBER        (0x1)
-#define IGMP_STATE_IDLE_MEMBER            (0x2)
-
-/* events */ 
-#define IGMP_EVENT_DELETE_GROUP           (0x0)
-#define IGMP_EVENT_CREATE_GROUP           (0x1)
-#define IGMP_EVENT_UPDATE_GROUP           (0x2)
-#define IGMP_EVENT_QUERY_RECV             (0x3)
-#define IGMP_EVENT_REPORT_RECV            (0x4)
-#define IGMP_EVENT_TIMER_EXPIRED          (0x5)
-
-/* message types */
-#define IGMP_TYPE_MEM_QUERY               (0x11)
-#define IGMP_TYPE_MEM_REPORT_V1           (0x12)
-#define IGMP_TYPE_MEM_REPORT_V2           (0x16)
-#define IGMP_TYPE_LEAVE_GROUP             (0x17)
-#define IGMP_TYPE_MEM_REPORT_V3           (0x22)
-
-/* group record types */
-#define IGMP_MODE_IS_INCLUDE              (1)
-#define IGMP_MODE_IS_EXCLUDE              (2)
-#define IGMP_CHANGE_TO_INCLUDE_MODE       (3)
-#define IGMP_CHANGE_TO_EXCLUDE_MODE       (4)
-#define IGMP_ALLOW_NEW_SOURCES            (5)
-#define IGMP_BLOCK_OLD_SOURCES            (6)
-
-/* host flag */
-#define IGMP_HOST_LAST                    (0x1)
-#define IGMP_HOST_NOT_LAST                (0x0)
-
-/* list of timers, counters and their default values */
-#define IGMP_ROBUSTNESS                   (2)
-#define IGMP_QUERY_INTERVAL               (125) /* secs */
-#define IGMP_QUERY_RESPONSE_INTERVAL      (10) /* secs */
-#define IGMP_STARTUP_QUERY_INTERVAL       (IGMPV3_QUERY_INTERVAL / 4)
-#define IGMP_STARTUP_QUERY_COUNT          (IGMPV3_ROBUSTNESS)
-#define IGMP_LAST_MEMBER_QUERY_INTERVAL   (1) /* secs */
-#define IGMP_LAST_MEMBER_QUERY_COUNT      (IGMPV3_ROBUSTNESS)
-#define IGMP_UNSOLICITED_REPORT_INTERVAL  (1) /* secs */
-#define IGMP_DEFAULT_MAX_RESPONSE_TIME    (100)
-
-/* custom timers types */
-#define IGMP_TIMER_GROUP_REPORT           (1)
-#define IGMP_TIMER_V1_QUERIER             (2)
-#define IGMP_TIMER_V2_QUERIER             (3)
-
-/* IGMP groups */
-#define IGMP_ALL_HOST_GROUP               long_be(0xE0000001) /* 224.0.0.1 */
-#define IGMP_ALL_ROUTER_GROUP             long_be(0xE0000002) /* 224.0.0.2 */
-#define IGMPV3_ALL_ROUTER_GROUP           long_be(0xE0000016) /* 224.0.0.22 */
-
-/* misc */
-#define IGMP_TIMER_STOPPED                (1)
-#define IP_OPTION_ROUTER_ALERT_LEN        (4)
-#define IGMP_MAX_GROUPS                   (32) /* max 255 */
-
-struct __attribute__((packed)) igmp_message {
-  uint8_t type;
-  uint8_t max_resp_time;
-  uint16_t crc;
-  uint32_t mcast_group;
-};
-
-struct __attribute__((packed)) igmpv3_query {
-  uint8_t type;
-  uint8_t max_resp_time;
-  uint16_t crc;
-  uint32_t mcast_group;
-  uint8_t rsq;
-  uint8_t qqic;
-  uint16_t sources;
-  uint32_t source_addr[0];
-};
-
-struct __attribute__((packed)) igmpv3_group_record {
-  uint8_t type;
-  uint8_t aux;
-  uint16_t sources;
-  uint32_t mcast_group;
-  uint32_t source_addr[0];
-};
-
-struct __attribute__((packed)) igmpv3_report {
-  uint8_t type;
-  uint8_t res0;
-  uint16_t crc;
-  uint16_t res1;
-  uint16_t groups;
-  struct igmpv3_group_record record[0];
-};
-
-struct igmp_parameters {
-  uint8_t event;
-  uint8_t state;
-  uint8_t last_host;
-  uint8_t filter_mode;
-  uint8_t max_resp_time;
-  struct pico_ip4 mcast_link;
-  struct pico_ip4 mcast_group;
-  struct pico_tree *MCASTFilter;
-  struct pico_frame *f;
-};
-
-struct igmp_timer {
-  uint8_t type;
-  uint8_t stopped;
-  unsigned long start;
-  unsigned long delay;
-  struct pico_ip4 mcast_link;
-  struct pico_ip4 mcast_group;
-  struct pico_frame *f;
-  void (*callback)(struct igmp_timer *t);
-};
-
-/* queues */
-static struct pico_queue igmp_in = {};
-static struct pico_queue igmp_out = {};
-
-/* finite state machine caller */
-static int pico_igmp_process_event(struct igmp_parameters *p);
-
-/* state callback prototype */
-typedef int (*callback)(struct igmp_parameters *);
-
-/* redblack trees */
-static int igmp_timer_cmp(void *ka, void *kb)
-{
-  struct igmp_timer *a = ka, *b =kb;
-  if (a->type < b->type)
-    return -1;
-  if (a->type > b->type)
-    return 1;
-  if (a->mcast_group.addr < b->mcast_group.addr)
-    return -1;
-  if (a->mcast_group.addr > b->mcast_group.addr)
-    return 1;
-  if (a->mcast_link.addr < b->mcast_link.addr)
-    return -1;
-  if (a->mcast_link.addr > b->mcast_link.addr)
-    return 1;
-  return 0;
-}
-PICO_TREE_DECLARE(IGMPTimers, igmp_timer_cmp);
-
-static int igmp_parameters_cmp(void *ka, void *kb)
-{
-  struct igmp_parameters *a = ka, *b = kb;
-  if (a->mcast_group.addr < b->mcast_group.addr)
-    return -1;
-  if (a->mcast_group.addr > b->mcast_group.addr)
-    return 1;
-  if (a->mcast_link.addr < b->mcast_link.addr)
-    return -1;
-  if (a->mcast_link.addr > b->mcast_link.addr)
-    return 1;
-  return 0;
-}
-PICO_TREE_DECLARE(IGMPParameters, igmp_parameters_cmp);
-
-static int igmp_sources_cmp(void *ka, void *kb)
-{
-  struct pico_ip4 *a = ka, *b = kb;
-  if (a->addr < b->addr)
-    return -1;
-  if (a->addr > b->addr)
-    return 1;
-  return 0;
-}
-PICO_TREE_DECLARE(IGMPAllow, igmp_sources_cmp);
-PICO_TREE_DECLARE(IGMPBlock, igmp_sources_cmp);
-
-static struct igmp_parameters *pico_igmp_find_parameter(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group)
-{
-  struct igmp_parameters test = {0};
-  test.mcast_link.addr = mcast_link->addr;
-  test.mcast_group.addr = mcast_group->addr;
-  return pico_tree_findKey(&IGMPParameters, &test);
-}
-
-static int pico_igmp_delete_parameter(struct igmp_parameters *p)
-{
-  if (pico_tree_delete(&IGMPParameters, p))
-    pico_free(p);
-  else
-    return -1;
-
-  return 0;
-}
-
-static void pico_igmp_timer_expired(unsigned long now, void *arg)
-{
-  struct igmp_timer *t = NULL, *timer = NULL, test = {0};
-
-  t = (struct igmp_timer *)arg;
-  test.type = t->type;
-  test.mcast_link = t->mcast_link;
-  test.mcast_group = t->mcast_group;
-  igmp_dbg("IGMP: timer expired for %08X link %08X type %u, delay %lu\n", t->mcast_group.addr, t->mcast_link.addr, t->type, t->delay);
-  timer = pico_tree_findKey(&IGMPTimers, &test);
-  if (!timer) {
-    return;
-  }
-  if (timer->stopped == IGMP_TIMER_STOPPED) {
-    pico_free(t);
-    return;
-  }
-  if (timer->start + timer->delay < PICO_TIME_MS()) {
-    pico_tree_delete(&IGMPTimers, timer);
-    if (timer->callback)
-      timer->callback(timer);
-    pico_free(timer);
-  } else {
-    igmp_dbg("IGMP: restart timer for %08X, delay %lu, new delay %lu\n", t->mcast_group.addr, t->delay,  (timer->start + timer->delay) - PICO_TIME_MS());
-    pico_timer_add((timer->start + timer->delay) - PICO_TIME_MS(), &pico_igmp_timer_expired, timer);
-  }
-  return;
-}
-
-static int pico_igmp_timer_reset(struct igmp_timer *t)
-{
-  struct igmp_timer *timer = NULL, test = {0};
-
-  igmp_dbg("IGMP: reset timer for %08X, delay %lu\n", t->mcast_group.addr, t->delay);
-  test.type = t->type;
-  test.mcast_link = t->mcast_link;
-  test.mcast_group = t->mcast_group;
-  timer = pico_tree_findKey(&IGMPTimers, &test);
-  if (!timer)
-    return -1;
-
-  *timer = *t;
-  timer->start = PICO_TIME_MS();
-  return 0;
-}
-
-static int pico_igmp_timer_start(struct igmp_timer *t)
-{
-  struct igmp_timer *timer = NULL, test = {0};
-
-  igmp_dbg("IGMP: start timer for %08X link %08X type %u, delay %lu\n", t->mcast_group.addr, t->mcast_link.addr, t->type, t->delay);
-  test.type = t->type;
-  test.mcast_link = t->mcast_link;
-  test.mcast_group = t->mcast_group;
-  timer = pico_tree_findKey(&IGMPTimers, &test);
-  if (timer)
-    return pico_igmp_timer_reset(t);
-
-  timer = pico_zalloc(sizeof(struct igmp_timer));
-  if (!timer) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  *timer = *t;
-  timer->start = PICO_TIME_MS();
-
-  pico_tree_insert(&IGMPTimers, timer);
-  pico_timer_add(timer->delay, &pico_igmp_timer_expired, timer);
-  return 0;
-}
-
-static int pico_igmp_timer_stop(struct igmp_timer *t)
-{
-  struct igmp_timer *timer = NULL, test = {0};
-
-  test.type = t->type;
-  test.mcast_link = t->mcast_link;
-  test.mcast_group = t->mcast_group;
-  timer = pico_tree_findKey(&IGMPTimers, &test);
-  if (!timer)
-    return 0;
-
-  igmp_dbg("IGMP: stop timer for %08X, delay %lu\n", timer->mcast_group.addr, timer->delay);
-  timer->stopped = IGMP_TIMER_STOPPED;
-  return 0;
-}
-
-static int pico_igmp_timer_is_running(struct igmp_timer *t)
-{
-  struct igmp_timer *timer = NULL, test = {0};
-
-  test.type = t->type;
-  test.mcast_link = t->mcast_link;
-  test.mcast_group = t->mcast_group;
-  timer = pico_tree_findKey(&IGMPTimers, &test);
-  if (timer)
-    return 1;
-  return 0;
-}
-
-static struct igmp_timer *pico_igmp_find_timer(uint8_t type, struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group)
-{
-  struct igmp_timer test = {0};
-
-  test.type = type;
-  test.mcast_link = *mcast_link;
-  test.mcast_group = *mcast_group;
-  return pico_tree_findKey(&IGMPTimers, &test);
-}
-
-static void pico_igmp_report_expired(struct igmp_timer *t)
-{
-  struct igmp_parameters *p = NULL;
-
-  p = pico_igmp_find_parameter(&t->mcast_link, &t->mcast_group);
-  if (!p)
-    return;
-
-  p->event = IGMP_EVENT_TIMER_EXPIRED;
-  pico_igmp_process_event(p);
-}
-
-static void pico_igmp_v2querier_expired(struct igmp_timer *t)
-{
-  struct pico_ipv4_link *link = NULL;
-  struct pico_tree_node *index = NULL, *_tmp = NULL;
-
-  link = pico_ipv4_link_by_dev(t->f->dev);
-  if (!link)
-    return;
-
-  /* When changing compatibility mode, cancel all pending response 
-   * and retransmission timers.
-   */
-  pico_tree_foreach_safe(index, &IGMPTimers, _tmp) 
-  {
-    ((struct igmp_timer *)index->keyValue)->stopped = IGMP_TIMER_STOPPED;
-    pico_tree_delete(&IGMPTimers, index->keyValue);
-  }
-  igmp_dbg("IGMP: switch to compatibility mode IGMPv3\n");
-  link->mcast_compatibility = PICO_IGMPV3;
-  return;
-}
-
-static int pico_igmp_is_checksum_valid(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = NULL;
-  uint8_t ihl = 24, datalen = 0;
-
-  hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  ihl = (hdr->vhl & 0x0F) * 4; /* IHL is in 32bit words */
-  datalen = short_be(hdr->len) - ihl;
-
-  if (short_be(pico_checksum(f->transport_hdr, datalen)) == 0)
-    return 1;
-  igmp_dbg("IGMP: invalid checksum\n");
-  return 0;
-}
-
-/* RFC 3376 $7.1 */
-static int pico_igmp_compatibility_mode(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = NULL;
-  struct pico_ipv4_link *link = NULL;
-  struct pico_tree_node *index = NULL, *_tmp = NULL;
-  struct igmp_timer t = {0};
-  uint8_t ihl = 24, datalen = 0;
-
-  link = pico_ipv4_link_by_dev(f->dev);
-  if (!link)
-    return -1;
-
-  hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  ihl = (hdr->vhl & 0x0F) * 4; /* IHL is in 32bit words */
-  datalen = short_be(hdr->len) - ihl;
-  igmp_dbg("IGMP: IHL = %u, LEN = %u, OCTETS = %u\n", ihl, short_be(hdr->len), datalen);
-
-  if (datalen > 12) {
-    /* IGMPv3 query */
-    t.type = IGMP_TIMER_V2_QUERIER;
-    if (pico_igmp_timer_is_running(&t)) { /* IGMPv2 querier present timer still running */
-      return -1;
-    } else {
-      link->mcast_compatibility = PICO_IGMPV3;
-      return 0;
-    }
-  } else if (datalen == 8) {
-    struct igmp_message *query = (struct igmp_message *)f->transport_hdr;
-    if (query->max_resp_time != 0) {
-      /* IGMPv2 query */
-      /* When changing compatibility mode, cancel all pending response 
-       * and retransmission timers.
-       */
-      pico_tree_foreach_safe(index, &IGMPTimers, _tmp) 
-      {
-        ((struct igmp_timer *)index->keyValue)->stopped = IGMP_TIMER_STOPPED;
-        pico_tree_delete(&IGMPTimers, index->keyValue);
-      }
-      igmp_dbg("IGMP: switch to compatibility mode IGMPv2\n");
-      link->mcast_compatibility = PICO_IGMPV2;
-      t.type = IGMP_TIMER_V2_QUERIER;
-      t.delay = ((IGMP_ROBUSTNESS * link->mcast_last_query_interval) + IGMP_QUERY_RESPONSE_INTERVAL) * 1000;
-      t.f = f;
-      t.callback = pico_igmp_v2querier_expired;
-      /* only one of this type of timer may exist! */
-      pico_igmp_timer_start(&t);
-    } else {
-      /* IGMPv1 query, not supported */
-      return -1;
-    }
-  } else {
-    /* invalid query, silently ignored */
-    return -1;
-  }
-  return 0;
-}
-
-static struct igmp_parameters *pico_igmp_analyse_packet(struct pico_frame *f)
-{
-  struct igmp_message *message = NULL;
-  struct igmp_parameters *p = NULL;
-  struct pico_ipv4_link *link = NULL;
-  struct pico_ip4 mcast_group = {0};
-
-  link = pico_ipv4_link_by_dev(f->dev);
-  if (!link)
-    return NULL;
-
-  /* IGMPv2 and IGMPv3 have a similar structure for the first 8 bytes */ 
-  message = (struct igmp_message *)f->transport_hdr;
-  mcast_group.addr = message->mcast_group;
-  p = pico_igmp_find_parameter(&link->address, &mcast_group);
-  if (!p && mcast_group.addr == 0) { /* general query */
-    p = pico_zalloc(sizeof(struct igmp_parameters));
-    if (!p)
-      return NULL;
-    p->state = IGMP_STATE_NON_MEMBER;
-    p->mcast_link.addr = link->address.addr;
-    p->mcast_group.addr = mcast_group.addr;
-    pico_tree_insert(&IGMPParameters, p);
-  } else if (!p) {
-    return NULL;
-  }
-
-  switch (message->type) {
-    case IGMP_TYPE_MEM_QUERY:
-       p->event = IGMP_EVENT_QUERY_RECV;
-       break;
-    case IGMP_TYPE_MEM_REPORT_V1:
-       p->event = IGMP_EVENT_REPORT_RECV;
-       break;
-    case IGMP_TYPE_MEM_REPORT_V2:
-       p->event = IGMP_EVENT_REPORT_RECV;
-       break;
-    case IGMP_TYPE_MEM_REPORT_V3:
-       p->event = IGMP_EVENT_REPORT_RECV;
-       break;
-    default:
-       return NULL;
-  }
-  p->max_resp_time = message->max_resp_time; /* if IGMPv3 report this will be 0 (res0 field) */
-  p->f = f;
-
-  return p;
-}
-
-static int pico_igmp_process_in(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct igmp_parameters *p = NULL;
- 
-  if (!pico_igmp_is_checksum_valid(f))
-    goto out;
-  if (pico_igmp_compatibility_mode(f) < 0)
-    goto out;
-  p = pico_igmp_analyse_packet(f);
-  if (!p)
-    goto out;
-
-  return pico_igmp_process_event(p);
-
-  out:
-    pico_frame_discard(f);
-    return 0;
-}
-
-static int pico_igmp_process_out(struct pico_protocol *self, struct pico_frame *f) {
-  /* packets are directly transferred to the IP layer by calling pico_ipv4_frame_push */
-  return 0;
-}
-
-/* Interface: protocol definition */
-struct pico_protocol pico_proto_igmp = {
-  .name = "igmp",
-  .proto_number = PICO_PROTO_IGMP,
-  .layer = PICO_LAYER_TRANSPORT,
-  .process_in = pico_igmp_process_in,
-  .process_out = pico_igmp_process_out,
-  .q_in = &igmp_in,
-  .q_out = &igmp_out,
-};
-
-int pico_igmp_state_change(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t filter_mode, struct pico_tree *MCASTFilter, uint8_t state) 
-{
-  struct igmp_parameters *p = NULL;
-  
-  if (mcast_group->addr == IGMP_ALL_HOST_GROUP)
-    return 0;
-
-  p = pico_igmp_find_parameter(mcast_link, mcast_group);
-  if (!p && state == PICO_IGMP_STATE_CREATE) {
-    p = pico_zalloc(sizeof(struct igmp_parameters));
-    if (!p) {
-      pico_err = PICO_ERR_ENOMEM;
-      return -1;
-    }
-    p->state = IGMP_STATE_NON_MEMBER;
-    p->mcast_link = *mcast_link;
-    p->mcast_group = *mcast_group;
-    pico_tree_insert(&IGMPParameters, p);
-  } else if (!p) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  switch (state) {
-    case PICO_IGMP_STATE_CREATE:
-      p->event = IGMP_EVENT_CREATE_GROUP;
-      break;
-
-    case PICO_IGMP_STATE_UPDATE:
-      p->event = IGMP_EVENT_UPDATE_GROUP;
-      break;
-    
-    case PICO_IGMP_STATE_DELETE:
-      p->event = IGMP_EVENT_DELETE_GROUP;
-      break;
-
-    default:
-      return -1;
-  }
-  p->filter_mode = filter_mode;
-  p->MCASTFilter = MCASTFilter;
-
-  return pico_igmp_process_event(p);
-}
-
-static int pico_igmp_send_report(struct igmp_parameters *p, struct pico_frame *f)
-{
-  struct pico_ip4 dst = {0};
-  struct pico_ip4 mcast_group = {0};
-  struct pico_ipv4_link *link = NULL;
-  
-  link = pico_ipv4_link_get(&p->mcast_link);
-  if (!link)
-    return -1;
-
-  mcast_group.addr = p->mcast_group.addr;
-  switch (link->mcast_compatibility) {
-    case PICO_IGMPV2:
-      if (p->event == IGMP_EVENT_DELETE_GROUP)
-        dst.addr = IGMP_ALL_ROUTER_GROUP;
-      else
-        dst.addr = mcast_group.addr;
-      break;
-
-    case PICO_IGMPV3:
-      dst.addr = IGMPV3_ALL_ROUTER_GROUP;
-      break;
-
-    default:
-      pico_err = PICO_ERR_EPROTONOSUPPORT;
-      return -1;
-  }
-
-  igmp_dbg("IGMP: send membership report on group %08X to %08X\n", mcast_group.addr, dst.addr);
-  pico_ipv4_frame_push(f, &dst, PICO_PROTO_IGMP);
-  return 0;
-}
-
-static int pico_igmp_generate_report(struct igmp_parameters *p)
-{
-  struct pico_ipv4_link *link = NULL;
-  int i = 0;
-
-  link = pico_ipv4_link_get(&p->mcast_link);
-  if (!link) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  switch (link->mcast_compatibility) {
-    case PICO_IGMPV1:
-      pico_err = PICO_ERR_EPROTONOSUPPORT;
-      return -1;
-      
-    case PICO_IGMPV2:
-    {
-      struct igmp_message *report = NULL;
-      uint8_t report_type = IGMP_TYPE_MEM_REPORT_V2;
-      if (p->event == IGMP_EVENT_DELETE_GROUP)
-        report_type = IGMP_TYPE_LEAVE_GROUP;
-
-      p->f = pico_proto_ipv4.alloc(&pico_proto_ipv4, IP_OPTION_ROUTER_ALERT_LEN + sizeof(struct igmp_message));
-      p->f->net_len += IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->transport_hdr += IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->transport_len -= IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->dev = pico_ipv4_link_find(&p->mcast_link);
-      /* p->f->len is correctly set by alloc */
-
-      report = (struct igmp_message *)p->f->transport_hdr;
-      report->type = report_type;
-      report->max_resp_time = IGMP_DEFAULT_MAX_RESPONSE_TIME;
-      report->mcast_group = p->mcast_group.addr;
-
-      report->crc = 0;
-      report->crc = short_be(pico_checksum(report, sizeof(struct igmp_message)));
-      break;
-    }
-    case PICO_IGMPV3:
-    {
-      struct igmpv3_report *report = NULL;
-      struct igmpv3_group_record *record = NULL;
-      struct pico_mcast_group *g = NULL, test = {0};
-      struct pico_tree_node *index = NULL, *_tmp = NULL;
-      struct pico_tree *IGMPFilter = NULL;
-      struct pico_ip4 *source = NULL;
-      uint8_t record_type = 0;
-      uint8_t sources = 0;
-      int len = 0;
-
-      test.mcast_addr = p->mcast_group;
-      g = pico_tree_findKey(link->MCASTGroups, &test);
-      if (!g) {
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-      }
-
-      if (p->event == IGMP_EVENT_DELETE_GROUP) { /* "non-existent" state of filter mode INCLUDE and empty source list */
-        p->filter_mode = PICO_IP_MULTICAST_INCLUDE;
-        p->MCASTFilter = NULL;
-      }
-
-      /* cleanup filters */
-      pico_tree_foreach_safe(index, &IGMPAllow, _tmp) 
-      {
-        pico_tree_delete(&IGMPAllow, index->keyValue);
-      }
-      pico_tree_foreach_safe(index, &IGMPBlock, _tmp) 
-      {
-        pico_tree_delete(&IGMPBlock, index->keyValue);
-      }
-
-      switch (g->filter_mode) {
-
-        case PICO_IP_MULTICAST_INCLUDE:
-          switch (p->filter_mode) {
-            case PICO_IP_MULTICAST_INCLUDE:
-              if (p->event == IGMP_EVENT_DELETE_GROUP) { /* all ADD_SOURCE_MEMBERSHIP had an equivalent DROP_SOURCE_MEMBERSHIP */
-                /* TO_IN (B) */
-                record_type = IGMP_CHANGE_TO_INCLUDE_MODE;
-                IGMPFilter = &IGMPAllow;
-                if (p->MCASTFilter) {
-                  pico_tree_foreach(index, p->MCASTFilter) /* B */
-                  {
-                    pico_tree_insert(&IGMPAllow, index->keyValue);
-                    sources++;
-                  }
-                } /* else { IGMPAllow stays empty } */
-                break;
-              }
-
-              /* ALLOW (B-A) */
-              /* if event is CREATE A will be empty, thus only ALLOW (B-A) has sense */
-              if (p->event == IGMP_EVENT_CREATE_GROUP) /* first ADD_SOURCE_MEMBERSHIP */
-                record_type = IGMP_CHANGE_TO_INCLUDE_MODE;
-              else
-                record_type = IGMP_ALLOW_NEW_SOURCES;
-              IGMPFilter = &IGMPAllow;
-              pico_tree_foreach(index, p->MCASTFilter) /* B */
-              {
-                pico_tree_insert(&IGMPAllow, index->keyValue);
-                sources++;
-              }
-              pico_tree_foreach(index, &g->MCASTSources) /* A */
-              {
-                source = pico_tree_findKey(&IGMPAllow, index->keyValue);
-                if (source) {
-                  pico_tree_delete(&IGMPAllow, source);
-                  sources--;
-                }
-              }
-              if (!pico_tree_empty(&IGMPAllow)) /* record type is ALLOW */
-                break;
-
-              /* BLOCK (A-B) */
-              record_type = IGMP_BLOCK_OLD_SOURCES;
-              IGMPFilter = &IGMPBlock;
-              pico_tree_foreach(index, &g->MCASTSources) /* A */
-              {
-                pico_tree_insert(&IGMPBlock, index->keyValue);
-                sources++;
-              }
-              pico_tree_foreach(index, p->MCASTFilter) /* B */
-              {
-                source = pico_tree_findKey(&IGMPBlock, index->keyValue);
-                if (source) {
-                  pico_tree_delete(&IGMPBlock, source);
-                  sources--;
-                }
-              }
-              if (!pico_tree_empty(&IGMPBlock)) /* record type is BLOCK */
-                break;
-
-              /* ALLOW (B-A) and BLOCK (A-B) are empty: do not send report (RFC 3376 $5.1) */
-              p->f = NULL;
-              return 0;
-
-            case PICO_IP_MULTICAST_EXCLUDE:
-              /* TO_EX (B) */
-              record_type = IGMP_CHANGE_TO_EXCLUDE_MODE;
-              IGMPFilter = &IGMPBlock;
-              pico_tree_foreach(index, p->MCASTFilter) /* B */
-              {
-                pico_tree_insert(&IGMPBlock, index->keyValue);
-                sources++;
-              }
-              break;
-
-            default:
-              pico_err = PICO_ERR_EINVAL;
-              return -1;
-          }
-          break;
-
-        case PICO_IP_MULTICAST_EXCLUDE:
-          switch (p->filter_mode) {
-            case PICO_IP_MULTICAST_INCLUDE:
-              /* TO_IN (B) */
-              record_type = IGMP_CHANGE_TO_INCLUDE_MODE;
-              IGMPFilter = &IGMPAllow;
-              if (p->MCASTFilter) {
-                pico_tree_foreach(index, p->MCASTFilter) /* B */
-                {
-                  pico_tree_insert(&IGMPAllow, index->keyValue);
-                  sources++;
-                }
-              } /* else { IGMPAllow stays empty } */
-              break;
-
-            case PICO_IP_MULTICAST_EXCLUDE:
-              /* BLOCK (B-A) */
-              record_type = IGMP_BLOCK_OLD_SOURCES;
-              IGMPFilter = &IGMPBlock;
-              pico_tree_foreach(index, p->MCASTFilter)
-              {
-                pico_tree_insert(&IGMPBlock, index->keyValue);
-                sources++;
-              }
-              pico_tree_foreach(index, &g->MCASTSources) /* A */
-              {
-                source = pico_tree_findKey(&IGMPBlock, index->keyValue); /* B */
-                if (source) {
-                  pico_tree_delete(&IGMPBlock, source);
-                  sources--;
-                }
-              }
-              if (!pico_tree_empty(&IGMPBlock)) /* record type is BLOCK */
-                break;
-
-              /* ALLOW (A-B) */
-              record_type = IGMP_ALLOW_NEW_SOURCES;
-              IGMPFilter = &IGMPAllow;
-              pico_tree_foreach(index, &g->MCASTSources)
-              {
-                pico_tree_insert(&IGMPAllow, index->keyValue);
-                sources++;
-              }
-              pico_tree_foreach(index, p->MCASTFilter) /* B */
-              {
-                source = pico_tree_findKey(&IGMPAllow, index->keyValue); /* A */
-                if (source) {
-                  pico_tree_delete(&IGMPAllow, source);
-                  sources--;
-                }
-              }
-              if (!pico_tree_empty(&IGMPAllow)) /* record type is ALLOW */
-                break;
-
-              /* BLOCK (B-A) and ALLOW (A-B) are empty: do not send report (RFC 3376 $5.1) */
-              p->f = NULL;
-              return 0;
-
-            default:
-              pico_err = PICO_ERR_EINVAL;
-              return -1;
-          }
-          break;
-
-        default:
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-      }
-
-      len = sizeof(struct igmpv3_report) + sizeof(struct igmpv3_group_record) + (sources * sizeof(struct pico_ip4));
-      p->f = pico_proto_ipv4.alloc(&pico_proto_ipv4, IP_OPTION_ROUTER_ALERT_LEN + len);
-      p->f->net_len += IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->transport_hdr += IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->transport_len -= IP_OPTION_ROUTER_ALERT_LEN;
-      p->f->dev = pico_ipv4_link_find(&p->mcast_link);
-      /* p->f->len is correctly set by alloc */
-
-      report = (struct igmpv3_report *)p->f->transport_hdr;
-      report->type = IGMP_TYPE_MEM_REPORT_V3;
-      report->res0 = 0;
-      report->crc = 0;
-      report->res1 = 0;
-      report->groups = short_be(1);
-
-      record = &report->record[0];
-      record->type = record_type;
-      record->aux = 0;
-      record->sources = short_be(sources);
-      record->mcast_group = p->mcast_group.addr;
-      if (!pico_tree_empty(IGMPFilter)) {
-        i = 0;
-        pico_tree_foreach(index, IGMPFilter)
-        {
-          record->source_addr[i] = ((struct pico_ip4 *)index->keyValue)->addr;
-          i++;
-        }
-      }
-      report->crc = short_be(pico_checksum(report, len));
-      break;
-    }
-
-    default:
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-  }
-  return 0;
-}
-
-/* stop timer, send leave if flag set */
-static int stslifs(struct igmp_parameters *p)
-{
-  struct igmp_timer t = {0};
-
-  igmp_dbg("IGMP: event = leave group | action = stop timer, send leave if flag set\n");
-
-  t.type = IGMP_TIMER_GROUP_REPORT;
-  t.mcast_link = p->mcast_link;
-  t.mcast_group = p->mcast_group;
-  if (pico_igmp_timer_stop(&t) < 0)
-    return -1;
-
-  /* always send leave, even if not last host */
-  if (pico_igmp_send_report(p, p->f) < 0)
-    return -1;
-
-  pico_igmp_delete_parameter(p);
-  igmp_dbg("IGMP: new state = non-member\n");
-  return 0;
-}
-
-/* send report, set flag, start timer */
-static int srsfst(struct igmp_parameters *p)
-{
-  struct igmp_timer t = {0};
-  struct pico_frame *copy_frame = NULL;
-
-  igmp_dbg("IGMP: event = join group | action = send report, set flag, start timer\n");
-
-  p->last_host = IGMP_HOST_LAST;
-
-  if (pico_igmp_generate_report(p) < 0)
-    return -1;
-  if (!p->f)
-    return 0;
-  copy_frame = pico_frame_copy(p->f);
-  if (!copy_frame) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  if (pico_igmp_send_report(p, copy_frame) < 0)
-    return -1;
-
-  t.type = IGMP_TIMER_GROUP_REPORT;
-  t.mcast_link = p->mcast_link;
-  t.mcast_group = p->mcast_group;
-  t.delay = (pico_rand() % (IGMP_UNSOLICITED_REPORT_INTERVAL * 10000)); 
-  t.f = p->f;
-  t.callback = pico_igmp_report_expired;
-  pico_igmp_timer_start(&t);
-
-  p->state = IGMP_STATE_DELAYING_MEMBER;
-  igmp_dbg("IGMP: new state = delaying member\n");
-  return 0;
-}
-
-/* merge report, send report, reset timer (IGMPv3 only) */
-static int mrsrrt(struct igmp_parameters *p)
-{
-  struct igmp_timer *t = NULL;
-  struct pico_frame *copy_frame = NULL;
-  struct pico_ipv4_link *link = NULL;
-
-  igmp_dbg("IGMP: event = update group | action = merge report, send report, reset timer (IGMPv3 only)\n");
-
-  link = pico_ipv4_link_get(&p->mcast_link);
-  if (!link)
-    return -1;
-
-  if (link->mcast_compatibility != PICO_IGMPV3) {
-    igmp_dbg("IGMP: no IGMPv3 compatible router on network\n");
-    return -1;
-  }
-
-  /* XXX: merge with pending report rfc 3376 $5.1 */
-
-  copy_frame = pico_frame_copy(p->f);
-  if (!copy_frame)
-    return -1;
-  if (pico_igmp_send_report(p, copy_frame) < 0)
-    return -1;
-
-  t = pico_igmp_find_timer(IGMP_TIMER_GROUP_REPORT, &p->mcast_link, &p->mcast_group);
-  if (!t)
-    return -1;
-  t->delay = (pico_rand() % (IGMP_UNSOLICITED_REPORT_INTERVAL * 10000)); 
-  pico_igmp_timer_reset(t);
-
-  p->state = IGMP_STATE_DELAYING_MEMBER;
-  igmp_dbg("IGMP: new state = delaying member\n");
-  return 0;
-}
-
-/* send report, start timer (IGMPv3 only) */
-static int srst(struct igmp_parameters *p)
-{
-  struct igmp_timer t = {0};
-  struct pico_frame *copy_frame = NULL;
-  struct pico_ipv4_link *link = NULL;
-
-  igmp_dbg("IGMP: event = update group | action = send report, start timer (IGMPv3 only)\n");
-
-  link = pico_ipv4_link_get(&p->mcast_link);
-  if (!link)
-    return -1;
-
-  if (link->mcast_compatibility != PICO_IGMPV3) {
-    igmp_dbg("IGMP: no IGMPv3 compatible router on network\n");
-    return -1;
-  }
-
-  if (pico_igmp_generate_report(p) < 0)
-    return -1;
-  if (!p->f)
-    return 0;
-  copy_frame = pico_frame_copy(p->f);
-  if (!copy_frame)
-    return -1;
-  if (pico_igmp_send_report(p, copy_frame) < 0)
-    return -1;
-
-  t.type = IGMP_TIMER_GROUP_REPORT;
-  t.mcast_link = p->mcast_link;
-  t.mcast_group = p->mcast_group;
-  t.delay = (pico_rand() % (IGMP_UNSOLICITED_REPORT_INTERVAL * 10000)); 
-  t.f = p->f;
-  t.callback = pico_igmp_report_expired;
-  pico_igmp_timer_start(&t);
-
-  p->state = IGMP_STATE_DELAYING_MEMBER;
-  igmp_dbg("IGMP: new state = delaying member\n");
-  return 0;
-}
-
-/* send leave if flag set */
-static int slifs(struct igmp_parameters *p)
-{
-  igmp_dbg("IGMP: event = leave group | action = send leave if flag set\n");
-
-  /* always send leave, even if not last host */
-  if (pico_igmp_send_report(p, p->f) < 0)
-    return -1;
-
-  pico_igmp_delete_parameter(p);
-  igmp_dbg("IGMP: new state = non-member\n");
-  return 0;
-}
-
-/* start timer */
-static int st(struct igmp_parameters *p)
-{
-  struct igmp_timer t = {0};
-
-  igmp_dbg("IGMP: event = query received | action = start timer\n");
-
-  if (pico_igmp_generate_report(p) < 0)
-    return -1;
-  if (!p->f)
-    return -1;
-
-  t.type = IGMP_TIMER_GROUP_REPORT;
-  t.mcast_link = p->mcast_link;
-  t.mcast_group = p->mcast_group;
-  t.delay = (pico_rand() % (p->max_resp_time * 100)); 
-  t.f = p->f;
-  t.callback = pico_igmp_report_expired;
-  pico_igmp_timer_start(&t);
-
-  p->state = IGMP_STATE_DELAYING_MEMBER;
-  igmp_dbg("IGMP: new state = delaying member\n");
-  return 0;
-}
-
-/* stop timer, clear flag */
-static int stcl(struct igmp_parameters *p)
-{
-  struct igmp_timer t = {0};
-
-  igmp_dbg("IGMP: event = report received | action = stop timer, clear flag\n");
-
-  t.type = IGMP_TIMER_GROUP_REPORT;
-  t.mcast_link = p->mcast_link;
-  t.mcast_group = p->mcast_group;
-  if (pico_igmp_timer_stop(&t) < 0)
-    return -1;
-
-  p->last_host = IGMP_HOST_NOT_LAST;
-  p->state = IGMP_STATE_IDLE_MEMBER;
-  igmp_dbg("IGMP: new state = idle member\n");
-  return 0;
-}
-
-/* send report, set flag */
-static int srsf(struct igmp_parameters *p)
-{
-  igmp_dbg("IGMP: event = timer expired | action = send report, set flag\n");
-
-  if (pico_igmp_send_report(p, p->f) < 0)
-    return -1;
-
-  p->state = IGMP_STATE_IDLE_MEMBER;
-  igmp_dbg("IGMP: new state = idle member\n"); 
-  return 0;
-}
-
-/* reset timer if max response time < current timer */
-static int rtimrtct(struct igmp_parameters *p)
-{
-  struct igmp_timer *t = NULL;
-  unsigned long time_to_run = 0;
-
-  igmp_dbg("IGMP: event = query received | action = reset timer if max response time < current timer\n");
-
-  t = pico_igmp_find_timer(IGMP_TIMER_GROUP_REPORT, &p->mcast_link, &p->mcast_group);
-  if (!t)
-    return -1;
-
-  time_to_run = t->start + t->delay - PICO_TIME_MS();
-  if ((p->max_resp_time * 100) < time_to_run) { /* max_resp_time in units of 1/10 seconds */
-    t->delay = pico_rand() % (p->max_resp_time * 100); 
-    pico_igmp_timer_reset(t);
-  }
-
-  p->state = IGMP_STATE_DELAYING_MEMBER;
-  igmp_dbg("IGMP: new state = delaying member\n"); 
-  return 0;
-}
-
-static int discard(struct igmp_parameters *p){
-  igmp_dbg("IGMP: ignore and discard frame\n");
-  pico_frame_discard(p->f);
-  return 0;
-}
-
-/* finite state machine table */
-const callback host_membership_diagram_table[3][6] =
-{ /* event                    |Delete Group  |Create Group |Update Group |Query Received  |Report Received  |Timer Expired */
-/* state Non-Member      */ { discard,       srsfst,       srsfst,       discard,         discard,          discard },
-/* state Delaying Member */ { stslifs,       mrsrrt,       mrsrrt,       rtimrtct,        stcl,             srsf    },
-/* state Idle Member     */ { slifs,         srst,         srst,         st,              discard,          discard }
-};
-
-static int pico_igmp_process_event(struct igmp_parameters *p)
-{
-  struct pico_tree_node *index = NULL;
-  struct igmp_parameters *_p = NULL;
-
-  igmp_dbg("IGMP: process event on group address %08X\n", p->mcast_group.addr);
-  if (p->event == IGMP_EVENT_QUERY_RECV && p->mcast_group.addr == 0) { /* general query */
-    pico_tree_foreach(index, &IGMPParameters) {
-      _p = index->keyValue;
-      _p->max_resp_time = p->max_resp_time;
-      _p->event = IGMP_EVENT_QUERY_RECV;
-      igmp_dbg("IGMP: for each mcast_group = %08X | state = %u\n", _p->mcast_group.addr, _p->state);
-      host_membership_diagram_table[_p->state][_p->event](_p);
-    }
-  } else {
-    igmp_dbg("IGMP: state = %u (0: non-member - 1: delaying member - 2: idle member)\n", p->state); 
-    host_membership_diagram_table[p->state][p->event](p);
-  }
-  return 0;
-}
-
--- a/modules/pico_igmp.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Kristof Roelants, Simon Maes, Brecht Van Cauwenberghe
-*********************************************************************/
-
-#ifndef _INCLUDE_PICO_IGMP
-#define _INCLUDE_PICO_IGMP
-
-#define PICO_IGMPV1               1
-#define PICO_IGMPV2               2
-#define PICO_IGMPV3               3
-
-#define PICO_IGMP_STATE_CREATE    1
-#define PICO_IGMP_STATE_UPDATE    2
-#define PICO_IGMP_STATE_DELETE    3
-
-#define PICO_IGMP_QUERY_INTERVAL  125
-
-extern struct pico_protocol pico_proto_igmp;
-
-int pico_igmp_state_change(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t filter_mode, struct pico_tree *MCASTFilter, uint8_t state);
-#endif /* _INCLUDE_PICO_IGMP */
--- a/modules/pico_ipfilter.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Simon Maes
-*********************************************************************/
-
-#include "pico_ipv4.h"
-#include "pico_config.h"
-#include "pico_icmp4.h"
-#include "pico_stack.h"
-#include "pico_eth.h"
-#include "pico_socket.h"
-#include "pico_device.h"
-#include "pico_ipfilter.h"
-#include "pico_tcp.h"
-#include "pico_udp.h"
-
-
-//#define ipf_dbg dbg
-#define ipf_dbg(...) do{}while(0)
-
-struct filter_node;
-typedef int (*func_pntr)(struct filter_node *filter, struct pico_frame *f);
-
-struct filter_node {
-  struct pico_device *fdev;
-  struct filter_node *next_filter;
-  uint32_t out_addr;
-  uint32_t out_addr_netmask;
-  uint32_t in_addr;
-  uint32_t in_addr_netmask;
-  uint16_t out_port;
-  uint16_t in_port;
-  uint8_t proto;
-  int8_t priority;
-  uint8_t tos;
-  uint8_t filter_id;
-  func_pntr function_ptr;
-};
-
-static struct filter_node *head = NULL;
-static struct filter_node *tail = NULL;
-
-/*======================== FUNCTION PNTRS ==========================*/
-
-static int fp_accept(struct filter_node *filter, struct pico_frame *f) {return 0;}
-
-static int fp_priority(struct filter_node *filter, struct pico_frame *f) {
-
-  //TODO do priority-stuff
-  return 0;
-}
-
-static int fp_reject(struct filter_node *filter, struct pico_frame *f) {
-// TODO check first if sender is pico itself or not
-  ipf_dbg("ipfilter> #reject\n");
-  pico_icmp4_packet_filtered(f);
-  pico_frame_discard(f);
-  return 1;
-}
-
-static int fp_drop(struct filter_node *filter, struct pico_frame *f) {
-
-  ipf_dbg("ipfilter> # drop\n");
-  pico_frame_discard(f);
-  return 1;
-}
-
-/*============================ API CALLS ============================*/
-int pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto, struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask, struct pico_ip4 *in_addr, struct pico_ip4 *in_addr_netmask, uint16_t out_port, uint16_t in_port, int8_t priority, uint8_t tos, enum filter_action action)
-{
-  static uint8_t filter_id = 0;
-  struct filter_node *new_filter;
-
-  if ( !(dev != NULL || proto != 0 || (out_addr != NULL && out_addr->addr != 0U) || (out_addr_netmask != NULL && out_addr_netmask->addr != 0U)|| (in_addr != NULL && in_addr->addr != 0U) || (in_addr_netmask != NULL && in_addr_netmask->addr != 0U)|| out_port != 0 || in_port !=0 || tos != 0 )) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  if ( priority > 10 || priority < -10) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  if (action > 3 || action < 0) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  ipf_dbg("ipfilter> # adding filter\n");
-
-  new_filter = pico_zalloc(sizeof(struct filter_node));
-  if (!head) {
-    head = tail = new_filter;
-  } else {
-    tail->next_filter = new_filter;
-    tail = new_filter;
-  }
-
-  new_filter->fdev = dev;
-  new_filter->proto = proto;
-  if (out_addr != NULL)
-    new_filter->out_addr = out_addr->addr;
-  else
-    new_filter->out_addr = 0U;
-
-  if (out_addr_netmask != NULL)
-    new_filter->out_addr_netmask = out_addr_netmask->addr;
-  else
-    new_filter->out_addr_netmask = 0U;
-
-  if (in_addr != NULL)
-    new_filter->in_addr = in_addr->addr;
-  else
-    new_filter->in_addr = 0U;
- 
-  if (in_addr_netmask != NULL)
-    new_filter->in_addr_netmask = in_addr_netmask->addr;
-  else
-    new_filter->in_addr_netmask = 0U;
-
-  new_filter->out_port = out_port;
-  new_filter->in_port = in_port;
-  new_filter->priority = priority;
-  new_filter->tos = tos;
-  new_filter->filter_id = filter_id++;
-
-  /*Define filterType_functionPointer here instead of in ipfilter-function, to prevent running multiple times through switch*/
-  switch (action) {
-    case FILTER_ACCEPT:
-      new_filter->function_ptr = fp_accept;
-      break;
-    case FILTER_PRIORITY:
-      new_filter->function_ptr = fp_priority;
-      break;
-    case FILTER_REJECT:
-      new_filter->function_ptr = fp_reject;
-      break;
-    case FILTER_DROP:
-      new_filter->function_ptr = fp_drop;
-      break;
-    default:
-      ipf_dbg("ipfilter> #unknown filter action\n");
-      break;
-  }
-  return new_filter->filter_id;
-}
-
-int pico_ipv4_filter_del(uint8_t filter_id)
-{
-  struct filter_node *work;
-  struct filter_node *prev;
-
-  if (!tail || !head) {
-    pico_err = PICO_ERR_EPERM;
-    return -1;
-  }
-
-  work = head;
-  if (work->filter_id == filter_id) {
-      /*delete filter_node from linked list*/
-      head = work->next_filter;
-      pico_free(work);
-      return 0;
-  }
-  prev = work;
-  work = work->next_filter;
-
-  while (1) {
-    if (work->filter_id == filter_id) {
-        if (work != tail) {
-        /*delete filter_node from linked list*/
-        prev->next_filter = work->next_filter;
-        pico_free(work);
-        return 0;
-        } else {
-          prev->next_filter = NULL;
-          pico_free(work);
-          return 0;
-        }
-    } else {
-      /*check next filter_node*/
-      prev = work;
-      work = work->next_filter;
-      if (work == tail) {
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-      }
-    }
-  }
-}
-
-/*================================== CORE FILTER FUNCTIONS ==================================*/
-int match_filter(struct filter_node *filter, struct pico_frame *f)
-{
-  struct filter_node temp;
-  struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_tcp_hdr *tcp_hdr;
-  struct pico_udp_hdr *udp_hdr;
-
-  if (!filter|| !f) {
-    ipf_dbg("ipfilter> ## nullpointer in match filter \n");
-    return -1;
-  }
-
-  temp.fdev = f->dev;
-  temp.out_addr = ipv4_hdr->dst.addr;
-  temp.in_addr = ipv4_hdr->src.addr;
-  if (ipv4_hdr->proto == PICO_PROTO_TCP ) {
-      tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-      temp.out_port = short_be(tcp_hdr->trans.dport);
-      temp.in_port = short_be(tcp_hdr->trans.sport);
-  }else if (ipv4_hdr->proto == PICO_PROTO_UDP ) {
-      udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-      temp.out_port = short_be(udp_hdr->trans.dport);
-      temp.in_port = short_be(udp_hdr->trans.sport);
-  } else {
-    temp.out_port = temp.in_port = 0;
-  }
-  temp.proto = ipv4_hdr->proto;
-  temp.priority = f->priority;
-  temp.tos = ipv4_hdr->tos;
-
-
-
-  if ( ((filter->fdev == NULL || filter->fdev == temp.fdev) && \
-        (filter->in_addr == 0 || ((filter->in_addr_netmask == 0) ? (filter->in_addr == temp.in_addr) : 1)) &&\
-        (filter->in_port == 0 || filter->in_port == temp.in_port) &&\
-        (filter->out_addr == 0 || ((filter->out_addr_netmask == 0) ? (filter->out_addr == temp.out_addr) : 1)) && \
-        (filter->out_port == 0 || filter->out_port == temp.out_port)  && \
-        (filter->proto == 0 || filter->proto == temp.proto ) &&\
-        (filter->priority == 0 || filter->priority == temp.priority ) &&\
-        (filter->tos == 0 || filter->tos == temp.tos ) &&\
-        (filter->out_addr_netmask == 0 || ((filter->out_addr & filter->out_addr_netmask) == (temp.out_addr & filter->out_addr_netmask)) ) &&\
-        (filter->in_addr_netmask == 0 || ((filter->in_addr & filter->in_addr_netmask) == (temp.in_addr & filter->in_addr_netmask)) )\
-       ) ) 
-    return 0;
-
-  //No filter match!
-  ipf_dbg("ipfilter> #no match\n");
-  return 1;
-}
-
-int ipfilter(struct pico_frame *f)
-{
-  struct filter_node *work = head;
-
-  /*return 1 if pico_frame is discarded as result of the filtering, 0 for an incomming packet, -1 for faults*/
-  if (!tail || !head)  {
-    return 0;
-  }
-
-  if ( match_filter(work, f) == 0 ) { 
-    ipf_dbg("ipfilter> # ipfilter match\n");
-    /*filter match, execute filter!*/
-    return work->function_ptr(work, f);
-  } 
-  while (tail != work) {
-    ipf_dbg("ipfilter> next filter..\n");
-    work = work->next_filter;
-    if ( match_filter(work, f) == 0 ) {
-      ipf_dbg("ipfilter> # ipfilter match\n");
-      /*filter match, execute filter!*/
-      return work->function_ptr(work, f);
-    }
-  }
-  return 0;
-}
-
--- a/modules/pico_ipfilter.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Simon Maes
-*********************************************************************/
-#ifndef _INCLUDE_PICO_IPFILTER
-#define _INCLUDE_PICO_IPFILTER
-
-#include "pico_device.h"
-
-enum filter_action {
-  FILTER_ACCEPT = 0,
-  FILTER_PRIORITY,
-  FILTER_REJECT,
-  FILTER_DROP,
-};
-
-
-
-int pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto,
-  struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask, struct pico_ip4 *in_addr,
-  struct pico_ip4 *in_addr_netmask, uint16_t out_port, uint16_t in_port,
-  int8_t priority, uint8_t tos, enum filter_action action);
-
-int pico_ipv4_filter_del(uint8_t filter_id);
-
-int ipfilter(struct pico_frame *f);
-
-#endif /* _INCLUDE_PICO_IPFILTER */
-
--- a/modules/pico_ipv4.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1418 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Authors: Daniele Lacamera, Markian Yskout
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_ipfilter.h"
-#include "pico_ipv4.h"
-#include "pico_icmp4.h"
-#include "pico_stack.h"
-#include "pico_eth.h"
-#include "pico_udp.h"
-#include "pico_tcp.h"
-#include "pico_socket.h"
-#include "pico_device.h"
-#include "pico_nat.h"
-#include "pico_igmp.h"
-#include "pico_tree.h"
-
-#ifdef PICO_SUPPORT_IPV4
-
-#ifdef PICO_SUPPORT_MCAST
-# define ip_mcast_dbg(...) do{}while(0) /* so_mcast_dbg in pico_socket.c */
-# define PICO_MCAST_ALL_HOSTS long_be(0xE0000001) /* 224.0.0.1 */
-/* Default network interface for multicast transmission */
-static struct pico_ipv4_link *mcast_default_link = NULL;
-#endif
-#ifdef PICO_SUPPORT_IPFRAG
-# define reassembly_dbg(...) do{}while(0) 
-#endif
-
-/* Queues */
-static struct pico_queue in = {};
-static struct pico_queue out = {};
-
-/* Functions */
-static int ipv4_route_compare(void *ka, void * kb);
-
-int pico_ipv4_to_string(char *ipbuf, const uint32_t ip)
-{
-  const unsigned char *addr = (unsigned char *) &ip;
-  int i;
-
-  if (!ipbuf) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  for(i = 0; i < 4; i++)
-  {
-    if(addr[i] > 99){
-      *ipbuf++ = '0' + (addr[i] / 100);
-      *ipbuf++ = '0' + ((addr[i] % 100) / 10);
-      *ipbuf++ = '0' + ((addr[i] % 100) % 10);
-    }else if(addr[i] > 9){
-      *ipbuf++ = '0' + (addr[i] / 10);
-      *ipbuf++ = '0' + (addr[i] % 10);
-    }else{
-      *ipbuf++ = '0' + addr[i];
-    }
-    if(i < 3)
-      *ipbuf++ = '.';
-  }
-  *ipbuf = '\0';
-  
-  return 0;
-}
-    
-int pico_string_to_ipv4(const char *ipstr, uint32_t *ip)
-{
-  unsigned char buf[4] = {0};
-  int cnt = 0;
-  int p;
-
-  if(!ipstr || !ip) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  while((p = *ipstr++) != 0)
-  {
-    if(pico_is_digit(p)){
-      buf[cnt] = (10 * buf[cnt]) + (p - '0');
-    }else if(p == '.'){
-        cnt++;
-    }else{
-      return -1;
-    }
-  }   
-  
-  /* Handle short notation */
-  if(cnt == 1){
-    buf[3] = buf[1];
-    buf[1] = 0;
-    buf[2] = 0;
-  }else if (cnt == 2){
-    buf[3] = buf[2];
-    buf[2] = 0;
-  }else if(cnt != 3){
-    /* String could not be parsed, return error */
-    return -1;
-  }   
-
-  *ip = long_from(buf);
-
-  return 0;
-
-}  
-
-int pico_ipv4_valid_netmask(uint32_t mask)
-{
-  int cnt = 0;
-  int end = 0;
-  int i;
-  uint32_t mask_swap = long_be(mask);
-
-  /* 
-   * Swap bytes for convenient parsing 
-   * e.g. 0x..f8ff will become 0xfff8..
-   * Then, we count the consecutive bits
-   *
-   * */
-
-  for(i = 0; i < 32; i++){
-    if((mask_swap << i) & (1 << 31)){
-      if(end) {
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-      }
-      cnt++;
-    }else{
-      end = 1;
-    }        
-  }
-  return cnt;
-}
-
-int pico_ipv4_is_unicast(uint32_t address) 
-{
-  const unsigned char *addr = (unsigned char *) &address;
-  if((addr[0] & 0xe0) == 0xe0)
-    return 0; /* multicast */
-    
-  return 1;
-}
-
-int pico_ipv4_is_multicast(uint32_t address) 
-{
-  const unsigned char *addr = (unsigned char *) &address;
-  if((addr[0] != 0xff) && ((addr[0] & 0xe0) == 0xe0))
-    return 1; /* multicast */
-    
-  return 0;
-}
-
-static int pico_ipv4_checksum(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  if (!hdr)
-    return -1;
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_checksum(hdr, f->net_len));
-  return 0;
-}
-
-#ifdef PICO_SUPPORT_IPFRAG
-struct pico_ipv4_fragmented_packet {
-  uint16_t id;
-  uint8_t proto;
-  struct pico_ip4 src;
-  struct pico_ip4 dst;
-  uint16_t total_len;
-  struct pico_tree *t;
-};
-
-static int pico_ipv4_fragmented_packet_cmp(void *ka, void *kb)
-{
-  struct pico_ipv4_fragmented_packet *a = ka, *b = kb;
-
-  if (a->id < b->id)
-    return -1; 
-  else if (a->id > b->id)
-    return 1;
-  else {
-    if (a->proto < b->proto)
-      return -1;
-    else if (a->proto > b->proto)
-      return 1;
-    else {
-      if (a->src.addr < b->src.addr)
-        return -1;
-      else if (a->src.addr > b->src.addr)
-        return 1;
-      else {
-        if (a->dst.addr < b->dst.addr)
-          return -1;
-        else if (a->dst.addr > b->dst.addr)
-          return 1;
-        else
-          return 0;
-      }
-    }
-  }
-} 
-
-static int pico_ipv4_fragmented_element_cmp(void *ka, void *kb)
-{
-  struct pico_frame *frame_a = ka, *frame_b = kb;
-  struct pico_ipv4_hdr *a, *b;
-  a = (struct pico_ipv4_hdr *) frame_a->net_hdr;
-  b = (struct pico_ipv4_hdr *) frame_b->net_hdr;
-
-  if (short_be((a->frag & PICO_IPV4_FRAG_MASK)) < short_be((b->frag & PICO_IPV4_FRAG_MASK)))
-    return -1; 
-  else if (short_be((a->frag & PICO_IPV4_FRAG_MASK)) > short_be((b->frag & PICO_IPV4_FRAG_MASK)))
-    return 1;
-  else
-    return 0;
-} 
-    
-PICO_TREE_DECLARE(pico_ipv4_fragmented_tree, pico_ipv4_fragmented_packet_cmp);
-
-static inline void pico_ipv4_fragmented_cleanup(struct pico_ipv4_fragmented_packet *pfrag)
-{
-  struct pico_tree_node *index = NULL, *_tmp = NULL;
-  struct pico_frame *f_frag = NULL;
-
-  pico_tree_foreach_safe(index, pfrag->t, _tmp) {
-    f_frag = index->keyValue;
-    reassembly_dbg("REASSEMBLY: remove packet with offset %u\n", short_be(((struct pico_ipv4_hdr *)f_frag->net_hdr)->frag) & PICO_IPV4_FRAG_MASK);
-    pico_tree_delete(pfrag->t, f_frag);
-    pico_frame_discard(f_frag);
-  }
-  pico_tree_delete(&pico_ipv4_fragmented_tree, pfrag);
-  pico_free(pfrag->t);
-  pico_free(pfrag);
-}
-#endif /* PICO_SUPPORT_IPFRAG */
-
-#ifdef PICO_SUPPORT_IPFRAG
-static inline int pico_ipv4_fragmented_check(struct pico_protocol *self, struct pico_frame **f)
-{
-  uint8_t *running_pointer = NULL;
-  uint16_t running_offset = 0;
-  uint16_t offset = 0;
-  uint16_t data_len = 0;
-  struct pico_ipv4_hdr *f_frag_hdr = NULL, *hdr = (struct pico_ipv4_hdr *) (*f)->net_hdr;
-  struct pico_udp_hdr *udp_hdr = NULL;
-  struct pico_tcp_hdr *tcp_hdr = NULL;
-  struct pico_ipv4_fragmented_packet *pfrag = NULL, frag; 
-  struct pico_frame *f_new = NULL, *f_frag = NULL;
-  struct pico_tree_node *index, *_tmp;
-
-  data_len = short_be(hdr->len) - (*f)->net_len;
-  offset = short_be(hdr->frag) & PICO_IPV4_FRAG_MASK;
-  if (short_be(hdr->frag) & PICO_IPV4_MOREFRAG) {
-    if (!offset) {
-      reassembly_dbg("REASSEMBLY: first element of a fragmented packet with id %X and offset %u\n", short_be(hdr->id), offset);
-      if (!pico_tree_empty(&pico_ipv4_fragmented_tree)) {
-        reassembly_dbg("REASSEMBLY: cleanup tree\n");
-        // only one entry allowed in this tree
-        pfrag = pico_tree_first(&pico_ipv4_fragmented_tree);
-        pico_ipv4_fragmented_cleanup(pfrag);
-      }
-      // add entry in tree for this ID and create secondary tree to contain fragmented elements
-      pfrag = pico_zalloc(sizeof(struct pico_ipv4_fragmented_packet));
-      if (!pfrag) {
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-      }
-      pfrag->id = short_be(hdr->id);
-      pfrag->proto = hdr->proto;
-      pfrag->src.addr = long_be(hdr->src.addr);
-      pfrag->dst.addr = long_be(hdr->dst.addr);
-      pfrag->total_len = short_be(hdr->len) - (*f)->net_len;
-      pfrag->t = pico_zalloc(sizeof(struct pico_tree));
-      if (!pfrag->t) {
-        pico_free(pfrag);
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-      }
-      pfrag->t->root = &LEAF;
-      pfrag->t->compare = pico_ipv4_fragmented_element_cmp;
-       
-      pico_tree_insert(pfrag->t, *f);
-      pico_tree_insert(&pico_ipv4_fragmented_tree, pfrag);
-      return 0;
-    }
-    else {
-      reassembly_dbg("REASSEMBLY: intermediate element of a fragmented packet with id %X and offset %u\n", short_be(hdr->id), offset);
-      frag.id = short_be(hdr->id);
-      frag.proto = hdr->proto;
-      frag.src.addr = long_be(hdr->src.addr);
-      frag.dst.addr = long_be(hdr->dst.addr);
-      pfrag = pico_tree_findKey(&pico_ipv4_fragmented_tree, &frag);
-      if (pfrag) {
-        pfrag->total_len += (short_be(hdr->len) - (*f)->net_len);
-        pico_tree_insert(pfrag->t, *f);
-        return 0;
-      } else {
-        reassembly_dbg("REASSEMBLY: silently discard intermediate frame, first packet was lost or disallowed (one fragmented packet at a time)\n");
-        pico_frame_discard(*f);
-        return 0;
-      }
-    }
-  } else if (offset) {
-    reassembly_dbg("REASSEMBLY: last element of a fragmented packet with id %X and offset %u\n", short_be(hdr->id), offset);
-    frag.id = short_be(hdr->id);
-    frag.proto = hdr->proto;
-    frag.src.addr = long_be(hdr->src.addr);
-    frag.dst.addr = long_be(hdr->dst.addr);
-    pfrag = pico_tree_findKey(&pico_ipv4_fragmented_tree, &frag);
-    if (pfrag) {
-      pfrag->total_len += (short_be(hdr->len) - (*f)->net_len);
-      reassembly_dbg("REASSEMBLY: fragmented packet in tree, reassemble packet of %u data bytes\n", pfrag->total_len);
-      f_new = self->alloc(self, pfrag->total_len);
-
-      f_frag = pico_tree_first(pfrag->t);
-      reassembly_dbg("REASSEMBLY: copy IP header information len = %lu\n", f_frag->net_len);
-      f_frag_hdr = (struct pico_ipv4_hdr *)f_frag->net_hdr;
-      data_len = short_be(f_frag_hdr->len) - f_frag->net_len; 
-      memcpy(f_new->net_hdr, f_frag->net_hdr, f_frag->net_len);
-      memcpy(f_new->transport_hdr, f_frag->transport_hdr, data_len);
-      running_pointer = f_new->transport_hdr + data_len;
-      offset = short_be(f_frag_hdr->frag) & PICO_IPV4_FRAG_MASK;
-      running_offset = data_len / 8;
-      pico_tree_delete(pfrag->t, f_frag);
-      pico_frame_discard(f_frag);
-      reassembly_dbg("REASSEMBLY: reassembled first packet of %u data bytes, offset = %u next expected offset = %u\n", data_len, offset, running_offset);
-
-      pico_tree_foreach_safe(index, pfrag->t, _tmp)
-      {
-        f_frag = index->keyValue;
-        f_frag_hdr = (struct pico_ipv4_hdr *)f_frag->net_hdr;
-        data_len = short_be(f_frag_hdr->len) - f_frag->net_len; 
-        memcpy(running_pointer, f_frag->transport_hdr, data_len);
-        running_pointer += data_len;
-        offset = short_be(f_frag_hdr->frag) & PICO_IPV4_FRAG_MASK;
-        if (offset != running_offset) {
-          reassembly_dbg("REASSEMBLY: error reassembling intermediate packet: offset %u != expected offset %u (missing fragment)\n", offset, running_offset);
-          pico_ipv4_fragmented_cleanup(pfrag);
-          return -1;
-        }
-        running_offset += (data_len / 8);
-        pico_tree_delete(pfrag->t, f_frag);
-        pico_frame_discard(f_frag);
-        reassembly_dbg("REASSEMBLY: reassembled intermediate packet of %u data bytes, offset = %u next expected offset = %u\n", data_len, offset, running_offset);
-      }
-      pico_tree_delete(&pico_ipv4_fragmented_tree, pfrag);
-      pico_free(pfrag);
-
-      data_len = short_be(hdr->len) - (*f)->net_len;
-      memcpy(running_pointer, (*f)->transport_hdr, data_len);
-      offset = short_be(hdr->frag) & PICO_IPV4_FRAG_MASK;
-      pico_frame_discard(*f);
-      reassembly_dbg("REASSEMBLY: reassembled last packet of %u data bytes, offset = %u\n", data_len, offset);
-      
-      hdr = (struct pico_ipv4_hdr *)f_new->net_hdr;
-      hdr->len = pfrag->total_len;
-      hdr->frag = 0; /* flags cleared and no offset */
-      hdr->crc = 0;
-      hdr->crc = short_be(pico_checksum(hdr, f_new->net_len));
-      /* Optional, the UDP/TCP CRC should already be correct */
-      if (0) {
-  #ifdef PICO_SUPPORT_TCP
-      } else if (hdr->proto == PICO_PROTO_TCP) {
-        tcp_hdr = (struct pico_tcp_hdr *) f_new->transport_hdr;
-        tcp_hdr->crc = 0;
-        tcp_hdr->crc = short_be(pico_tcp_checksum_ipv4(f_new));
-  #endif
-  #ifdef PICO_SUPPORT_UDP
-      } else if (hdr->proto == PICO_PROTO_UDP){
-        udp_hdr = (struct pico_udp_hdr *) f_new->transport_hdr;
-        udp_hdr->crc = 0;
-        udp_hdr->crc = short_be(pico_udp_checksum_ipv4(f_new));
-  #endif
-      }
-      reassembly_dbg("REASSEMBLY: packet with id %X reassembled correctly\n", short_be(hdr->id));
-      *f = f_new;
-      return 1;
-    } else {
-      reassembly_dbg("REASSEMBLY: silently discard last frame, first packet was lost or disallowed (one fragmented packet at a time)\n");
-      pico_frame_discard(*f);
-      return 0;
-    }
-  } else {
-    return 1;
-  }
-}
-#else
-static inline int pico_ipv4_fragmented_check(struct pico_protocol *self, struct pico_frame **f)
-{
-  return 1;
-}
-#endif /* PICO_SUPPORT_IPFRAG */
-
-#ifdef PICO_SUPPORT_CRC
-static inline int pico_ipv4_crc_check(struct pico_frame *f)
-{
-  uint16_t checksum_invalid = 1;
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-
-  checksum_invalid = short_be(pico_checksum(hdr, f->net_len));
-  if (checksum_invalid) {
-    dbg("IP: checksum failed!\n");
-    pico_frame_discard(f);
-    return 0;
-  }
-  return 1;
-}
-#else
-static inline int pico_ipv4_crc_check(struct pico_frame *f)
-{
-  return 1;
-}
-#endif /* PICO_SUPPORT_CRC */
-
-static int pico_ipv4_forward(struct pico_frame *f);
-#ifdef PICO_SUPPORT_MCAST
-static int pico_ipv4_mcast_filter(struct pico_frame *f);
-#endif
-
-static int ipv4_link_compare(void *ka, void *kb)
-{
-  struct pico_ipv4_link *a = ka, *b =kb;
-  if (a->address.addr < b->address.addr)
-    return -1;
-  if (a->address.addr > b->address.addr)
-    return 1;
-
-  //zero can be assigned multiple times (e.g. for DHCP)
-  if (a->dev != NULL && b->dev != NULL && a->address.addr == PICO_IP4_ANY && b->address.addr == PICO_IP4_ANY){
-    if (a->dev < b->dev)
-      return -1;
-    if (a->dev > b->dev)
-      return 1;
-  }
-  return 0;
-}
-
-PICO_TREE_DECLARE(Tree_dev_link, ipv4_link_compare);
-
-static int pico_ipv4_process_in(struct pico_protocol *self, struct pico_frame *f)
-{
-  uint8_t option_len = 0;
-  int ret = 0;
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_ipv4_link test = {.address = {.addr = PICO_IP4_ANY}, .dev = NULL};
-
-  /* NAT needs transport header information */
-  if(((hdr->vhl) & 0x0F )> 5){
-     option_len =  4*(((hdr->vhl) & 0x0F)-5);
-  }
-  f->transport_hdr = ((uint8_t *)f->net_hdr) + PICO_SIZE_IP4HDR + option_len;
-  f->transport_len = short_be(hdr->len) - PICO_SIZE_IP4HDR - option_len;
-  f->net_len = PICO_SIZE_IP4HDR + option_len;
-
-#ifdef PICO_SUPPORT_IPFILTER
-  if (ipfilter(f)) {
-    /*pico_frame is discarded as result of the filtering*/
-    return 0;
-  }
-#endif
-
-  /* ret == 1 indicates to continue the function */
-  ret = pico_ipv4_crc_check(f);
-  if (ret < 1)
-    return ret;
-  ret = pico_ipv4_fragmented_check(self, &f);
-  if (ret < 1)
-    return ret;
-
-#ifdef PICO_SUPPORT_MCAST
-  /* Multicast address in source, discard quietly */
-  if (pico_ipv4_is_multicast(hdr->src.addr)) {
-    ip_mcast_dbg("MCAST: ERROR multicast address %08X in source address\n", hdr->src.addr);
-    pico_frame_discard(f);
-    return 0;
-  }
-#endif
-  if (hdr->frag & 0x80) {
-    pico_frame_discard(f); //RFC 3514
-    return 0;
-  }
-  if (0) {
-#ifdef PICO_SUPPORT_UDP
-  } else if (pico_ipv4_is_broadcast(hdr->dst.addr) && (hdr->proto == PICO_PROTO_UDP)) {
-      /* Receiving UDP broadcast datagram */
-      f->flags |= PICO_FRAME_FLAG_BCAST;
-      pico_enqueue(pico_proto_udp.q_in, f);
-#endif
-  } else if (pico_ipv4_is_multicast(hdr->dst.addr)) {
-#ifdef PICO_SUPPORT_MCAST
-    /* Receiving UDP multicast datagram TODO set f->flags? */
-    if (hdr->proto == PICO_PROTO_IGMP) {
-      ip_mcast_dbg("MCAST: received IGMP message\n");
-      pico_transport_receive(f, PICO_PROTO_IGMP);
-    } else if ((pico_ipv4_mcast_filter(f) == 0) && (hdr->proto == PICO_PROTO_UDP)) {
-      pico_enqueue(pico_proto_udp.q_in, f);
-    } else {
-      pico_frame_discard(f);
-    }
-#endif
-  } else if (pico_ipv4_link_find(&hdr->dst)) {
-   if (pico_ipv4_nat_isenabled_in(f) == 0) {  /* if NAT enabled (dst port registerd), do NAT */
-      if(pico_ipv4_nat(f, hdr->dst) != 0) {
-        return -1;
-      }
-      pico_ipv4_forward(f); /* Local packet became forward packet after NAT */
-    } else {                              /* no NAT so enqueue to next layer */
-      pico_transport_receive(f, hdr->proto);
-    }
-  } else if (pico_tree_findKey(&Tree_dev_link, &test)){
-#ifdef PICO_SUPPORT_UDP
-    //address of this device is apparently 0.0.0.0; might be a DHCP packet
-    pico_enqueue(pico_proto_udp.q_in, f);
-#endif
-  } else {
-    /* Packet is not local. Try to forward. */
-    if (pico_ipv4_forward(f) != 0) {
-      pico_frame_discard(f);
-    }
-  }
-  return 0;
-}
-
-PICO_TREE_DECLARE(Routes, ipv4_route_compare);
-
-
-static int pico_ipv4_process_out(struct pico_protocol *self, struct pico_frame *f)
-{
-  f->start = (uint8_t*) f->net_hdr;
-  #ifdef PICO_SUPPORT_IPFILTER
-  if (ipfilter(f)) {
-    /*pico_frame is discarded as result of the filtering*/
-    return 0;
-  }
-  #endif
-  return pico_sendto_dev(f);
-}
-
-
-static struct pico_frame *pico_ipv4_alloc(struct pico_protocol *self, int size)
-{
-  struct pico_frame *f =  pico_frame_alloc(size + PICO_SIZE_IP4HDR + PICO_SIZE_ETHHDR);
-  if (!f)
-    return NULL;
-  f->datalink_hdr = f->buffer;
-  f->net_hdr = f->buffer + PICO_SIZE_ETHHDR;
-  f->net_len = PICO_SIZE_IP4HDR;
-  f->transport_hdr = f->net_hdr + PICO_SIZE_IP4HDR;
-  f->transport_len = size;
-  f->len =  size + PICO_SIZE_IP4HDR;
-  return f;
-}
-
-static int pico_ipv4_frame_sock_push(struct pico_protocol *self, struct pico_frame *f);
-
-/* Interface: protocol definition */
-struct pico_protocol pico_proto_ipv4 = {
-  .name = "ipv4",
-  .proto_number = PICO_PROTO_IPV4,
-  .layer = PICO_LAYER_NETWORK,
-  .alloc = pico_ipv4_alloc,
-  .process_in = pico_ipv4_process_in,
-  .process_out = pico_ipv4_process_out,
-  .push = pico_ipv4_frame_sock_push,
-  .q_in = &in,
-  .q_out = &out,
-};
-
-struct pico_ipv4_route
-{
-  struct pico_ip4 dest;
-  struct pico_ip4 netmask;
-  struct pico_ip4 gateway;
-  struct pico_ipv4_link *link;
-  uint32_t metric;
-};
-
-
-static int ipv4_route_compare(void *ka, void * kb)
-{
-  struct pico_ipv4_route *a = ka, *b = kb;
-
-  /* Routes are sorted by (host side) netmask len, then by addr, then by metric. */
-  if (long_be(a->netmask.addr) < long_be(b->netmask.addr))
-    return -1;
-
-  if (long_be(a->netmask.addr) > long_be(b->netmask.addr))
-    return 1;
-
-  if (a->dest.addr < b->dest.addr)
-    return -1;
-
-  if (a->dest.addr > b->dest.addr)
-    return 1;
-
-  if (a->metric < b->metric)
-    return -1;
-
-  if (a->metric > b->metric)
-    return 1;
-
-  return 0;
-}
-
-static struct pico_ipv4_route *route_find(struct pico_ip4 *addr)
-{
-  struct pico_ipv4_route *r;
-  struct pico_tree_node * index;
-
-  if(addr->addr != PICO_IP4_BCAST)
-  {
-    pico_tree_foreach_reverse(index, &Routes) {
-      r = index->keyValue;
-      if ((addr->addr & (r->netmask.addr)) == (r->dest.addr)) {
-        return r;
-      }
-    }
-  }
-  else
-  {
-    r = pico_tree_first(&Routes);
-    if(!r->netmask.addr)
-    {
-      return r;
-    }
-    else
-    {
-      dbg("WARNING: no default route for a global broadcast found\n");
-    }
-  }
-
-  return NULL;
-}
-
-struct pico_ip4 pico_ipv4_route_get_gateway(struct pico_ip4 *addr)
-{
-  struct pico_ip4 nullip;
-  struct pico_ipv4_route *route;
-  nullip.addr = 0U;
-
-  if(!addr) {
-    pico_err = PICO_ERR_EINVAL;
-    return nullip;
-  }
-
-  route = route_find(addr);
-  if (!route) {
-    pico_err = PICO_ERR_EHOSTUNREACH;
-    return nullip;
-  }
-  else
-    return route->gateway;
-}
-
-struct pico_ip4 *pico_ipv4_source_find(struct pico_ip4 *dst)
-{
-  struct pico_ip4 *myself = NULL;
-  struct pico_ipv4_route *rt;
-
-  if(!dst) {
-    pico_err = PICO_ERR_EINVAL;
-    return NULL;
-  }
-
-  rt = route_find(dst);
-  if (rt) {
-    myself = &rt->link->address;
-  } else
-    pico_err = PICO_ERR_EHOSTUNREACH;
-  return myself;
-}
-
-
-#ifdef PICO_SUPPORT_MCAST
-/*                        link
- *                         |  
- *                    MCASTGroups
- *                    |    |     |
- *         ------------    |     ------------
- *         |               |                |
- *   MCASTSources    MCASTSources     MCASTSources    
- *   |  |  |  |      |  |  |  |       |  |  |  |
- *   S  S  S  S      S  S  S  S       S  S  S  S
- *
- *   MCASTGroups: RBTree(mcast_group)
- *   MCASTSources: RBTree(source)
- */
-static int ipv4_mcast_groups_cmp(void * ka, void * kb)
-{
-  struct pico_mcast_group *a = ka, *b = kb;
-  if (a->mcast_addr.addr < b->mcast_addr.addr) {
-    return -1;
-  } else if (a->mcast_addr.addr > b->mcast_addr.addr) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-static int ipv4_mcast_sources_cmp(void *ka, void *kb)
-{
-  struct pico_ip4 *a = ka, *b = kb;
-  if (a->addr < b->addr)
-    return -1;
-  if (a->addr > b->addr)
-    return 1;
-  return 0;
-}
-
-static void pico_ipv4_mcast_print_groups(struct pico_ipv4_link *mcast_link)
-{
-  uint16_t i = 0;
-  struct pico_mcast_group __attribute__ ((unused)) *g = NULL;
-  struct pico_ip4 __attribute__ ((unused)) *source = NULL;
-  struct pico_tree_node *index = NULL, *index2 = NULL;
-
-  ip_mcast_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-  ip_mcast_dbg("+                           MULTICAST list interface %-16s             +\n", mcast_link->dev->name);
-  ip_mcast_dbg("+---------------------------------------------------------------------------------+\n");
-  ip_mcast_dbg("+  nr  |    interface     | host group | reference count | filter mode |  source  +\n");
-  ip_mcast_dbg("+---------------------------------------------------------------------------------+\n");
-
-  pico_tree_foreach(index, mcast_link->MCASTGroups)
-  {
-    g = index->keyValue;
-    ip_mcast_dbg("+ %04d | %16s |  %08X  |      %05u      |      %u      | %8s +\n", i, mcast_link->dev->name, g->mcast_addr.addr, g->reference_count, g->filter_mode, "");
-    pico_tree_foreach(index2, &g->MCASTSources)
-    {
-      source = index2->keyValue;
-      ip_mcast_dbg("+ %4s | %16s |  %8s  |      %5s      |      %s      | %08X +\n", "", "", "", "", "", source->addr);
-    }
-    i++;
-  }
-  ip_mcast_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-}
-
-int pico_ipv4_mcast_join(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter)
-{
-  struct pico_mcast_group *g = NULL, test = {0};
-  struct pico_ipv4_link *link = NULL;
-  struct pico_tree_node *index = NULL, *_tmp = NULL;
-  struct pico_ip4 *source = NULL;
-
-  if (mcast_link)
-    link = pico_ipv4_link_get(mcast_link);
-  else
-    link = mcast_default_link;
-
-  test.mcast_addr = *mcast_group;
-  g = pico_tree_findKey(link->MCASTGroups, &test);
-  if (g) {
-    if (reference_count)
-      g->reference_count++;
-    pico_igmp_state_change(mcast_link, mcast_group, filter_mode, MCASTFilter, PICO_IGMP_STATE_UPDATE);
-  } else {
-    g = pico_zalloc(sizeof(struct pico_mcast_group));
-    if (!g) {
-      pico_err = PICO_ERR_ENOMEM;
-      return -1;
-    }
-    /* "non-existent" state of filter mode INCLUDE and empty source list */
-    g->filter_mode = PICO_IP_MULTICAST_INCLUDE;
-    g->reference_count = 1;
-    g->mcast_addr = *mcast_group;
-    g->MCASTSources.root = &LEAF;
-    g->MCASTSources.compare = ipv4_mcast_sources_cmp;
-    pico_tree_insert(link->MCASTGroups, g);
-    pico_igmp_state_change(mcast_link, mcast_group, filter_mode, MCASTFilter, PICO_IGMP_STATE_CREATE);
-  }
-
-  /* cleanup filter */
-  pico_tree_foreach_safe(index, &g->MCASTSources, _tmp)
-  {
-    source = index->keyValue;
-    pico_tree_delete(&g->MCASTSources, source);
-    pico_free(source);
-  }
-  /* insert new filter */
-  if (MCASTFilter) {
-    pico_tree_foreach(index, MCASTFilter)
-    {
-      source = pico_zalloc(sizeof(struct pico_ip4));
-      if (!source) {
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-      }
-      source->addr = ((struct pico_ip4 *)index->keyValue)->addr;
-      pico_tree_insert(&g->MCASTSources, source);
-    }
-  }
-  g->filter_mode = filter_mode;
-
-  pico_ipv4_mcast_print_groups(link);
-  return 0;
-}
-
-int pico_ipv4_mcast_leave(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter)
-{
-
-  struct pico_mcast_group *g = NULL, test = {0};
-  struct pico_ipv4_link *link = NULL;
-  struct pico_tree_node *index = NULL, *_tmp = NULL;
-  struct pico_ip4 *source = NULL;
-
-  if (mcast_link)
-    link = pico_ipv4_link_get(mcast_link);
-  else
-    link = mcast_default_link;
-
-  test.mcast_addr = *mcast_group;
-  g = pico_tree_findKey(link->MCASTGroups, &test);
-  if (!g) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    if (reference_count && (--(g->reference_count) < 1)) {
-      pico_igmp_state_change(mcast_link, mcast_group, filter_mode, MCASTFilter, PICO_IGMP_STATE_DELETE);
-      /* cleanup filter */
-      pico_tree_foreach_safe(index, &g->MCASTSources, _tmp)
-      {
-        source = index->keyValue;
-        pico_tree_delete(&g->MCASTSources, source);
-        pico_free(source);
-      }
-      pico_tree_delete(link->MCASTGroups, g);
-      pico_free(g); 
-    } else {
-      pico_igmp_state_change(mcast_link, mcast_group, filter_mode, MCASTFilter, PICO_IGMP_STATE_UPDATE);
-      /* cleanup filter */
-      pico_tree_foreach_safe(index, &g->MCASTSources, _tmp)
-      {
-        source = index->keyValue;
-        pico_tree_delete(&g->MCASTSources, source);
-        pico_free(source);
-      }
-      /* insert new filter */
-      if (MCASTFilter) {
-        pico_tree_foreach(index, MCASTFilter)
-        {
-          source = pico_zalloc(sizeof(struct pico_ip4));
-          if (!source) {
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          source->addr = ((struct pico_ip4 *)index->keyValue)->addr;
-          pico_tree_insert(&g->MCASTSources, source);
-        }
-      }
-      g->filter_mode = filter_mode;
-    }
-  }
-
-  pico_ipv4_mcast_print_groups(link);
-  return 0;
-}
-
-struct pico_ipv4_link *pico_ipv4_get_default_mcastlink(void)
-{
-  return mcast_default_link;
-}
-
-static int pico_ipv4_mcast_filter(struct pico_frame *f)
-{
-  struct pico_ipv4_link *link = NULL;
-  struct pico_tree_node *index = NULL, *index2 = NULL;
-  struct pico_mcast_group *g = NULL, test = {0};
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-
-  test.mcast_addr = hdr->dst; 
-
-  pico_tree_foreach(index, &Tree_dev_link) 
-  {
-    link = index->keyValue;
-    g = pico_tree_findKey(link->MCASTGroups, &test);
-    if (g) {
-      if (f->dev == link->dev) {
-        ip_mcast_dbg("MCAST: IP %08X is group member of current link %s\n", hdr->dst.addr, f->dev->name);
-        /* perform source filtering */
-        switch (g->filter_mode)
-        {
-          case PICO_IP_MULTICAST_INCLUDE:
-            pico_tree_foreach(index2, &g->MCASTSources)
-            {
-              if (hdr->src.addr == ((struct pico_ip4 *)index2->keyValue)->addr) {
-                ip_mcast_dbg("MCAST: IP %08X in included interface source list\n", hdr->src.addr);
-                return 0;
-              }
-            }
-            ip_mcast_dbg("MCAST: IP %08X NOT in included interface source list\n", hdr->src.addr);
-            return -1;
-            break;
-
-          case PICO_IP_MULTICAST_EXCLUDE:
-            pico_tree_foreach(index2, &g->MCASTSources)
-            {
-              if (hdr->src.addr == ((struct pico_ip4 *)index2->keyValue)->addr) {
-                ip_mcast_dbg("MCAST: IP %08X in excluded interface source list\n", hdr->src.addr);
-                return -1;
-              }
-            }
-            ip_mcast_dbg("MCAST: IP %08X NOT in excluded interface source list\n", hdr->src.addr);
-            return 0;
-            break;
-
-          default:
-            return -1;
-            break;
-        }
-      } else {
-        ip_mcast_dbg("MCAST: IP %08X is group member of different link %s\n", hdr->dst.addr, link->dev->name);
-      }
-    } else {
-      ip_mcast_dbg("MCAST: IP %08X is not a group member of link %s\n", hdr->dst.addr, f->dev->name);
-    }
-  }
-  return -1;
-}
-
-#else 
-
-int pico_ipv4_mcast_join(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-int pico_ipv4_mcast_leave(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-struct pico_ipv4_link *pico_ipv4_get_default_mcastlink(void)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return NULL;
-}
-#endif /* PICO_SUPPORT_MCAST */
-
-int pico_ipv4_frame_push(struct pico_frame *f, struct pico_ip4 *dst, uint8_t proto)
-{
-
-  struct pico_ipv4_route *route;
-  struct pico_ipv4_link *link;
-  struct pico_ipv4_hdr *hdr;
-  uint8_t ttl = PICO_IPV4_DEFAULT_TTL;
-  uint8_t vhl = 0x45; /* version 4, header length 20 */
-  static uint16_t ipv4_progressive_id = 0x91c0;
-#ifdef PICO_SUPPORT_MCAST
-  struct pico_tree_node *index;
-#endif
-
-  if(!f || !dst) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  if (!hdr) {
-    dbg("IP header error\n");
-    pico_err = PICO_ERR_EINVAL;
-    goto drop;
-  }
-
-  if (dst->addr == 0) {
-    dbg("IP destination addr error\n");
-    pico_err = PICO_ERR_EINVAL;
-    goto drop;
-  }
-
-  route = route_find(dst);
-  if (!route) {
-    dbg("Route to %08x not found.\n", long_be(dst->addr));
-    pico_err = PICO_ERR_EHOSTUNREACH;
-    goto drop;
-  } else {
-    link = route->link;
-#ifdef PICO_SUPPORT_MCAST
-    if (pico_ipv4_is_multicast(dst->addr)) { /* if multicast */
-      switch (proto) {
-        case PICO_PROTO_UDP:
-          if(pico_udp_get_mc_ttl(f->sock, &ttl) < 0)
-            ttl = PICO_IP_DEFAULT_MULTICAST_TTL;
-          break;
-        case PICO_PROTO_IGMP:
-          vhl = 0x46; /* header length 24 */
-          ttl = 1;
-          /* router alert (RFC 2113) */ 
-          hdr->options[0] = 0x94;
-          hdr->options[1] = 0x04;
-          hdr->options[2] = 0x00;
-          hdr->options[3] = 0x00;
-          if (f->dev && link->dev != f->dev) { /* default link is not requested link */
-            pico_tree_foreach(index, &Tree_dev_link) {
-              link = index->keyValue;
-              if (link->dev == f->dev)
-                break;
-            }
-          }
-          break;
-        default:
-          ttl = PICO_IPV4_DEFAULT_TTL;
-      }
-    }
-#endif
-  }
-
-  hdr->vhl = vhl;
-  hdr->len = short_be(f->transport_len + f->net_len);
-  if (f->transport_hdr != f->payload)
-    ipv4_progressive_id++;
-  hdr->id = short_be(ipv4_progressive_id);
-  hdr->dst.addr = dst->addr;
-  hdr->src.addr = link->address.addr;
-  hdr->ttl = ttl;
-  hdr->proto = proto;
-  hdr->frag = short_be(PICO_IPV4_DONTFRAG);
-#ifdef PICO_SUPPORT_IPFRAG
-#  ifdef PICO_SUPPORT_UDP
-  if (proto == PICO_PROTO_UDP) {
-    /* first fragment, can not use transport_len to calculate IP length */
-    if (f->transport_hdr != f->payload)
-      hdr->len = short_be(f->payload_len + sizeof(struct pico_udp_hdr) + f->net_len);
-    /* set fragmentation flags and offset calculated in socket layer */
-    hdr->frag = f->frag;
-  }
-#  endif /* PICO_SUPPORT_UDP */
-#endif /* PICO_SUPPORT_IPFRAG */
-  pico_ipv4_checksum(f);
-
-  if (f->sock && f->sock->dev){
-    //if the socket has its device set, use that (currently used for DHCP)
-    f->dev = f->sock->dev;
-  } else {
-    f->dev = link->dev;
-  }
-
-#ifdef PICO_SUPPORT_MCAST
-  if (pico_ipv4_is_multicast(hdr->dst.addr)) {
-    struct pico_frame *cpy;
-    /* Sending UDP multicast datagram, am I member? If so, loopback copy */
-    if ((proto != PICO_PROTO_IGMP) && (pico_ipv4_mcast_filter(f) == 0)) {
-      ip_mcast_dbg("MCAST: sender is member of group, loopback copy\n");
-      cpy = pico_frame_copy(f);
-      pico_enqueue(&in, cpy);
-    }
-  }
-#endif
-
-  if(pico_ipv4_link_get(&hdr->dst)){
-    //it's our own IP
-    return pico_enqueue(&in, f);
-  }else{
-    /* TODO: Check if there are members subscribed here */
-    return pico_enqueue(&out, f);
-  }
-
-drop:
-  pico_frame_discard(f);
-  return -1;
-}
-
-
-static int pico_ipv4_frame_sock_push(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_ip4 *dst;
-  struct pico_remote_duple *remote_duple = (struct pico_remote_duple *) f->info;
-  if (!f->sock) {
-    pico_frame_discard(f);
-    return -1;
-  }
-
-  if (remote_duple) {
-    dst = &remote_duple->remote_addr.ip4;
-  } else {
-    dst = &f->sock->remote_addr.ip4;
-  }
-
-  return pico_ipv4_frame_push(f, dst, f->sock->proto->proto_number);
-}
-
-
-#ifdef DEBUG_ROUTE
-static void dbg_route(void)
-{
-  struct pico_ipv4_route *r;
-  struct pico_tree_node * index;
-  pico_tree_foreach(index,&Routes){
-    r = index->keyValue;
-    dbg("Route to %08x/%08x, gw %08x, dev: %s, metric: %d\n", r->dest.addr, r->netmask.addr, r->gateway.addr, r->link->dev->name, r->metric);
-  }
-}
-#else
-#define dbg_route() do{ }while(0)
-#endif
-
-int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
-{
-  struct pico_ipv4_route test, *new;
-  test.dest.addr = address.addr;
-  test.netmask.addr = netmask.addr;
-  test.metric = metric;
-
-  if(pico_tree_findKey(&Routes,&test)){
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  
-  new = pico_zalloc(sizeof(struct pico_ipv4_route));
-  if (!new) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  new->dest.addr = address.addr;
-  new->netmask.addr = netmask.addr;
-  new->gateway.addr = gateway.addr;
-  new->metric = metric;
-  if (gateway.addr == 0) {
-    /* No gateway provided, use the link */
-    new->link = link;
-  } else {
-    struct pico_ipv4_route *r = route_find(&gateway);
-    if (!r ) { /* Specified Gateway is unreachable */
-      pico_err = PICO_ERR_EHOSTUNREACH;
-      pico_free(new);
-      return -1;
-    }
-    if (r->gateway.addr) { /* Specified Gateway is not a neighbor */
-      pico_err = PICO_ERR_ENETUNREACH;
-      pico_free(new);
-      return -1;
-    }
-    new->link = r->link;
-  }
-  if (!new->link) {
-      pico_err = PICO_ERR_EINVAL;
-      pico_free(new);
-      return -1;
-  }
-
-  pico_tree_insert(&Routes,new);
-  dbg_route();
-  return 0;
-}
-
-int pico_ipv4_route_del(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
-{
-  struct pico_ipv4_route test, *found;
-  if (!link) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  test.dest.addr = address.addr;
-  test.netmask.addr = netmask.addr;
-  test.metric = metric;
-
-  found = pico_tree_findKey(&Routes,&test);
-  if (found) {
-
-    pico_tree_delete(&Routes,found);
-    pico_free(found);
-
-    dbg_route();
-    return 0;
-  }
-  pico_err = PICO_ERR_EINVAL;
-  return -1;
-}
-
-
-int pico_ipv4_link_add(struct pico_device *dev, struct pico_ip4 address, struct pico_ip4 netmask)
-{
-  struct pico_ipv4_link test, *new;
-  struct pico_ip4 network, gateway;
-  char ipstr[30];
-
-  if(!dev) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  test.address.addr = address.addr;
-  test.netmask.addr = netmask.addr;
-  test.dev = dev;
-  /** XXX: Valid netmask / unicast address test **/
-
-  if(pico_tree_findKey(&Tree_dev_link, &test)) {
-    dbg("IPv4: Trying to assign an invalid address (in use)\n");
-    pico_err = PICO_ERR_EADDRINUSE;
-    return -1;
-  }
-
-  /** XXX: Check for network already in use (e.g. trying to assign 10.0.0.1/24 where 10.1.0.1/8 is in use) **/
-  new = pico_zalloc(sizeof(struct pico_ipv4_link));
-  if (!new) {
-    dbg("IPv4: Out of memory!\n");
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-  new->address.addr = address.addr;
-  new->netmask.addr = netmask.addr;
-  new->dev = dev;
-#ifdef PICO_SUPPORT_MCAST
-  new->MCASTGroups = pico_zalloc(sizeof(struct pico_tree));
-  if (!new->MCASTGroups) {
-    pico_free(new);
-    dbg("IPv4: Out of memory!\n");
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-
-  new->MCASTGroups->root = &LEAF;
-  new->MCASTGroups->compare = ipv4_mcast_groups_cmp;
-  new->mcast_compatibility = PICO_IGMPV3; /* default RFC 3376 $7.2.1 */
-  new->mcast_last_query_interval = PICO_IGMP_QUERY_INTERVAL;
-#endif
-
-  pico_tree_insert(&Tree_dev_link, new);
-#ifdef PICO_SUPPORT_MCAST
-  do {
-    struct pico_ip4 mcast_all_hosts, mcast_addr, mcast_nm, mcast_gw;
-    if (!mcast_default_link) {
-      mcast_addr.addr = long_be(0xE0000000); /* 224.0.0.0 */
-      mcast_nm.addr = long_be(0xF0000000); /* 15.0.0.0 */
-      mcast_gw.addr = long_be(0x00000000);
-      mcast_default_link = new;
-      pico_ipv4_route_add(mcast_addr, mcast_nm, mcast_gw, 1, new);
-    }
-    mcast_all_hosts.addr = PICO_MCAST_ALL_HOSTS;
-    pico_ipv4_mcast_join(&address, &mcast_all_hosts, 1, PICO_IP_MULTICAST_EXCLUDE, NULL);
-  } while(0);
-#endif
-
-  network.addr = address.addr & netmask.addr;
-  gateway.addr = 0U;
-  pico_ipv4_route_add(network, netmask, gateway, 1, new);
-  pico_ipv4_to_string(ipstr, new->address.addr);
-  dbg("Assigned ipv4 %s to device %s\n", ipstr, new->dev->name);
-  return 0;
-}
-
-
-int pico_ipv4_link_del(struct pico_device *dev, struct pico_ip4 address)
-{
-  struct pico_ipv4_link test, *found;
-  struct pico_ip4 network;
-
-  if(!dev) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  test.address.addr = address.addr;
-  test.dev = dev;
-  found = pico_tree_findKey(&Tree_dev_link, &test);
-  if (!found) {
-    pico_err = PICO_ERR_ENXIO;
-    return -1;
-  }
-
-  network.addr = found->address.addr & found->netmask.addr;
-  pico_ipv4_route_del(network, found->netmask,pico_ipv4_route_get_gateway(&found->address), 1, found);
-#ifdef PICO_SUPPORT_MCAST
-  do {
-    struct pico_ip4 mcast_all_hosts, mcast_addr, mcast_nm, mcast_gw;
-    struct pico_mcast_group *g = NULL;
-    struct pico_tree_node * index, * _tmp;
-    if (found == mcast_default_link) {
-      mcast_addr.addr = long_be(0xE0000000); /* 224.0.0.0 */
-      mcast_nm.addr = long_be(0xF0000000); /* 15.0.0.0 */
-      mcast_gw.addr = long_be(0x00000000);
-      mcast_default_link = NULL;
-      pico_ipv4_route_del(mcast_addr, mcast_nm, mcast_gw, 1, found);
-    }
-    mcast_all_hosts.addr = PICO_MCAST_ALL_HOSTS;
-    pico_ipv4_mcast_leave(&address, &mcast_all_hosts, 1, PICO_IP_MULTICAST_EXCLUDE, NULL);
-    pico_tree_foreach_safe(index,found->MCASTGroups, _tmp)
-    {
-      g = index->keyValue;
-      pico_tree_delete(found->MCASTGroups, g);
-      pico_free(g);
-    }
-  } while(0);
-#endif
-
-  pico_tree_delete(&Tree_dev_link, found);
-  /* XXX: pico_free(found); */
-  /* XXX: cleanup all routes containing the removed link */
-  return 0;
-}
-
-
-struct pico_ipv4_link *pico_ipv4_link_get(struct pico_ip4 *address)
-{
-  struct pico_ipv4_link test = {0}, *found = NULL;
-  test.address.addr = address->addr;
-
-  found = pico_tree_findKey(&Tree_dev_link, &test);
-  if (!found)
-    return NULL;
-  else
-    return found;
-}
-
-struct pico_ipv4_link *pico_ipv4_link_by_dev(struct pico_device *dev)
-{
-  struct pico_tree_node *index = NULL;
-  struct pico_ipv4_link *link = NULL;
-
-  pico_tree_foreach(index, &Tree_dev_link) 
-  {
-    link = index->keyValue;
-    if (link->dev == dev)
-      return link;
-  }
-  return NULL;
-}
-
-
-struct pico_device *pico_ipv4_link_find(struct pico_ip4 *address)
-{
-  struct pico_ipv4_link test, *found;
-  if(!address) {
-    pico_err = PICO_ERR_EINVAL;
-    return NULL;
-  }
-  test.dev = NULL;
-  test.address.addr = address->addr;
-  found = pico_tree_findKey(&Tree_dev_link, &test);
-  if (!found) {
-    pico_err = PICO_ERR_ENXIO;
-    return NULL;
-  }
-  return found->dev;
-}
-
-int pico_ipv4_rebound(struct pico_frame *f)
-{
-  struct pico_ip4 dst;
-  struct pico_ipv4_hdr *hdr;
-  if(!f) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  if (!hdr) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  dst.addr = hdr->src.addr;
-  return pico_ipv4_frame_push(f, &dst, hdr->proto);
-}
-
-static int pico_ipv4_forward(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  struct pico_ipv4_route *rt;
-  if (!hdr) {
-    return -1;
-  }
-
-  //dbg("IP> FORWARDING.\n");
-  rt = route_find(&hdr->dst);
-  if (!rt) {
-    pico_notify_dest_unreachable(f);
-    return -1;
-  }
-  //dbg("ROUTE: valid..\n");
-  f->dev = rt->link->dev;
-  hdr->ttl-=1;
-  if (hdr->ttl < 1) {
-    pico_notify_ttl_expired(f);
-    return -1;
-  }
-  hdr->crc++;
-
-  /* check if NAT enbled on link and do NAT if so */
-  if (pico_ipv4_nat_isenabled_out(rt->link) == 0)
-    pico_ipv4_nat(f, rt->link->address);
-
-  //dbg("Routing towards %s\n", f->dev->name);
-  f->start = f->net_hdr;
-  if(f->dev->eth != NULL)
-    f->len -= PICO_SIZE_ETHHDR;
-  pico_sendto_dev(f);
-  return 0;
-
-}
-
-int pico_ipv4_is_broadcast(uint32_t addr)
-{
-  struct pico_ipv4_link *link;
-  struct pico_tree_node * index;
-  if (addr == PICO_IP4_ANY)
-    return 1;
-  if (addr == PICO_IP4_BCAST)
-    return 1;
-
-  pico_tree_foreach(index,&Tree_dev_link) {
-    link = index->keyValue;
-    if ((link->address.addr | (~link->netmask.addr)) == addr)
-      return 1;
-  }
-  return 0;
-}
-
-void pico_ipv4_unreachable(struct pico_frame *f, int err)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-#if defined PICO_SUPPORT_TCP || defined PICO_SUPPORT_UDP
-  f->transport_hdr = ((uint8_t *)f->net_hdr) + PICO_SIZE_IP4HDR;
-  pico_transport_error(f, hdr->proto, err);
-#endif
-}
-
-#endif
--- a/modules/pico_ipv4.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_IPV4
-#define _INCLUDE_PICO_IPV4
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-#include "pico_tree.h"
-
-#define PICO_IPV4_INADDR_ANY 0x00000000U
-
-#define PICO_SIZE_IP4HDR ((sizeof(struct pico_ipv4_hdr)))
-#define PICO_IPV4_DONTFRAG 0x4000
-#define PICO_IPV4_MOREFRAG 0x2000
-#define PICO_IPV4_FRAG_MASK 0x1FFF
-#define PICO_IPV4_DEFAULT_TTL 64
-
-extern struct pico_protocol pico_proto_ipv4;
-
-struct __attribute__((packed)) pico_ipv4_hdr {
-  uint8_t vhl;
-  uint8_t tos;
-  uint16_t len;
-  uint16_t id;
-  uint16_t frag;
-  uint8_t ttl;
-  uint8_t proto;
-  uint16_t crc;
-  struct pico_ip4 src;
-  struct pico_ip4 dst;
-  uint8_t options[0];
-};
-
-struct __attribute__((packed)) pico_ipv4_pseudo_hdr
-{
-  struct pico_ip4 src;
-  struct pico_ip4 dst;
-  uint8_t zeros;
-  uint8_t proto;
-  uint16_t len;
-};
-
-/* Interface: link to device */
-struct pico_mcast_list;
-
-struct pico_ipv4_link
-{
-  struct pico_device *dev;
-  struct pico_ip4 address;
-  struct pico_ip4 netmask;
-#ifdef PICO_SUPPORT_MCAST
-  struct pico_tree *MCASTGroups;
-  uint8_t mcast_compatibility;
-  uint8_t mcast_last_query_interval;
-#endif
-};
-
-#ifdef PICO_SUPPORT_MCAST
-struct pico_mcast_group {
-  uint8_t filter_mode;
-  uint16_t reference_count;
-  struct pico_ip4 mcast_addr;
-  struct pico_tree MCASTSources;
-};
-#endif
-
-int pico_ipv4_to_string(char *ipbuf, const uint32_t ip);
-int pico_string_to_ipv4(const char *ipstr, uint32_t *ip);
-int pico_ipv4_valid_netmask(uint32_t mask);
-int pico_ipv4_is_unicast(uint32_t address); 
-int pico_ipv4_is_multicast(uint32_t address); 
-int pico_ipv4_is_broadcast(uint32_t addr);
-
-int pico_ipv4_link_add(struct pico_device *dev, struct pico_ip4 address, struct pico_ip4 netmask);
-int pico_ipv4_link_del(struct pico_device *dev, struct pico_ip4 address);
-int pico_ipv4_rebound(struct pico_frame *f);
-
-int pico_ipv4_frame_push(struct pico_frame *f, struct pico_ip4 *dst, uint8_t proto);
-struct pico_ipv4_link *pico_ipv4_link_get(struct pico_ip4 *address);
-struct pico_ipv4_link *pico_ipv4_link_by_dev(struct pico_device *dev);
-struct pico_device *pico_ipv4_link_find(struct pico_ip4 *address);
-struct pico_ip4 *pico_ipv4_source_find(struct pico_ip4 *dst);
-int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
-int pico_ipv4_route_del(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
-struct pico_ip4 pico_ipv4_route_get_gateway(struct pico_ip4 *addr);
-void pico_ipv4_unreachable(struct pico_frame *f, int err);
-
-int pico_ipv4_mcast_join(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter);
-int pico_ipv4_mcast_leave(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter);
-struct pico_ipv4_link *pico_ipv4_get_default_mcastlink(void);
-
-#endif /* _INCLUDE_PICO_IPV4 */
--- a/modules/pico_ipv6.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_IPV6
-#define _INCLUDE_PICO_IPV6
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-
-extern struct pico_protocol pico_proto_ipv6;
-extern const uint8_t PICO_IPV6_ANY[PICO_SIZE_IP6];
-
-
-/* This module is responsible for routing outgoing packets and 
- * delivering incoming packets to other layers
- */
-
-/* Interface for processing incoming ipv6 packets (decap/deliver) */
-int pico_ipv6_process_in(struct pico_frame *f);
-
-/* Interface for processing outgoing ipv6 frames (encap/push) */
-int pico_ipv6_process_out(struct pico_frame *f);
-
-/* Return estimated overhead for ipv6 frames to define allocation */
-int pico_ipv6_overhead(struct pico_frame *f);
-
-#endif
--- a/modules/pico_mbed.cpp	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#include <mbed.h>
-#include <rtos.h>
-
-extern "C" {
-    void *pico_mutex_init(void)
-    {
-        return new Mutex();
-    }
-
-    void pico_mutex_lock(void *_m)
-    {
-        Mutex *m = (Mutex *)_m;
-        m->lock();
-    }
-
-    void pico_mutex_unlock(void *_m)
-    {
-        Mutex *m = (Mutex *)_m;
-        m->unlock();
-    }
-}
--- a/modules/pico_nat.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,683 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Kristof Roelants, Brecht Van Cauwenberghe,
-         Simon Maes, Philippe Mariman
-*********************************************************************/
-
-#include "pico_stack.h"
-#include "pico_frame.h"
-#include "pico_tcp.h"
-#include "pico_udp.h"
-#include "pico_ipv4.h"
-#include "pico_addressing.h"
-#include "pico_nat.h"
-
-
-#ifdef PICO_SUPPORT_IPV4
-#ifdef PICO_SUPPORT_NAT
-
-#define nat_dbg(...) do{}while(0)
-//#define nat_dbg dbg
-#define NAT_TCP_TIMEWAIT 240000 /* 4mins (in msec) */
-//#define NAT_TCP_TIMEWAIT 10000 /* 10 sec (in msec)  - for testing purposes only*/
-
-
-struct pico_nat_key {
-  struct pico_ip4 pub_addr;
-  uint16_t pub_port;
-  struct pico_ip4 priv_addr;
-  uint16_t priv_port;
-  uint8_t proto;
-  /*
-  del_flags:
-              1                   0 
-    5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |F|B|S|R|P|~| CONNECTION ACTIVE |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-  F: FIN from Forwarding packet
-  B: FIN from Backwarding packet
-  S: SYN 
-  R: RST  
-  P: Persistant
-         
-  */
-  uint16_t del_flags;
-  /* Connector for trees */
-};
-
-static struct pico_ipv4_link pub_link;
-static uint8_t enable_nat_flag = 0;
-
-static int nat_cmp_backward(void * ka, void * kb)
-{
-    struct pico_nat_key *a = ka, *b = kb;
-  if (a->pub_port < b->pub_port) {
-    return -1;
-  }
-  else if (a->pub_port > b->pub_port) {
-    return 1;
-  }
-  else {
-    if (a->proto < b->proto) {
-      return -1;
-    }
-    else if (a->proto > b->proto) {
-      return 1;
-    }
-    else {
-      /* a and b are identical */
-      return 0;
-    }
-  }
-}
-
-static int nat_cmp_forward(void * ka, void * kb)
-{
-    struct pico_nat_key *a =ka, *b = kb;
-  if (a->priv_addr.addr < b->priv_addr.addr) {
-    return -1;
-  }
-  else if (a->priv_addr.addr > b->priv_addr.addr) {
-    return 1;
-  }
-  else {
-    if (a->priv_port < b->priv_port) {
-      return -1;
-    }
-    else if (a->priv_port > b->priv_port) {
-      return 1;
-    }
-    else {
-      if (a->proto < b->proto) {
-        return -1;
-      }
-      else if (a->proto > b->proto) {
-        return 1;
-      }
-      else {
-        /* a and b are identical */
-        return 0;
-      }
-    }
-  }
-}
-
-PICO_TREE_DECLARE(KEYTable_forward,nat_cmp_forward);
-PICO_TREE_DECLARE(KEYTable_backward,nat_cmp_backward);
-
-/* 
-  2 options: 
-    find on proto and pub_port 
-    find on priv_addr, priv_port and proto 
-  zero the unused parameters 
-*/
-static struct pico_nat_key *pico_ipv4_nat_find_key(uint16_t pub_port, struct pico_ip4 *priv_addr, uint16_t priv_port, uint8_t proto)
-{
-  struct pico_nat_key test;
-  test.pub_port = pub_port;
-  test.priv_port = priv_port;
-  test.proto = proto;
-  if (priv_addr)
-    test.priv_addr = *priv_addr;
-  else
-    test.priv_addr.addr = 0;
-
-  /* returns NULL if test can not be found */ 
-  if (!pub_port)
-      return pico_tree_findKey(&KEYTable_forward,&test);
-  else
-      return pico_tree_findKey(&KEYTable_backward, &test);
-}
-
-int pico_ipv4_nat_find(uint16_t pub_port, struct pico_ip4 *priv_addr, uint16_t priv_port, uint8_t proto)
-{
-  struct pico_nat_key *k = NULL;
-
-  k = pico_ipv4_nat_find_key(pub_port, priv_addr, priv_port, proto); 
-  if (k)
-    return 0;
-  else
-    return -1;
-}
-
-int pico_ipv4_nat_snif_forward(struct pico_nat_key *nk, struct pico_frame *f)
-{
-  uint8_t proto;
-  struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  struct pico_tcp_hdr *tcp_hdr;
- 
-  if (!ipv4_hdr)
-    return -1;
-  proto = ipv4_hdr->proto;
-
-  if (proto == PICO_PROTO_TCP) {
-    tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-    if (!tcp_hdr)
-      return -1;
-    if (tcp_hdr->flags & PICO_TCP_FIN) {
-      nk->del_flags |= PICO_DEL_FLAGS_FIN_FORWARD; //FIN from forwarding packet
-    }
-    if (tcp_hdr->flags & PICO_TCP_SYN) {
-      nk->del_flags |= PICO_DEL_FLAGS_SYN; 
-    }
-    if (tcp_hdr->flags & PICO_TCP_RST) {
-      nk->del_flags |= PICO_DEL_FLAGS_RST;
-    }
-  } else if (proto == PICO_PROTO_UDP) {
-    /* set conn active to 1 */
-    nk->del_flags &= 0xFE00; 
-    nk->del_flags++;
-  } 
-  return 0; 
-}
-
-
-int pico_ipv4_nat_snif_backward(struct pico_nat_key *nk, struct pico_frame *f)
-{
-  uint8_t proto;
-  struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  struct pico_tcp_hdr *tcp_hdr;
-
-  if (!ipv4_hdr)
-    return -1;
-  proto = ipv4_hdr->proto;
-
-  if (proto == PICO_PROTO_TCP) {
-    tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-    if (!tcp_hdr)
-      return -1;
-    if (tcp_hdr->flags & PICO_TCP_FIN) {
-      nk->del_flags |= PICO_DEL_FLAGS_FIN_BACKWARD; //FIN from backwarding packet
-    }
-    if (tcp_hdr->flags & PICO_TCP_SYN) {
-      nk->del_flags |= PICO_DEL_FLAGS_SYN;
-    }
-    if (tcp_hdr->flags & PICO_TCP_RST) {
-      nk->del_flags |= PICO_DEL_FLAGS_RST;
-    }
-  } else if (proto == PICO_PROTO_UDP) {
-    /* set conn active to 1 */
-    nk->del_flags &= 0xFE00; 
-    nk->del_flags++;
-  }
-  return 0;
-}
-
-void pico_ipv4_nat_table_cleanup(unsigned long now, void *_unused)
-{
-  struct pico_tree_node * idx, * safe;
-  struct pico_nat_key *k = NULL;
-    nat_dbg("NAT: before table cleanup:\n");
-  pico_ipv4_nat_print_table();
-
-  //struct pico_nat_key *tmp;
-  pico_tree_foreach_reverse_safe(idx,&KEYTable_forward,safe){
-      k = idx->keyValue;
-    switch (k->proto)
-    {
-      case PICO_PROTO_TCP:
-        if ((k->del_flags & 0x0800) >> 11) {
-          /* entry is persistant */
-          break;
-        }
-        else if ((k->del_flags & 0x01FF) == 0) {
-          /* conn active is zero, delete entry */
-          pico_ipv4_nat_del(k->pub_port, k->proto);
-        }
-        else if ((k->del_flags & 0x1000) >> 12) {
-          /* RST flag set, set conn active to zero */
-          k->del_flags &= 0xFE00;
-        }
-        else if (((k->del_flags & 0x8000) >> 15) && ((k->del_flags & 0x4000) >> 14)) {
-          /* FIN1 and FIN2 set, set conn active to zero */
-          k->del_flags &= 0xFE00; 
-        }
-        else if ((k->del_flags & 0x01FF) > 360) {
-          /* conn is active for 24 hours, delete entry */
-          pico_ipv4_nat_del(k->pub_port, k->proto);
-        }
-        else {
-          k->del_flags++;
-        } 
-        break;
-
-      case PICO_PROTO_UDP:
-        if ((k->del_flags & 0x0800) >> 11) {
-          /* entry is persistant */
-          break;
-        }
-        else if ((k->del_flags & 0x01FF) > 1) {
-          /* Delete entry when it has existed NAT_TCP_TIMEWAIT */
-          pico_ipv4_nat_del(k->pub_port, k->proto);
-        }
-        else {
-          k->del_flags++;
-        }
-        break;
-
-      default:
-        /* Unknown protocol in NAT table, delete when it has existed NAT_TCP_TIMEWAIT */
-        if ((k->del_flags & 0x01FF) > 1) {
-          pico_ipv4_nat_del(k->pub_port, k->proto);
-        }
-        else {
-          k->del_flags++;
-        }
-    }
-  }
-
-  nat_dbg("NAT: after table cleanup:\n");
-  pico_ipv4_nat_print_table();
-  pico_timer_add(NAT_TCP_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL);
-}
-
-int pico_ipv4_nat_add(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto)
-{
-  struct pico_nat_key *key = pico_zalloc(sizeof(struct pico_nat_key));
-  if (!key) {
-    pico_err = PICO_ERR_ENOMEM;
-    return -1;
-  }
-
-  key->pub_addr = pub_addr;
-  key->pub_port = pub_port;
-  key->priv_addr = priv_addr;
-  key->priv_port = priv_port;
-  key->proto = proto;
-  key->del_flags = 0x0001; /* set conn active to 1, other flags to 0 */
-
-  /* RB_INSERT returns NULL when element added, pointer to the element if already in tree */
-  if(!pico_tree_insert(&KEYTable_forward, key) && !pico_tree_insert(&KEYTable_backward, key)){
-    return 0; /* New element added */
-  }
-  else {
-    pico_free(key);
-    pico_err = PICO_ERR_EINVAL;
-    return -1; /* Element key already exists */
-  }
-}
-
-
-int pico_ipv4_nat_del(uint16_t pub_port, uint8_t proto)
-{
-  struct pico_nat_key *key = NULL;
-  key = pico_ipv4_nat_find_key(pub_port, NULL, 0, proto);
-  if (!key) {
-    nat_dbg("NAT: key to delete not found: proto %u | pub_port %u\n", proto, pub_port);
-    return -1;
-  }
-  else {
-    nat_dbg("NAT: key to delete found: proto %u | pub_port %u\n", proto, pub_port);  
-    /* RB_REMOVE returns pointer to removed element, NULL to indicate error */
-    if(pico_tree_delete(&KEYTable_forward, key) && pico_tree_delete(&KEYTable_backward, key))
-          pico_free(key);
-    else
-      return -1; /* Error on removing element, do not free! */
-  }
-  return 0;
-}
-
-int pico_ipv4_port_forward(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto, uint8_t persistant)
-{
-  struct pico_nat_key *key = NULL;
-
-  switch (persistant)
-  {
-    case PICO_IPV4_FORWARD_ADD:
-      if (pico_ipv4_nat_add(pub_addr, pub_port, priv_addr, priv_port, proto) != 0)
-        return -1;  /* pico_err set in nat_add */
-      key = pico_ipv4_nat_find_key(pub_port, &priv_addr, priv_port, proto);
-      if (!key) {
-        pico_err = PICO_ERR_EAGAIN;
-        return -1;
-      }
-      key->del_flags = (key->del_flags & ~(0x1 << 11)) | (persistant << 11);
-      break;
-
-    case PICO_IPV4_FORWARD_DEL:
-      return pico_ipv4_nat_del(pub_port, proto);
-
-    default:
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-  }
-  pico_ipv4_nat_print_table();
-  return 0;
-}
-
-
-void pico_ipv4_nat_print_table(void)
-{
-  struct pico_nat_key __attribute__((unused)) *k = NULL ;
-  struct pico_tree_node * index;
-  uint16_t i = 0;
-
-  nat_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-  nat_dbg("+                                                       NAT table                                                       +\n");
-  nat_dbg("+-----------------------------------------------------------------------------------------------------------------------+\n");
-  nat_dbg("+  pointer   | private_addr | private_port | proto | pub_addr | pub_port | conn active | FIN1 | FIN2 | SYN | RST | PERS +\n");
-  nat_dbg("+-----------------------------------------------------------------------------------------------------------------------+\n");
-
-  pico_tree_foreach(index,&KEYTable_forward){
-      k = index->keyValue;
-    nat_dbg("+ %10p |   %08X   |    %05u     |  %04u | %08X |  %05u   |     %03u     |   %u  |   %u  |  %u  |  %u  |   %u  +\n", 
-           k, k->priv_addr.addr, k->priv_port, k->proto, k->pub_addr.addr, k->pub_port, (k->del_flags)&0x01FF, ((k->del_flags)&0x8000)>>15, 
-           ((k->del_flags)&0x4000)>>14, ((k->del_flags)&0x2000)>>13, ((k->del_flags)&0x1000)>>12, ((k->del_flags)&0x0800)>>11);
-    i++;
-  }
-  nat_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-}
-
-int pico_ipv4_nat_generate_key(struct pico_nat_key* nk, struct pico_frame* f, struct pico_ip4 pub_addr)
-{
-  uint16_t pub_port = 0;
-  uint8_t proto;
-  struct pico_tcp_hdr *tcp_hdr = NULL;  /* forced to use pico_trans */
-  struct pico_udp_hdr *udp_hdr = NULL;  /* forced to use pico_trans */
-  struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  if (!ipv4_hdr)
-    return -1;
-  proto = ipv4_hdr->proto;
-  do {
-    /* 1. generate valid new NAT port entry */
-    uint32_t rand = pico_rand();
-    pub_port = (uint16_t) (rand & 0xFFFFU);
-    pub_port = (uint16_t)(pub_port % (65535 - 1024)) + 1024U;
-        pub_port = short_be(pub_port);
-
-    /* 2. check if already in table, if no exit */
-    nat_dbg("NAT: check if generated port %u is free\n", short_be(pub_port));
-    if (pico_is_port_free(proto, pub_port, NULL, &pico_proto_ipv4))
-      break;
-  
-  } while (1);
-  nat_dbg("NAT: port %u is free\n", short_be(pub_port));
-    
-  if (proto == PICO_PROTO_TCP) {  
-    tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-    if (!tcp_hdr)
-      return -1;
-    nk->priv_port = tcp_hdr->trans.sport; 
-  } else if (proto == PICO_PROTO_UDP) {
-    udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-    if (!udp_hdr)
-      return -1;
-    nk->priv_port = udp_hdr->trans.sport; 
-  } else if (proto == PICO_PROTO_ICMP4) {
-    nk->priv_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF); 
-    pub_port = (uint16_t)(ipv4_hdr->dst.addr & 0x00FF);
-    if (!pico_is_port_free(proto, pub_port, NULL, &pico_proto_ipv4))
-      return -1;
-  }
-
-  nk->pub_addr = pub_addr; /* get public ip address from device */
-  nk->pub_port = pub_port;
-  nk->priv_addr = ipv4_hdr->src;
-  nk->proto = ipv4_hdr->proto;
-  nk->del_flags = 0x0001; /* set conn active to 1 */
-  if (pico_ipv4_nat_add(nk->pub_addr, nk->pub_port, nk->priv_addr, nk->priv_port, nk->proto) < 0) {
-    return -1;
-  } else {
-    return 0;
-  }
-}
-
-
-static int pico_nat_tcp_checksum(struct pico_frame *f)
-{
-  struct pico_tcp_hdr *trans_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  struct pico_ipv4_hdr *net_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-
-  struct tcp_pseudo_hdr_ipv4 pseudo;
-  if (!trans_hdr || !net_hdr)
-    return -1;
-
-  pseudo.src.addr = net_hdr->src.addr;
-  pseudo.dst.addr = net_hdr->dst.addr;
-  pseudo.res = 0;
-  pseudo.proto = PICO_PROTO_TCP;
-  pseudo.tcp_len = short_be(f->transport_len);
-
-  trans_hdr->crc = 0;
-  trans_hdr->crc = pico_dualbuffer_checksum(&pseudo, sizeof(struct tcp_pseudo_hdr_ipv4), trans_hdr, f->transport_len);
-  trans_hdr->crc = short_be(trans_hdr->crc);
-  return 0;
-}
-
-
-int pico_ipv4_nat_translate(struct pico_nat_key* nk, struct pico_frame* f)
-{
-  uint8_t proto;
-  struct pico_tcp_hdr *tcp_hdr = NULL;  /* forced to use pico_trans */
-  struct pico_udp_hdr *udp_hdr = NULL;  /* forced to use pico_trans */
-
-  struct pico_ipv4_hdr* ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  if (!ipv4_hdr)
-    return -1;
-  proto = ipv4_hdr->proto;
-  
-  if (proto == PICO_PROTO_TCP) {
-    tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-    if (!tcp_hdr)
-      return -1;
-    tcp_hdr->trans.sport = nk->pub_port;
-  } else if (proto == PICO_PROTO_UDP) {  
-    udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-    if (!udp_hdr)
-      return -1;
-    udp_hdr->trans.sport = nk->pub_port;
-  }
-
-  //if(f->proto == PICO_PROTO_ICMP){
-  //} XXX no action
-
-  ipv4_hdr->src = nk->pub_addr;
-
-  if (proto == PICO_PROTO_TCP) {
-    pico_nat_tcp_checksum(f);
-  } else if (proto == PICO_PROTO_UDP){
-    udp_hdr->crc = 0;
-    udp_hdr->crc = short_be(pico_udp_checksum_ipv4(f));
-  }
-
-  // pico_ipv4_checksum(f);
-  ipv4_hdr->crc = 0;
-  ipv4_hdr->crc = short_be(pico_checksum(ipv4_hdr, f->net_len));
-
-  return 0;
-}
-
-
-int pico_ipv4_nat_port_forward(struct pico_frame* f)
-{
-  struct pico_nat_key *nk = NULL;
-  struct pico_tcp_hdr *tcp_hdr = NULL;
-  struct pico_udp_hdr *udp_hdr = NULL; 
-  struct pico_icmp4_hdr *icmp_hdr = NULL;
-  struct pico_ipv4_hdr* ipv4_hdr;
-  uint16_t pub_port = 0; 
-  uint8_t proto;
-
-  ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-  if (!ipv4_hdr)
-    return -1; 
-  proto = ipv4_hdr->proto; 
-  
-  if (proto == PICO_PROTO_TCP) {
-    tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-    if (!tcp_hdr)
-      return -1;
-    pub_port = tcp_hdr->trans.dport;  
-  } else if (proto == PICO_PROTO_UDP) {  
-    udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-    if (!udp_hdr)
-      return -1;
-    pub_port = udp_hdr->trans.dport;
-  } else if (proto == PICO_PROTO_ICMP4) {
-    icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
-    if (!icmp_hdr)
-      return -1;
-    /* XXX PRELIMINARY ONLY LAST 16 BITS OF IP */
-    pub_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF);
-  }
-
-  nk = pico_ipv4_nat_find_key(pub_port, 0, 0, proto);
-
-  if (!nk) {
-    nat_dbg("\nNAT: ERROR key not found in table\n");
-    return -1;
-  } else {
-    pico_ipv4_nat_snif_forward(nk,f);
-    ipv4_hdr->dst.addr = nk->priv_addr.addr;
-
-    if (proto == PICO_PROTO_TCP) {
-       tcp_hdr->trans.dport = nk->priv_port;
-       pico_nat_tcp_checksum(f);
-    } else if (proto == PICO_PROTO_UDP) {
-      udp_hdr->trans.dport = nk->priv_port;
-      udp_hdr->crc = 0;
-      udp_hdr->crc = short_be(pico_udp_checksum_ipv4(f));
-    }
-  }
-
-  ipv4_hdr->crc = 0;
-  ipv4_hdr->crc = short_be(pico_checksum(ipv4_hdr, f->net_len));
- 
-  return 0; 
-}
-
-
-
-int pico_ipv4_nat(struct pico_frame *f, struct pico_ip4 pub_addr)
-{
-  /*do nat---------*/
-  struct pico_nat_key *nk = NULL;
-  struct pico_nat_key key;
-  struct pico_ipv4_hdr *net_hdr = (struct pico_ipv4_hdr *) f->net_hdr; 
-  struct pico_tcp_hdr *tcp_hdr = NULL;  
-  struct pico_udp_hdr *udp_hdr = NULL;  
-  int ret;
-  uint8_t proto = net_hdr->proto;
-  uint16_t priv_port = 0;
-  struct pico_ip4 priv_addr= net_hdr->src;
-
-  nk= &key;
-
-  /* TODO DELME check if IN */
-  if (pub_addr.addr == net_hdr->dst.addr) {
-    nat_dbg("NAT: backward translation {dst.addr, dport}: {%08X,%u} ->", net_hdr->dst.addr, ((struct pico_trans *)f->transport_hdr)->dport);
-    ret = pico_ipv4_nat_port_forward(f);  /* our IN definition */
-    nat_dbg(" {%08X,%u}\n", net_hdr->dst.addr, short_be(((struct pico_trans *)f->transport_hdr)->dport));
-  } else {
-    if (net_hdr->proto == PICO_PROTO_TCP) {
-      tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-      priv_port = tcp_hdr->trans.sport;
-    } else if (net_hdr->proto == PICO_PROTO_UDP) {
-      udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-      priv_port = udp_hdr->trans.sport;
-    } else if (net_hdr->proto == PICO_PROTO_ICMP4) {
-      //udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-      priv_port = (uint16_t)(net_hdr->src.addr & 0x00FF);
-    }
-
-    ret = pico_ipv4_nat_find(0, &priv_addr, priv_port, proto);
-    if (ret >= 0) {
-      // Key is available in table
-      nk = pico_ipv4_nat_find_key(0, &priv_addr, priv_port, proto);
-    } else {
-      nat_dbg("NAT: key not found in NAT table -> generate key\n");
-      pico_ipv4_nat_generate_key(nk, f, pub_addr);
-    }
-    pico_ipv4_nat_snif_backward(nk,f);
-    nat_dbg("NAT: forward translation {src.addr, sport}: {%08X,%u} ->", net_hdr->src.addr, short_be(((struct pico_trans *)f->transport_hdr)->sport));
-    pico_ipv4_nat_translate(nk, f); /* our OUT definition */
-    nat_dbg(" {%08X,%u}\n", net_hdr->src.addr, short_be(((struct pico_trans *)f->transport_hdr)->sport));
-  } 
-  return 0;
-}
-
-
-int pico_ipv4_nat_enable(struct pico_ipv4_link *link)
-{
-  if (link == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  pub_link = *link;
-  pico_timer_add(NAT_TCP_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL);
-  enable_nat_flag = 1;
-  return 0;
-}
- 
-int pico_ipv4_nat_disable(void)
-{
-  pub_link.address.addr = 0;
-  enable_nat_flag = 0;   
-  return 0;
-}
-
-
-int pico_ipv4_nat_isenabled_out(struct pico_ipv4_link *link)
-{
-  if (enable_nat_flag) {
-    // is pub_link = *link
-    if (pub_link.address.addr == link->address.addr)
-      return 0;
-    else
-      return -1;
-  } else {
-    return -1;
-  }
-}
-
-
-int pico_ipv4_nat_isenabled_in(struct pico_frame *f)
-{
-  if (enable_nat_flag) {
-    struct pico_tcp_hdr *tcp_hdr = NULL;
-    struct pico_udp_hdr *udp_hdr = NULL;
-    uint16_t pub_port = 0;
-    int ret;
-    uint8_t proto;
- 
-    struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr; 
-    if (!ipv4_hdr)
-      return -1;
-    proto = ipv4_hdr->proto;    
-
-    if (proto == PICO_PROTO_TCP) {
-      tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-      if (!tcp_hdr)
-        return -1;
-      pub_port= tcp_hdr->trans.dport;
-    } else if (proto == PICO_PROTO_UDP) {
-      udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-      if (!udp_hdr)
-        return -1;
-      pub_port= udp_hdr->trans.dport;
-    } else if (proto == PICO_PROTO_ICMP4) {
-      //icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
-      //if (!icmp_hdr)
-      //  return -1;
-      /* XXX PRELIMINARY ONLY LAST 16 BITS OF IP */
-      pub_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF);
-    }
-    ret = pico_ipv4_nat_find(pub_port, NULL, 0, proto);
-    if (ret == 0)
-      return 0;
-    else
-      return -1;
-  } else {
-    return -1;    
-  }
-}
-#endif
-#endif
-
--- a/modules/pico_nat.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-  
-Authors: Kristof Roelants, Simon Maes, Brecht Van Cauwenberghe
-*********************************************************************/
-
-#ifndef _INCLUDE_PICO_NAT
-#define _INCLUDE_PICO_NAT
-#include "pico_frame.h"
-
-#define PICO_DEL_FLAGS_FIN_FORWARD   (0x8000)
-#define PICO_DEL_FLAGS_FIN_BACKWARD  (0x4000)
-#define PICO_DEL_FLAGS_SYN           (0x2000)
-#define PICO_DEL_FLAGS_RST           (0x1000)
-
-#define PICO_IPV4_FORWARD_DEL 0
-#define PICO_IPV4_FORWARD_ADD 1
-
-#ifdef PICO_SUPPORT_NAT
-void pico_ipv4_nat_print_table(void);
-int pico_ipv4_nat_add(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto);
-int pico_ipv4_nat_del(uint16_t pub_port, uint8_t proto);
-int pico_ipv4_nat_find(uint16_t pub_port, struct pico_ip4 *priv_addr, uint16_t priv_port, uint8_t proto);
-int pico_ipv4_port_forward(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto, uint8_t persistant);
-
-int pico_ipv4_nat(struct pico_frame* f, struct pico_ip4 pub_addr);
-int pico_ipv4_nat_enable(struct pico_ipv4_link *link);
-int pico_ipv4_nat_isenabled_out(struct pico_ipv4_link *link);
-int pico_ipv4_nat_isenabled_in(struct pico_frame *f);
-
-#else
-
-static inline int pico_ipv4_nat_isenabled_out(struct pico_ipv4_link *link)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-static inline int pico_ipv4_nat_isenabled_in(struct pico_frame *f)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-static inline int pico_ipv4_nat(struct pico_frame* f, struct pico_ip4 pub_addr)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-static inline int pico_ipv4_nat_enable(struct pico_ipv4_link *link)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-#define pico_ipv4_nat_print_table() do{}while(0)
-
-static inline int pico_ipv4_nat_add(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-static inline int pico_ipv4_nat_del(uint16_t pub_port, uint8_t proto)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-
-static inline int pico_ipv4_nat_find(uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-
-static inline int pico_ipv4_port_forward(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto, uint8_t persistant)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-#endif
-
-#endif /* _INCLUDE_PICO_NAT */
-
--- a/modules/pico_simple_http.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#include "pico_config.h"
-#include "pico_socket.h"
-#include "pico_tcp.h"
-#include "pico_ipv4.h"
-#include "pico_simple_http.h"
-
-/* The HTTP Server cannot be available without TCP support */
-#if (defined PICO_SUPPORT_HTTP) && (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_TCP)
-
-#define HTTP_LISTEN_PORT    80u
-#define HTTP_BACKLOG             5u
-#define HTTP_HEADER_SIZE  256u
-
-#define HTTP_SUCCESS            0
-#define HTTP_ERROR                -1
-
-static struct pico_socket * httpServer = NULL;
-static char   httpResponse[] =
-"HTTP/1.0 200 OK\r\n\
-Content-Type: text/html\r\n\
-\r\n\
-<html><head>\r\n\
-<title>picoTCP Simple Http server</title>\r\n\
-</head>\r\n\
-<body>\r\n\
-<h1>Hello world from picoTCP !!</h1>\r\n\
-</body>\r\n";
-
-static void httpEventCbk(uint16_t ev, struct pico_socket *self)
-{
-    static struct pico_socket * client = NULL;
-    uint32_t peer;
-    uint16_t port;
-    int r;
-    char buffer[HTTP_HEADER_SIZE];
-
-    switch(ev)
-    {
-        case PICO_SOCK_EV_CONN :
-            if(!client)
-                client = pico_socket_accept(self, &peer, &port);
-            break;
-
-        case PICO_SOCK_EV_RD:
-            // do not check http integrity, just mark that the http header has arrived
-            // prepare to send the response
-            r = pico_socket_recvfrom(self, buffer, HTTP_HEADER_SIZE, &peer, &port);
-            if(r>0 && memcmp(buffer,"GET",3u) == 0u)
-            { // it is an http header asking for data, return data and close
-                pico_socket_write(self,httpResponse,sizeof(httpResponse));
-                pico_socket_close(self);
-            }
-            else
-            {
-                // kill the connection, invalid header
-                pico_socket_close(self);
-            }
-            break;
-
-        case PICO_SOCK_EV_ERR:
-        case PICO_SOCK_EV_CLOSE:
-            // free the used socket
-            client = NULL;
-            break;
-
-        default :
-            break;
-    }
-}
-
-int pico_startHttpServer(struct pico_ip4 * address)
-{
-
-    uint16_t localHttpPort = short_be(HTTP_LISTEN_PORT);
-
-    if(!pico_is_port_free(localHttpPort,PICO_PROTO_TCP, address, &pico_proto_ipv4))
-    {
-        pico_err = PICO_ERR_EADDRINUSE;
-        return HTTP_ERROR;
-    }
-
-    httpServer = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, httpEventCbk);
-
-    if(!httpServer)
-    {
-        pico_err = PICO_ERR_ENOMEM;
-        return HTTP_ERROR;
-    }
-
-    // both functions set the pico_err themselves.
-    if(pico_socket_bind(httpServer,address,&localHttpPort))
-        return HTTP_ERROR;
-
-    if(pico_socket_listen(httpServer,HTTP_BACKLOG))
-        return HTTP_ERROR;
-
-    return HTTP_SUCCESS;
-}
-
-int pico_stopHttpServer(void)
-{
-    if(!httpServer)
-    {
-        pico_err = PICO_ERR_EINVAL;
-        return HTTP_ERROR;
-    }
-
-    if(pico_socket_close(httpServer))
-    {
-        // no need to set the error here, function already set it
-        httpServer = NULL;
-        return HTTP_ERROR;
-    }
-
-    httpServer = NULL;
-    return HTTP_SUCCESS;
-}
-
-#endif
-
-
--- a/modules/pico_simple_http.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#ifndef PICO_SIMPLE_HTTP
-#define PICO_SIMPLE_HTTP
-
-extern int pico_startHttpServer(struct pico_ip4 * address);
-extern int pico_stopHttpServer(void);
-
-#endif
--- a/modules/pico_tcp.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2190 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera, Philippe Mariman
-*********************************************************************/
-
-#include "pico_tcp.h"
-#include "pico_config.h"
-#include "pico_eth.h"
-#include "pico_socket.h"
-#include "pico_stack.h"
-#include "pico_socket.h"
-#include "pico_queue.h"
-#include "pico_tree.h"
-
-#define TCP_SOCK(s) ((struct pico_socket_tcp *)s)
-#define SEQN(f) (f?(long_be(((struct pico_tcp_hdr *)(f->transport_hdr))->seq)):0)
-#define ACKN(f) (f?(long_be(((struct pico_tcp_hdr *)(f->transport_hdr))->ack)):0)
-
-#define PICO_TCP_RTO_MIN 1000
-#define PICO_TCP_RTO_MAX 120000
-#define PICO_TCP_IW 2
-
-#define PICO_TCP_MAX_CONNECT_RETRIES 7
-
-#define PICO_TCP_LOOKAHEAD      0x00
-#define PICO_TCP_FIRST_DUPACK   0x01
-#define PICO_TCP_SECOND_DUPACK  0x02
-#define PICO_TCP_RECOVER        0x03
-#define PICO_TCP_BLACKOUT       0x04
-#define PICO_TCP_UNREACHABLE    0x05
-#define PICO_TCP_WINDOW_FULL    0x06
-
-/* check if the Nagle algorithm is enabled on the socket */
-#define IS_NAGLE_ENABLED(s)     (!(!(!(s->opt_flags & (1 << PICO_SOCKET_OPT_TCPNODELAY)))))
-/* check if tcp connection is "idle" according to Nagle (RFC 896) */
-#define IS_TCP_IDLE(t)          ((t->in_flight == 0) && (t->tcpq_out.size == 0))
-/* check if the hold queue contains data (again Nagle) */
-#define IS_TCP_HOLDQ_EMPTY(t)   (t->tcpq_hold.size == 0)
-
-#ifdef PICO_SUPPORT_TCP
-#define tcp_dbg(...) do{}while(0)
-//#define tcp_dbg dbg
-
-
-#ifdef PICO_SUPPORT_MUTEX
-static void * Mutex = NULL;
-#define LOCK(x) {\
-  if (x == NULL) \
-    x = pico_mutex_init(); \
-  pico_mutex_lock(x); \
-}
-#define UNLOCK(x) pico_mutex_unlock(x);
-
-#else
-#define LOCK(x) do{}while(0)
-#define UNLOCK(x) do{}while(0)
-#endif
-
-
-static inline int seq_compare(uint32_t a, uint32_t b)
-{
-  uint32_t thresh = ((uint32_t)(-1))>>1;
-  if (((a > thresh) && (b > thresh)) || ((a <= thresh) && (b <= thresh))) {
-    if (a > b)
-      return 1;
-    if (b > a)
-      return -1;
-  } else {
-    if (a > b)
-      return -2;
-    if (b > a)
-      return 2;
-  }
-  return 0;
-}
-
-static int segment_compare(void * ka, void * kb)
-{
-  struct pico_frame *a = ka, *b = kb;
-  return seq_compare(SEQN(a), SEQN(b));
-}
-
-struct pico_tcp_queue
-{
-  struct pico_tree pool;
-  uint32_t max_size;
-  uint32_t size;
-  uint32_t frames;
-};
-
-static struct pico_frame *peek_segment(struct pico_tcp_queue *tq, uint32_t seq)
-{
-  struct pico_tcp_hdr H;
-  struct pico_frame f = {};
-  f.transport_hdr = (uint8_t *) (&H);
-  H.seq = long_be(seq);
-
-  return pico_tree_findKey(&tq->pool,&f);
-}
-
-static struct pico_frame *first_segment(struct pico_tcp_queue *tq)
-{
-  return pico_tree_first(&tq->pool);
-}
-
-static struct pico_frame *next_segment(struct pico_tcp_queue *tq, struct pico_frame *cur)
-{
-  if (!cur)
-    return NULL;
-  return peek_segment(tq, SEQN(cur) + cur->payload_len);
-}
-
-static int pico_enqueue_segment(struct pico_tcp_queue *tq, struct pico_frame *f)
-{
-    int ret = -1;
-  if (f->payload_len <= 0) {
-    tcp_dbg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TRIED TO ENQUEUE INVALID SEGMENT!\n");
-    //abort();
-    return -1;
-  }
-    LOCK(Mutex);
-  if ((tq->size + f->payload_len) > tq->max_size)
-  {
-    ret = 0;
-    goto out;
-  }
-  if (pico_tree_insert(&tq->pool,f) != 0)
-  {
-    ret = 0;
-    goto out;
-  }
-  tq->size += f->payload_len;
-  if (f->payload_len > 0)
-    tq->frames++;
-  ret = f->payload_len;
-
-out :
-  UNLOCK(Mutex);
-  return ret;
-}
-
-static void pico_discard_segment(struct pico_tcp_queue *tq, struct pico_frame *f)
-{
-  struct pico_frame *f1;
-  LOCK(Mutex);
-  f1 = pico_tree_delete(&tq->pool,f);
-  if (f1) {
-    tq->size -= f->payload_len;
-    if (f->payload_len > 0)
-      tq->frames--;
-  }
-  pico_frame_discard(f);
-  UNLOCK(Mutex);
-}
-
-/* Structure for TCP socket */
-struct tcp_sack_block {
-  uint32_t left;
-  uint32_t right;
-  struct tcp_sack_block *next;
-};
-
-struct pico_socket_tcp {
-  struct pico_socket sock;
-
-  /* Tree/queues */
-  struct pico_tcp_queue tcpq_in;
-  struct pico_tcp_queue tcpq_out;
-  struct pico_tcp_queue tcpq_hold;  /* buffer to hold delayed frames according to Nagle */
-
-  /* tcp_output */
-  uint32_t snd_nxt;
-  uint32_t snd_last;
-  uint32_t snd_old_ack;
-  uint32_t snd_retry;
-  uint32_t snd_last_out;
-
-  /* congestion control */
-  uint32_t avg_rtt;
-  uint32_t rttvar;
-  uint32_t rto;
-  uint32_t in_flight;
-  uint8_t  timer_running;
-  uint8_t  keepalive_timer_running;
-  uint16_t cwnd_counter;
-  uint16_t cwnd;
-  uint16_t ssthresh;
-  uint16_t recv_wnd;
-  uint16_t recv_wnd_scale;
-
-  /* tcp_input */
-  uint32_t rcv_nxt;
-  uint32_t rcv_ackd;
-  uint32_t rcv_processed;
-  uint16_t wnd;
-  uint16_t wnd_scale;
-
-  /* options */
-  uint32_t ts_nxt;
-  uint16_t mss;
-  uint8_t sack_ok;
-  uint8_t ts_ok;
-  uint8_t mss_ok;
-  uint8_t scale_ok;
-  struct tcp_sack_block *sacks;
-  uint8_t jumbo;
-
-  /* Transmission */
-  uint8_t  x_mode;
-  uint8_t  dupacks;
-  uint8_t  backoff;
-
-};
-
-/* Queues */
-static struct pico_queue tcp_in = {};
-static struct pico_queue tcp_out = {};
-
-/* If Nagle enabled, this function can make 1 new segment from smaller segments in hold queue */
-static struct pico_frame * pico_hold_segment_make(struct pico_socket_tcp *t);
-
-/* checks if tcpq_in is empty */
-int pico_tcp_queue_in_is_empty(struct pico_socket *s)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) s;
-
-  if (t->tcpq_in.frames == 0)
-    return 1;
-  else
-    return 0;
-}
-
-/* Useful for getting rid of the beginning of the buffer (read() op) */
-static int release_until(struct pico_tcp_queue *q, uint32_t seq)
-{
-  struct pico_frame *head = first_segment(q);
-  int ret = 0;
-  while (head && (seq_compare(SEQN(head) + head->payload_len, seq) <= 0)) {
-    struct pico_frame *cur = head;
-    head = next_segment(q, cur);
-    tcp_dbg("Releasing %p\n", q);
-    pico_discard_segment(q, cur);
-    ret++;
-  }
-  return ret;
-}
-
-static int release_all_until(struct pico_tcp_queue *q, uint32_t seq)
-{
-  struct pico_frame *f = NULL, *tmp __attribute__((unused));
-  struct pico_tree_node * idx, * temp;
-  int ret = 0;
-
-  pico_tree_foreach_safe(idx,&q->pool,temp){
-  f = idx->keyValue;
-    if (seq_compare(SEQN(f) + f->payload_len, seq) <= 0) {
-      tcp_dbg("Releasing %p\n", f);
-      pico_discard_segment(q, f);
-      ret++;
-    } else
-      return ret;
-  }
-  return ret;
-}
-
-/* API calls */
-
-uint16_t pico_tcp_checksum_ipv4(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_tcp_hdr *tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  struct pico_socket *s = f->sock;
-  struct pico_ipv4_pseudo_hdr pseudo;
-
-  if (s) {
-    /* Case of outgoing frame */
-    //dbg("TCP CRC: on outgoing frame\n");
-    pseudo.src.addr = s->local_addr.ip4.addr;
-    pseudo.dst.addr = s->remote_addr.ip4.addr;
-  } else {
-    /* Case of incomming frame */
-    //dbg("TCP CRC: on incomming frame\n");
-    pseudo.src.addr = hdr->src.addr;
-    pseudo.dst.addr = hdr->dst.addr;
-  }
-  pseudo.zeros = 0;
-  pseudo.proto = PICO_PROTO_TCP;
-  pseudo.len = short_be(f->transport_len);
-
-  return pico_dualbuffer_checksum(&pseudo, sizeof(struct pico_ipv4_pseudo_hdr), tcp_hdr, f->transport_len);
-}
-
-static int pico_tcp_process_out(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_tcp_hdr *hdr;
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)f->sock;
-  hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-
-  if (f->payload_len > 0) {
-    tcp_dbg("Process out: sending %p (%d bytes)\n",f, f->payload_len);
-  } else {
-    tcp_dbg("Sending empty packet\n");
-  }
-
-  if (f->payload_len > 0) {
-    if (seq_compare(SEQN(f) + f->payload_len, t->snd_nxt) > 0) {
-      t->snd_nxt = SEQN(f) + f->payload_len;
-      tcp_dbg("%s: snd_nxt is now %08x\n", __FUNCTION__, t->snd_nxt);
-    }
-  } else if (hdr->flags == PICO_TCP_ACK) { /* pure ack */
-    hdr->seq = long_be(t->snd_nxt);
-  } else {
-    tcp_dbg("%s: non-pure ACK with len=0, fl:%04x\n", __FUNCTION__, hdr->flags);
-  }
-  pico_network_send(f);
-  return 0;
-}
-
-int pico_tcp_push(struct pico_protocol *self, struct pico_frame *data);
-
-/* Interface: protocol definition */
-struct pico_protocol pico_proto_tcp = {
-  .name = "tcp",
-  .proto_number = PICO_PROTO_TCP,
-  .layer = PICO_LAYER_TRANSPORT,
-  .process_in = pico_transport_process_in,
-  .process_out = pico_tcp_process_out,
-  .push = pico_tcp_push,
-  .q_in = &tcp_in,
-  .q_out = &tcp_out,
-};
-
-static uint32_t pico_paws(void)
-{
-  static unsigned long _paws = 0;
-  _paws = pico_rand();
-  return long_be(_paws); /*XXX: implement paws */
-}
-
-static void tcp_add_options(struct pico_socket_tcp *ts, struct pico_frame *f, uint16_t flags, int optsiz)
-{
-  uint32_t tsval = long_be(pico_tick);
-  uint32_t tsecr = long_be(ts->ts_nxt);
-  int i = 0;
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-
-  memset(f->start, PICO_TCP_OPTION_NOOP, optsiz); /* fill blanks with noop */
-
-  if (flags & PICO_TCP_SYN) {
-    f->start[i++] = PICO_TCP_OPTION_MSS;
-    f->start[i++] = PICO_TCPOPTLEN_MSS;
-    f->start[i++] = (ts->mss >> 8) & 0xFF;
-    f->start[i++] = ts->mss & 0xFF;
-    f->start[i++] = PICO_TCP_OPTION_SACK_OK;
-    f->start[i++] = PICO_TCPOPTLEN_SACK_OK;
-  }
-
-  f->start[i++] = PICO_TCP_OPTION_WS;
-  f->start[i++] = PICO_TCPOPTLEN_WS;
-  f->start[i++] = ts->wnd_scale;
-
-  if (optsiz >= 12) {
-    f->start[i++] = PICO_TCP_OPTION_TIMESTAMP;
-    f->start[i++] = PICO_TCPOPTLEN_TIMESTAMP;
-    memcpy(f->start + i, &tsval, 4);
-    i += 4;
-    memcpy(f->start + i, &tsecr, 4);
-    i += 4;
-  }
-
-  if (flags & PICO_TCP_ACK) {
-    struct tcp_sack_block *sb;
-    int len_off;
-
-    if (ts->sack_ok && ts->sacks) {
-      f->start[i++] = PICO_TCP_OPTION_SACK;
-      len_off = i;
-      f->start[i++] = PICO_TCPOPTLEN_SACK;
-      while(ts->sacks) {
-        sb = ts->sacks;
-        ts->sacks = sb->next;
-        memcpy(f->start + i, sb, 2 * sizeof(uint32_t));
-        i += (2 * sizeof(uint32_t));
-        f->start[len_off] += (2 * sizeof(uint32_t));
-        pico_free(sb);
-      }
-    }
-  }
-  if (i < optsiz)
-    f->start[ optsiz - 1 ] = PICO_TCP_OPTION_END;
-}
-
-static void tcp_send_ack(struct pico_socket_tcp *t);
-
-static void tcp_set_space(struct pico_socket_tcp *t)
-{
-  int mtu, space;
-  int shift = 0;
-
-  mtu = t->mss + PICO_SIZE_TCPHDR + PICO_SIZE_TCPOPT_SYN ;
-  if (t->tcpq_in.max_size == 0) {
-    space = 1024 * 1024 * 1024; /* One Gigabyte, for unlimited sockets. */
-  } else {
-    space = ((t->tcpq_in.max_size - t->tcpq_in.size) / mtu) * t->mss;
-  }
-  if (space < 0)
-    space = 0;
-  while(space > 0xFFFF) {
-    space >>= 1;
-    shift++;
-  }
-  if ((space != t->wnd) || (shift != t->wnd_scale) || ((space - t->wnd) > (space>>2))) {
-    t->wnd = space;
-    t->wnd_scale = shift;
-  }
-}
-
-/* Return 32-bit aligned option size */
-static int tcp_options_size(struct pico_socket_tcp *t, uint16_t flags)
-{
-  int size = 0;
-  struct tcp_sack_block *sb = t->sacks;
-
-  if (flags & PICO_TCP_SYN) {  /* Full options */
-    size = PICO_TCPOPTLEN_MSS + PICO_TCP_OPTION_SACK_OK + PICO_TCPOPTLEN_WS + PICO_TCPOPTLEN_TIMESTAMP;
-  } else {
-
-   /* Always update window scale. */
-    size += PICO_TCPOPTLEN_WS;
-
-    if (t->ts_ok)
-      size += PICO_TCPOPTLEN_TIMESTAMP;
-
-    size+= PICO_TCPOPTLEN_END;
-  }
-  if ((flags & PICO_TCP_ACK) && (t->sack_ok && sb)) {
-    size += 2;
-    while(sb) {
-      size += (2 * sizeof(uint32_t));
-      sb = sb->next;
-    }
-  }
-  size = (((size + 3) >> 2) << 2);
-  return size;
-}
-
-int pico_tcp_overhead(struct pico_socket *s)
-{
-  if (!s)
-    return 0;
-
-  return PICO_SIZE_TCPHDR + tcp_options_size((struct pico_socket_tcp *)s, 0); /* hdr + Options size for data pkt */
-
-}
-
-static void tcp_process_sack(struct pico_socket_tcp *t, uint32_t start, uint32_t end)
-{
-  struct pico_frame *f;
-  struct pico_tree_node * index, * temp;
-  int cmp;
-  int count = 0;
-
-  pico_tree_foreach_safe(index,&t->tcpq_out.pool,temp){
-    f = index->keyValue;
-    cmp = seq_compare(SEQN(f), start);
-    if (cmp > 0)
-      goto done;
-
-    if (cmp == 0) {
-      cmp = seq_compare(SEQN(f) + f->payload_len, end);
-      if (cmp > 0) {
-        tcp_dbg("Invalid SACK: ignoring.\n");
-      }
-
-      tcp_dbg("Marking (by SACK) segment %08x BLK:[%08x::%08x]\n", SEQN(f), start, end);
-      f->flags |= PICO_FRAME_FLAG_SACKED;
-      count++;
-
-      if (cmp == 0) {
-        /* that was last segment sacked. Job done */
-        goto done;
-      }
-    }
-  }
-
-done:
-  if (t->x_mode > PICO_TCP_LOOKAHEAD) {
-    if (t->in_flight > (count))
-      t->in_flight -= (count);
-    else
-      t->in_flight = 0;
-  }
-}
-
-static void tcp_rcv_sack(struct pico_socket_tcp *t, uint8_t *opt, int len)
-{
-  uint32_t start, end;
-  int i = 0;
-  if (len % 8) {
-    tcp_dbg("SACK: Invalid len.\n");
-    return;
-  }
-  while (i < len) {
-    start = long_from(opt + i);
-    i += 4;
-    end = long_from(opt + i);
-    i += 4;
-    tcp_process_sack(t, long_be(start), long_be(end));
-  }
-}
-
-static void tcp_parse_options(struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)f->sock;
-  uint8_t *opt = f->transport_hdr + PICO_SIZE_TCPHDR;
-  int i = 0;
-  while (i < (f->transport_len - PICO_SIZE_TCPHDR)) {
-    uint8_t type =  opt[i++];
-    uint8_t len;
-    if(i < (f->transport_len - PICO_SIZE_TCPHDR) && (type > 1))
-      len =  opt[i++];
-    else
-      len = 1;
-    if (f->payload && ((opt + i) > f->payload))
-      break;
-    tcp_dbg("Received option '%d', len = %d \n", type, len);
-    switch (type) {
-      case PICO_TCP_OPTION_NOOP:
-      case PICO_TCP_OPTION_END:
-        break;
-      case PICO_TCP_OPTION_WS:
-        if (len != PICO_TCPOPTLEN_WS) {
-          tcp_dbg("TCP Window scale: bad len received (%d).\n", len);
-          i += len - 2;
-          break;
-        }
-        t->recv_wnd_scale = opt[i++];
-        tcp_dbg("TCP Window scale: received %d\n", t->recv_wnd_scale);
-        break;
-      case PICO_TCP_OPTION_SACK_OK:
-        if (len != PICO_TCPOPTLEN_SACK_OK) {
-          tcp_dbg("TCP option sack: bad len received.\n");
-          i += len - 2;
-          break;
-        }
-        t->sack_ok = 1;
-        break;
-      case PICO_TCP_OPTION_MSS: {
-        uint16_t mss;
-        if (len != PICO_TCPOPTLEN_MSS) {
-          tcp_dbg("TCP option mss: bad len received.\n");
-          i += len - 2;
-          break;
-        }
-        t->mss_ok = 1;
-        mss = short_from(opt + i);
-        i += sizeof(uint16_t);
-        if (t->mss > short_be(mss))
-          t->mss = short_be(mss);
-        break;
-      }
-      case PICO_TCP_OPTION_TIMESTAMP: {
-        uint32_t tsval, tsecr;
-        if (len != PICO_TCPOPTLEN_TIMESTAMP) {
-          tcp_dbg("TCP option timestamp: bad len received.\n");
-          i += len - 2;
-          break;
-        }
-        t->ts_ok = 1;
-        tsval = long_from(opt + i);
-        i += sizeof(uint32_t);
-        tsecr = long_from(opt + i);
-        f->timestamp = long_be(tsecr);
-        i += sizeof(uint32_t);
-
-        t->ts_nxt = long_be(tsval);
-        break;
-      }
-      case PICO_TCP_OPTION_SACK:
-      {
-        tcp_rcv_sack(t, opt + i, len - 2);
-        i += len - 2;
-        break;
-      }
-      default:
-        tcp_dbg("TCP: received unsupported option %u\n", type);
-        i += len - 2;
-    }
-  }
-}
-
-static int tcp_send(struct pico_socket_tcp *ts, struct pico_frame *f)
-{
-  struct pico_tcp_hdr *hdr= (struct pico_tcp_hdr *) f->transport_hdr;
-  struct pico_frame *cpy;
-  hdr->trans.sport = ts->sock.local_port;
-  hdr->trans.dport = ts->sock.remote_port;
-  if (!hdr->seq)
-    hdr->seq = long_be(ts->snd_nxt);
-
-  if (ts->rcv_nxt != 0) {
-    if ( (ts->rcv_ackd == 0) || (seq_compare(ts->rcv_ackd, ts->rcv_nxt) != 0) || (hdr->flags & PICO_TCP_ACK)) {
-      hdr->flags |= PICO_TCP_ACK;
-      hdr->ack = long_be(ts->rcv_nxt);
-      ts->rcv_ackd = ts->rcv_nxt;
-    }
-  }
-
-  if (hdr->flags & PICO_TCP_SYN) {
-    ts->snd_nxt++;
-  }
-  if (f->payload_len > 0) {
-    hdr->flags |= PICO_TCP_PSH | PICO_TCP_ACK;
-    hdr->ack = long_be(ts->rcv_nxt);
-    ts->rcv_ackd = ts->rcv_nxt;
-  }
-
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-  hdr->rwnd = short_be(ts->wnd);
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-
-  /* TCP: ENQUEUE to PROTO ( Transmit ) */
-  cpy = pico_frame_copy(f);
-  if (pico_enqueue(&tcp_out, cpy) > 0) {
-    if (f->payload_len > 0)
-      ts->in_flight++;
-    tcp_dbg("DBG> [tcp output] state: %02x --> local port:%d remote port: %d seq: %08x ack: %08x flags: %02x = t_len: %d, hdr: %u payload: %d\n",
-      TCPSTATE(&ts->sock) >> 8, short_be(hdr->trans.sport), short_be(hdr->trans.dport), SEQN(f), ACKN(f), hdr->flags, f->transport_len, (hdr->len & 0xf0) >> 2 , f->payload_len );
-  } else {
-    pico_frame_discard(cpy);
-  }
-  return 0;
-}
-
-//#define PICO_TCP_SUPPORT_SOCKET_STATS
-
-#ifdef PICO_TCP_SUPPORT_SOCKET_STATS
-static void sock_stats(unsigned long when, void *arg)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)arg;
-  tcp_dbg("STATISTIC> [%lu] socket state: %02x --> local port:%d remote port: %d queue size: %d snd_una: %08x snd_nxt: %08x timer: %d cwnd: %d\n",
-    when, t->sock.state, short_be(t->sock.local_port), short_be(t->sock.remote_port), t->tcpq_out.size, SEQN(first_segment(&t->tcpq_out)), t->snd_nxt, t->timer_running, t->cwnd);
-  pico_timer_add(2000, sock_stats, t);
-}
-#endif
-
-struct pico_socket *pico_tcp_open(void)
-{
-  struct pico_socket_tcp *t = pico_zalloc(sizeof(struct pico_socket_tcp));
-  if (!t)
-    return NULL;
-  t->mss = PICO_TCP_DEFAULT_MSS;
-
-  t->tcpq_in.pool.root = t->tcpq_hold.pool.root = t->tcpq_out.pool.root = &LEAF;
-  t->tcpq_hold.pool.compare = t->tcpq_in.pool.compare = t->tcpq_out.pool.compare = segment_compare;
-
-  t->tcpq_in.max_size = PICO_DEFAULT_SOCKETQ;
-  t->tcpq_out.max_size = PICO_DEFAULT_SOCKETQ;
-  t->tcpq_hold.max_size = 2*PICO_TCP_DEFAULT_MSS;
-
-  /* enable Nagle by default */
-  t->sock.opt_flags &= (~(1 << PICO_SOCKET_OPT_TCPNODELAY));
-
-#ifdef PICO_TCP_SUPPORT_SOCKET_STATS
-  pico_timer_add(2000, sock_stats, t);
-#endif
-  tcp_set_space(t);
-
-  return &t->sock;
-}
-
-int pico_tcp_read(struct pico_socket *s, void *buf, int len)
-{
-  struct pico_socket_tcp *t = TCP_SOCK(s);
-  struct pico_frame *f;
-  uint32_t in_frame_off, in_frame_len;
-  int tot_rd_len = 0;
-
-  while (tot_rd_len < len) {
-    /* To be sure we don't have garbage at the beginning */
-    release_until(&t->tcpq_in, t->rcv_processed);
-    f = first_segment(&t->tcpq_in);
-    if (!f) {
-      tcp_set_space(t);
-      goto out;
-    }
-
-    /* Hole at the beginning of data, awaiting retransmissions. */
-    if (seq_compare(t->rcv_processed, SEQN(f)) < 0) {
-      tcp_dbg("TCP> read hole beginning of data, %08x - %08x. rcv_nxt is %08x\n",t->rcv_processed, SEQN(f), t->rcv_nxt);
-      goto out;
-    }
-
-    if(seq_compare(t->rcv_processed, SEQN(f)) > 0) {
-      in_frame_off = t->rcv_processed - SEQN(f);
-      in_frame_len = f->payload_len - in_frame_off;
-    } else {
-      in_frame_off = 0;
-      in_frame_len = f->payload_len;
-    }
-    if ((in_frame_len + tot_rd_len) > len) {
-      in_frame_len = len - tot_rd_len;
-    }
-
-    if (in_frame_len > f->payload_len - in_frame_off)
-      in_frame_len = f->payload_len - in_frame_off;
-
-    memcpy(buf + tot_rd_len, f->payload + in_frame_off, in_frame_len);
-    tot_rd_len += in_frame_len;
-    t->rcv_processed += in_frame_len;
-
-    if ((in_frame_len == 0) || (in_frame_len == f->payload_len)) {
-      pico_discard_segment(&t->tcpq_in, f);
-    }
-  }
-
-out:
-  tcp_set_space(t);
-  if (t->tcpq_in.size == 0) {
-    s->ev_pending &= (~PICO_SOCK_EV_RD);
-  }
-  return tot_rd_len;
-}
-
-int pico_tcp_initconn(struct pico_socket *s);
-static void initconn_retry(unsigned long when, void *arg)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)arg;
-  if (TCPSTATE(&t->sock) == PICO_SOCKET_STATE_TCP_SYN_SENT) {
-    if (t->backoff > PICO_TCP_MAX_CONNECT_RETRIES) {
-      tcp_dbg("TCP> Connection timeout. \n");
-      if (t->sock.wakeup)
-        t->sock.wakeup(PICO_SOCK_EV_ERR, &t->sock);
-      return;
-    }
-    tcp_dbg("TCP> SYN retry %d...\n", t->backoff);
-    t->backoff++;
-    pico_tcp_initconn(&t->sock);
-  } else {
-    tcp_dbg("TCP> Connection is already established: no retry needed. good.\n");
-  }
-}
-
-int pico_tcp_initconn(struct pico_socket *s)
-{
-  struct pico_socket_tcp *ts = TCP_SOCK(s);
-  struct pico_frame *syn;
-  struct pico_tcp_hdr *hdr;
-  int opt_len = tcp_options_size(ts, PICO_TCP_SYN);
-
-  syn = s->net->alloc(s->net, PICO_SIZE_TCPHDR + opt_len);
-  if (!syn)
-    return -1;
-  hdr = (struct pico_tcp_hdr *) syn->transport_hdr;
-
-  if (!ts->snd_nxt)
-    ts->snd_nxt = long_be(pico_paws());
-  ts->snd_last = ts->snd_nxt;
-  ts->cwnd = PICO_TCP_IW;
-  ts->ssthresh = 40;
-  syn->sock = s;
-  hdr->seq = long_be(ts->snd_nxt);
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | ts->jumbo;
-  hdr->flags = PICO_TCP_SYN;
-  tcp_set_space(ts);
-  hdr->rwnd = short_be(ts->wnd);
-  tcp_add_options(ts,syn, PICO_TCP_SYN, opt_len);
-  hdr->trans.sport = ts->sock.local_port;
-  hdr->trans.dport = ts->sock.remote_port;
-
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(syn));
-
-  /* TCP: ENQUEUE to PROTO ( SYN ) */
-  tcp_dbg("Sending SYN... (ports: %d - %d) size: %d\n", short_be(ts->sock.local_port), short_be(ts->sock.remote_port), syn->buffer_len);
-  pico_enqueue(&tcp_out, syn);
-  pico_timer_add(PICO_TCP_RTO_MIN << ts->backoff, initconn_retry, ts);
-  return 0;
-}
-
-static int tcp_send_synack(struct pico_socket *s)
-{
-  struct pico_socket_tcp *ts = TCP_SOCK(s);
-  struct pico_frame *synack;
-  struct pico_tcp_hdr *hdr;
-  int opt_len = tcp_options_size(ts, PICO_TCP_SYN | PICO_TCP_ACK);
-
-  synack = s->net->alloc(s->net, PICO_SIZE_TCPHDR + opt_len);
-  if (!synack)
-    return -1;
-  hdr = (struct pico_tcp_hdr *) synack->transport_hdr;
-
-  synack->sock = s;
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | ts->jumbo;
-  hdr->flags = PICO_TCP_SYN | PICO_TCP_ACK;
-  hdr->rwnd = short_be(ts->wnd);
-  hdr->seq = long_be(ts->snd_nxt);
-  ts->rcv_processed = long_be(hdr->seq);
-  ts->snd_last = ts->snd_nxt;
-  tcp_set_space(ts);
-  tcp_add_options(ts,synack, hdr->flags, opt_len);
-  synack->payload_len = 0;
-  synack->timestamp = pico_tick;
-  tcp_send(ts, synack);
-  pico_frame_discard(synack);
-  return 0;
-}
-
-static void tcp_send_empty(struct pico_socket_tcp *t, uint16_t flags)
-{
-  struct pico_frame *f;
-  struct pico_tcp_hdr *hdr;
-  int opt_len = tcp_options_size(t, flags);
-  f = t->sock.net->alloc(t->sock.net, PICO_SIZE_TCPHDR + opt_len);
-  if (!f) {
-    return;
-  }
-  f->sock = &t->sock;
-  hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | t->jumbo;
-  hdr->flags = flags;
-  hdr->rwnd = short_be(t->wnd);
-  tcp_set_space(t);
-  tcp_add_options(t,f, flags, opt_len);
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-  hdr->seq = long_be(t->snd_nxt);
-  if ((flags & PICO_TCP_ACK) != 0)
-    hdr->ack = long_be(t->rcv_nxt);
-  t->rcv_ackd = t->rcv_nxt;
-
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-  hdr->rwnd = short_be(t->wnd);
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-
-  /* TCP: ENQUEUE to PROTO */
-  pico_enqueue(&tcp_out, f);
-}
-
-static void tcp_send_ack(struct pico_socket_tcp *t)
-{
-  return tcp_send_empty(t, PICO_TCP_ACK);
-}
-
-static int tcp_send_rst(struct pico_socket *s, struct pico_frame *fr)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) s;
-  struct pico_frame *f;
-  struct pico_tcp_hdr *hdr, *hdr_rcv;
-  int opt_len = tcp_options_size(t, PICO_TCP_RST);
-
-  tcp_dbg("TCP SEND_RST >>>>>>>>>>>>>>> START\n");
-  /* go to CLOSED here to prevent timer callback to go on after timeout */
-  (t->sock).state &= 0x00FFU;
-  (t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-
-  f = t->sock.net->alloc(t->sock.net, PICO_SIZE_TCPHDR + opt_len);
-
-  if (!f) {
-    return -1;
-  }
-
-  hdr_rcv = (struct pico_tcp_hdr *) fr->transport_hdr;
-
-  f->sock = &t->sock;
-  hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | t->jumbo;
-  hdr->flags = PICO_TCP_RST;
-  hdr->rwnd = short_be(t->wnd);
-  tcp_set_space(t);
-  tcp_add_options(t,f, PICO_TCP_RST, opt_len);
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-  hdr->seq = long_be(t->snd_nxt);
-
-  /* check if state is synchronized */
-  if (((s->state & PICO_SOCKET_STATE_TCP) > PICO_SOCKET_STATE_TCP_SYN_RECV)) {
-    /* in synchronized state: send RST with seq = ack from previous segment */
-    hdr->seq = hdr_rcv->ack;
-  } else {
-    /* non-synchronized state */
-  }
-
-  hdr->ack = long_be(t->rcv_nxt);
-  t->rcv_ackd = t->rcv_nxt;
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-  hdr->rwnd = short_be(t->wnd);
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-
-  /* TCP: ENQUEUE to PROTO */
-  pico_enqueue(&tcp_out, f);
-
-  /* goto CLOSED */
-  //(t->sock).state &= 0x00FFU;
-  //(t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-  (t->sock).state &= 0xFF00U;
-  (t->sock).state |= PICO_SOCKET_STATE_CLOSED;
-
-  /* call EV_FIN wakeup before deleting */
-  if ((t->sock).wakeup)
-    (t->sock).wakeup(PICO_SOCK_EV_FIN, &(t->sock));
-
-  /* delete socket */
-  pico_socket_del(&t->sock);
-
-  tcp_dbg("TCP SEND_RST >>>>>>>>>>>>>>> DONE, deleted socket\n");
-
-  return 0;
-}
-
-int pico_tcp_reply_rst(struct pico_frame *fr)
-{
-  struct pico_tcp_hdr *hdr;
-  struct pico_frame *f;
-  int size = PICO_SIZE_TCPHDR;
-
-  tcp_dbg("TCP>>>>>>>>>>>>>>>> sending RST ... <<<<<<<<<<<<<<<<<<\n");
-
-  f = fr->sock->net->alloc(fr->sock->net, size);
-
-  /* fill in IP data from original frame */
-  // TODO if IPv4
-  ((struct pico_ipv4_hdr *)(f->net_hdr))->dst.addr = ((struct pico_ipv4_hdr *)(fr->net_hdr))->src.addr;
-  ((struct pico_ipv4_hdr *)(f->net_hdr))->src.addr = ((struct pico_ipv4_hdr *)(fr->net_hdr))->dst.addr;
-
-  /* fill in TCP data from original frame */
-  ((struct pico_tcp_hdr *)(f->transport_hdr))->trans.dport = ((struct pico_tcp_hdr *)(fr->transport_hdr))->trans.sport;
-  ((struct pico_tcp_hdr *)(f->transport_hdr))->trans.sport = ((struct pico_tcp_hdr *)(fr->transport_hdr))->trans.dport;
-  hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  hdr->len   = size << 2;
-  hdr->flags = PICO_TCP_RST | PICO_TCP_ACK;
-  hdr->rwnd  = 0;
-  if (((struct pico_tcp_hdr *)(fr->transport_hdr))->flags & PICO_TCP_ACK) {
-    hdr->seq = ((struct pico_tcp_hdr *)(fr->transport_hdr))->ack;
-  } else {
-    hdr->seq = 0U;
-  }
-
-  hdr->ack = ((struct pico_tcp_hdr *)(fr->transport_hdr))->seq + short_be(fr->payload_len);
-
-  /* enqueue for transmission */
-  pico_ipv4_frame_push(f,&(((struct pico_ipv4_hdr *)(f->net_hdr))->dst),PICO_PROTO_TCP);
-
-  return 0;
-}
-
-static int tcp_nosync_rst(struct pico_socket *s, struct pico_frame *fr)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) s;
-  struct pico_frame *f;
-  struct pico_tcp_hdr *hdr, *hdr_rcv;
-  int opt_len = tcp_options_size(t, PICO_TCP_RST | PICO_TCP_ACK);
-
-  tcp_dbg("TCP SEND RST (NON-SYNC) >>>>>>>>>>>>>>>>>> state %x\n",(s->state & PICO_SOCKET_STATE_TCP));
-  if (((s->state & PICO_SOCKET_STATE_TCP) ==  PICO_SOCKET_STATE_TCP_LISTEN)) {
-    /* XXX TODO NOTE: to prevent the parent socket from trying to send, because this socket has no knowledge of dst IP !!! */
-    return pico_tcp_reply_rst(fr);
-  }
-
-  /***************************************************************************/
-  /* sending RST */
-  f = t->sock.net->alloc(t->sock.net, PICO_SIZE_TCPHDR + opt_len);
-
-  if (!f) {
-    return -1;
-  }
-
-  hdr_rcv = (struct pico_tcp_hdr *) fr->transport_hdr;
-
-  f->sock = &t->sock;
-  hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | t->jumbo;
-  hdr->flags = PICO_TCP_RST | PICO_TCP_ACK;
-  hdr->rwnd = short_be(t->wnd);
-  tcp_set_space(t);
-  tcp_add_options(t,f, PICO_TCP_RST | PICO_TCP_ACK, opt_len);
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-
-  /* non-synchronized state */
-  if (hdr_rcv->flags & PICO_TCP_ACK) {
-    hdr->seq = hdr_rcv->ack;
-  } else {
-    hdr->seq = 0U;
-  }
-
-  hdr->ack = hdr_rcv->seq + short_be(fr->payload_len);
-
-  t->rcv_ackd = t->rcv_nxt;
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-  hdr->rwnd = short_be(t->wnd);
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-
-  /* TCP: ENQUEUE to PROTO */
-  pico_enqueue(&tcp_out, f);
-
-  /***************************************************************************/
-
-  tcp_dbg("TCP SEND_RST (NON_SYNC) >>>>>>>>>>>>>>> DONE, ...\n");
-
-  return 0;
-}
-
-static void tcp_send_fin(struct pico_socket_tcp *t)
-{
-  struct pico_frame *f;
-  struct pico_tcp_hdr *hdr;
-  int opt_len = tcp_options_size(t, PICO_TCP_FIN);
-  f = t->sock.net->alloc(t->sock.net, PICO_SIZE_TCPHDR + opt_len);
-  if (!f) {
-    return;
-  }
-  f->sock = &t->sock;
-  hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  hdr->len = (PICO_SIZE_TCPHDR + opt_len) << 2 | t->jumbo;
-  hdr->flags = PICO_TCP_FIN | PICO_TCP_ACK;
-  hdr->ack = long_be(t->rcv_nxt);
-  t->rcv_ackd = t->rcv_nxt;
-  hdr->rwnd = short_be(t->wnd);
-  tcp_set_space(t);
-  tcp_add_options(t,f, PICO_TCP_FIN, opt_len);
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-  hdr->seq = long_be(t->snd_nxt);
-
-  f->start = f->transport_hdr + PICO_SIZE_TCPHDR;
-  hdr->rwnd = short_be(t->wnd);
-  hdr->crc = 0;
-  hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-  //tcp_dbg("SENDING FIN...\n");
-  /* TCP: ENQUEUE to PROTO ( Pure ACK ) */
-  pico_enqueue(&tcp_out, f);
-  t->snd_nxt++;
-}
-
-static void tcp_sack_prepare(struct pico_socket_tcp *t)
-{
-  struct pico_frame *pkt;
-  uint32_t left=0, right=0;
-  struct tcp_sack_block *sb;
-  int n = 0;
-  if (t->sacks) /* previous sacks are pending */
-    return;
-
-  pkt = first_segment(&t->tcpq_in);
-  while(n < 3) {
-    if (!pkt) {
-      if(left) {
-        sb = pico_zalloc(sizeof(struct tcp_sack_block));
-        if (!sb)
-          break;
-        sb->left = long_be(left);
-        sb->right = long_be(right);
-        n++;
-        sb->next = t->sacks;
-        t->sacks = sb;
-        left = 0;
-        right = 0;
-      }
-      break;
-    }
-    if ((SEQN(pkt) < t->rcv_nxt)) {
-      pkt = next_segment(&t->tcpq_in, pkt);
-      continue;
-    }
-    if (!left) {
-      left = SEQN(pkt);
-      right = SEQN(pkt) + pkt->payload_len;
-      pkt = next_segment(&t->tcpq_in, pkt);
-      continue;
-    }
-    if(SEQN(pkt) == (right + 1)) {
-      right += pkt->payload_len;
-      pkt = next_segment(&t->tcpq_in, pkt);
-      continue;
-    } else {
-      sb = pico_zalloc(sizeof(struct tcp_sack_block));
-      if (!sb)
-        break;
-      sb->left = long_be(left);
-      sb->right = long_be(right);
-      n++;
-      sb->next = t->sacks;
-      t->sacks = sb;
-      left = 0;
-      right = 0;
-      pkt = next_segment(&t->tcpq_in, pkt);
-    }
-  }
-}
-
-static int tcp_data_in(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-
-  if (((hdr->len & 0xf0) >> 2) <= f->transport_len) {
-    tcp_parse_options(f);
-    f->payload = f->transport_hdr + ((hdr->len & 0xf0) >>2);
-    f->payload_len = f->transport_len - ((hdr->len & 0xf0) >>2);
-
-    if (seq_compare(SEQN(f), t->rcv_nxt) >= 0) {
-      struct pico_frame *cpy = pico_frame_copy(f);
-      struct pico_frame *nxt;
-      /* Enqueue: try to put into RCV buffer */
-      if (pico_enqueue_segment(&t->tcpq_in, cpy) <= 0) {
-        pico_frame_discard(cpy);
-        return -1;
-      }
-      if (seq_compare(SEQN(f), t->rcv_nxt) == 0) { /* Exactly what we expected */
-        t->rcv_nxt = SEQN(f) + f->payload_len;
-        nxt = peek_segment(&t->tcpq_in, t->rcv_nxt);
-        while(nxt) {
-          tcp_dbg("scrolling rcv_nxt...%08x\n", t->rcv_nxt);
-          t->rcv_nxt += f->payload_len;
-          nxt = peek_segment(&t->tcpq_in, t->rcv_nxt);
-        }
-        t->sock.ev_pending |= PICO_SOCK_EV_RD;
-        t->rcv_nxt = SEQN(f) + f->payload_len;
-      } else {
-        tcp_dbg("TCP> lo segment. Possible retransmission. (exp: %x got: %x)\n", t->rcv_nxt, SEQN(f));
-      }
-    } else {
-      tcp_dbg("TCP> hi segment. Possible packet loss. I'll dupack this. (exp: %x got: %x)\n", t->rcv_nxt, SEQN(f));
-      if (t->sack_ok) {
-        tcp_sack_prepare(t);
-      }
-    }
-    /* In either case, ack til recv_nxt. */
-    if ( ((t->sock.state & PICO_SOCKET_STATE_TCP) != PICO_SOCKET_STATE_TCP_CLOSE_WAIT) && ((t->sock.state & PICO_SOCKET_STATE_TCP) != PICO_SOCKET_STATE_TCP_SYN_SENT) && ((t->sock.state & PICO_SOCKET_STATE_TCP) != PICO_SOCKET_STATE_TCP_SYN_RECV)) {
-      //tcp_dbg("SENDACK CALLED FROM OUTSIDE tcp_synack, state %x\n",t->sock.state);
-      tcp_send_ack(t);
-    } else {
-      //tcp_dbg("SENDACK PREVENTED IN SYNSENT STATE\n");
-    }
-    return 0;
-  } else {
-    tcp_dbg("TCP: invalid data in pkt len, exp: %d, got %d\n", (hdr->len & 0xf0) >> 2, f->transport_len);
-    return -1;
-  }
-}
-
-static int tcp_ack_advance_una(struct pico_socket_tcp *t, struct pico_frame *f)
-{
-  int ret =  release_all_until(&t->tcpq_out, ACKN(f));
-  if (ret > 0)
-    t->sock.ev_pending |= PICO_SOCK_EV_WR;
-  return ret;
-}
-
-static uint16_t time_diff(unsigned long a, unsigned long b)
-{
-  if (a >= b)
-    return (a - b);
-  else
-    return (b - a);
-}
-
-static void tcp_rtt(struct pico_socket_tcp *t, uint32_t rtt)
-{
-
-  uint32_t avg = t->avg_rtt;
-  uint32_t rvar = t->rttvar;
-  if (!avg) {
-    /* This follows RFC2988
-     * (2.2) When the first RTT measurement R is made, the host MUST set
-     *
-     * SRTT <- R
-     * RTTVAR <- R/2
-     * RTO <- SRTT + max (G, K*RTTVAR)
-     */
-    t->avg_rtt = rtt;
-    t->rttvar = rtt >> 1;
-    t->rto = t->avg_rtt + (t->rttvar << 4);
-  } else {
-    int var = (t->avg_rtt - rtt);
-    if (var < 0)
-      var = 0-var;
-    /* RFC2988, section (2.3). Alpha and beta are the ones suggested. */
-
-    /* First, evaluate a new value for the rttvar */
-    t->rttvar <<= 2;
-    t->rttvar -= rvar;
-    t->rttvar += var;
-    t->rttvar >>= 2;
-
-    /* Then, calculate the new avg_rtt */
-    t->avg_rtt <<= 3;
-    t->avg_rtt -= avg;
-    t->avg_rtt += rtt;
-    t->avg_rtt >>= 3;
-
-    /* Finally, assign a new value for the RTO, as specified in the RFC, with K=4 */
-    t->rto = t->avg_rtt + (t->rttvar << 2);
-  }
-  tcp_dbg(" -----=============== RTT AVG: %u RTTVAR: %u RTO: %u ======================----\n", t->avg_rtt, t->rttvar, t->rto);
-}
-
-static void tcp_congestion_control(struct pico_socket_tcp *t)
-{
-  if (t->x_mode > PICO_TCP_LOOKAHEAD)
-    return;
-  if (t->cwnd > t->tcpq_out.frames) {
-    tcp_dbg("Limited by app: %d\n", t->cwnd);
-    return;
-  }
-  tcp_dbg("Doing congestion control\n");
-  if (t->cwnd < t->ssthresh) {
-    t->cwnd++;
-  } else {
-    t->cwnd_counter++;
-    if (t->cwnd_counter >= t->cwnd) {
-      t->cwnd++;
-      t->cwnd_counter = 0;
-    }
-  }
-  tcp_dbg("TCP_CWND, %lu, %u, %u, %u\n", pico_tick, t->cwnd, t->ssthresh, t->in_flight);
-}
-
-static void add_retransmission_timer(struct pico_socket_tcp *t, unsigned long next_ts);
-static void tcp_retrans_timeout(unsigned long val, void *sock)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) sock;
-  struct pico_frame *f = NULL;
-  unsigned long limit = val - t->rto;
-  struct pico_tcp_hdr *hdr;
-  if(t->sock.net && ((t->sock.state & 0xFF00) == PICO_SOCKET_STATE_TCP_ESTABLISHED))
-  {
-        tcp_dbg("\n\nTIMEOUT! backoff = %d\n", t->backoff);
-        /* was timer cancelled? */
-        if (t->timer_running == 0) {
-            add_retransmission_timer(t, 0);
-            return;
-        }
-        t->timer_running--;
-
-        f = first_segment(&t->tcpq_out);
-        while (f) {
-            if ((t->x_mode == PICO_TCP_WINDOW_FULL) ||
-                    ((f->timestamp != 0) && (f->timestamp <= limit))) {
-                struct pico_frame *cpy;
-                hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-                tcp_dbg("TCP BLACKOUT> TIMED OUT (output) frame %08x, len= %d rto=%d\n", SEQN(f), f->payload_len, t->rto);
-                if ((t->x_mode != PICO_TCP_WINDOW_FULL) ) {
-                    t->x_mode = PICO_TCP_BLACKOUT;
-                    tcp_dbg("Mode: Blackout.\n");
-                    t->cwnd = PICO_TCP_IW;
-                    t->in_flight = 0;
-                }
-                f->timestamp = pico_tick;
-                tcp_add_options(t, f, 0, f->transport_len - f->payload_len - PICO_SIZE_TCPHDR);
-                hdr->rwnd = short_be(t->wnd);
-                hdr->flags |= PICO_TCP_PSH;
-                hdr->ack = long_be(t->rcv_nxt);
-                hdr->crc = 0;
-                hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-                /* TCP: ENQUEUE to PROTO ( retransmit )*/
-                cpy = pico_frame_copy(f);
-                if (pico_enqueue(&tcp_out, cpy) > 0) {
-                    t->backoff++;
-                    add_retransmission_timer(t, (t->rto << t->backoff) + pico_tick);
-                    tcp_dbg("TCP_CWND, %lu, %u, %u, %u\n", pico_tick, t->cwnd, t->ssthresh, t->in_flight);
-                    return;
-                } else {
-                    add_retransmission_timer(t, (t->rto << t->backoff) + pico_tick);
-                    pico_frame_discard(cpy);
-                }
-            }
-            f = next_segment(&t->tcpq_out, f);
-        }
-        t->backoff = 0;
-        add_retransmission_timer(t, 0);
-        if (t->tcpq_out.size < t->tcpq_out.max_size)
-             t->sock.ev_pending |= PICO_SOCK_EV_WR;
-        return;
-    }
-}
-
-static void add_retransmission_timer(struct pico_socket_tcp *t, unsigned long next_ts)
-{
-  struct pico_tree_node * index;
-
-  if (t->timer_running > 0)
-    return;
-
-  if (next_ts == 0) {
-    struct pico_frame *f;
-
-    pico_tree_foreach(index,&t->tcpq_out.pool){
-      f = index->keyValue;
-      if (((next_ts == 0) || (f->timestamp < next_ts)) && (f->timestamp > 0)) {
-        next_ts = f->timestamp;
-      }
-    }
-  }
-  if (next_ts > 0) {
-    if ((next_ts + t->rto) > pico_tick) {
-      pico_timer_add(next_ts + t->rto - pico_tick, tcp_retrans_timeout, t);
-    } else {
-      pico_timer_add(1, tcp_retrans_timeout, t);
-    }
-    t->timer_running++;
-  }
-}
-
-static int tcp_retrans(struct pico_socket_tcp *t, struct pico_frame *f)
-{
-  struct pico_frame *cpy;
-  struct pico_tcp_hdr *hdr;
-  if (f) {
-    hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-    tcp_dbg("TCP> RETRANS (by dupack) frame %08x, len= %d\n", SEQN(f), f->payload_len);
-    f->timestamp = pico_tick;
-    tcp_add_options(t, f, 0, f->transport_len - f->payload_len - PICO_SIZE_TCPHDR);
-    hdr->rwnd = short_be(t->wnd);
-    hdr->flags |= PICO_TCP_PSH;
-    hdr->ack = long_be(t->rcv_nxt);
-    hdr->crc = 0;
-    hdr->crc = short_be(pico_tcp_checksum_ipv4(f));
-    /* TCP: ENQUEUE to PROTO ( retransmit )*/
-    cpy = pico_frame_copy(f);
-    if (pico_enqueue(&tcp_out, cpy) > 0) {
-      t->in_flight++;
-      t->snd_last_out = SEQN(cpy);
-      add_retransmission_timer(t, pico_tick + t->rto);
-    } else {
-      pico_frame_discard(cpy);
-    }
-    return(f->payload_len);
-  }
-  return 0;
-}
-
-#ifdef TCP_ACK_DBG
-static void tcp_ack_dbg(struct pico_socket *s, struct pico_frame *f)
-{
-  uint32_t una, nxt, ack, cur;
-  struct pico_frame *una_f = NULL, *cur_f;
-  struct pico_tree_node *idx;
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  char info[64];
-  char tmp[64];
-  ack = ACKN(f);
-  nxt = t->snd_nxt;
-  tcp_dbg("===================================\n");
-  tcp_dbg("Queue out (%d/%d). ACKED=%08x\n", t->tcpq_out.size, t->tcpq_out.max_size, ack);
-
-  pico_tree_foreach(idx, &t->tcpq_out.pool) {
-    info[0] = 0;
-    cur_f = idx->keyValue;
-    cur = SEQN(cur_f);
-    if (!una_f) {
-      una_f = cur_f;
-      una = SEQN(una_f);
-    }
-
-    if (cur == nxt) {
-      strncpy(tmp, info, strlen(info));
-      snprintf(info,64, "%s SND_NXT", tmp);
-    }
-    if (cur == ack) {
-      strncpy(tmp, info, strlen(info));
-      snprintf(info,64, "%s ACK", tmp);
-    }
-    if (cur == una) {
-      strncpy(tmp, info, strlen(info));
-      snprintf(info,64, "%s SND_UNA", tmp);
-    }
-    if (cur == t->snd_last) {
-      strncpy(tmp, info, strlen(info));
-      snprintf(info,64, "%s SND_LAST", tmp);
-    }
-    tcp_dbg("%08x %d%s\n", cur, cur_f->payload_len, info);
-
-  }
-  tcp_dbg("SND_NXT is %08x, snd_LAST is %08x", nxt, t->snd_last);
-  tcp_dbg("===================================\n");
-  tcp_dbg("\n\n");
-}
-#endif
-
-static int tcp_ack(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_frame *f_new; /* use with Nagle to push to out queue */
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *) f->transport_hdr;
-  uint32_t rtt = 0;
-  int acked = 0;
-  struct pico_frame *una = NULL;
-  if ((hdr->flags & PICO_TCP_ACK) == 0)
-    return -1;
-
-#ifdef TCP_ACK_DBG
-  tcp_ack_dbg(s,f);
-#endif
-
-  tcp_parse_options(f);
-  t->recv_wnd = short_be(hdr->rwnd);
-
-  acked = tcp_ack_advance_una(t, f);
-  una = first_segment(&t->tcpq_out);
-
-  if ((t->x_mode == PICO_TCP_BLACKOUT) || 
-    ((t->x_mode == PICO_TCP_WINDOW_FULL) && ((t->recv_wnd << t->recv_wnd_scale) > t->mss))) {
-    tcp_dbg("Re-entering look-ahead...\n\n\n");
-    t->x_mode = PICO_TCP_LOOKAHEAD;
-    t->backoff = 0;
-  }
-
-  /* One should be acked. */
-//  if ((acked == 0) && (t->in_flight > 0))
-  if ((acked == 0) && (f->payload_len  == 0) && (t->in_flight > 0))
-    t->in_flight--;
-  if (!una || acked > 0) {
-    t->x_mode = PICO_TCP_LOOKAHEAD;
-    tcp_dbg("Mode: Look-ahead. In flight: %d/%d buf: %d\n", t->in_flight, t->cwnd, t->tcpq_out.frames);
-    t->backoff = 0;
-
-    /* Do rtt/rttvar/rto calculations */
-    if(una && (una->timestamp != 0)) {
-      rtt = time_diff(pico_tick, una->timestamp);
-      if (rtt)
-        tcp_rtt(t, rtt);
-    }
-
-    tcp_dbg("TCP ACK> FRESH ACK %08x (acked %d) Queue size: %u/%u frames: %u cwnd: %u in_flight: %u snd_una: %u\n", ACKN(f), acked, t->tcpq_out.size, t->tcpq_out.max_size, t->tcpq_out.frames, t->cwnd, t->in_flight, SEQN(una));
-    if (acked > t->in_flight) {
-      tcp_dbg("WARNING: in flight < 0\n");
-      t->in_flight = 0;
-    } else
-      t->in_flight -= (acked);
-
-  } else if ((t->snd_old_ack == ACKN(f)) && /* We've just seen this ack, and... */
-      ((0 == (hdr->flags & (PICO_TCP_PSH | PICO_TCP_SYN))) &&
-          (f->payload_len == 0)) && /* This is a pure ack, and... */
-      (ACKN(f) != t->snd_nxt)) /* There is something in flight awaiting to be acked... */
-  {
-    /* Process incoming duplicate ack. */
-    if (t->x_mode < PICO_TCP_RECOVER) {
-      t->x_mode++;
-      tcp_dbg("Mode: DUPACK %d, due to PURE ACK %0x, len = %d\n", t->x_mode, SEQN(f), f->payload_len);
-      tcp_dbg("ACK: %x - QUEUE: %x\n",ACKN(f), SEQN(first_segment(&t->tcpq_out)));
-      if (t->x_mode == PICO_TCP_RECOVER) { /* Switching mode */
-        t->snd_retry = SEQN(first_segment(&t->tcpq_out));
-        if (t->ssthresh > t->cwnd)
-          t->ssthresh >>=2;
-        else
-          t->ssthresh = (t->cwnd >> 1);
-        if (t->ssthresh < 2)
-          t->ssthresh = 2;
-      }
-    } else if (t->x_mode == PICO_TCP_RECOVER) {
-     tcp_dbg("TCP RECOVER> DUPACK! snd_una: %08x, snd_nxt: %08x, acked now: %08x\n", SEQN(first_segment(&t->tcpq_out)), t->snd_nxt, ACKN(f));
-      if (t->in_flight <= t->cwnd) {
-        struct pico_frame *nxt = peek_segment(&t->tcpq_out, t->snd_retry);
-        if (!nxt)
-          nxt = first_segment(&t->tcpq_out);
-
-        while (nxt && (nxt->flags & PICO_FRAME_FLAG_SACKED) && (nxt != first_segment(&t->tcpq_out))) {
-          tcp_dbg("Skipping %08x because it is sacked.\n", SEQN(nxt));
-          nxt = next_segment(&t->tcpq_out, nxt);
-        }
-
-        if (nxt && (seq_compare(SEQN(nxt), t->snd_nxt)) > 0)
-          nxt = NULL;
-        if (nxt && (seq_compare(SEQN(nxt), SEQN(first_segment(&t->tcpq_out))) > (t->recv_wnd << t->recv_wnd_scale)))
-          nxt = NULL;
-
-        if(!nxt)
-          nxt = first_segment(&t->tcpq_out);
-        if (nxt) {
-          tcp_retrans(t, peek_segment(&t->tcpq_out, t->snd_retry));
-          t->snd_retry = SEQN(nxt);
-        }
-      }
-
-      if (++t->cwnd_counter > 1) {
-        t->cwnd--;
-        if (t->cwnd < 2)
-          t->cwnd = 2;
-        t->cwnd_counter = 0;
-      }
-    } else {
-      tcp_dbg("DUPACK in mode %d \n", t->x_mode);
-
-    }
-  } /* End case duplicate ack detection */
-
-  /* Do congestion control */
-  tcp_congestion_control(t);
-  if ((acked > 0) && t->sock.wakeup) {
-    if (t->tcpq_out.size < t->tcpq_out.max_size)
-      t->sock.wakeup(PICO_SOCK_EV_WR, &(t->sock));
-      //t->sock.ev_pending |= PICO_SOCK_EV_WR;
-  }
-
-  /* if Nagle enabled, check if no unack'ed data and fill out queue (till window) */
-  if (IS_NAGLE_ENABLED((&(t->sock)))) {
-    while (!IS_TCP_HOLDQ_EMPTY(t) && ((t->tcpq_out.max_size - t->tcpq_out.size) >= PICO_TCP_DEFAULT_MSS)) {
-      tcp_dbg("TCP_ACK - NAGLE add new segment\n");
-      f_new = pico_hold_segment_make(t);
-      if (f_new == NULL)
-        break;            /* XXX corrupt !!! (or no memory) */
-      if (pico_enqueue_segment(&t->tcpq_out,f_new) <= 0)
-        // handle error
-        tcp_dbg("TCP_ACK - NAGLE FAILED to enqueue in out\n");
-    }
-  }
-
-  /* If some space was created, put a few segments out. */
-  tcp_dbg("TCP_CWND, %lu, %u, %u, %u\n", pico_tick, t->cwnd, t->ssthresh, t->in_flight);
-  if (t->x_mode ==  PICO_TCP_LOOKAHEAD) {
-    if ((t->cwnd >= t->in_flight) && (t->snd_nxt > t->snd_last_out)) {
-      pico_tcp_output(&t->sock, t->cwnd - t->in_flight);
-    }
-  }
-
-  t->snd_old_ack = ACKN(f);
-  return 0;
-}
-
-static int tcp_finwaitack(struct pico_socket *s, struct pico_frame *f)
-{
-  tcp_dbg("RECEIVED ACK IN FIN_WAIT1\nTCP> IN STATE FIN_WAIT2\n");
-
-  /* acking part */
-  tcp_ack(s,f);
-  /* update TCP state */
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_FIN_WAIT2;
-
-  return 0;
-}
-
-static void tcp_deltcb(unsigned long when, void *arg)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)arg;
-  if (TCPSTATE(&t->sock) == PICO_SOCKET_STATE_TCP_TIME_WAIT) {
-    tcp_dbg("TCP> state: time_wait, final timer expired, going to closed state\n");
-    /* update state */
-    (t->sock).state &= 0x00FFU;
-    (t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-    (t->sock).state &= 0xFF00U;
-    (t->sock).state |= PICO_SOCKET_STATE_CLOSED;
-    /* call EV_FIN wakeup before deleting */
-    if (t->sock.wakeup) {
-      (t->sock).wakeup(PICO_SOCK_EV_FIN, &(t->sock));
-    }
-    /* delete socket */
-    pico_socket_del(&t->sock);
-  } else {
-    tcp_dbg("TCP> trying to go to closed, wrong state\n");
-  }
-}
-
-static int tcp_finwaitfin(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  struct pico_tcp_hdr *hdr  = (struct pico_tcp_hdr *) (f->transport_hdr);
-  tcp_dbg("TCP> received fin in FIN_WAIT2\n");
-  /* received FIN, increase ACK nr */
-  t->rcv_nxt = long_be(hdr->seq) + 1;
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_TIME_WAIT;
-  /* set SHUT_REMOTE */
-  s->state |= PICO_SOCKET_STATE_SHUT_REMOTE;
-  if (s->wakeup)
-    s->wakeup(PICO_SOCK_EV_CLOSE, s);
-  if (f->payload_len > 0) /* needed?? */
-    tcp_data_in(s,f);
-  /* send ACK */
-  tcp_send_ack(t);
-  /* set timer */
-  pico_timer_add(200, tcp_deltcb, t);
-  return 0;
-}
-
-static int tcp_closewaitack(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  tcp_dbg("TCP> received ack in CLOSING\n");
-  /* acking part */
-  tcp_ack(s,f);
-  /* update TCP state */
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_TIME_WAIT;
-  /* set timer */
-  pico_timer_add(200, tcp_deltcb, t);
-  return 0;
-}
-
-static int tcp_lastackwait(struct pico_socket *s, struct pico_frame *f)
-{
-  tcp_dbg("TCP> state: last_ack, received ack, to closed\n");
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_CLOSED;
-  s->state &= 0xFF00U;
-  s->state |= PICO_SOCKET_STATE_CLOSED;
-  /* call socket wakeup with EV_FIN */
-  if (s->wakeup)
-    s->wakeup(PICO_SOCK_EV_FIN, s);
-  /* delete socket */
-  pico_socket_del(s);
-  return 0;
-}
-
-static int tcp_syn(struct pico_socket *s, struct pico_frame *f)
-{
-  /* TODO: Check against backlog length */
-  struct pico_socket_tcp *new = (struct pico_socket_tcp *)pico_socket_clone(s);
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-  if (!new)
-    return -1;
-
-#ifdef PICO_TCP_SUPPORT_SOCKET_STATS
-  pico_timer_add(2000, sock_stats, s);
-#endif
-
-  new->sock.remote_port = ((struct pico_trans *)f->transport_hdr)->sport;
-#ifdef PICO_SUPPORT_IPV4
-  if (IS_IPV4(f)) {
-    new->sock.remote_addr.ip4.addr = ((struct pico_ipv4_hdr *)(f->net_hdr))->src.addr;
-    new->sock.local_addr.ip4.addr = ((struct pico_ipv4_hdr *)(f->net_hdr))->dst.addr;
-  }
-#endif
-#ifdef PICO_SUPPORT_IPV6
-  if (IS_IPV6(f)) {
-    memcpy(new->sock.remote_addr.ip6.addr, ((struct pico_ipv6_hdr *)(f->net_hdr))->src, PICO_SIZE_IP6);
-    memcpy(new->sock.remote_addr.ip6.addr, ((struct pico_ipv6_hdr *)(f->net_hdr))->src, PICO_SIZE_IP6);
-  }
-#endif
-
-  /* Set socket limits */
-  new->tcpq_in.max_size = PICO_DEFAULT_SOCKETQ;
-  new->tcpq_out.max_size = PICO_DEFAULT_SOCKETQ;
-  new->tcpq_hold.max_size = 2*PICO_TCP_DEFAULT_MSS;
-
-  f->sock = &new->sock;
-  tcp_parse_options(f);
-  new->mss = PICO_TCP_DEFAULT_MSS;
-  new->rcv_nxt = long_be(hdr->seq) + 1;
-  new->snd_nxt = long_be(pico_paws());
-  new->snd_last = new->snd_nxt;
-  new->cwnd = PICO_TCP_IW;
-  new->ssthresh = 40;
-  new->recv_wnd = short_be(hdr->rwnd);
-  new->jumbo = hdr->len & 0x07;
-  new->sock.parent = s;
-  new->sock.wakeup = s->wakeup;
-  /* Initialize timestamp values */
-  new->sock.state = PICO_SOCKET_STATE_BOUND | PICO_SOCKET_STATE_CONNECTED | PICO_SOCKET_STATE_TCP_SYN_RECV;
-  pico_socket_add(&new->sock);
-  tcp_send_synack(&new->sock);
-  tcp_dbg("SYNACK sent, socket added. snd_nxt is %08x\n", new->snd_nxt);
-  return 0;
-}
-
-static void tcp_set_init_point(struct pico_socket *s)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  t->rcv_processed = t->rcv_nxt;
-}
-
-static int tcp_synack(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) s;
-  struct pico_tcp_hdr *hdr  = (struct pico_tcp_hdr *)f->transport_hdr;
-
-  if (ACKN(f) ==  (1 + t->snd_nxt)) {
-    t->rcv_nxt = long_be(hdr->seq);
-    t->rcv_processed = t->rcv_nxt + 1;
-    tcp_ack(s, f);
-
-    s->state &= 0x00FFU;
-    s->state |= PICO_SOCKET_STATE_TCP_ESTABLISHED;
-    tcp_dbg("TCP> Established. State: %x\n", s->state);
-
-    if (s->wakeup)
-      s->wakeup(PICO_SOCK_EV_CONN, s);
-    s->ev_pending |= PICO_SOCK_EV_WR;
-
-    t->rcv_nxt++;
-    t->snd_nxt++;
-    tcp_send_ack(t);  /* return ACK */
-
-    return 0;
-
-  } else {
-    tcp_dbg("TCP> Not established, RST sent.\n");
-    tcp_nosync_rst(s,f);
-    return 0;
-  }
-}
-
-static int tcp_first_ack(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  tcp_dbg("ACK in SYN_RECV: expecting %08x got %08x\n", t->snd_nxt, ACKN(f));
-  if (t->snd_nxt == ACKN(f)) {
-    tcp_set_init_point(s);
-    tcp_ack(s, f);
-    s->state &= 0x00FFU;
-    s->state |= PICO_SOCKET_STATE_TCP_ESTABLISHED;
-    tcp_dbg("TCP: Established. State now: %04x\n", s->state);
-    if( !s->parent && s->wakeup) { /* If the socket has no parent, -> sending socket that has a sim_open */
-        tcp_dbg("FIRST ACK - No parent found -> sending socket\n");
-        s->wakeup(PICO_SOCK_EV_CONN,  s);
-    }
-    if (s->parent && s->parent->wakeup) {
-      tcp_dbg("FIRST ACK - Parent found -> listening socket\n");
-      s->wakeup = s->parent->wakeup;
-      s->parent->wakeup(PICO_SOCK_EV_CONN, s->parent);
-    }
-    s->ev_pending |= PICO_SOCK_EV_WR;
-    tcp_dbg("%s: snd_nxt is now %08x\n", __FUNCTION__, t->snd_nxt);
-    return 0;
-  } else {
-    tcp_nosync_rst(s,f);
-    return 0;
-  }
-}
-
-static int tcp_closewait(struct pico_socket *s, struct pico_frame *f)
-{
-
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  struct pico_tcp_hdr *hdr  = (struct pico_tcp_hdr *) (f->transport_hdr);
-
-  if (f->payload_len > 0)
-    tcp_data_in(s,f);
-  if (f->flags & PICO_TCP_ACK)
-    tcp_ack(s,f);
-  if (seq_compare(SEQN(f), t->rcv_nxt) == 0) {
-    /* received FIN, increase ACK nr */
-    t->rcv_nxt = long_be(hdr->seq) + 1;
-    s->state &= 0x00FFU;
-    s->state |= PICO_SOCKET_STATE_TCP_CLOSE_WAIT;
-    /* set SHUT_REMOTE */
-    s->state |= PICO_SOCKET_STATE_SHUT_REMOTE;
-      tcp_dbg("TCP> Close-wait\n");
-    if (s->wakeup){
-      if(f->payload_len>0){
-        struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-        t->sock.ev_pending |=PICO_SOCK_EV_CLOSE;
-      }else
-        s->wakeup(PICO_SOCK_EV_CLOSE, s);
-    }
-  } else {
-    tcp_send_ack(t);  /* return ACK */
-  }
-  return 0;
-}
-
-/*static int tcp_fin(struct pico_socket *s, struct pico_frame *f)
-{
-  return 0;
-}*/
-
-static int tcp_rcvfin(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  tcp_dbg("TCP> Received FIN in FIN_WAIT1\n");
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_CLOSING;
-  t->rcv_processed = t->rcv_nxt + 1;
-  t->rcv_nxt++;
-  /* send ACK */
-  tcp_send_ack(t);
-  return 0;
-}
-
-static int tcp_finack(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  tcp_dbg("TCP> ENTERED finack\n");
-  t->rcv_nxt++;
-  /* send ACK */
-  tcp_send_ack(t);
-
-  /* call socket wakeup with EV_FIN */
-  if (s->wakeup)
-    s->wakeup(PICO_SOCK_EV_FIN, s);
-  s->state &= 0x00FFU;
-  s->state |= PICO_SOCKET_STATE_TCP_TIME_WAIT;
-  /* set SHUT_REMOTE */
-  s->state |= PICO_SOCKET_STATE_SHUT_REMOTE;
-  pico_timer_add(2000, tcp_deltcb, t);
-
-  return 0;
-}
-
-static int tcp_rst(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) s;
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *) (f->transport_hdr);
-
-  tcp_dbg("TCP >>>>>>>>>>>>>> received RST <<<<<<<<<<<<<<<<<<<<\n");
-  if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_SYN_SENT) {
-    /* the RST is acceptable if the ACK field acknowledges the SYN */
-    if ((t->snd_nxt + 1) == ACKN(f)) {  /* valid, got to closed state */
-      /* update state */
-      (t->sock).state &= 0x00FFU;
-      (t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-      (t->sock).state &= 0xFF00U;
-      (t->sock).state |= PICO_SOCKET_STATE_CLOSED;
-
-      /* call EV_FIN wakeup before deleting */
-      if ((t->sock).wakeup)
-        (t->sock).wakeup(PICO_SOCK_EV_FIN, &(t->sock));
-
-      /* call EV_ERR wakeup before deleting */
-      pico_err = PICO_ERR_ECONNRESET;
-      if ((t->sock).wakeup)
-        (t->sock).wakeup(PICO_SOCK_EV_ERR, &(t->sock));
-
-      /* delete socket */
-      pico_socket_del(&t->sock);
-    } else {                      /* not valid, ignore */
-      tcp_dbg("TCP RST> IGNORE\n");
-      return 0;
-    }
-  } else {  /* all other states */
-    /* all reset (RST) segments are validated by checking their SEQ-fields,
-    a reset is valid if its sequence number is in the window */
-    if ((long_be(hdr->seq) >= t->rcv_ackd) && (long_be(hdr->seq) <= ((short_be(hdr->rwnd)<<(t->wnd_scale)) + t->rcv_ackd))) {
-      if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_SYN_RECV) {
-        /* go to closed */
-        (t->sock).state &= 0x00FFU;
-        (t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-        (t->sock).state &= 0xFF00U;
-        (t->sock).state |= PICO_SOCKET_STATE_CLOSED;
-        /* call EV_ERR wakeup */
-        pico_err = PICO_ERR_ECONNRESET;
-        if ((t->sock).wakeup)
-          (t->sock).wakeup(PICO_SOCK_EV_ERR, &(t->sock));
-        tcp_dbg("TCP RST> SOCKET BACK TO LISTEN\n");
-        pico_socket_del(s);
-      } else {
-        /* go to closed */
-        (t->sock).state &= 0x00FFU;
-        (t->sock).state |= PICO_SOCKET_STATE_TCP_CLOSED;
-        (t->sock).state &= 0xFF00U;
-        (t->sock).state |= PICO_SOCKET_STATE_CLOSED;
-
-        /* call EV_FIN wakeup before deleting */
-        if ((t->sock).wakeup)
-          (t->sock).wakeup(PICO_SOCK_EV_FIN, &(t->sock));
-        /* call EV_ERR wakeup before deleting */
-        pico_err = PICO_ERR_ECONNRESET;
-        if ((t->sock).wakeup)
-          (t->sock).wakeup(PICO_SOCK_EV_ERR, &(t->sock));
-
-        /* delete socket */
-        pico_socket_del(&t->sock);
-      }
-    } else {                      /* not valid, ignore */
-      tcp_dbg("TCP RST> IGNORE\n");
-      return 0;
-    }
-  }
-
-  return 0;
-}
-
-struct tcp_action_entry {
-  uint16_t tcpstate;
-  int (*syn)(struct pico_socket *s, struct pico_frame *f);
-  int (*synack)(struct pico_socket *s, struct pico_frame *f);
-  int (*ack)(struct pico_socket *s, struct pico_frame *f);
-  int (*data)(struct pico_socket *s, struct pico_frame *f);
-  int (*fin)(struct pico_socket *s, struct pico_frame *f);
-  int (*finack)(struct pico_socket *s, struct pico_frame *f);
-  int (*rst)(struct pico_socket *s, struct pico_frame *f);
-};
-
-static struct tcp_action_entry tcp_fsm[] = {
-    /* State                            syn              synack             ack                data             fin              finack           rst*/
-  { PICO_SOCKET_STATE_TCP_UNDEF,        NULL,            NULL,              NULL,              NULL,            NULL,            NULL,            NULL     },
-  { PICO_SOCKET_STATE_TCP_CLOSED,       NULL,            NULL,              NULL,              NULL,            NULL,            NULL,            NULL     },
-  { PICO_SOCKET_STATE_TCP_LISTEN,       &tcp_syn,        &tcp_nosync_rst,   &tcp_nosync_rst,   &tcp_nosync_rst, &tcp_nosync_rst, &tcp_nosync_rst, NULL     },
-  { PICO_SOCKET_STATE_TCP_SYN_SENT,     &tcp_nosync_rst, &tcp_synack,     &tcp_nosync_rst,   &tcp_nosync_rst, &tcp_nosync_rst, &tcp_nosync_rst, &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_SYN_RECV,     &tcp_nosync_rst, &tcp_nosync_rst,   &tcp_first_ack,    &tcp_nosync_rst, &tcp_nosync_rst, &tcp_nosync_rst, &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_ESTABLISHED,  &tcp_send_rst,   &tcp_send_rst,     &tcp_ack,          &tcp_data_in,    &tcp_closewait,  &tcp_closewait,  &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_CLOSE_WAIT,   &tcp_send_rst,   &tcp_send_rst,     &tcp_ack,          &tcp_send_rst,   &tcp_send_rst,   &tcp_send_rst,   &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_LAST_ACK,     &tcp_send_rst,   &tcp_send_rst,     &tcp_lastackwait,  &tcp_send_rst,   &tcp_send_rst,   &tcp_send_rst,   &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_FIN_WAIT1,    &tcp_send_rst,   &tcp_send_rst,     &tcp_finwaitack,   &tcp_data_in,    &tcp_rcvfin,     &tcp_finack,     &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_FIN_WAIT2,    &tcp_send_rst,   &tcp_send_rst,     &tcp_ack,          &tcp_data_in,    &tcp_finwaitfin, &tcp_finack,     &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_CLOSING,      &tcp_send_rst,   &tcp_send_rst,     &tcp_closewaitack, &tcp_send_rst,   &tcp_send_rst,   &tcp_send_rst,   &tcp_rst },
-  { PICO_SOCKET_STATE_TCP_TIME_WAIT,    &tcp_send_rst,   &tcp_send_rst,     &tcp_send_rst,     &tcp_send_rst,   &tcp_send_rst,   &tcp_send_rst,   &tcp_rst }
-};
-
-/*
-   NOTE: in SYN-RECV receiving syn when cloned by default (see yellow pos-it), should send reset.
-*/
-
-int pico_tcp_input(struct pico_socket *s, struct pico_frame *f)
-{
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *) (f->transport_hdr);
-  int ret = 0;
-  uint8_t flags = hdr->flags;
-  struct tcp_action_entry *action = &tcp_fsm[s->state >> 8];
-
-  f->payload = (f->transport_hdr + ((hdr->len & 0xf0) >> 2));
-  f->payload_len = f->transport_len - ((hdr->len & 0xf0) >> 2);
-
-  tcp_dbg("[%lu] TCP> [tcp input] socket: %p state: %d <-- local port:%d remote port: %d seq: %08x ack: %08x flags: %02x = t_len: %d, hdr: %u payload: %d\n", pico_tick,
-      s, s->state >> 8, short_be(hdr->trans.dport), short_be(hdr->trans.sport), SEQN(f), ACKN(f), hdr->flags, f->transport_len, (hdr->len & 0xf0) >> 2, f->payload_len );
-
-  /* This copy of the frame has the current socket as owner */
-  f->sock = s;
-
-  /* Those are not supported at this time. */
-  flags &= ~(PICO_TCP_CWR | PICO_TCP_URG | PICO_TCP_ECN);
-  if (flags == PICO_TCP_SYN) {
-    if (action->syn)
-      action->syn(s,f);
-  } else if (flags == (PICO_TCP_SYN | PICO_TCP_ACK)) {
-    if (action->synack)
-      action->synack(s,f);
-  } else {
-    if ((flags == PICO_TCP_ACK) || (flags == (PICO_TCP_ACK | PICO_TCP_PSH))) {
-      if (action->ack) {
-        action->ack(s,f);
-      }
-    }
-    if (f->payload_len > 0) {
-      ret = f->payload_len;
-      if (action->data)
-        action->data(s,f);
-    }
-    if (flags == PICO_TCP_FIN) {
-      if (action->fin)
-        action->fin(s,f);
-    }
-    if ((flags == (PICO_TCP_FIN | PICO_TCP_ACK)) || (flags == (PICO_TCP_FIN | PICO_TCP_ACK | PICO_TCP_PSH))) {
-      if (action->finack)
-        action->finack(s,f);
-    }
-    if (flags & PICO_TCP_RST) {
-      if (action->rst)
-        action->rst(s,f);
-    }
-  }
-
-//discard:
-  pico_frame_discard(f);
-  return ret;
-}
-
-static void tcp_send_keepalive(unsigned long when, void *_t)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)_t;
-  tcp_dbg("\n\nSending keepalive (%d), [State = %d]...\n", t->backoff,t->sock.state );
-  if( t->sock.net && ((t->sock.state & 0xFF00) == PICO_SOCKET_STATE_TCP_ESTABLISHED) )
-  {
-        tcp_send_ack(t);
-
-        if (t->keepalive_timer_running > 0) {
-            t->keepalive_timer_running--;
-        }
-
-        if (t->keepalive_timer_running == 0) {
-            t->keepalive_timer_running++;
-            tcp_dbg("[Self] Adding timer(retransmit keepalive)\n");
-            pico_timer_add(t->rto << (++t->backoff), tcp_send_keepalive, t);
-        }
-  }
-}
-
-int pico_tcp_output(struct pico_socket *s, int loop_score)
-{
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *)s;
-  struct pico_frame *f, *una;
-  struct pico_tcp_hdr *hdr;
-  int sent = 0;
-
-  una = first_segment(&t->tcpq_out);
-
-  f = peek_segment(&t->tcpq_out, t->snd_nxt);
-  while((f) && (t->cwnd >= t->in_flight)) {
-    hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-    f->timestamp = pico_tick;
-    tcp_add_options(t, f, hdr->flags, tcp_options_size(t, hdr->flags));
-    if (seq_compare(SEQN(f) + f->payload_len, SEQN(una) + (t->recv_wnd << t->recv_wnd_scale)) > 0) {
-      t->cwnd = t->in_flight;
-      if (t->cwnd < 1)
-        t->cwnd = 1;
-      if (t->x_mode != PICO_TCP_WINDOW_FULL) {
-        tcp_dbg("TCP> RIGHT SIZING (rwnd: %d, frame len: %d\n",t->recv_wnd << t->recv_wnd_scale, f->payload_len);
-        tcp_dbg("In window full...\n");
-        t->snd_nxt = SEQN(una);
-
-        /* Alternative to the line above:  (better performance, but seems to lock anyway with larger buffers)
-        if (seq_compare(t->snd_nxt, SEQN(una)) > 0)
-          t->snd_nxt -= f->payload_len;
-        */
-
-        t->x_mode = PICO_TCP_WINDOW_FULL;
-        if (t->keepalive_timer_running == 0) {
-          tcp_dbg("[Window full] Adding timer(send keepalive)\n");
-          tcp_send_keepalive(0, t);
-        }
-      }
-      break;
-    }
-    tcp_dbg("TCP> DEQUEUED (for output) frame %08x, acks %08x len= %d, remaining frames %d\n", SEQN(f), ACKN(f), f->payload_len,t->tcpq_out.frames);
-    tcp_send(t, f);
-    sent++;
-    loop_score--;
-    t->snd_last_out = SEQN(f);
-    if (loop_score < 1)
-      break;
-    if (f->payload_len > 0) {
-      f = next_segment(&t->tcpq_out, f);
-    } else {
-      f = NULL;
-    }
-  }
-  if (sent > 0) {
-    if (t->rto < PICO_TCP_RTO_MIN)
-      t->rto = PICO_TCP_RTO_MIN;
-    add_retransmission_timer(t, pico_tick + t->rto);
-  } else {
-    // no packets in queue ??
-  }
-
-  if ((t->tcpq_out.frames == 0) && (s->state & PICO_SOCKET_STATE_SHUT_LOCAL)) {    /* if no more packets in queue, XXX replacled !f by tcpq check */
-    if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_ESTABLISHED) {
-      tcp_dbg("TCP> buffer empty, shutdown established ...\n");
-      /* send fin if queue empty and in state shut local (write) */
-      tcp_send_fin(t);
-      /* change tcp state to FIN_WAIT1 */
-      s->state &= 0x00FFU;
-      s->state |= PICO_SOCKET_STATE_TCP_FIN_WAIT1;
-    } else if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_CLOSE_WAIT) {
-      /* send fin if queue empty and in state shut local (write) */
-      tcp_send_fin(t);
-      /* change tcp state to LAST_ACK */
-      s->state &= 0x00FFU;
-      s->state |= PICO_SOCKET_STATE_TCP_LAST_ACK;
-      tcp_dbg("TCP> STATE: LAST_ACK.\n");
-    }
-  }
-  return loop_score;
-}
-
-/* function to make new segment from hold queue with specific size (mss) */
-static struct pico_frame * pico_hold_segment_make(struct pico_socket_tcp *t)
-{
-  struct pico_frame *f_temp,*f_new;
-  struct pico_socket *s = (struct pico_socket *) &t->sock;
-  struct pico_tcp_hdr *hdr;
-  int total_len = 0, total_payload_len = 0;
-  int off = 0, test = 0;
-
-  off = pico_tcp_overhead(s);
-
-  /* init with first frame in hold queue */
-  f_temp = first_segment(&t->tcpq_hold);
-  total_len = f_temp->payload_len;
-  f_temp = next_segment(&t->tcpq_hold, f_temp);
-
-  /* check till total_len <= MSS */
-  while ((f_temp != NULL) && ((total_len+f_temp->payload_len) <= PICO_TCP_DEFAULT_MSS)) {
-    total_len += f_temp->payload_len;
-    f_temp = next_segment(&t->tcpq_hold, f_temp);
-    if (f_temp == NULL)
-      break;
-  }
-  /* alloc new frame with payload size = off + total_len */
-  f_new = pico_socket_frame_alloc(s, off + total_len);
-  if (!f_new) {
-    pico_err = PICO_ERR_ENOMEM;
-    return f_new;
-  }
-
-  hdr = (struct pico_tcp_hdr *) f_new->transport_hdr;
-  /* init new frame */
-  f_new->payload += off;
-  f_new->payload_len -= off;
-  f_new->sock = s;
-
-  f_temp = first_segment(&t->tcpq_hold);
-  hdr->seq = ((struct pico_tcp_hdr *)(f_temp->transport_hdr))->seq;  /* get sequence number of first frame */
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-
-  /* check till total_payload_len <= MSS */
-  while ((f_temp != NULL) && ((total_payload_len + f_temp->payload_len) <= PICO_TCP_DEFAULT_MSS)) {
-    /* cpy data and discard frame */
-    test++;
-    memcpy(f_new->payload + total_payload_len, f_temp->payload, f_temp->payload_len);
-    total_payload_len += f_temp->payload_len;
-    pico_discard_segment(&t->tcpq_hold, f_temp);
-    f_temp = first_segment(&t->tcpq_hold);
-  }
-
-  hdr->len = (f_new->payload - f_new->transport_hdr) << 2 | t->jumbo;
-
-  tcp_dbg("NAGLE make - joined %d segments, len %d bytes\n",test,total_payload_len);
-
-  return f_new;
-}
-
-/* original behavior kept when Nagle disabled;
-   Nagle algorithm added here, keeping hold frame queue instead of eg linked list of data */
-int pico_tcp_push(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_tcp_hdr *hdr = (struct pico_tcp_hdr *)f->transport_hdr;
-  struct pico_socket_tcp *t = (struct pico_socket_tcp *) f->sock;
-  struct pico_frame *f_new;
-  int total_len = 0;
-
-  hdr->trans.sport = t->sock.local_port;
-  hdr->trans.dport = t->sock.remote_port;
-  hdr->seq = long_be(t->snd_last + 1);
-  hdr->len = (f->payload - f->transport_hdr) << 2 | t->jumbo;
-
-  if (f->payload_len > (t->tcpq_out.max_size - t->tcpq_out.size))
-    t->sock.ev_pending &= (~PICO_SOCK_EV_WR);
-
-  /***************************************************************************/
-
-  if (!IS_NAGLE_ENABLED((&(t->sock)))) {
-    /* TCP_NODELAY enabled, original behavior */
-    if (pico_enqueue_segment(&t->tcpq_out,f) > 0) {
-      tcp_dbg("TCP_PUSH - NO NAGLE - Pushing segment %08x, len %08x to socket %p\n", t->snd_last + 1, f->payload_len, t);
-      t->snd_last += f->payload_len;
-      return f->payload_len;
-    } else {
-      tcp_dbg("Enqueue failed.\n");
-      return 0;
-    }
-  }
-  /***************************************************************************/
-  else {
-    /* Nagle's algorithm enabled, check if ready to send, or put frame in hold queue */
-    if (IS_TCP_IDLE(t) && IS_TCP_HOLDQ_EMPTY(t)) {  /* opt 1. send frame */
-      if (pico_enqueue_segment(&t->tcpq_out,f) > 0) {
-        tcp_dbg("TCP_PUSH - NAGLE - Pushing segment %08x, len %08x to socket %p\n", t->snd_last + 1, f->payload_len, t);
-        t->snd_last += f->payload_len;
-        return f->payload_len;
-      } else {
-        tcp_dbg("Enqueue failed.\n");
-        return 0;
-      }
-    } else {                                        /* opt 2. hold data back */
-      total_len = f->payload_len + t->tcpq_hold.size;
-      if ((total_len >= PICO_TCP_DEFAULT_MSS) && ((t->tcpq_out.max_size - t->tcpq_out.size) >= PICO_TCP_DEFAULT_MSS)) {/* TODO check mss socket */
-        /* IF enough data in hold (>mss) AND space in out queue (>mss) */
-        /* add current frame in hold and make new segment */
-        if (pico_enqueue_segment(&t->tcpq_hold,f) > 0 ) {
-          tcp_dbg("TCP_PUSH - NAGLE - Pushed into hold, make new (enqueued frames out %d)\n",t->tcpq_out.frames);
-          t->snd_last += f->payload_len;    /* XXX  WATCH OUT */
-          f_new = pico_hold_segment_make(t);
-        } else {
-          tcp_dbg("TCP_PUSH - NAGLE - enqueue hold failed 1\n");
-          return 0;
-        }
-        /* and put new frame in out queue */
-        if ((f_new != NULL) && (pico_enqueue_segment(&t->tcpq_out,f_new) > 0)) {
-          return f_new->payload_len;
-        } else {
-          tcp_dbg("TCP_PUSH - NAGLE - enqueue out failed, f_new = %p\n",f_new);
-          return -1;                        /* XXX something seriously wrong */
-        }
-      } else {
-        /* ELSE put frame in hold queue */
-        if (pico_enqueue_segment(&t->tcpq_hold,f) > 0) {
-          tcp_dbg("TCP_PUSH - NAGLE - Pushed into hold (enqueued frames out %d)\n",t->tcpq_out.frames);
-          t->snd_last += f->payload_len;    /* XXX  WATCH OUT */
-          return f->payload_len;
-        } else {
-          tcp_dbg("TCP_PUSH - NAGLE - enqueue hold failed 2\n");
-          return 0;
-        }
-      }
-    }
-  }
-  /***************************************************************************/
-}
-#endif //PICO_SUPPORT_TCP
--- a/modules/pico_tcp.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_TCP
-#define _INCLUDE_PICO_TCP
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-#include "pico_socket.h"
-
-extern struct pico_protocol pico_proto_tcp;
-
-struct __attribute__((packed)) pico_tcp_hdr {
-  struct pico_trans trans;
-  uint32_t seq;
-  uint32_t ack;
-  uint8_t  len;
-  uint8_t flags;
-  uint16_t  rwnd;
-  uint16_t crc;
-  uint16_t urgent;
-};
-
-struct __attribute__((packed)) tcp_pseudo_hdr_ipv4
-{
-  struct pico_ip4 src;
-  struct pico_ip4 dst;
-  uint16_t tcp_len;
-  uint8_t res;
-  uint8_t proto;
-};
-
-#define PICO_TCPHDR_SIZE 20
-#define PICO_SIZE_TCPOPT_SYN 20
-#define PICO_SIZE_TCPHDR (sizeof(struct pico_tcp_hdr))
-
-#define PICO_TCP_DEFAULT_MSS 1444
-
-
-
-/* TCP options */
-#define PICO_TCP_OPTION_END         0x00
-#define PICO_TCPOPTLEN_END        1
-#define PICO_TCP_OPTION_NOOP        0x01
-#define PICO_TCPOPTLEN_NOOP       1
-#define PICO_TCP_OPTION_MSS         0x02
-#define PICO_TCPOPTLEN_MSS        4
-#define PICO_TCP_OPTION_WS          0x03
-#define PICO_TCPOPTLEN_WS         3
-#define PICO_TCP_OPTION_SACK_OK        0x04
-#define PICO_TCPOPTLEN_SACK_OK       2
-#define PICO_TCP_OPTION_SACK        0x05
-#define PICO_TCPOPTLEN_SACK       2 /* Plus the block */
-#define PICO_TCP_OPTION_TIMESTAMP   0x08
-#define PICO_TCPOPTLEN_TIMESTAMP  10
-
-/* TCP flags */
-#define PICO_TCP_FIN 0x01
-#define PICO_TCP_SYN 0x02
-#define PICO_TCP_RST 0x04
-#define PICO_TCP_PSH 0x08
-#define PICO_TCP_ACK 0x10
-#define PICO_TCP_URG 0x20
-#define PICO_TCP_ECN 0x40
-#define PICO_TCP_CWR 0x80
-
-
-
-struct __attribute__((packed)) pico_tcp_option
-{
-  uint8_t kind;
-  uint8_t len;
-#if 0
-  union {
-   uint16_t mss;
-    uint8_t wshift;
-    struct {
-      uint32_t tsval;
-      uint32_t tsecr;
-    } timestamp;
-  } data;
-#endif
-};
-
-struct pico_socket *pico_tcp_open(void);
-int pico_tcp_read(struct pico_socket *s, void *buf, int len);
-int pico_tcp_initconn(struct pico_socket *s);
-int pico_tcp_input(struct pico_socket *s, struct pico_frame *f);
-uint16_t pico_tcp_checksum_ipv4(struct pico_frame *f);
-int pico_tcp_overhead(struct pico_socket *s);
-int pico_tcp_output(struct pico_socket *s, int loop_score);
-int pico_tcp_queue_in_is_empty(struct pico_socket *s);
-int pico_tcp_reply_rst(struct pico_frame *f);
-
-#endif
--- a/modules/pico_udp.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_udp.h"
-#include "pico_config.h"
-#include "pico_eth.h"
-#include "pico_socket.h"
-#include "pico_stack.h"
-
-
-/* Queues */
-static struct pico_queue udp_in = {};
-static struct pico_queue udp_out = {};
-
-
-/* Functions */
-
-uint16_t pico_udp_checksum_ipv4(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_udp_hdr *udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-  struct pico_socket *s = f->sock;
-  struct pico_ipv4_pseudo_hdr pseudo;
-
-  if (s) {
-    /* Case of outgoing frame */
-    //dbg("UDP CRC: on outgoing frame\n");
-    pseudo.src.addr = s->local_addr.ip4.addr;
-    pseudo.dst.addr = s->remote_addr.ip4.addr;
-  } else {
-    /* Case of incomming frame */
-    //dbg("UDP CRC: on incomming frame\n");
-    pseudo.src.addr = hdr->src.addr;
-    pseudo.dst.addr = hdr->dst.addr;
-  }
-  pseudo.zeros = 0;
-  pseudo.proto = PICO_PROTO_UDP;
-  pseudo.len = short_be(f->transport_len);
-
-  return pico_dualbuffer_checksum(&pseudo, sizeof(struct pico_ipv4_pseudo_hdr), udp_hdr, f->transport_len);
-}
-
-
-static int pico_udp_process_out(struct pico_protocol *self, struct pico_frame *f)
-{
-  return pico_network_send(f); 
-}
-
-static int pico_udp_push(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_udp_hdr *hdr = (struct pico_udp_hdr *) f->transport_hdr;
-  struct pico_remote_duple *remote_duple = (struct pico_remote_duple *) f->info;
-
-  /* this (fragmented) frame should contain a transport header */
-  if (f->transport_hdr != f->payload) {
-    hdr->trans.sport = f->sock->local_port;
-    if (remote_duple) {
-      hdr->trans.dport = remote_duple->remote_port;
-    } else {
-      hdr->trans.dport = f->sock->remote_port;
-    }
-    hdr->len = short_be(f->transport_len);
-    /* do not perform CRC validation. If you want to, a system needs to be 
-       implemented to calculate the CRC over the total payload of a 
-       fragmented payload */
-    hdr->crc = 0;
-  }
-
-  if (pico_enqueue(self->q_out, f) > 0) {
-    return f->payload_len;
-  } else {
-    return 0;
-  }    
-}
-
-/* Interface: protocol definition */
-struct pico_protocol pico_proto_udp = {
-  .name = "udp",
-  .proto_number = PICO_PROTO_UDP,
-  .layer = PICO_LAYER_TRANSPORT,
-  .process_in = pico_transport_process_in,
-  .process_out = pico_udp_process_out,
-  .push = pico_udp_push,
-  .q_in = &udp_in,
-  .q_out = &udp_out,
-};
-
-
-#define PICO_UDP_MODE_UNICAST 0x01
-#define PICO_UDP_MODE_MULTICAST 0x02
-#define PICO_UDP_MODE_BROADCAST 0xFF
-
-struct pico_socket_udp
-{
-  struct pico_socket sock;
-  int mode;
-#ifdef PICO_SUPPORT_MCAST
-  uint8_t mc_ttl; /* Multicasting TTL */
-#endif
-};
-
-#ifdef PICO_SUPPORT_MCAST
-int pico_udp_set_mc_ttl(struct pico_socket *s, uint8_t ttl)
-{
-  struct pico_socket_udp *u;
-  if(!s) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-  u = (struct pico_socket_udp *) s;
-  u->mc_ttl = ttl;
-  return 0;
-}
-
-int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl)
-{
-  struct pico_socket_udp *u;
-  if(!s)
-    return -1;
-  u = (struct pico_socket_udp *) s;
-  *ttl = u->mc_ttl;
-  return 0;
-}
-#endif /* PICO_SUPPORT_MCAST */
-
-struct pico_socket *pico_udp_open(void)
-{
-  struct pico_socket_udp *u = pico_zalloc(sizeof(struct pico_socket_udp));
-  if (!u)
-    return NULL;
-  u->mode = PICO_UDP_MODE_UNICAST;
-
-#ifdef PICO_SUPPORT_MCAST
-  u->mc_ttl = PICO_IP_DEFAULT_MULTICAST_TTL;
-  /* enable multicast loopback by default */
-  u->sock.opt_flags |= (1 << PICO_SOCKET_OPT_MULTICAST_LOOP);
-#endif
-
-  return &u->sock;
-}
-
-int pico_udp_recv(struct pico_socket *s, void *buf, int len, void *src, uint16_t *port)
-{
-  struct pico_frame *f = pico_queue_peek(&s->q_in);
-  if (f) {
-    f->payload = f->transport_hdr + sizeof(struct pico_udp_hdr);
-    f->payload_len = f->transport_len - sizeof(struct pico_udp_hdr);
-//    dbg("expected: %d, got: %d\n", len, f->payload_len);
-    if (src)
-      pico_store_network_origin(src, f);
-    if (port) {
-      struct pico_trans *hdr = (struct pico_trans *)f->transport_hdr;
-      *port = hdr->sport;
-    }
-    if (f->payload_len > len) {
-      memcpy(buf, f->payload, len);
-      f->payload += len;
-      f->payload_len -= len;
-      return len;
-    } else {
-      int ret = f->payload_len;
-      memcpy(buf, f->payload, f->payload_len);
-      f = pico_dequeue(&s->q_in);
-      pico_frame_discard(f);
-      return ret;
-    }
-  } else return 0;
-}
-
--- a/modules/pico_udp.h	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-*********************************************************************/
-#ifndef _INCLUDE_PICO_UDP
-#define _INCLUDE_PICO_UDP
-#include "pico_addressing.h"
-#include "pico_protocol.h"
-
-extern struct pico_protocol pico_proto_udp;
-
-struct __attribute__((packed)) pico_udp_hdr {
-  struct pico_trans trans;
-  uint16_t len;
-  uint16_t crc;
-};
-#define PICO_UDPHDR_SIZE 8
-
-struct pico_socket *pico_udp_open(void);
-int pico_udp_recv(struct pico_socket *s, void *buf, int len, void *src, uint16_t *port);
-uint16_t pico_udp_checksum_ipv4(struct pico_frame *f);
-
-#ifdef PICO_SUPPORT_MCAST
-int pico_udp_set_mc_ttl(struct pico_socket *s, uint8_t ttl);
-int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl);
-#else
-static inline int pico_udp_set_mc_ttl(struct pico_socket *s, uint8_t ttl)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-static inline int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl)
-{
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  return -1;
-}
-#endif /* PICO_SUPPORT_MCAST */
-
-#endif
--- a/stack/pico_arp.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_arp.h"
-#include "pico_tree.h"
-#include "pico_ipv4.h"
-#include "pico_device.h"
-#include "pico_stack.h"
-
-const uint8_t PICO_ETHADDR_ALL[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-#define PICO_ARP_TIMEOUT 600000
-#define PICO_ARP_RETRY 300
-
-#ifdef DEBUG_ARP
-    #define arp_dbg dbg
-#else
-    #define arp_dbg(...) do{}while(0)
-#endif
-
-static struct pico_queue pending;
-static int pending_timer_on = 0;
-
-void check_pending(unsigned long now, void *_unused)
-{
-  struct pico_frame *f = pico_dequeue(&pending);
-  if (!f) {
-    pending_timer_on = 0;
-    return;
-  }
-  if(pico_ethernet_send(f) > 0)
-    pico_frame_discard(f);
-  pico_timer_add(PICO_ARP_RETRY, &check_pending, NULL);
-}
-
-
-struct
-__attribute__ ((__packed__)) 
-pico_arp_hdr
-{
-  uint16_t htype;
-  uint16_t ptype;
-  uint8_t hsize;
-  uint8_t psize;
-  uint16_t opcode;
-  uint8_t s_mac[PICO_SIZE_ETH];
-  struct pico_ip4 src;
-  uint8_t d_mac[PICO_SIZE_ETH];
-  struct pico_ip4 dst;
-};
-
-
-#define PICO_SIZE_ARPHDR ((sizeof(struct pico_arp_hdr)))
-
-/* Arp Entries for the tables. */
-struct pico_arp {
-/* CAREFUL MAN! ARP entry MUST begin with a pico_eth structure, 
- * due to in-place casting!!! */
-  struct pico_eth eth;
-  struct pico_ip4 ipv4;
-  int    arp_status;
-  uint32_t timestamp;
-  struct pico_device *dev;
-};
-
-
-
-/*****************/
-/**  ARP TREE **/
-/*****************/
-
-/* Routing destination */
-
-static int arp_compare(void * ka, void * kb)
-{
-    struct pico_arp *a = ka, *b = kb;
-  if (a->ipv4.addr < b->ipv4.addr)
-    return -1;
-  else if (a->ipv4.addr > b->ipv4.addr)
-    return 1;
-  return 0;
-}
-
-PICO_TREE_DECLARE(arp_tree, arp_compare);
-
-/*********************/
-/**  END ARP TREE **/
-/*********************/
-
-struct pico_eth *pico_arp_lookup(struct pico_ip4 *dst)
-{
-  struct pico_arp search, *found;
-  search.ipv4.addr = dst->addr;
-  found = pico_tree_findKey(&arp_tree,&search);
-  if (found && (found->arp_status != PICO_ARP_STATUS_STALE))
-    return &found->eth;
-  return NULL;
-}
-
-struct pico_ip4 *pico_arp_reverse_lookup(struct pico_eth *dst)
-{
-  struct pico_arp* search;
-  struct pico_tree_node * index;
-  pico_tree_foreach(index,&arp_tree){
-      search = index->keyValue;
-    if(memcmp(&(search->eth.addr), &dst->addr, 6) == 0)
-      return &search->ipv4;
-  }
-  return NULL;
-}
-
-struct pico_eth *pico_arp_get(struct pico_frame *f) {
-  struct pico_eth *a4;
-  struct pico_ip4 gateway;
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_ipv4_link *l;
-
-  l = pico_ipv4_link_get(&hdr->dst);
-  if(l){
-    //address belongs to ourself
-    return &l->dev->eth->mac;
-  }
-
-  gateway = pico_ipv4_route_get_gateway(&hdr->dst);
-  /* check if dst is local (gateway = 0), or if to use gateway */
-  if (gateway.addr != 0)
-    a4 = pico_arp_lookup(&gateway);          /* check if gateway ip mac in cache */
-  else
-    a4 = pico_arp_lookup(&hdr->dst);         /* check if local ip mac in cache */
-  if (!a4) {
-     if (++f->failure_count < 4) {
-       dbg ("================= ARP REQUIRED: %d =============\n\n", f->failure_count);
-       /* check if dst is local (gateway = 0), or if to use gateway */
-       if (gateway.addr != 0)
-         pico_arp_query(f->dev, &gateway);  /* arp to gateway */
-       else
-         pico_arp_query(f->dev, &hdr->dst); /* arp to dst */
-
-       pico_enqueue(&pending, f);
-       if (!pending_timer_on) {
-        pending_timer_on++;
-        pico_timer_add(PICO_ARP_RETRY, &check_pending, NULL);
-       }
-     } else {
-      dbg("ARP: Destination Unreachable\n");
-      pico_notify_dest_unreachable(f);
-      pico_frame_discard(f);
-    }
-  }
-  return a4;
-}
-
-#ifdef DEBUG_ARP
-void dbg_arp(void)
-{
-  struct pico_arp *a;
-  struct pico_tree_node * index;
-
-  pico_tree_foreach(index,&arp_tree) {
-      a = index->keyValue;
-    arp_dbg("ARP to  %08x, mac: %02x:%02x:%02x:%02x:%02x:%02x\n", a->ipv4.addr,a->eth.addr[0],a->eth.addr[1],a->eth.addr[2],a->eth.addr[3],a->eth.addr[4],a->eth.addr[5] );
-  }
-}
-#endif
-
-void arp_expire(unsigned long now, void *_stale)
-{
-  struct pico_arp *stale = (struct pico_arp *) _stale;
-  stale->arp_status = PICO_ARP_STATUS_STALE;
-  arp_dbg("ARP: Setting arp_status to STALE\n");
-  pico_arp_query(stale->dev, &stale->ipv4);
-
-}
-
-void pico_arp_add_entry(struct pico_arp *entry)
-{
-    entry->arp_status = PICO_ARP_STATUS_REACHABLE;
-    entry->timestamp  = PICO_TIME();
-
-    pico_tree_insert(&arp_tree,entry);
-    arp_dbg("ARP ## reachable.\n");
-    pico_timer_add(PICO_ARP_TIMEOUT, arp_expire, entry);
-}
-
-int pico_arp_create_entry(uint8_t* hwaddr, struct pico_ip4 ipv4, struct pico_device* dev)
-{
-    struct pico_arp* arp = pico_zalloc(sizeof(struct pico_arp));
-    if(!arp){
-        pico_err = PICO_ERR_ENOMEM;
-        return -1;
-    }
-    memcpy(arp->eth.addr, hwaddr, 6);
-    arp->ipv4.addr = ipv4.addr;
-    arp->dev = dev;
-
-    pico_arp_add_entry(arp);
-
-    return 0;
-}
-
-int pico_arp_receive(struct pico_frame *f)
-{
-  struct pico_arp_hdr *hdr;
-  struct pico_arp search, *found, *new = NULL;
-  int ret = -1;
-  hdr = (struct pico_arp_hdr *) f->net_hdr;
-
-  if (!hdr)
-    goto end;
-
-
-  /* Populate a new arp entry */
-  search.ipv4.addr = hdr->src.addr;
-  memcpy(search.eth.addr, hdr->s_mac, PICO_SIZE_ETH);
-
-  /* Search for already existing entry */
-
-  found = pico_tree_findKey(&arp_tree,&search);
-  if (!found) {
-    new = pico_zalloc(sizeof(struct pico_arp));
-    if (!new)
-      goto end;
-    new->ipv4.addr = hdr->src.addr;
-  }
-  else if (found->arp_status == PICO_ARP_STATUS_STALE) {
-    /* Replace if stale */
-    new = found;
-
-    pico_tree_delete(&arp_tree,new);
-  }
-
-  ret = 0;
-
-  if (new) {
-    memcpy(new->eth.addr, hdr->s_mac, PICO_SIZE_ETH);
-    new->dev = f->dev;
-    pico_arp_add_entry(new);
-  }
-
-  if (hdr->opcode == PICO_ARP_REQUEST) {
-    struct pico_ip4 me;
-    struct pico_eth_hdr *eh = (struct pico_eth_hdr *)f->datalink_hdr;
-    struct pico_device *link_dev;
-    me.addr = hdr->dst.addr;
-
-    link_dev = pico_ipv4_link_find(&me);
-    if (link_dev != f->dev)
-      goto end;
-
-    hdr->opcode = PICO_ARP_REPLY;
-    memcpy(hdr->d_mac, hdr->s_mac, PICO_SIZE_ETH);
-    memcpy(hdr->s_mac, f->dev->eth->mac.addr, PICO_SIZE_ETH);
-    hdr->dst.addr = hdr->src.addr;
-    hdr->src.addr = me.addr;
-
-    /* Prepare eth header for arp reply */
-    memcpy(eh->daddr, eh->saddr, PICO_SIZE_ETH);
-    memcpy(eh->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
-    f->start = f->datalink_hdr;
-    f->len = PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR;
-    f->dev->send(f->dev, f->start, f->len);
-  }
-
-#ifdef DEBUG_ARG
-  dbg_arp();
-#endif
-
-end:
-  pico_frame_discard(f);
-  return ret;
-}
-
-int pico_arp_query(struct pico_device *dev, struct pico_ip4 *dst)
-{
-  struct pico_frame *q = pico_frame_alloc(PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR);
-  struct pico_eth_hdr *eh;
-  struct pico_arp_hdr *ah;
-  struct pico_ip4 *src;
-  int ret;
-
-  src = pico_ipv4_source_find(dst);
-  if (!src)
-    return -1;
-
-  arp_dbg("QUERY: %08x\n", dst->addr);
-
-  if (!q)
-    return -1;
-  eh = (struct pico_eth_hdr *)q->start;
-  ah = (struct pico_arp_hdr *) (q->start + PICO_SIZE_ETHHDR);
-
-  /* Fill eth header */
-  memcpy(eh->saddr, dev->eth->mac.addr, PICO_SIZE_ETH);
-  memcpy(eh->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH);
-  eh->proto = PICO_IDETH_ARP;
-
-  /* Fill arp header */
-  ah->htype  = PICO_ARP_HTYPE_ETH;
-  ah->ptype  = PICO_IDETH_IPV4;
-  ah->hsize  = PICO_SIZE_ETH;
-  ah->psize  = PICO_SIZE_IP4;
-  ah->opcode = PICO_ARP_REQUEST;
-  memcpy(ah->s_mac, dev->eth->mac.addr, PICO_SIZE_ETH);
-  ah->src.addr = src->addr;
-  ah->dst.addr = dst->addr;
-  arp_dbg("Sending arp query.\n");
-  ret = dev->send(dev, q->start, q->len);
-  pico_frame_discard(q);
-  return ret;
-}
--- a/stack/pico_device.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_device.h"
-#include "pico_stack.h"
-#include "pico_protocol.h"
-#include "pico_tree.h"
-
-
-static int pico_dev_cmp(void *ka, void *kb)
-{
-    struct pico_device *a = ka, *b = kb;
-  if (a->hash < b->hash)
-    return -1;
-  if (a->hash > b->hash)
-    return 1;
-  return 0;
-}
-
-PICO_TREE_DECLARE(Device_tree,pico_dev_cmp);
-
-int pico_device_init(struct pico_device *dev, char *name, uint8_t *mac)
-{
-    int len = strlen(name);
-    if(len>MAX_DEVICE_NAME)
-        len = MAX_DEVICE_NAME;
-  memcpy(dev->name, name, len);
-  dev->hash = pico_hash(dev->name);
-
-  pico_tree_insert(&Device_tree,dev);
-  dev->q_in = pico_zalloc(sizeof(struct pico_queue));
-  dev->q_out = pico_zalloc(sizeof(struct pico_queue));
-
-  if (mac) {
-    dev->eth = pico_zalloc(sizeof(struct pico_ethdev));
-    memcpy(dev->eth->mac.addr, mac, PICO_SIZE_ETH);
-  } else {
-    dev->eth = NULL;
-  }
-
-  if (!dev->q_in || !dev->q_out || (mac && !dev->eth))
-    return -1;
-  return 0;
-}
-
-void pico_device_destroy(struct pico_device *dev)
-{
-  if (dev->destroy)
-    dev->destroy(dev);
-
-  if (dev->q_in) {
-    pico_queue_empty(dev->q_in);
-    pico_free(dev->q_in);
-  }
-  if (dev->q_out) {
-    pico_queue_empty(dev->q_out);
-    pico_free(dev->q_out);
-  }
-
-  if (dev->eth)
-    pico_free(dev->eth);
-
-  pico_tree_delete(&Device_tree,dev);
-  pico_free(dev);
-}
-
-static int devloop(struct pico_device *dev, int loop_score, int direction)
-{
-  struct pico_frame *f;
-
-  /* If device supports interrupts, read the value of the condition and trigger the dsr */
-  if ((dev->__serving_interrupt) && (dev->dsr)) {
-    /* call dsr routine */
-    loop_score = dev->dsr(dev, loop_score);
-  }
-
-  /* If device supports polling, give control. Loop score is managed internally, 
-   * remaining loop points are returned. */
-  if (dev->poll) {
-    loop_score = dev->poll(dev, loop_score);
-  }
-
-  if (direction == PICO_LOOP_DIR_OUT) {
-
-    while(loop_score > 0) {
-      if (dev->q_out->frames <= 0)
-        break;
-
-      /* Device dequeue + send */
-      f = pico_dequeue(dev->q_out);
-      if (f) {
-        if (dev->eth) {
-          int ret = pico_ethernet_send(f);
-          if (0 == ret) {
-            loop_score--;
-            continue;
-          } if (ret < 0) {
-            if (!pico_source_is_local(f)) { 
-              dbg("Destination unreachable -------> SEND ICMP\n");
-              pico_notify_dest_unreachable(f);
-            } else {
-              dbg("Destination unreachable -------> LOCAL\n");
-            }
-            pico_frame_discard(f);
-            continue;
-          }
-        } else {
-          dev->send(dev, f->start, f->len);
-        }
-        pico_frame_discard(f);
-        loop_score--;
-      }
-    }
-
-  } else if (direction == PICO_LOOP_DIR_IN) {
-
-    while(loop_score > 0) {
-      if (dev->q_in->frames <= 0)
-        break;
-
-      /* Receive */
-      f = pico_dequeue(dev->q_in);
-      if (f) {
-        if (dev->eth) {
-          f->datalink_hdr = f->buffer;
-          pico_ethernet_receive(f);
-        } else {
-          f->net_hdr = f->buffer;
-          pico_network_receive(f);
-        }
-        loop_score--;
-      }
-    }
-  }
-
-  return loop_score;
-}
-
-
-#define DEV_LOOP_MIN  16
-
-int pico_devices_loop(int loop_score, int direction)
-{
-  struct pico_device *start;
-  static struct pico_device *next = NULL, *next_in = NULL, *next_out = NULL;
-  static struct pico_tree_node * next_node, * in_node, * out_node;
-
-  if (next_in == NULL) {
-    in_node = pico_tree_firstNode(Device_tree.root);
-    next_in = in_node->keyValue;
-  }
-  if (next_out == NULL) {
-      out_node = pico_tree_firstNode(Device_tree.root);
-    next_out = out_node->keyValue;
-  }
-  
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      next_node = in_node;
-    next = next_in;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      next_node = out_node;
-    next = next_out;
-  }
-
-  /* init start node */
-  start = next;
-
-  /* round-robin all devices, break if traversed all devices */
-  while (loop_score > DEV_LOOP_MIN && next != NULL) {
-    loop_score = devloop(next, loop_score, direction);
-
-    next_node = pico_tree_next(next_node);
-    next = next_node->keyValue;
-
-    if (next == NULL)
-    {
-        next_node = pico_tree_firstNode(Device_tree.root);
-      next = next_node->keyValue;
-    }
-    if (next == start)
-      break;
-  }
-
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      in_node = next_node;
-    next_in = next;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      out_node = next_node;
-    next_out = next;
-  }
-
-  return loop_score;
-}
-
-struct pico_device* pico_get_device(char* name)
-{
-  struct pico_device *dev;
-  struct pico_tree_node * index;
-  pico_tree_foreach(index, &Device_tree){
-      dev = index->keyValue;
-    if(strcmp(name, dev->name) == 0)
-      return dev;
-  }
-  return NULL;
-}
-
-int pico_device_broadcast(struct pico_frame * f)
-{
-    struct pico_tree_node * index;
-    int ret = -1;
-
-    pico_tree_foreach(index,&Device_tree)
-    {
-        struct pico_device * dev = index->keyValue;
-        if(dev != f->dev)
-        {
-            struct pico_frame * copy = pico_frame_copy(f);
-
-            if(!copy)
-                return -1;
-            copy->dev = dev;
-            copy->dev->send(copy->dev, copy->start, copy->len);
-            pico_frame_discard(copy);
-        }
-        else
-        {
-            ret = f->dev->send(f->dev, f->start, f->len);
-        }
-    }
-
-    return ret;
-}
--- a/stack/pico_frame.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_frame.h"
-
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-static int n_frames_allocated;
-#endif
-
-/** frame alloc/dealloc/copy **/
-void pico_frame_discard(struct pico_frame *f)
-{
-  (*f->usage_count)--;
-  if (*f->usage_count <= 0) {
-    pico_free(f->usage_count);
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-    dbg("Discarded buffer @%p, caller: %p\n", f->buffer, __builtin_return_address(3));
-    dbg("DEBUG MEMORY: %d frames in use.\n", --n_frames_allocated);
-#endif
-    pico_free(f->buffer);
-    if (f->info)
-      pico_free(f->info);
-  }
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-  else {
-    dbg("Removed frame @%p(copy), usage count now: %d\n", f, *f->usage_count);
-  }
-#endif
-  pico_free(f);
-}
-
-struct pico_frame *pico_frame_copy(struct pico_frame *f)
-{
-  struct pico_frame *new = pico_zalloc(sizeof(struct pico_frame));
-  if (!new)
-    return NULL;
-  memcpy(new, f, sizeof(struct pico_frame));
-  *(new->usage_count) += 1;
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-  dbg("Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
-#endif
-  new->next = NULL;
-  return new;
-}
-
-
-struct pico_frame *pico_frame_alloc(int size)
-{
-  struct pico_frame *p = pico_zalloc(sizeof(struct pico_frame));
-  if (!p)
-    return NULL;
-  p->buffer = pico_zalloc(size);
-  if (!p->buffer) {
-    pico_free(p);
-    return NULL;
-  }
-  p->usage_count = pico_zalloc(sizeof(uint32_t));
-  if (!p->usage_count) {
-    pico_free(p->buffer);
-    pico_free(p);
-    return NULL;
-  }
-  p->buffer_len = size;
-
-
-  /* By default, frame content is the full buffer. */
-  p->start = p->buffer;
-  p->len = p->buffer_len;
-  *p->usage_count = 1;
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-    dbg("Allocated buffer @%p, len= %d caller: %p\n", p->buffer, p->buffer_len, __builtin_return_address(2));
-    dbg("DEBUG MEMORY: %d frames in use.\n", ++n_frames_allocated);
-#endif
-  return p;
-}
-
-struct pico_frame *pico_frame_deepcopy(struct pico_frame *f)
-{
-  struct pico_frame *new = pico_frame_alloc(f->buffer_len);
-  int addr_diff;
-  unsigned char *buf;
-  uint32_t *uc;
-  if (!new)
-    return NULL;
-
-  /* Save the two key pointers... */
-  buf = new->buffer;
-  uc  = new->usage_count;
-
-  /* Overwrite all fields with originals */
-  memcpy(new, f, sizeof(struct pico_frame));
-
-  /* ...restore the two key pointers */
-  new->buffer = buf;
-  new->usage_count = uc;
-
-  /* Update in-buffer pointers with offset */
-  addr_diff = (int)new->buffer - (int)f->buffer;
-  new->net_hdr += addr_diff;
-  new->transport_hdr += addr_diff;
-  new->app_hdr += addr_diff;
-  new->start += addr_diff;
-  new->payload += addr_diff;
-
-#ifdef PICO_SUPPORT_DEBUG_MEMORY
-  dbg("Deep-Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
-#endif
-  new->next = NULL;
-  return new;
-}
-
-/**
- * Calculate checksum of a given string
- */
-uint16_t pico_checksum(void *inbuf, int len)
-{
-  uint8_t *buf = (uint8_t *) inbuf;
-  uint16_t tmp = 0;
-  uint32_t sum = 0, carry=0;
-  int i=0;
-  for(i=0; i<len; i++){
-    if (i%2){
-      sum+=buf[i];
-    }else{
-      tmp = buf[i];
-      sum+=( tmp << 8);
-    }
-  }
-  carry = (sum&0xFFFF0000) >>16;
-  sum = (sum&0x0000FFFF);
-  return (uint16_t) ~(sum + carry)  ;
-}
-
-uint16_t pico_dualbuffer_checksum(void *inbuf1, int len1, void *inbuf2, int len2)
-{
-  uint8_t *b1 = (uint8_t *) inbuf1;
-  uint8_t *b2 = (uint8_t *) inbuf2;
-  uint16_t tmp = 0;
-  uint32_t sum = 0, carry=0;
-  int i=0, j=0;
-  for(i=0; i<len1; i++){
-    if (j%2){
-      sum+=b1[i];
-    }else{
-      tmp = b1[i];
-      sum+=( tmp << 8);
-    }
-    j++;
-  }
-
-  for(i=0; i<len2; i++){
-    if (j%2){
-      sum+=b2[i];
-    }else{
-      tmp = b2[i];
-      sum+=( tmp << 8);
-    }
-    j++;
-  }
-  carry = (sum&0xFFFF0000) >>16;
-  sum = (sum&0x0000FFFF);
-  return (uint16_t) (~(sum + carry))  ;
-}
-
-uint16_t pico_dualbuffer_checksum_broken(void *inbuf1, int len1, void *inbuf2, int len2)
-{
-  uint16_t *b1 = (uint16_t *) inbuf1;
-  uint16_t *b2 = (uint16_t *) inbuf2;
-  uint32_t sum = 0;
-  int i=0, j=0;
-  for(i=0; i<(len1>>1); i++){
-    sum += short_be(b1[i]);
-    j++;
-  }
-  for(i=0; i<(len2>>1); i++){
-    sum += short_be(b2[i]);
-    j++;
-  }
-  sum = (sum & 0xFFFF) + (sum >> 16);
-  sum += (sum >> 16);
-  
-  // Take the bitwise complement of sum
-  sum = ~sum;
-  return (uint16_t) (sum)  ;
-}
-
-
--- a/stack/pico_protocol.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,350 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_protocol.h"
-#include "pico_tree.h"
-
-static int pico_proto_cmp(void *ka, void *kb)
-{
-    struct pico_protocol *a = ka, *b=kb;
-  if (a->hash < b->hash)
-    return -1;
-  if (a->hash > b->hash)
-    return 1;
-  return 0;
-}
-
-PICO_TREE_DECLARE(Datalink_proto_tree,pico_proto_cmp);
-PICO_TREE_DECLARE(Network_proto_tree,pico_proto_cmp);
-PICO_TREE_DECLARE(Transport_proto_tree,pico_proto_cmp);
-PICO_TREE_DECLARE(Socket_proto_tree,pico_proto_cmp);
-
-static int proto_loop(struct pico_protocol *proto, int loop_score, int direction)
-{
-  struct pico_frame *f;
-
-  if (direction == PICO_LOOP_DIR_IN) {
-
-    while(loop_score >0) {
-      if (proto->q_in->frames <= 0)
-        break;
-
-      f = pico_dequeue(proto->q_in);
-      if ((f) &&(proto->process_in(proto, f) > 0)) {
-        loop_score--;
-      }
-    }
-
-  } else if (direction == PICO_LOOP_DIR_OUT) {
-
-    while(loop_score >0) {
-      if (proto->q_out->frames <= 0)
-        break;
-
-      f = pico_dequeue(proto->q_out);
-      if ((f) &&(proto->process_out(proto, f) > 0)) {
-        loop_score--;
-      }
-    }
-  }
-
-  return loop_score;
-}
-
-#define DL_LOOP_MIN 1
-
-int pico_protocol_datalink_loop(int loop_score, int direction)
-{
-  struct pico_protocol *start;
-  static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
-  static struct pico_tree_node * next_node, * in_node, * out_node;
-
-  if (next_in == NULL) {
-      in_node = pico_tree_firstNode(Datalink_proto_tree.root);
-    if (in_node)
-      next_in = in_node->keyValue;
-  }
-  if (next_out == NULL) {
-    out_node = pico_tree_firstNode(Datalink_proto_tree.root);
-    if (out_node)
-      next_out = out_node->keyValue;
-  }
-  
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      next_node = in_node;
-    next = next_in;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      next_node = out_node;
-    next = next_out;
-  }
-
-  /* init start node */
-  start = next;
-
-  /* round-robin all datalink protocols, break if traversed all protocols */
-  while (loop_score > DL_LOOP_MIN && next != NULL) {
-    loop_score = proto_loop(next, loop_score, direction);
-
-    //next = RB_NEXT(pico_protocol_tree, &Datalink_proto_tree, next);
-    next_node = pico_tree_next(next_node);
-    next = next_node->keyValue;
-
-    if (next == NULL)
-    {
-        next_node = pico_tree_firstNode(Datalink_proto_tree.root);
-        next = next_node->keyValue;
-    }
-    if (next == start)
-      break;
-  }
-
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      in_node = next_node;
-    next_in = next;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      out_node = next_node;
-    next_out = next;
-  }
-
-  return loop_score;
-}
-
-
-#define NW_LOOP_MIN 1
-
-int pico_protocol_network_loop(int loop_score, int direction)
-{
-  struct pico_protocol *start;
-  static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
-  static struct pico_tree_node * next_node, * in_node, * out_node;
-
-  if (next_in == NULL) {
-    in_node = pico_tree_firstNode(Network_proto_tree.root);
-    if (in_node)
-      next_in = in_node->keyValue;
-  }
-  if (next_out == NULL) {
-      out_node = pico_tree_firstNode(Network_proto_tree.root);
-    if (out_node)
-        next_out = out_node->keyValue;
-  }
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      next_node = in_node;
-    next = next_in;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      next_node = out_node;
-    next = next_out;
-  }
-
-  /* init start node */
-  start = next;
-
-  /* round-robin all network protocols, break if traversed all protocols */
-  while (loop_score > NW_LOOP_MIN && next != NULL) {
-    loop_score = proto_loop(next, loop_score, direction);
-
-    next_node = pico_tree_next(next_node);
-    next = next_node->keyValue;
-
-    if (next == NULL)
-    {
-        next_node = pico_tree_firstNode(Network_proto_tree.root);
-        next = next_node->keyValue;
-    }
-    if (next == start)
-      break;
-  }
-
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      in_node = next_node;
-    next_in = next;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      out_node = next_node;
-    next_out = next;
-  }
-
-  return loop_score;
-}
-
-#define TP_LOOP_MIN 1
-
-int pico_protocol_transport_loop(int loop_score, int direction)
-{
-  struct pico_protocol *start;
-  static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
-  static struct pico_tree_node * next_node, * in_node, * out_node;
-
-  if (next_in == NULL) {
-      in_node = pico_tree_firstNode(Transport_proto_tree.root);
-    if (in_node)
-        next_in = in_node->keyValue;
-  }
-  if (next_out == NULL) {
-      out_node = pico_tree_firstNode(Transport_proto_tree.root);
-    if (out_node)
-        next_out = out_node->keyValue;
-  }
-  
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      next_node = in_node;
-    next = next_in;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      next_node = out_node;
-    next = next_out;
-  }
-
-  /* init start node */
-  start = next;
-
-  /* round-robin all transport protocols, break if traversed all protocols */
-  while (loop_score > DL_LOOP_MIN && next != NULL) {
-    loop_score = proto_loop(next, loop_score, direction);
-
-    //next = RB_NEXT(pico_protocol_tree, &Transport_proto_tree, next);
-    next_node = pico_tree_next(next_node);
-    next = next_node->keyValue;
-
-    if (next == NULL)
-    {
-        next_node = pico_tree_firstNode(Transport_proto_tree.root);
-        next = next_node->keyValue;
-    }
-    if (next == start)
-      break;
-  }
-
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      in_node = next_node;
-    next_in = next;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      out_node = next_node;
-    next_out = next;
-  }
-
-  return loop_score;
-}
-
-
-#define SOCK_LOOP_MIN 1
-
-int pico_protocol_socket_loop(int loop_score, int direction)
-{
-  struct pico_protocol *start;
-  static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
-  static struct pico_tree_node * next_node, * in_node, * out_node;
-
-  if (next_in == NULL) {
-      in_node = pico_tree_firstNode(Socket_proto_tree.root);
-    if(in_node)
-        next_in = in_node->keyValue;
-  }
-  if (next_out == NULL) {
-      out_node = pico_tree_firstNode(Socket_proto_tree.root);
-    if(out_node)
-      next_out = out_node->keyValue;
-  }
-  
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      next_node = in_node;
-    next = next_in;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-         next_node = out_node;
-      next = next_out;
-  }
-
-  /* init start node */
-  start = next;
-
-  /* round-robin all transport protocols, break if traversed all protocols */
-  while (loop_score > SOCK_LOOP_MIN && next != NULL) {
-    loop_score = proto_loop(next, loop_score,direction);
-
-    next_node = pico_tree_next(next_node);
-    next = next_node->keyValue;
-
-    if (next == NULL)
-    {
-      next_node = pico_tree_firstNode(next_node);
-        next = next_node->keyValue;
-    }
-    if (next == start)
-      break;
-  }
-
-  if (direction == PICO_LOOP_DIR_IN)
-  {
-      in_node = next_node;
-    next_in = next;
-  }
-  else if (direction == PICO_LOOP_DIR_OUT)
-  {
-      out_node = next_node;
-    next_out = next;
-  }
-
-  return loop_score;
-}
-
-int pico_protocols_loop(int loop_score)
-{
-/*
-  loop_score = pico_protocol_datalink_loop(loop_score);
-  loop_score = pico_protocol_network_loop(loop_score);
-  loop_score = pico_protocol_transport_loop(loop_score);
-  loop_score = pico_protocol_socket_loop(loop_score);
-*/
-  return loop_score;
-}
-
-void pico_protocol_init(struct pico_protocol *p)
-{
-  if (!p)
-    return;
-
-  p->hash = pico_hash(p->name);
-  switch (p->layer) {
-    case PICO_LAYER_DATALINK:
-      pico_tree_insert(&Datalink_proto_tree, p);
-      break;
-    case PICO_LAYER_NETWORK:
-      pico_tree_insert(&Network_proto_tree,p);
-      break;
-    case PICO_LAYER_TRANSPORT:
-      pico_tree_insert(&Transport_proto_tree,p);
-      break;
-    case PICO_LAYER_SOCKET:
-      pico_tree_insert(&Socket_proto_tree,p);
-      break;
-  }
-  dbg("Protocol %s registered (layer: %d).\n", p->name, p->layer);
-
-}
-
--- a/stack/pico_socket.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2270 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_queue.h"
-#include "pico_socket.h"
-#include "pico_ipv4.h"
-#include "pico_ipv6.h"
-#include "pico_udp.h"
-#include "pico_tcp.h"
-#include "pico_stack.h"
-#include "pico_icmp4.h"
-#include "pico_nat.h"
-#include "pico_tree.h"
-#include "pico_device.h"
-
-#if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6)
-#if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP)
-
-
-#ifdef PICO_SUPPORT_MUTEX
-static void * Mutex = NULL;
-#define LOCK(x) {\
-  if (x == NULL) \
-    x = pico_mutex_init(); \
-  pico_mutex_lock(x); \
-}
-#define UNLOCK(x) pico_mutex_unlock(x);
-
-#else
-#define LOCK(x) do{}while(0)
-#define UNLOCK(x) do{}while(0)
-#endif
-
-
-#define PROTO(s) ((s)->proto->proto_number)
-
-#ifdef PICO_SUPPORT_TCP
-# define IS_NAGLE_ENABLED(s) (!(!(!(s->opt_flags & (1 << PICO_SOCKET_OPT_TCPNODELAY)))))
-#endif
-
-#define PICO_SOCKET_MTU 1480 /* Ethernet MTU(1500) - IP header size(20) */
-
-#ifdef PICO_SUPPORT_IPV4
-# define IS_SOCK_IPV4(s) ((s->net == &pico_proto_ipv4))
-#else
-# define IS_SOCK_IPV4(s) (0)
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-# define IS_SOCK_IPV6(s) ((s->net == &pico_proto_ipv6))
-#else
-# define IS_SOCK_IPV6(s) (0)
-#endif
-
-#ifdef PICO_SUPPORT_IPFRAG
-# define frag_dbg(...) do{}while(0) 
-#endif
-
-#ifdef PICO_SUPPORT_MCAST 
-# define so_mcast_dbg(...) do{}while(0) /* ip_mcast_dbg in pico_ipv4.c */
-#endif
-
-static struct pico_sockport *sp_udp = NULL ,*sp_tcp = NULL;
-
-struct pico_frame *pico_socket_frame_alloc(struct pico_socket *s, int len);
-
-static int socket_cmp(void * ka, void * kb)
-{
-  struct pico_socket *a = ka, *b = kb;
-  int a_is_ip6 = is_sock_ipv6(a);
-  int b_is_ip6 = is_sock_ipv6(b);
-
-  int diff;
-
-  /* First, order by network ver */
-  if (a_is_ip6 < b_is_ip6)
-    return -1;
-  if (a_is_ip6 > b_is_ip6)
-    return 1;
-
-  /* If either socket is PICO_IPV4_INADDR_ANY mode, skip local address comparison */
-
-  /* At this point, sort by local host */
-
-  if (0) {
-#ifdef PICO_SUPPORT_IPV6
-  } else if (a_is_ip6) {
-    if ((memcmp(a->local_addr.ip6.addr, PICO_IP6_ANY, PICO_SIZE_IP6)==0) || memcmp((b->local_addr.ip6.addr, PICO_IP6_ANY, PICO_SIZE_IP6) == 0))
-      diff = 0;
-    else
-      diff = memcmp(a->local_addr.ip6.addr, b->local_addr.ip6.addr, PICO_SIZE_IP6);
-#endif
-  } else {
-    if ((a->local_addr.ip4.addr == PICO_IP4_ANY) || (b->local_addr.ip4.addr == PICO_IP4_ANY))
-      diff = 0;
-    else
-      diff = a->local_addr.ip4.addr - b->local_addr.ip4.addr;
-  }
-
-  if (diff)
-    return diff;
-
-
-  /* Sort by remote host */
-  if (a_is_ip6)
-    diff = memcmp(a->remote_addr.ip6.addr, b->remote_addr.ip6.addr, PICO_SIZE_IP6);
-  else
-    diff = a->remote_addr.ip4.addr - b->remote_addr.ip4.addr;
-
-  if (diff)
-    return diff;
-
-  /* And finally by remote port. The two sockets are coincident if the quad is the same. */
-  return b->remote_port - a->remote_port;
-}
-
-struct pico_sockport
-{
-  struct pico_tree socks; // how you make the connection ?
-  uint16_t number;
-  uint16_t proto;
-};
-
-#define INIT_SOCKPORT { {&LEAF , socket_cmp}, 0, 0 }
-
-int sockport_cmp(void * ka, void * kb)
-{
-  struct pico_sockport *a = ka, *b = kb;
-  if (a->number < b->number)
-    return -1;
-  if (a->number > b->number)
-    return 1;
-  return 0;
-}
-
-PICO_TREE_DECLARE(UDPTable,sockport_cmp);
-PICO_TREE_DECLARE(TCPTable,sockport_cmp);
-
-#ifdef PICO_SUPPORT_MCAST
-/*                       socket
- *                         |  
- *                    MCASTListen
- *                    |    |     |
- *         ------------    |     ------------
- *         |               |                |
- *   MCASTSources    MCASTSources     MCASTSources    
- *   |  |  |  |      |  |  |  |       |  |  |  |
- *   S  S  S  S      S  S  S  S       S  S  S  S
- *
- *   MCASTListen: RBTree(mcast_link, mcast_group)
- *   MCASTSources: RBTree(source)
- */
-struct pico_mcast_listen
-{
-  uint8_t filter_mode;
-  struct pico_ip4 mcast_link;
-  struct pico_ip4 mcast_group;
-  struct pico_tree MCASTSources;
-};
-
-static int mcast_listen_cmp(void *ka, void *kb)
-{
-  struct pico_mcast_listen *a = ka, *b = kb;
-  if (a->mcast_group.addr < b->mcast_group.addr)
-    return -1;
-  if (a->mcast_group.addr > b->mcast_group.addr)
-    return 1;
-
-  if (a->mcast_link.addr < b->mcast_link.addr)
-    return -1;
-  if (a->mcast_link.addr > b->mcast_link.addr)
-    return 1;
-
-  return 0;
-}
-
-static int mcast_sources_cmp(void *ka, void *kb)
-{
-  struct pico_ip4 *a = ka, *b = kb;
-  if (a->addr < b->addr)
-    return -1;
-  if (a->addr > b->addr)
-    return 1;
-  return 0;
-}
-
-static int mcast_socket_cmp(void *ka, void *kb)
-{
-  struct pico_socket *a = ka, *b = kb;
-  if (a < b)
-    return -1;
-  if (a > b)
-    return 1;
-  return 0;
-}
-/* gather all multicast sockets to hasten filter aggregation */
-PICO_TREE_DECLARE(MCASTSockets, mcast_socket_cmp);
-
-static int mcast_filter_cmp(void *ka, void *kb)
-{
-  struct pico_ip4 *a = ka, *b = kb;
-  if (a->addr < b->addr)
-    return -1;
-  if (a->addr > b->addr)
-    return 1;
-  return 0;
-}
-/* gather sources to be filtered */
-PICO_TREE_DECLARE(MCASTFilter, mcast_filter_cmp);
-
-/* MCASTFilter will be empty if no socket is listening on mcast_group on mcast_link anymore */
-static int pico_socket_aggregate_mcastfilters(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group)
-{
-  uint8_t filter_mode = PICO_IP_MULTICAST_INCLUDE;
-  struct pico_mcast_listen *listen = NULL, ltest = {0};
-  struct pico_ip4 *source = NULL;
-  struct pico_socket *mcast_sock = NULL;
-  struct pico_tree_node *index = NULL, *_tmp = NULL, *index2 = NULL, *_tmp2 = NULL;
-
-  ltest.mcast_link = *mcast_link;
-  ltest.mcast_group = *mcast_group;
-
-  /* cleanup old filter */
-  pico_tree_foreach_safe(index, &MCASTFilter, _tmp)
-  {
-    pico_tree_delete(&MCASTFilter, index->keyValue);
-  }
-
-  /* construct new filter */
-  pico_tree_foreach(index, &MCASTSockets)
-  {
-    mcast_sock = index->keyValue;
-    listen = pico_tree_findKey(mcast_sock->MCASTListen, &ltest);
-    if (listen) {
-      /* aggregate filter */
-      switch(filter_mode)
-      {
-        case PICO_IP_MULTICAST_INCLUDE:
-          switch (listen->filter_mode)
-          {
-            case PICO_IP_MULTICAST_INCLUDE:
-              /* filter = summation of INCLUDEs */
-              /* mode stays INCLUDE, add all sources to filter */
-              pico_tree_foreach(index2, &listen->MCASTSources)
-              {
-                source = index2->keyValue;
-                pico_tree_insert(&MCASTFilter, source); 
-              }
-              break;
-
-            case PICO_IP_MULTICAST_EXCLUDE:
-              /* filter = EXCLUDE - INCLUDE */
-              /* delete from the interface INCLUDE filter any source NOT in the socket EXCLUDE filter */
-              pico_tree_foreach_safe(index2, &MCASTFilter, _tmp2)
-              {
-                source = pico_tree_findKey(&listen->MCASTSources, index2->keyValue);
-                if (!source)
-                  pico_tree_delete(&MCASTFilter, index2->keyValue);
-              }
-              /* any record with filter mode EXCLUDE, causes the interface mode to be EXCLUDE */
-              filter_mode = PICO_IP_MULTICAST_EXCLUDE;
-              /* add to the interface EXCLUDE filter any socket source NOT in the former interface INCLUDE filter */
-              pico_tree_foreach(index2, &listen->MCASTSources)
-              {
-                source = pico_tree_insert(&MCASTFilter, index2->keyValue); 
-                if (source) 
-                  pico_tree_delete(&MCASTFilter, source);
-              }
-              break;
-
-            default:
-              return -1;
-          }
-          break;
-
-        case PICO_IP_MULTICAST_EXCLUDE:
-          switch (listen->filter_mode)
-          {
-            case PICO_IP_MULTICAST_INCLUDE:
-              /* filter = EXCLUDE - INCLUDE */
-              /* any record with filter mode EXCLUDE, causes the interface mode to be EXCLUDE */
-              /* remove from the interface EXCLUDE filter any source in the socket INCLUDE filter */
-              pico_tree_foreach(index2, &listen->MCASTSources)
-              {
-                source = pico_tree_findKey(&MCASTFilter, index2->keyValue);
-                if (source)
-                  pico_tree_delete(&MCASTFilter, source);
-              }
-              break;
-
-            case PICO_IP_MULTICAST_EXCLUDE:
-              /* filter = intersection of EXCLUDEs */
-              /* any record with filter mode EXCLUDE, causes the interface mode to be EXCLUDE */
-              /* remove from the interface EXCLUDE filter any source not in the socket EXCLUDE filter */
-              pico_tree_foreach_safe(index2, &MCASTFilter, _tmp2)
-              {
-                source = pico_tree_findKey(&listen->MCASTSources, index2->keyValue);
-                if (!source)
-                  pico_tree_delete(&MCASTFilter, index2->keyValue);
-              }
-              break;
-
-            default:
-              return -1;
-          }
-          break;
-
-        default:
-          return -1;
-      }
-    }
-  }
-  return filter_mode;
-}
-
-static int pico_socket_mcast_filter(struct pico_socket *s, struct pico_ip4 *mcast_group, struct pico_ip4 *src)
-{
-  struct pico_ipv4_link *mcast_link = NULL;
-  struct pico_mcast_listen *listen = NULL, ltest = {0};
-  struct pico_tree_node *index = NULL;
-
-  /* no multicast enabled on socket */
-  if (!s->MCASTListen)
-    return 0;
-
-  mcast_link = pico_ipv4_link_get(&s->local_addr.ip4);
-  if (!mcast_link) 
-    return -1;
-
-  ltest.mcast_link.addr = mcast_link->address.addr;
-  ltest.mcast_group = *mcast_group;
-  listen = pico_tree_findKey(s->MCASTListen, &ltest);
-  if (!listen)
-    return -1;
-
-  /* perform source filtering */
-  switch (listen->filter_mode)
-  {
-    case PICO_IP_MULTICAST_INCLUDE:
-      pico_tree_foreach(index, &listen->MCASTSources)
-      {
-        if (src->addr == ((struct pico_ip4 *)index->keyValue)->addr) {
-          so_mcast_dbg("MCAST: IP %08X in included socket source list\n", src->addr);
-          return 0;
-        }
-      }
-      so_mcast_dbg("MCAST: IP %08X NOT in included socket source list\n", src->addr);
-      return -1;
-      break;
-
-    case PICO_IP_MULTICAST_EXCLUDE:
-      pico_tree_foreach(index, &listen->MCASTSources)
-      {
-        if (src->addr == ((struct pico_ip4 *)index->keyValue)->addr) {
-          so_mcast_dbg("MCAST: IP %08X in excluded socket source list\n", src->addr);
-          return -1;
-        }
-      }
-      so_mcast_dbg("MCAST: IP %08X NOT in excluded socket source list\n", src->addr);
-      return 0;
-      break;
-
-    default:
-      return -1;
-      break;
-  }
-  return -1;
-}
-
-static inline struct pico_ipv4_link *pico_socket_setoption_mcastargs_validation(struct pico_ip_mreq *mreq, struct pico_ip_mreq_source *mreq_source)
-{
-  struct pico_ipv4_link *mcast_link = NULL;
-
-  if (!mreq && !mreq_source)
-    return NULL;
-
-  if (mreq) {
-    if (!mreq->mcast_group_addr.addr)
-      return NULL;
-    if (pico_ipv4_is_unicast(mreq->mcast_group_addr.addr))
-      return NULL;
-
-    if (!mreq->mcast_link_addr.addr) {
-      mcast_link = pico_ipv4_get_default_mcastlink();
-      if (!mcast_link)
-        return NULL;
-    } else {
-      mcast_link = pico_ipv4_link_get(&mreq->mcast_link_addr);
-      if (!mcast_link)
-        return NULL;
-    }
-  }
-  if (mreq_source) {
-    if (!mreq_source->mcast_group_addr.addr)
-      return NULL;
-    if (pico_ipv4_is_unicast(mreq_source->mcast_group_addr.addr))
-      return NULL;
-
-    if (!mreq_source->mcast_source_addr.addr)
-      return NULL;
-    if (!pico_ipv4_is_unicast(mreq_source->mcast_source_addr.addr))
-      return NULL;
-
-    if (!mreq_source->mcast_link_addr.addr) {
-      mcast_link = pico_ipv4_get_default_mcastlink();
-      if (!mcast_link)
-        return NULL;
-    } else {
-      mcast_link = pico_ipv4_link_get(&mreq_source->mcast_link_addr);
-      if (!mcast_link)
-        return NULL;
-    }
-  }
-  return mcast_link;
-}
-#else
-static int pico_socket_mcast_filter(struct pico_socket *s, struct pico_ip4 *mcast_group, struct pico_ip4 *src) {
-  return 0;
-}
-#endif /* PICO_SUPPORT_MCAST */
-
-static struct pico_sockport *pico_get_sockport(uint16_t proto, uint16_t port)
-{
-  struct pico_sockport test = INIT_SOCKPORT;
-  test.number = port;
-
-  if (proto == PICO_PROTO_UDP)
-    return pico_tree_findKey(&UDPTable,&test);
-
-  else if (proto == PICO_PROTO_TCP)
-    return pico_tree_findKey(&TCPTable,&test);
-
-  else return NULL;
-}
-
-int pico_is_port_free(uint16_t proto, uint16_t port, void *addr, void *net)
-{
-  struct pico_sockport *sp;
-  struct pico_ip4 ip;
-  sp = pico_get_sockport(proto, port);
-
-  if (!net)
-    net = &pico_proto_ipv4;
-
-  /** IPv6 (wip) ***/
-  if (net != &pico_proto_ipv4) {
-    dbg("IPV6!!!!!\n");
-    return (!sp);
-  }
-
-  /* IPv4 */
-#ifdef PICO_SUPPORT_NAT
-  if (pico_ipv4_nat_find(port,NULL, 0,proto) == 0) {
-    dbg("In use by nat....\n");
-    return 0;
-  }
-#endif
-  if (addr)
-    ip.addr = ((struct pico_ip4 *)addr)->addr;
-  else
-    ip.addr = PICO_IPV4_INADDR_ANY;
-
-  if (ip.addr == PICO_IPV4_INADDR_ANY) {
-    if (!sp) return 1;
-      else {
-        dbg("In use, and asked for ANY\n");
-        return 0;
-      }
-  }
-  if (sp) {
-    struct pico_ip4 *s_local;
-    struct pico_tree_node *idx;
-    struct pico_socket *s;
-    pico_tree_foreach(idx, &sp->socks) {
-      s = idx->keyValue;
-      if (s->net == &pico_proto_ipv4) {
-        s_local = (struct pico_ip4*) &s->local_addr;
-        if ((s_local->addr == PICO_IPV4_INADDR_ANY) || (s_local->addr == ip.addr))
-          return 0;
-      }
-    }
-  }
-  return 1;
-}
-
-static int pico_check_socket(struct pico_socket *s)
-{
-  struct pico_sockport *test;
-  struct pico_socket *found;
-  struct pico_tree_node * index;
-
-  test = pico_get_sockport(PROTO(s), s->local_port);
-  
-  if (!test) {
-    return -1;
-  }
-
-  pico_tree_foreach(index,&test->socks){
-    found = index->keyValue;
-    if (s == found) {
-      return 0;
-    }
-  }
-
-  return -1;
-}
-
-
-int pico_socket_add(struct pico_socket *s)
-{
-  struct pico_sockport *sp = pico_get_sockport(PROTO(s), s->local_port);
-  LOCK(Mutex);
-  if (!sp) {
-    //dbg("Creating sockport..%04x\n", s->local_port); /* In comment due to spam during test */
-    sp = pico_zalloc(sizeof(struct pico_sockport));
-
-    if (!sp) {
-      pico_err = PICO_ERR_ENOMEM;
-      UNLOCK(Mutex);
-      return -1;
-    }
-    sp->proto = PROTO(s);
-    sp->number = s->local_port;
-    sp->socks.root = &LEAF;
-    sp->socks.compare = socket_cmp;
-
-    if (PROTO(s) == PICO_PROTO_UDP)
-    {
-      pico_tree_insert(&UDPTable,sp);
-    }
-    else if (PROTO(s) == PICO_PROTO_TCP)
-    {
-      pico_tree_insert(&TCPTable,sp);
-    }
-  }
-
-  pico_tree_insert(&sp->socks,s);
-  s->state |= PICO_SOCKET_STATE_BOUND;
-    UNLOCK(Mutex);
-#if DEBUG_SOCKET_TREE
-  {
-    struct pico_tree_node * index;
-    //RB_FOREACH(s, socket_tree, &sp->socks) {
-    pico_tree_foreach(index,&sp->socks){
-      s = index->keyValue;
-      dbg(">>>> List Socket lc=%hu rm=%hu\n", short_be(s->local_port), short_be(s->remote_port));
-    }
-
-  }
-#endif
-  return 0;
-}
-
-static void socket_garbage_collect(unsigned long now, void *arg)
-{
-  struct pico_socket *s = (struct pico_socket *) arg;
-  pico_free(s);
-}
-
-int pico_socket_del(struct pico_socket *s)
-{
-  struct pico_sockport *sp = pico_get_sockport(PROTO(s), s->local_port);
-
-  if (!sp) {
-    pico_err = PICO_ERR_ENXIO;
-    return -1;
-  }
-
-  LOCK(Mutex);
-  pico_tree_delete(&sp->socks,s);
-  s->net = NULL;
-  if(pico_tree_empty(&sp->socks)){
-    if (PROTO(s) == PICO_PROTO_UDP)
-    {
-      pico_tree_delete(&UDPTable,sp);
-    }
-    else if (PROTO(s) == PICO_PROTO_TCP)
-    {
-      pico_tree_delete(&TCPTable,sp);
-    }
-
-    if(sp_tcp == sp)  sp_tcp = NULL;
-
-    if(sp_udp == sp)   sp_udp = NULL;
-
-    pico_free(sp);
-
-  }
-
-#ifdef PICO_SUPPORT_MCAST
-  do {
-    uint8_t filter_mode = 0;
-    struct pico_tree_node *index = NULL, *_tmp = NULL, *index2 = NULL, *_tmp2 = NULL;
-    struct pico_mcast_listen *listen = NULL;
-    struct pico_ip4 *source = NULL;
-    if (s->MCASTListen) {
-      pico_tree_delete(&MCASTSockets, s);
-      pico_tree_foreach_safe(index, s->MCASTListen, _tmp)
-      {
-        listen = index->keyValue;
-        pico_tree_foreach_safe(index2, &listen->MCASTSources, _tmp2)
-        {
-          source = index->keyValue;
-          pico_tree_delete(&listen->MCASTSources, source);
-          pico_free(source);
-        }
-        filter_mode = pico_socket_aggregate_mcastfilters(&listen->mcast_link, &listen->mcast_group);
-        pico_ipv4_mcast_leave(&listen->mcast_link, &listen->mcast_group, 1, filter_mode, &MCASTFilter);
-        pico_tree_delete(s->MCASTListen, listen);
-        pico_free(listen);
-      }
-      pico_free(s->MCASTListen);
-    }
-  } while (0);
-#endif
-
-  s->state = PICO_SOCKET_STATE_CLOSED;
-  pico_timer_add(3000, socket_garbage_collect, s);
-    UNLOCK(Mutex);
-  return 0;
-}
-
-static int pico_socket_alter_state(struct pico_socket *s, uint16_t more_states, uint16_t less_states, uint16_t tcp_state)
-{
-  struct pico_sockport *sp;
-  if (more_states & PICO_SOCKET_STATE_BOUND)
-    return pico_socket_add(s);
-
-  if (less_states & PICO_SOCKET_STATE_BOUND)
-    return pico_socket_del(s);
-
-  sp = pico_get_sockport(PROTO(s), s->local_port);
-  if (!sp) {
-    pico_err = PICO_ERR_ENXIO;
-    return -1;
-  }
-
-  s->state |= more_states;
-  s->state &= (~less_states);
-  if (tcp_state) {
-    s->state &= 0x00FF;
-    s->state |= tcp_state;
-  }
-
-  return 0;
-}
-
-static int pico_socket_deliver(struct pico_protocol *p, struct pico_frame *f, uint16_t localport)
-{
-  struct pico_frame *cpy = NULL;
-  struct pico_sockport *sp = NULL;
-  struct pico_socket *s = NULL, *found = NULL;
-  struct pico_tree_node *index = NULL;
-  struct pico_tree_node *_tmp;
-  struct pico_trans *tr = (struct pico_trans *) f->transport_hdr;
-  #ifdef PICO_SUPPORT_IPV4
-  struct pico_ipv4_hdr *ip4hdr;
-  #endif
-  #ifdef PICO_SUPPORT_IPV6
-  struct pico_ipv6_hdr *ip6hdr;
-  #endif
-
-  if (!tr)
-    return -1;
-
-  sp = pico_get_sockport(p->proto_number, localport);
-
-  if (!sp) {
-    dbg("No such port %d\n",short_be(localport));
-    return -1;
-  }
-
-  #ifdef PICO_SUPPORT_TCP
-  if (p->proto_number == PICO_PROTO_TCP) {
-    pico_tree_foreach_safe(index,&sp->socks, _tmp){
-      s = index->keyValue;
-      /* 4-tuple identification of socket (port-IP) */
-      #ifdef PICO_SUPPORT_IPV4
-      if (IS_IPV4(f)) {
-        struct pico_ip4 s_local, s_remote, p_src, p_dst;
-        ip4hdr = (struct pico_ipv4_hdr*)(f->net_hdr);
-        s_local.addr = s->local_addr.ip4.addr;
-        s_remote.addr = s->remote_addr.ip4.addr;
-        p_src.addr = ip4hdr->src.addr;
-        p_dst.addr = ip4hdr->dst.addr;
-        if (  (s->remote_port == tr->sport) && /* remote port check */
-              (s_remote.addr == p_src.addr) && /* remote addr check */ 
-              ((s_local.addr == PICO_IPV4_INADDR_ANY) || (s_local.addr == p_dst.addr))) { /* Either local socket is ANY, or matches dst */
-          found = s;
-          break;
-        } else if ( (s->remote_port == 0)  && /* not connected... listening */
-         ((s_local.addr == PICO_IPV4_INADDR_ANY) || (s_local.addr == p_dst.addr))) { /* Either local socket is ANY, or matches dst */
-          /* listen socket */
-          found = s;
-        }
-      }
-      #endif
-      #ifdef PICO_SUPPORT_IPV6    /* XXX TODO make compare for ipv6 addresses */
-      if (IS_IPV6(f)) {
-        ip6hdr = (struct pico_ipv6_hdr*)(f->net_hdr);
-        if ( (s->remote_port == localport) ) { // && (((struct pico_ip6) s->remote_addr.ip6).addr == ((struct pico_ip6)(ip6hdr->src)).addr) ) {
-          found = s;
-          break;
-        } else if (s->remote_port == 0) {
-          /* listen socket */
-          found = s;
-        }
-      }
-      #endif 
-    } /* FOREACH */
-    if (found != NULL) {
-      pico_tcp_input(found,f);
-      if ((found->ev_pending) && found->wakeup) {
-        found->wakeup(found->ev_pending, found);
-      }
-      return 0;
-    } else {
-      dbg("SOCKET> mmm something wrong (prob sockport)\n");
-      return -1;
-    }
-  } /* TCP CASE */
-#endif
-
-#ifdef PICO_SUPPORT_UDP
-  if (p->proto_number == PICO_PROTO_UDP) {
-    pico_tree_foreach_safe(index,&sp->socks, _tmp){
-      s = index->keyValue;
-      if (IS_IPV4(f)) { /* IPV4 */
-        struct pico_ip4 s_local, p_dst;
-        ip4hdr = (struct pico_ipv4_hdr*)(f->net_hdr);
-        s_local.addr = s->local_addr.ip4.addr;
-        p_dst.addr = ip4hdr->dst.addr;
-        if ((pico_ipv4_is_broadcast(p_dst.addr)) || pico_ipv4_is_multicast(p_dst.addr)) {
-          struct pico_device *dev = pico_ipv4_link_find(&s->local_addr.ip4);
-          if (pico_ipv4_is_multicast(p_dst.addr) && (pico_socket_mcast_filter(s, &ip4hdr->dst, &ip4hdr->src) < 0))
-            return -1;
-          if ((s_local.addr == PICO_IPV4_INADDR_ANY) || /* If our local ip is ANY, or.. */
-            (dev == f->dev) ) { /* the source of the bcast packet is a neighbor... */
-            cpy = pico_frame_copy(f);
-            if (!cpy)
-              return -1;
-            if (pico_enqueue(&s->q_in, cpy) > 0) {
-              if (s->wakeup)
-                s->wakeup(PICO_SOCK_EV_RD, s);
-            }
-          }
-        } else if ((s_local.addr == PICO_IPV4_INADDR_ANY) || (s_local.addr == p_dst.addr))
-        { /* Either local socket is ANY, or matches dst */
-          cpy = pico_frame_copy(f);
-          if (!cpy)
-            return -1;
-          if (pico_enqueue(&s->q_in, cpy) > 0) {
-            if (s->wakeup)
-              s->wakeup(PICO_SOCK_EV_RD, s);
-          }
-        }
-      } else {
-        /*... IPv6 */
-      }
-    } /* FOREACH */
-    pico_frame_discard(f);
-    if (s)
-      return 0;
-    else
-      return -1;
-  }
-#endif
-  return -1;
-}
-
-struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *))
-{
-
-  struct pico_socket *s = NULL;
-
-#ifdef PICO_SUPPORT_UDP
-  if (proto == PICO_PROTO_UDP) {
-    s = pico_udp_open();
-    s->proto = &pico_proto_udp;
-  }
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  if (proto == PICO_PROTO_TCP) {
-    s = pico_tcp_open();
-    s->proto = &pico_proto_tcp;
-    /*check if Nagle enabled */
-    if (!IS_NAGLE_ENABLED(s))
-      dbg("ERROR Nagle should be enabled here\n\n");
-  }
-#endif
-
-  if (!s) {
-    pico_err = PICO_ERR_EPROTONOSUPPORT;
-    return NULL;
-  }
-
-#ifdef PICO_SUPPORT_IPV4
-  if (net == PICO_PROTO_IPV4)
-    s->net = &pico_proto_ipv4;
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  if (net == PICO_PROTO_IPV6)
-    s->net = &pico_proto_ipv6;
-#endif
-
-  s->q_in.max_size = PICO_DEFAULT_SOCKETQ;
-  s->q_out.max_size = PICO_DEFAULT_SOCKETQ;
-  s->wakeup = wakeup;
-
-  if (!s->net) {
-    pico_free(s);
-    pico_err = PICO_ERR_ENETUNREACH;
-    return NULL;
-  }
-  return s;
-}
-
-
-struct pico_socket *pico_socket_clone(struct pico_socket *facsimile)
-{
-  struct pico_socket *s = NULL;
-
-#ifdef PICO_SUPPORT_UDP
-  if (facsimile->proto->proto_number == PICO_PROTO_UDP) {
-    s = pico_udp_open();
-    s->proto = &pico_proto_udp;
-  }
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  if (facsimile->proto->proto_number == PICO_PROTO_TCP) {
-    s = pico_tcp_open();
-    s->proto = &pico_proto_tcp; 
-  }
-#endif
-
-  if (!s) {
-    pico_err = PICO_ERR_EPROTONOSUPPORT;
-    return NULL;
-  }
-  s->local_port = facsimile->local_port;
-  s->remote_port = facsimile->remote_port;
-  s->state = facsimile->state;
-
-#ifdef PICO_SUPPORT_IPV4
-  if (facsimile->net == &pico_proto_ipv4) {
-    s->net = &pico_proto_ipv4;
-    memcpy(&s->local_addr, &facsimile->local_addr, sizeof(struct pico_ip4));
-    memcpy(&s->remote_addr, &facsimile->remote_addr, sizeof(struct pico_ip4));
-  }
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  if (net == &pico_proto_ipv6) {
-    s->net = &pico_proto_ipv6;
-    memcpy(&s->local_addr, &facsimile->local_addr, sizeof(struct pico_ip6));
-    memcpy(&s->remote_addr, &facsimile->remote_addr, sizeof(struct pico_ip6));
-  }
-#endif
-  s->q_in.max_size = PICO_DEFAULT_SOCKETQ;
-  s->q_out.max_size = PICO_DEFAULT_SOCKETQ;
-  s->wakeup = NULL;
-  if (!s->net) {
-    pico_free(s);
-    pico_err = PICO_ERR_ENETUNREACH;
-    return NULL;
-  }
-  return s;
-}
-
-int pico_socket_read(struct pico_socket *s, void *buf, int len)
-{
-  if (!s || buf == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    /* See task #178 */
-    if (pico_check_socket(s) != 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    pico_err = PICO_ERR_EIO;
-    return -1;
-  }
-#ifdef PICO_SUPPORT_UDP 
-  if (PROTO(s) == PICO_PROTO_UDP)
-    return pico_udp_recv(s, buf, len, NULL, NULL);
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  if (PROTO(s) == PICO_PROTO_TCP){
-    /* check if in shutdown state and if no more data in tcpq_in */
-    if ((s->state & PICO_SOCKET_STATE_SHUT_REMOTE) && pico_tcp_queue_in_is_empty(s) ) {  
-      pico_err = PICO_ERR_ESHUTDOWN;
-      return -1;
-    } else {
-      return pico_tcp_read(s, buf, len);
-    }
-  }
-#endif
-  return 0;
-}
-
-int pico_socket_write(struct pico_socket *s, void *buf, int len)
-{
-  if (!s || buf == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    /* See task #178 */
-    if (pico_check_socket(s) != 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    pico_err = PICO_ERR_EIO;
-    return -1;
-  }
-  if ((s->state & PICO_SOCKET_STATE_CONNECTED) == 0) {
-    pico_err = PICO_ERR_ENOTCONN;
-    return -1;
-  } else if (s->state & PICO_SOCKET_STATE_SHUT_LOCAL) {  /* check if in shutdown state */
-    pico_err = PICO_ERR_ESHUTDOWN;
-    return -1;
-  } else {
-    return pico_socket_sendto(s, buf, len, &s->remote_addr, s->remote_port);
-  }
-}
-
-uint16_t pico_socket_high_port(uint16_t proto)
-{
-  uint16_t port;
-  if (0 || 
-#ifdef PICO_SUPPORT_TCP
-  (proto == PICO_PROTO_TCP) ||
-#endif
-#ifdef PICO_SUPPORT_TCP
-  (proto == PICO_PROTO_UDP) ||
-#endif
-  0) {
-    do {
-      uint32_t rand = pico_rand();
-      port = (uint16_t) (rand & 0xFFFFU);
-      port = (uint16_t)(port % (65535 - 1024)) + 1024U; 
-      if (pico_is_port_free(proto, port, NULL, NULL)) {
-        return short_be(port);
-      }
-    } while(1);
-  }
-  else return 0U;
-}
-
-
-int pico_socket_sendto(struct pico_socket *s, void *buf, int len, void *dst, uint16_t remote_port)
-{
-  struct pico_frame *f;
-  struct pico_remote_duple *remote_duple = NULL;
-  int header_offset = 0;
-  int total_payload_written = 0;
-#ifdef PICO_SUPPORT_IPV4
-  struct pico_ip4 *src4;
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  struct pico_ip6 *src6;
-#endif
-  if (len == 0) {
-    return 0;
-  } else if (len < 0) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if (buf == NULL || s == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if (!dst || !remote_port) {
-    pico_err = PICO_ERR_EADDRNOTAVAIL;
-    return -1;
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_CONNECTED) != 0) {
-    if (remote_port != s->remote_port) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-#ifdef PICO_SUPPORT_IPV4
-  if (IS_SOCK_IPV4(s)) {
-    if ((s->state & PICO_SOCKET_STATE_CONNECTED)) {
-      if  (s->remote_addr.ip4.addr != ((struct pico_ip4 *)dst)->addr ) {
-        pico_err = PICO_ERR_EADDRNOTAVAIL;
-        return -1;
-      }
-    } else {
-      src4 = pico_ipv4_source_find(dst);
-      if (!src4) {
-        pico_err = PICO_ERR_EHOSTUNREACH;
-        return -1;
-      }
-      if (src4->addr != PICO_IPV4_INADDR_ANY)
-        s->local_addr.ip4.addr = src4->addr;
-#     ifdef PICO_SUPPORT_UDP
-      /* socket remote info could change in a consecutive call, make persistent */
-      if (PROTO(s) == PICO_PROTO_UDP) {
-        remote_duple = pico_zalloc(sizeof(struct pico_remote_duple));
-        remote_duple->remote_addr.ip4.addr = ((struct pico_ip4 *)dst)->addr;
-        remote_duple->remote_port = remote_port;
-      }
-#     endif
-    }
-  }
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  if (IS_SOCK_IPV6(s)) {
-    if (s->state & PICO_SOCKET_STATE_CONNECTED) {
-      if (memcmp(&s->remote_addr, dst, PICO_SIZE_IP6))
-        return -1;
-    } else {
-      src6 = pico_ipv6_source_find(dst);
-      if (!src6) {
-        pico_err = PICO_ERR_EHOSTUNREACH;
-        return -1;
-      }
-      memcpy(&s->local_addr, src6, PICO_SIZE_IP6);
-      memcpy(&s->remote_addr, dst, PICO_SIZE_IP6);
-#     ifdef PICO_SUPPORT_UDP
-      if (PROTO(s) == PICO_PROTO_UDP) {
-        remote_duple = pico_zalloc(sizeof(struct pico_remote_duple));
-        remote_duple->remote_addr.ip6.addr = ((struct pico_ip6 *)dst)->addr;
-        remote_duple->remote_port = remote_port;
-      }
-#     endif
-    }
-  }
-#endif
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    s->local_port = pico_socket_high_port(s->proto->proto_number);
-    if (s->local_port == 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-  if ((s->state & PICO_SOCKET_STATE_CONNECTED) == 0) {
-    s->remote_port = remote_port;
-  }
-
-#ifdef PICO_SUPPORT_TCP
-  if (PROTO(s) == PICO_PROTO_TCP)
-    header_offset = pico_tcp_overhead(s);
-#endif
-
-#ifdef PICO_SUPPORT_UDP
-  if (PROTO(s) == PICO_PROTO_UDP)
-    header_offset = sizeof(struct pico_udp_hdr);
-#endif
-
-  while (total_payload_written < len) {
-    int transport_len = (len - total_payload_written) + header_offset; 
-    if (transport_len > PICO_SOCKET_MTU)
-      transport_len = PICO_SOCKET_MTU;
-#ifdef PICO_SUPPORT_IPFRAG
-    else {
-      if (total_payload_written)
-        transport_len -= header_offset; /* last fragment, do not allocate memory for transport header */
-    }
-#endif /* PICO_SUPPORT_IPFRAG */
-
-    f = pico_socket_frame_alloc(s, transport_len);
-    if (!f) {
-      pico_err = PICO_ERR_ENOMEM;
-      return -1;
-    }
-    f->payload += header_offset;
-    f->payload_len -= header_offset;
-    f->sock = s;
-    if (remote_duple) {
-      f->info = pico_zalloc(sizeof(struct pico_remote_duple));
-      memcpy(f->info, remote_duple, sizeof(struct pico_remote_duple));
-    }
-
-#ifdef PICO_SUPPORT_IPFRAG
-#  ifdef PICO_SUPPORT_UDP
-    if (PROTO(s) == PICO_PROTO_UDP && ((len + header_offset) > PICO_SOCKET_MTU)) {
-      /* hacking way to identify fragmentation frames: payload != transport_hdr -> first frame */
-      if (!total_payload_written) {
-        frag_dbg("FRAG: first fragmented frame %p | len = %u offset = 0\n", f, f->payload_len);
-        /* transport header length field contains total length + header length */
-        f->transport_len = len + header_offset;
-        f->frag = short_be(PICO_IPV4_MOREFRAG); 
-      } else {
-        /* no transport header in fragmented IP */
-        f->payload = f->transport_hdr;
-        f->payload_len += header_offset;
-        /* set offset in octets */
-        f->frag = short_be((total_payload_written + header_offset) / 8); 
-        if (total_payload_written + f->payload_len < len) {
-          frag_dbg("FRAG: intermediate fragmented frame %p | len = %u offset = %u\n", f, f->payload_len, short_be(f->frag));
-          f->frag |= short_be(PICO_IPV4_MOREFRAG);
-        } else {
-          frag_dbg("FRAG: last fragmented frame %p | len = %u offset = %u\n", f, f->payload_len, short_be(f->frag));
-          f->frag &= short_be(PICO_IPV4_FRAG_MASK);
-        }
-      }
-    } else {
-      f->frag = short_be(PICO_IPV4_DONTFRAG);
-    }
-#  endif /* PICO_SUPPORT_UDP */
-#endif /* PICO_SUPPORT_IPFRAG */
-
-    if (f->payload_len <= 0) {
-      pico_frame_discard(f);
-      if (remote_duple)
-        pico_free(remote_duple);
-      return total_payload_written;
-    }
-
-    memcpy(f->payload, buf + total_payload_written, f->payload_len);
-    //dbg("Pushing segment, hdr len: %d, payload_len: %d\n", header_offset, f->payload_len);
-
-    if (s->proto->push(s->proto, f) > 0) {
-      total_payload_written += f->payload_len;
-    } else {
-      pico_frame_discard(f);
-      pico_err = PICO_ERR_EAGAIN;
-      break;
-    }
-  }
-  if (remote_duple)
-    pico_free(remote_duple);
-  return total_payload_written;
-}
-
-int pico_socket_send(struct pico_socket *s, void *buf, int len)
-{
-  if (!s || buf == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    /* See task #178 */
-    if (pico_check_socket(s) != 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_CONNECTED) == 0) {
-    pico_err = PICO_ERR_ENOTCONN;
-    return -1;
-  }
-  return pico_socket_sendto(s, buf, len, &s->remote_addr, s->remote_port);
-}
-
-int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port)
-{
-  if (!s || buf == NULL) { /// || orig == NULL || remote_port == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    if (pico_check_socket(s) != 0) {
-      pico_err = PICO_ERR_EINVAL;
-    /* See task #178 */
-      return -1;
-    }
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    pico_err = PICO_ERR_EADDRNOTAVAIL;
-    return -1;
-  }
-#ifdef PICO_SUPPORT_UDP 
-  if (PROTO(s) == PICO_PROTO_UDP) {
-    return pico_udp_recv(s, buf, len, orig, remote_port);
-  }
-#endif
-#ifdef PICO_SUPPORT_TCP
-  if (PROTO(s) == PICO_PROTO_TCP) {
-    /* check if in shutdown state and if tcpq_in empty */
-    if ((s->state & PICO_SOCKET_STATE_SHUT_REMOTE) && pico_tcp_queue_in_is_empty(s)) {
-      pico_err = PICO_ERR_ESHUTDOWN;
-      return -1;
-    } else {
-      //dbg("socket tcp recv\n");
-      return pico_tcp_read(s, buf, len);
-    }
-  }
-#endif
-  //dbg("socket return 0\n");
-  return 0;
-}
-
-int pico_socket_recv(struct pico_socket *s, void *buf, int len)
-{
-  return pico_socket_recvfrom(s, buf, len, NULL, NULL);
-}
-
-
-int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port)
-{
-  if (!s || !local_addr || !port) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if (!is_sock_ipv6(s)) {
-    struct pico_ip4 *ip = (struct pico_ip4 *)local_addr;
-    if (ip->addr != PICO_IPV4_INADDR_ANY) {
-      if (!pico_ipv4_link_find(local_addr)) {
-        pico_err = PICO_ERR_EINVAL;
-        return -1;
-      }
-    }
-  } else {
-    /*... IPv6 */
-  }
-
-
-  /* When given port = 0, get a random high port to bind to. */
-  if (*port == 0) {
-    *port = pico_socket_high_port(PROTO(s));
-    if (*port == 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if (pico_is_port_free(PROTO(s), *port, local_addr, s->net) == 0) {
-    pico_err = PICO_ERR_EADDRINUSE;
-    return -1;
-  }
-  s->local_port = *port;
-
-  if (is_sock_ipv6(s)) {
-    struct pico_ip6 *ip = (struct pico_ip6 *) local_addr;
-    memcpy(s->local_addr.ip6.addr, ip, PICO_SIZE_IP6);
-    /* XXX: port ipv4 functionality to ipv6 */
-    /* Check for port already in use */
-    if (pico_is_port_free(PROTO(s), *port, &local_addr, s->net)) {
-      pico_err = PICO_ERR_EADDRINUSE;
-      return -1;
-    }
-  } else if (is_sock_ipv4(s)) {
-    struct pico_ip4 *ip = (struct pico_ip4 *) local_addr;
-    s->local_addr.ip4.addr = ip->addr;
-  }
-  return pico_socket_alter_state(s, PICO_SOCKET_STATE_BOUND, 0, 0);
-}
-
-int pico_socket_connect(struct pico_socket *s, void *remote_addr, uint16_t remote_port)
-{
-  int ret = -1;
-  pico_err = PICO_ERR_EPROTONOSUPPORT;
-  if (!s || remote_addr == NULL || remote_port == 0) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  s->remote_port = remote_port;
-
-  if (s->local_port == 0) {
-    s->local_port = pico_socket_high_port(PROTO(s));
-    if (!s->local_port) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if (is_sock_ipv6(s)) {
-    struct pico_ip6 *ip = (struct pico_ip6 *) remote_addr;
-    memcpy(s->remote_addr.ip6.addr, ip, PICO_SIZE_IP6);
-  } else if (is_sock_ipv4(s)) {
-    struct pico_ip4 *local, *ip = (struct pico_ip4 *) remote_addr;
-    s->remote_addr.ip4.addr = ip->addr;
-    local = pico_ipv4_source_find(ip);
-    if (local) {
-      s->local_addr.ip4.addr = local->addr;
-    } else {
-      pico_err = PICO_ERR_EHOSTUNREACH;
-      return -1;
-    }
-  }
-
-  pico_socket_alter_state(s, PICO_SOCKET_STATE_BOUND, 0, 0);
-
-#ifdef PICO_SUPPORT_UDP
-  if (PROTO(s) == PICO_PROTO_UDP) {
-    pico_socket_alter_state(s, PICO_SOCKET_STATE_CONNECTED, 0, 0);
-    pico_err = PICO_ERR_NOERR;
-    ret = 0;
-  }
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  if (PROTO(s) == PICO_PROTO_TCP) {
-    if (pico_tcp_initconn(s) == 0) {
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_CONNECTED | PICO_SOCKET_STATE_TCP_SYN_SENT, 0, 0);
-      pico_err = PICO_ERR_NOERR;
-      ret = 0;
-    } else {
-      pico_err = PICO_ERR_EHOSTUNREACH;
-    }
-  }
-#endif
-
-  return ret;
-}
-
-#ifdef PICO_SUPPORT_TCP
-
-int pico_socket_listen(struct pico_socket *s, int backlog)
-{
-  if (!s || backlog < 1) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    /* See task #178 */
-    if (pico_check_socket(s) != 0) {
-      pico_err = PICO_ERR_EINVAL;
-      return -1;
-    }
-  }
-
-  if (PROTO(s) == PICO_PROTO_UDP) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    pico_err = PICO_ERR_EISCONN;
-    return -1;
-  }
-
-  if (backlog < 1) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  if (PROTO(s) == PICO_PROTO_TCP)
-    pico_socket_alter_state(s, PICO_SOCKET_STATE_TCP_SYN_SENT, 0, PICO_SOCKET_STATE_TCP_LISTEN);
-  s->max_backlog = backlog;
-
-  return 0;
-}
-
-struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, uint16_t *port)
-{
-  if (!s || !orig || !port) {
-    pico_err = PICO_ERR_EINVAL;
-    return NULL;
-  }
-
-  pico_err = PICO_ERR_EINVAL;
-
-  if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
-    return NULL;
-  }
-
-  if (PROTO(s) == PICO_PROTO_UDP) {
-    return NULL;
-  }
-
-  if (TCPSTATE(s) == PICO_SOCKET_STATE_TCP_LISTEN) {
-    struct pico_sockport *sp = pico_get_sockport(PICO_PROTO_TCP, s->local_port);
-    struct pico_socket *found;
-    /* If at this point no incoming connection socket is found,
-     * the accept call is valid, but no connection is established yet.
-     */
-    pico_err = PICO_ERR_EAGAIN; 
-    if (sp) {
-      struct pico_tree_node * index;
-      //RB_FOREACH(found, socket_tree, &sp->socks) {
-      pico_tree_foreach(index,&sp->socks){
-        found = index->keyValue;
-        if (s == found->parent) {
-          found->parent = NULL;
-          pico_err = PICO_ERR_NOERR;
-          memcpy(orig, &found->remote_addr, sizeof(struct pico_ip4));
-          *port = found->remote_port;
-          return found;
-        }
-      }
-    }
-  }
-  return NULL;
-}
-
-#else
-
-int pico_socket_listen(struct pico_socket *s, int backlog)
-{
-  pico_err = PICO_ERR_EINVAL;
-  return -1;
-}
-
-struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, uint16_t *local_port)
-{
-  pico_err = PICO_ERR_EINVAL;
-  return NULL;
-}
-
-#endif
-
-#define PICO_SOCKET_SETOPT_EN(socket,index)  (socket->opt_flags |=  (1 << index))
-#define PICO_SOCKET_SETOPT_DIS(socket,index) (socket->opt_flags &= ~(1 << index))
-
-int pico_socket_setoption(struct pico_socket *s, int option, void *value) // XXX no check against proto (vs setsockopt) or implicit by socket?
-{
-  if (s == NULL) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  pico_err = PICO_ERR_NOERR;
-
-  switch (option)
-  {
-#ifdef PICO_SUPPORT_TCP
-    case PICO_TCP_NODELAY:
-          if (!value) {
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          if (s->proto->proto_number == PICO_PROTO_TCP) {
-            int *val = (int*)value;
-            if (*val > 0) {
-              dbg("setsockopt: Nagle algorithm disabled.\n");
-              PICO_SOCKET_SETOPT_EN(s,PICO_SOCKET_OPT_TCPNODELAY);
-            } else {
-              dbg("setsockopt: Nagle algorithm enabled.\n");
-              PICO_SOCKET_SETOPT_DIS(s,PICO_SOCKET_OPT_TCPNODELAY);
-            }
-          } else {
-            pico_err = PICO_ERR_EINVAL;
-          }
-          break;
-#endif
-
-
-#ifdef PICO_SUPPORT_MCAST
-    case PICO_IP_MULTICAST_IF:
-          pico_err = PICO_ERR_EOPNOTSUPP;
-          return -1;
-          break;
-
-    case PICO_IP_MULTICAST_TTL:
-          if (s->proto->proto_number == PICO_PROTO_UDP) {
-            return pico_udp_set_mc_ttl(s, *((uint8_t *) value));
-          }
-          break;
-
-    case PICO_IP_MULTICAST_LOOP:
-          if (s->proto->proto_number == PICO_PROTO_UDP) {
-            switch (*(uint8_t *) value)
-            {
-              case 0:
-                /* do not loop back multicast datagram */
-                PICO_SOCKET_SETOPT_DIS(s,PICO_SOCKET_OPT_MULTICAST_LOOP);
-                break;
-
-              case 1:
-                /* do loop back multicast datagram */
-                PICO_SOCKET_SETOPT_EN(s,PICO_SOCKET_OPT_MULTICAST_LOOP);
-                break;  
-
-              default:
-                pico_err = PICO_ERR_EINVAL;
-                return -1;
-             }
-          }
-          break;
-
-    case PICO_IP_ADD_MEMBERSHIP:
-      /* EXCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
-        struct pico_ip_mreq *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ipv4_link *mcast_link = NULL;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(mreq, NULL);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          s->MCASTListen = pico_zalloc(sizeof(struct pico_tree));
-          if (!s->MCASTListen) {
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          s->MCASTListen->root = &LEAF;
-          s->MCASTListen->compare = mcast_listen_cmp;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (listen) {
-          if (listen->filter_mode != PICO_IP_MULTICAST_EXCLUDE) {
-            so_mcast_dbg("pico_socket_setoption: ERROR any-source multicast (exclude) on source-specific multicast (include)\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          } else {
-            so_mcast_dbg("pico_socket_setoption: ERROR duplicate PICO_IP_ADD_MEMBERSHIP\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-        } else {
-          listen = pico_zalloc(sizeof(struct pico_mcast_listen));
-          if (!listen) {
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          listen->filter_mode = PICO_IP_MULTICAST_EXCLUDE;
-          listen->mcast_link = mreq->mcast_link_addr;
-          listen->mcast_group = mreq->mcast_group_addr;
-          listen->MCASTSources.root = &LEAF;
-          listen->MCASTSources.compare = mcast_sources_cmp;
-          pico_tree_insert(s->MCASTListen, listen);
-        }
-
-        pico_tree_insert(&MCASTSockets, s);
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_join(&mreq->mcast_link_addr, &mreq->mcast_group_addr, 1, filter_mode, &MCASTFilter);
-      }          
-      break;
-
-    case PICO_IP_DROP_MEMBERSHIP:
-      /* EXCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
-        struct pico_ip_mreq *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ip4 *source = NULL;
-        struct pico_ipv4_link *mcast_link = NULL;
-        struct pico_tree_node *index, *_tmp;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(mreq, NULL);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          so_mcast_dbg("socket_setoption: ERROR PICO_IP_DROP_MEMBERSHIP before any PICO_IP_ADD_MEMBERSHIP/SOURCE_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (!listen) {
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_DROP_MEMBERSHIP before PICO_IP_ADD_MEMBERSHIP/SOURCE_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EADDRNOTAVAIL;
-          return -1;
-        } else {
-          pico_tree_foreach_safe(index, &listen->MCASTSources, _tmp)
-          {
-            source = index->keyValue;
-            pico_tree_delete(&listen->MCASTSources, source);
-            pico_free(source);
-          }
-          pico_tree_delete(s->MCASTListen, listen);
-          pico_free(listen);
-          if (pico_tree_empty(s->MCASTListen)) {
-            pico_free(s->MCASTListen);
-            s->MCASTListen = NULL;
-            pico_tree_delete(&MCASTSockets, s);
-          }
-        }
-
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_leave(&mreq->mcast_link_addr, &mreq->mcast_group_addr, 1, filter_mode, &MCASTFilter);
-      }          
-      break;
-
-    case PICO_IP_UNBLOCK_SOURCE:
-      /* EXCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
-        struct pico_ip_mreq_source *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ip4 *source = NULL, stest = {0};
-        struct pico_ipv4_link *mcast_link = NULL;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq_source *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(NULL, mreq);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_UNBLOCK_SOURCE before any PICO_IP_ADD_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (!listen) {
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_UNBLOCK_SOURCE before PICO_IP_ADD_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        } else {
-          if (listen->filter_mode != PICO_IP_MULTICAST_EXCLUDE) {
-            so_mcast_dbg("pico_socket_setoption: ERROR any-source multicast (exclude) on source-specific multicast (include)\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          stest.addr = mreq->mcast_source_addr.addr;
-          source = pico_tree_findKey(&listen->MCASTSources, &stest);
-          if (!source) {
-            so_mcast_dbg("pico_socket_setoption: ERROR address to unblock not in source list\n");
-            pico_err = PICO_ERR_EADDRNOTAVAIL;
-            return -1;
-          } else {
-            pico_tree_delete(&listen->MCASTSources, source);
-            pico_free(source);
-          }
-        }
-
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_leave(&mreq->mcast_link_addr, &mreq->mcast_group_addr, 0, filter_mode, &MCASTFilter);
-      }          
-      break;
-
-    case PICO_IP_BLOCK_SOURCE:
-      /* EXCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
-        struct pico_ip_mreq_source *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ip4 *source = NULL, stest = {0};
-        struct pico_ipv4_link *mcast_link = NULL;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq_source *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(NULL, mreq);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_BLOCK_SOURCE before any PICO_IP_ADD_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (!listen) {
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_BLOCK_SOURCE before PICO_IP_ADD_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        } else {
-          if (listen->filter_mode != PICO_IP_MULTICAST_EXCLUDE) {
-            so_mcast_dbg("pico_socket_setoption: ERROR any-source multicast (exclude) on source-specific multicast (include)\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          stest.addr = mreq->mcast_source_addr.addr;
-          source = pico_tree_findKey(&listen->MCASTSources, &stest);
-          if (source) {
-            so_mcast_dbg("pico_socket_setoption: ERROR address to block already in source list\n");
-            pico_err = PICO_ERR_EADDRNOTAVAIL;
-            return -1;
-          } else {
-            source = pico_zalloc(sizeof(struct pico_ip4));
-            if (!source) {
-              pico_err = PICO_ERR_ENOMEM;
-              return -1;
-            }
-            source->addr = mreq->mcast_source_addr.addr;
-            pico_tree_insert(&listen->MCASTSources, source);
-          }
-        }
-
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_join(&mreq->mcast_link_addr, &mreq->mcast_group_addr, 0, filter_mode, &MCASTFilter);
-      }          
-      break;
-
-    case PICO_IP_ADD_SOURCE_MEMBERSHIP:
-      /* INCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0, reference_count = 0;
-        struct pico_ip_mreq_source *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ip4 *source = NULL, stest = {0};
-        struct pico_ipv4_link *mcast_link = NULL;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq_source *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(NULL, mreq);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          s->MCASTListen = pico_zalloc(sizeof(struct pico_tree));
-          if (!s->MCASTListen) {
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          s->MCASTListen->root = &LEAF;
-          s->MCASTListen->compare = mcast_listen_cmp;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (listen) {
-          if (listen->filter_mode != PICO_IP_MULTICAST_INCLUDE) {
-            so_mcast_dbg("pico_socket_setoption: ERROR source-specific multicast (include) on any-source multicast (exclude)\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          stest.addr = mreq->mcast_source_addr.addr;
-          source = pico_tree_findKey(&listen->MCASTSources, &stest);
-          if (source) {
-            so_mcast_dbg("pico_socket_setoption: ERROR source address to allow already in source list\n");
-            pico_err = PICO_ERR_EADDRNOTAVAIL;
-            return -1;
-          } else {
-            source = pico_zalloc(sizeof(struct pico_ip4));
-            if (!source) {
-              pico_err = PICO_ERR_ENOMEM;
-              return -1;
-            }
-            source->addr = mreq->mcast_source_addr.addr;
-            pico_tree_insert(&listen->MCASTSources, source);
-          }
-        } else {
-          listen = pico_zalloc(sizeof(struct pico_mcast_listen));
-          if (!listen) {
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          listen->filter_mode = PICO_IP_MULTICAST_INCLUDE;
-          listen->mcast_link = mreq->mcast_link_addr;
-          listen->mcast_group = mreq->mcast_group_addr;
-          listen->MCASTSources.root = &LEAF;
-          listen->MCASTSources.compare = mcast_sources_cmp;
-          source = pico_zalloc(sizeof(struct pico_ip4));
-          if (!source) {
-            pico_free(listen);
-            pico_err = PICO_ERR_ENOMEM;
-            return -1;
-          }
-          source->addr = mreq->mcast_source_addr.addr;
-          pico_tree_insert(&listen->MCASTSources, source);
-          pico_tree_insert(s->MCASTListen, listen);
-          reference_count = 1;
-        }
-
-        pico_tree_insert(&MCASTSockets, s);
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_join(&mreq->mcast_link_addr, &mreq->mcast_group_addr, reference_count, filter_mode, &MCASTFilter);
-      }          
-      break;
-
-    case PICO_IP_DROP_SOURCE_MEMBERSHIP:
-      /* INCLUDE mode */
-      if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0, reference_count = 0;
-        struct pico_ip_mreq_source *mreq = NULL;
-        struct pico_mcast_listen *listen = NULL, ltest = {0};
-        struct pico_ip4 *source = NULL, stest = {0};
-        struct pico_ipv4_link *mcast_link = NULL;
-
-        if (!value) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        mreq = (struct pico_ip_mreq_source *) value;
-        mcast_link = pico_socket_setoption_mcastargs_validation(NULL, mreq);
-        if (!mcast_link) {
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        if (!mreq->mcast_link_addr.addr)
-          mreq->mcast_link_addr.addr = mcast_link->address.addr;
-
-        if (!s->MCASTListen) { /* No RBTree allocated yet */
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_DROP_SOURCE_MEMBERSHIP before any PICO_IP_ADD_SOURCE_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-        }
-        ltest.mcast_link = mreq->mcast_link_addr;
-        ltest.mcast_group = mreq->mcast_group_addr;
-        listen = pico_tree_findKey(s->MCASTListen, &ltest);
-        if (!listen) {
-          so_mcast_dbg("pico_socket_setoption: ERROR PICO_IP_DROP_SOURCE_MEMBERSHIP before PICO_IP_ADD_SOURCE_MEMBERSHIP\n");
-          pico_err = PICO_ERR_EADDRNOTAVAIL;
-          return -1;
-        } else {
-          if (listen->filter_mode != PICO_IP_MULTICAST_INCLUDE) {
-            so_mcast_dbg("pico_socket_setoption: ERROR source-specific multicast (include) on any-source multicast (exclude)\n");
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          stest.addr = mreq->mcast_source_addr.addr;
-          source = pico_tree_findKey(&listen->MCASTSources, &stest);
-          if (!source) {
-            so_mcast_dbg("pico_socket_setoption: ERROR address to drop not in source list\n");
-            pico_err = PICO_ERR_EADDRNOTAVAIL;
-            return -1;
-          } else {
-            pico_tree_delete(&listen->MCASTSources, source);
-            pico_free(source);
-            if (pico_tree_empty(&listen->MCASTSources)) { /* 1 if empty, 0 otherwise */
-              reference_count = 1;
-              pico_tree_delete(s->MCASTListen, listen);
-              pico_free(listen);
-              if (pico_tree_empty(s->MCASTListen)) {
-                pico_free(s->MCASTListen);
-                s->MCASTListen = NULL;
-                pico_tree_delete(&MCASTSockets, s);
-              }
-            }
-          }
-        }
-
-        filter_mode = pico_socket_aggregate_mcastfilters(&mcast_link->address, &mreq->mcast_group_addr);
-        if (filter_mode < 0) 
-          return -1;
-
-        return pico_ipv4_mcast_leave(&mreq->mcast_link_addr, &mreq->mcast_group_addr, reference_count, filter_mode, &MCASTFilter);
-      }          
-      break;
-#endif /* PICO_SUPPORT_MCAST */
-
-    default:
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-  }
-
-  if (pico_err != PICO_ERR_NOERR)
-    return -1;
-  else
-    return 0;
-}
-
-#define PICO_SOCKET_GETOPT(socket,index) ((socket->opt_flags & (1 << index)) != 0)
-
-int pico_socket_getoption(struct pico_socket *s, int option, void *value)
-{  
-  if (!s || !value) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  }
-
-  switch (option)
-  {
-#ifdef PICO_SUPPORT_TCP
-    case PICO_TCP_NODELAY:
-          if (s->proto->proto_number == PICO_PROTO_TCP)
-            /* state of the NODELAY option */
-            *(int *)value = PICO_SOCKET_GETOPT(s,PICO_SOCKET_OPT_TCPNODELAY);
-          else
-            *(int *)value = 0;
-          break;
-#endif
-
-#ifdef PICO_SUPPORT_MCAST
-    case PICO_IP_MULTICAST_IF:
-          pico_err = PICO_ERR_EOPNOTSUPP;
-          return -1;
-          break;
-
-    case PICO_IP_MULTICAST_TTL:
-          if (s->proto->proto_number == PICO_PROTO_UDP) {
-            pico_udp_get_mc_ttl(s, (uint8_t *) value);
-          } else {
-            *(uint8_t *)value = 0;
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }            
-          break;
-
-    case PICO_IP_MULTICAST_LOOP:
-          if (s->proto->proto_number == PICO_PROTO_UDP) {
-            *(uint8_t *)value = PICO_SOCKET_GETOPT(s,PICO_SOCKET_OPT_MULTICAST_LOOP);
-          } else {
-            *(uint8_t *)value = 0;
-            pico_err = PICO_ERR_EINVAL;
-            return -1;
-          }
-          break;
-#endif /* PICO_SUPPORT_MCAST */
-
-    default:
-          pico_err = PICO_ERR_EINVAL;
-          return -1;
-  }
-
-  return 0;
-}
-
-
-int pico_socket_shutdown(struct pico_socket *s, int mode)
-{
-  if (!s) {
-    pico_err = PICO_ERR_EINVAL;
-    return -1;
-  } else {
-    /* check if exists in tree */
-    /* See task #178 */
-    if (pico_check_socket(s) != 0) {
-      pico_free(s); /* close socket after bind or connect failed */
-      return 0;
-    }
-  }
-
-#ifdef PICO_SUPPORT_UDP
-  if (PROTO(s) == PICO_PROTO_UDP) {
-    if (mode & PICO_SHUT_RDWR)
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_CLOSED, PICO_SOCKET_STATE_CLOSING |PICO_SOCKET_STATE_BOUND | PICO_SOCKET_STATE_CONNECTED, 0);
-    else if (mode & PICO_SHUT_RD)
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_BOUND, 0, 0);
-  }
-#endif
-#ifdef PICO_SUPPORT_TCP
-  if (PROTO(s) == PICO_PROTO_TCP) {
-    if (mode & PICO_SHUT_WR)
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL, 0, 0);
-    else if (mode & PICO_SHUT_RD)
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0);
-    else if (mode & PICO_SHUT_RDWR)
-      pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL | PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0);
-  }
-#endif
-  return 0;
-}
-
-int pico_socket_close(struct pico_socket *s)
-{
-  return pico_socket_shutdown(s, PICO_SHUT_RDWR);
-}
-
-#ifdef PICO_SUPPORT_CRC
-static inline int pico_transport_crc_check(struct pico_frame *f)
-{
-  struct pico_ipv4_hdr *net_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-  struct pico_udp_hdr *udp_hdr = NULL;
-  uint16_t checksum_invalid = 1;
-
-  switch (net_hdr->proto)
-  {
-    case PICO_PROTO_TCP:
-      checksum_invalid = short_be(pico_tcp_checksum_ipv4(f));
-      //dbg("TCP CRC validation == %u\n", checksum_invalid);
-      if (checksum_invalid) {
-        //dbg("TCP CRC: validation failed!\n");
-        pico_frame_discard(f);
-        return 0;
-      }
-      break;
-
-    case PICO_PROTO_UDP:
-      udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
-      if (short_be(udp_hdr->crc)) {
-        checksum_invalid = short_be(pico_udp_checksum_ipv4(f));
-        //dbg("UDP CRC validation == %u\n", checksum_invalid);
-        if (checksum_invalid) {
-          //dbg("UDP CRC: validation failed!\n");
-          pico_frame_discard(f);
-          return 0;
-        }
-      }
-      break;
-
-    default:
-      // Do nothing
-      break;
-  }
-  return 1;
-}
-#else
-static inline int pico_transport_crc_check(struct pico_frame *f)
-{
-  return 1;
-}
-#endif /* PICO_SUPPORT_CRC */
-
-int pico_transport_process_in(struct pico_protocol *self, struct pico_frame *f)
-{
-  struct pico_trans *hdr = (struct pico_trans *) f->transport_hdr;
-  int ret = 0;
-
-  if (!hdr) {
-    pico_err = PICO_ERR_EFAULT;
-    return -1;
-  }
-
-  ret = pico_transport_crc_check(f);
-  if (ret < 1)
-    return ret;
-  else
-    ret = 0;
-
-  if ((hdr) && (pico_socket_deliver(self, f, hdr->dport) == 0))
-    return ret;
-
-  if (!IS_BCAST(f)) {
-    dbg("Socket not found... \n");
-    pico_notify_socket_unreachable(f);
-#ifdef PICO_SUPPORT_TCP
-    /* if tcp protocol send RST segment */
-    //if (self->proto_number == PICO_PROTO_TCP)
-    //  pico_tcp_reply_rst(f);
-#endif
-    ret = -1;
-    pico_err = PICO_ERR_ENOENT;
-  }
-  pico_frame_discard(f);
-  return ret;
-}
-
-#define SL_LOOP_MIN 1
-
-
-int pico_sockets_loop(int loop_score)
-{
-  static struct pico_tree_node *index_udp, * index_tcp;
-
-  struct pico_sockport *start;
-  struct pico_socket *s;
-
-#ifdef PICO_SUPPORT_UDP
-  struct pico_frame *f;
-
-  if (sp_udp == NULL)
-  {
-    index_udp = pico_tree_firstNode(UDPTable.root);
-    sp_udp = index_udp->keyValue;
-  }
-
-  /* init start node */
-  start = sp_udp;
-
-  /* round-robin all transport protocols, break if traversed all protocols */
-  while (loop_score > SL_LOOP_MIN && sp_udp != NULL) {
-    struct pico_tree_node * index;
-
-    pico_tree_foreach(index,&sp_udp->socks){
-      s = index->keyValue;
-      f = pico_dequeue(&s->q_out);
-      while (f && (loop_score > 0)) {
-        pico_proto_udp.push(&pico_proto_udp, f);
-        loop_score -= 1;
-        f = pico_dequeue(&s->q_out);
-      }
-    }
-
-    index_udp = pico_tree_next(index_udp);
-    sp_udp = index_udp->keyValue;
-
-    if (sp_udp == NULL)
-    {
-      index_udp = pico_tree_firstNode(UDPTable.root);
-      sp_udp = index_udp->keyValue;
-    }
-    if (sp_udp == start)
-      break;
-  }
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  if (sp_tcp == NULL)
-  {
-    index_tcp = pico_tree_firstNode(TCPTable.root);
-    sp_tcp = index_tcp->keyValue;
-  }
-
-  /* init start node */
-  start = sp_tcp;
-
-  while (loop_score > SL_LOOP_MIN && sp_tcp != NULL) {
-    struct pico_tree_node * index;
-    pico_tree_foreach(index, &sp_tcp->socks){
-      s = index->keyValue;
-      loop_score = pico_tcp_output(s, loop_score);
-      if ((s->ev_pending) && s->wakeup) {
-        s->wakeup(s->ev_pending, s);
-      }
-      if (loop_score <= 0) {
-        loop_score = 0;
-        break;
-      }
-    }
-
-    /* check if RB_FOREACH ended, if not, break to keep the cur sp_tcp */
-    if (s != NULL)
-      break;
-
-    index_tcp = pico_tree_next(index_tcp);
-    sp_tcp = index_tcp->keyValue;
-
-    if (sp_tcp == NULL)
-    {
-      index_tcp = pico_tree_firstNode(TCPTable.root);
-      sp_tcp = index_tcp->keyValue;
-    }
-    if (sp_tcp == start)
-      break;
-  }
-#endif
-
-  return loop_score;
-}
-
-
-struct pico_frame *pico_socket_frame_alloc(struct pico_socket *s, int len)
-{
-  struct pico_frame *f = NULL;
-
-#ifdef PICO_SUPPORT_IPV6
-  if (IS_SOCK_IPV6(s))
-    f = pico_proto_ipv6.alloc(&pico_proto_ipv6, len);
-#endif
-
-#ifdef PICO_SUPPORT_IPV4
-  if (IS_SOCK_IPV4(s))
-    f = pico_proto_ipv4.alloc(&pico_proto_ipv4, len);
-#endif
-  if (!f) {
-    pico_err = PICO_ERR_ENOMEM;
-    return f;
-  }
-  f->payload = f->transport_hdr;
-  f->payload_len = len;
-  f->sock = s;
-  return f;
-}
-
-int pico_transport_error(struct pico_frame *f, uint8_t proto, int code)
-{
-  int ret = -1;
-  struct pico_trans *trans = (struct pico_trans*) f->transport_hdr;
-  struct pico_sockport *port = NULL;
-  struct pico_socket *s = NULL;
-  switch (proto) {
-
-
-#ifdef PICO_SUPPORT_UDP
-  case PICO_PROTO_UDP:
-    port = pico_get_sockport(proto, trans->sport);
-    break;
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  case PICO_PROTO_TCP:
-    port = pico_get_sockport(proto, trans->sport);
-    break;
-#endif
-
-  default:
-    /* Protocol not available */
-    ret = -1;
-  }
-  if (port) {
-    struct pico_tree_node * index;
-    ret = 0;
-
-    pico_tree_foreach(index,&port->socks) {
-      s = index->keyValue;
-      if (trans->dport == s->remote_port) {
-        if (s->wakeup) {
-          //dbg("SOCKET ERROR FROM ICMP NOTIFICATION. (icmp code= %d)\n\n", code);
-          switch(code) {
-            case PICO_ICMP_UNREACH_PROTOCOL:
-              pico_err = PICO_ERR_EPROTO;
-              break;
-
-            case PICO_ICMP_UNREACH_PORT:
-              pico_err = PICO_ERR_ECONNREFUSED;
-              break;
-
-            case PICO_ICMP_UNREACH_NET:
-            case PICO_ICMP_UNREACH_NET_PROHIB:
-            case PICO_ICMP_UNREACH_NET_UNKNOWN:
-              pico_err = PICO_ERR_ENETUNREACH;
-              break;
-
-            default:
-              pico_err = PICO_ERR_EHOSTUNREACH;
-          }
-          s->wakeup(PICO_SOCK_EV_ERR, s);
-        }
-        break;
-      }
-    }
-  }
-  pico_frame_discard(f);
-  return ret;
-}
-#endif
-#endif
--- a/stack/pico_stack.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,733 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-.
-
-Authors: Daniele Lacamera
-*********************************************************************/
-
-
-#include "pico_config.h"
-#include "pico_frame.h"
-#include "pico_device.h"
-#include "pico_protocol.h"
-#include "pico_stack.h"
-#include "pico_addressing.h"
-#include "pico_dns_client.h"
-
-#include "pico_eth.h"
-#include "pico_arp.h"
-#include "pico_ipv4.h"
-#include "pico_ipv6.h"
-#include "pico_icmp4.h"
-#include "pico_igmp.h"
-#include "pico_udp.h"
-#include "pico_tcp.h"
-#include "pico_socket.h"
-#include "heap.h"
-
-#define IS_LIMITED_BCAST(f) ( ((struct pico_ipv4_hdr *) f->net_hdr)->dst.addr == PICO_IP4_BCAST )
-
-#ifdef PICO_SUPPORT_MCAST
-# define PICO_SIZE_MCAST 3
-  const uint8_t PICO_ETHADDR_MCAST[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
-#endif
-
-uint32_t cur_mem = 0;
-uint32_t max_mem = 0;
-
-
-volatile unsigned long pico_tick;
-volatile pico_err_t pico_err;
-
-static uint32_t _rand_seed;
-
-void pico_rand_feed(uint32_t feed)
-{
-  if (!feed)
-    return;
-  _rand_seed *= 1664525;
-  _rand_seed += 1013904223;
-  _rand_seed ^= ~(feed);
-}
-
-uint32_t pico_rand(void)
-{
-  pico_rand_feed(pico_tick);
-  return _rand_seed;
-}
-
-/* NOTIFICATIONS: distributed notifications for stack internal errors.
- */
-
-int pico_notify_socket_unreachable(struct pico_frame *f)
-{
-  if (0) {}
-#ifdef PICO_SUPPORT_ICMP4 
-  else if (IS_IPV4(f)) {
-    pico_icmp4_port_unreachable(f);
-  }
-#endif
-#ifdef PICO_SUPPORT_ICMP6 
-  else if (IS_IPV6(f)) {
-    pico_icmp6_port_unreachable(f);
-  }
-#endif
-
-  return 0;
-}
-
-int pico_notify_proto_unreachable(struct pico_frame *f)
-{
-  if (0) {}
-#ifdef PICO_SUPPORT_ICMP4 
-  else if (IS_IPV4(f)) {
-    pico_icmp4_proto_unreachable(f);
-  }
-#endif
-#ifdef PICO_SUPPORT_ICMP6 
-  else if (IS_IPV6(f)) {
-    pico_icmp6_proto_unreachable(f);
-  }
-#endif
-  return 0;
-}
-
-int pico_notify_dest_unreachable(struct pico_frame *f)
-{
-  if (0) {}
-#ifdef PICO_SUPPORT_ICMP4 
-  else if (IS_IPV4(f)) {
-    pico_icmp4_dest_unreachable(f);
-  }
-#endif
-#ifdef PICO_SUPPORT_ICMP6 
-  else if (IS_IPV6(f)) {
-    pico_icmp6_dest_unreachable(f);
-  }
-#endif
-  return 0;
-}
-
-int pico_notify_ttl_expired(struct pico_frame *f)
-{
-  if (0) {}
-#ifdef PICO_SUPPORT_ICMP4 
-  else if (IS_IPV4(f)) {
-    pico_icmp4_ttl_expired(f);
-  }
-#endif
-#ifdef PICO_SUPPORT_ICMP6 
-  else if (IS_IPV6(f)) {
-    pico_icmp6_ttl_expired(f);
-  }
-#endif
-  return 0;
-}
-
-
-/* Transport layer */
-int pico_transport_receive(struct pico_frame *f, uint8_t proto)
-{
-  int ret = -1;
-  switch (proto) {
-
-#ifdef PICO_SUPPORT_ICMP4
-  case PICO_PROTO_ICMP4:
-    ret = pico_enqueue(pico_proto_icmp4.q_in, f);
-    break;
-#endif
-
-#ifdef PICO_SUPPORT_IGMP
-  case PICO_PROTO_IGMP:
-    ret = pico_enqueue(pico_proto_igmp.q_in, f);
-    break;
-#endif
-
-#ifdef PICO_SUPPORT_UDP
-  case PICO_PROTO_UDP:
-    ret = pico_enqueue(pico_proto_udp.q_in, f);
-    break;
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  case PICO_PROTO_TCP:
-    ret = pico_enqueue(pico_proto_tcp.q_in, f);
-    break;
-#endif
-
-  default:
-    /* Protocol not available */
-    dbg("pkt: no such protocol (%d)\n", proto);
-    pico_notify_proto_unreachable(f);
-    pico_frame_discard(f);
-    ret = -1;
- }
- return ret;
-}
-
-int pico_transport_send(struct pico_frame *f)
-{
-  if (!f || !f->sock || !f->sock->proto) {
-    pico_frame_discard(f);
-    return -1;
-  }
-  return f->sock->proto->push(f->sock->net, f);
-}
-
-int pico_network_receive(struct pico_frame *f)
-{
-  if (0) {}
-#ifdef PICO_SUPPORT_IPV4
-  else if (IS_IPV4(f)) {
-    pico_enqueue(pico_proto_ipv4.q_in, f);
-  }
-#endif
-#ifdef PICO_SUPPORT_IPV6
-  else if (IS_IPV6(f)) {
-    pico_enqueue(pico_proto_ipv6.q_in, f);
-  }
-#endif
-  else {
-    dbg("Network not found.\n");
-    pico_frame_discard(f);
-    return -1;
-  }
-  return f->buffer_len;
-}
-
-
-/* Network layer: interface towards socket for frame sending */
-int pico_network_send(struct pico_frame *f)
-{
-  if (!f || !f->sock || !f->sock->net) {
-    pico_frame_discard(f);
-    return -1;
-  }
-  return f->sock->net->push(f->sock->net, f);
-}
-
-int pico_destination_is_local(struct pico_frame *f)
-{
-  if (0) { }
-#ifdef PICO_SUPPORT_IPV4
-  else if (IS_IPV4(f)) {
-    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-    if (pico_ipv4_link_find(&hdr->dst))
-      return 1;
-  }
-#endif
-#ifdef PICO_SUPPORT_IPV6
-  else if (IS_IPV6(f)) {
-  }
-#endif
-  return 0;
-}
-
-int pico_source_is_local(struct pico_frame *f)
-{
-  if (0) { }
-#ifdef PICO_SUPPORT_IPV4
-  else if (IS_IPV4(f)) {
-    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr;
-    if (hdr->src.addr == PICO_IPV4_INADDR_ANY)
-      return 1;
-    if (pico_ipv4_link_find(&hdr->src))
-      return 1;
-  }
-#endif
-#ifdef PICO_SUPPORT_IPV6
-  else if (IS_IPV6(f)) {
-  /* XXX */
-  }
-#endif
-  return 0;
-
-
-}
-
-
-/* DATALINK LEVEL: interface from network to the device
- * and vice versa.
- */
-
-/* The pico_ethernet_receive() function is used by 
- * those devices supporting ETH in order to push packets up 
- * into the stack. 
- */
-int pico_ethernet_receive(struct pico_frame *f)
-{
-  struct pico_eth_hdr *hdr;
-  if (!f || !f->dev || !f->datalink_hdr)
-    goto discard;
-  hdr = (struct pico_eth_hdr *) f->datalink_hdr;
-  if ( (memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) && 
-#ifdef PICO_SUPPORT_MCAST
-    (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) &&
-#endif
-    (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0) ) 
-    goto discard;
-
-  f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
-  if (hdr->proto == PICO_IDETH_ARP)
-    return pico_arp_receive(f);
-  if ((hdr->proto == PICO_IDETH_IPV4) || (hdr->proto == PICO_IDETH_IPV6))
-    return pico_network_receive(f);
-discard:
-  pico_frame_discard(f);
-  return -1;
-}
-
-static int destination_is_bcast(struct pico_frame *f)
-{
-  if (!f)
-    return 0;
-
-  if (IS_IPV6(f))
-    return 0;
-#ifdef PICO_SUPPORT_IPV4
-  else {
-    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-    return pico_ipv4_is_broadcast(hdr->dst.addr);
-  }
-#endif
-  return 0;
-}
-
-#ifdef PICO_SUPPORT_MCAST
-static int destination_is_mcast(struct pico_frame *f)
-{
-  if (!f)
-    return 0;
-
-  if (IS_IPV6(f))
-    return 0;
-#ifdef PICO_SUPPORT_IPV4
-  else {
-    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-    return pico_ipv4_is_multicast(hdr->dst.addr);
-  }
-#endif
-  return 0;
-}
-
-static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac)
-{
-  struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-
-  /* place 23 lower bits of IP in lower 23 bits of MAC */
-  pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FF);
-  pico_mcast_mac[4] = (long_be(hdr->dst.addr) & 0x0000FF00) >> 8; 
-  pico_mcast_mac[3] = (long_be(hdr->dst.addr) & 0x007F0000) >> 16;
-
-  return (struct pico_eth *)pico_mcast_mac;
-}
-
-
-#endif /* PICO_SUPPORT_MCAST */
-
-/* This is called by dev loop in order to ensure correct ethernet addressing.
- * Returns 0 if the destination is unknown, and -1 if the packet is not deliverable
- * due to ethernet addressing (i.e., no arp association was possible. 
- *
- * Only IP packets must pass by this. ARP will always use direct dev->send() function, so
- * we assume IP is used.
- */
-int pico_ethernet_send(struct pico_frame *f)
-{
-  struct pico_eth *dstmac = NULL;
-
-  if (IS_IPV6(f)) {
-    /*TODO: Neighbor solicitation */
-    dstmac = NULL;
-  }
-
-  else if (IS_IPV4(f)) {
-    if (IS_BCAST(f) || destination_is_bcast(f)) {
-      dstmac = (struct pico_eth *) PICO_ETHADDR_ALL;
-    } 
-#ifdef PICO_SUPPORT_MCAST
-    else if (destination_is_mcast(f)) {
-      uint8_t pico_mcast_mac[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
-      dstmac = pico_ethernet_mcast_translate(f, pico_mcast_mac);
-    } 
-#endif
-    else {
-      dstmac = pico_arp_get(f);
-      if (!dstmac)
-        return 0;
-    }
-    /* This sets destination and source address, then pushes the packet to the device. */
-    if (dstmac && (f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) {
-      struct pico_eth_hdr *hdr;
-      f->start -= PICO_SIZE_ETHHDR;
-      f->len += PICO_SIZE_ETHHDR;
-      f->datalink_hdr = f->start;
-      hdr = (struct pico_eth_hdr *) f->datalink_hdr;
-      memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
-      memcpy(hdr->daddr, dstmac, PICO_SIZE_ETH);
-      hdr->proto = PICO_IDETH_IPV4;
-      if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)){
-        dbg("sending out packet destined for our own mac\n");
-        return pico_ethernet_receive(f);
-      }else if(IS_LIMITED_BCAST(f)){
-        return pico_device_broadcast(f);
-      }else {
-        return f->dev->send(f->dev, f->start, f->len);
-        /* Frame is discarded after this return by the caller */
-      }
-    } else {
-      return -1;
-    }
-  } /* End IPV4 ethernet addressing */
-  return -1;
-}
-
-void pico_store_network_origin(void *src, struct pico_frame *f)
-{
-  #ifdef PICO_SUPPORT_IPV4
-  struct pico_ip4 *ip4;
-  #endif
-
-  #ifdef PICO_SUPPORT_IPV6
-  struct pico_ip6 *ip6;
-  #endif
-
-  #ifdef PICO_SUPPORT_IPV4
-  if (IS_IPV4(f)) {
-    struct pico_ipv4_hdr *hdr;
-    hdr = (struct pico_ipv4_hdr *) f->net_hdr;
-    ip4 = (struct pico_ip4 *) src;
-    ip4->addr = hdr->src.addr;
-  }
-  #endif
-  #ifdef PICO_SUPPORT_IPV6
-  if (IS_IPV6(f)) {
-    struct pico_ipv6_hdr *hdr;
-    hdr = (struct pico_ipv6_hdr *) f->net_hdr;
-    ip6 = (struct pico_ip6 *) src;
-    memcpy(ip6->addr, hdr->src.addr, PICO_SIZE_IP6);
-  }
-  #endif
-}
-
-
-/* LOWEST LEVEL: interface towards devices. */
-/* Device driver will call this function which returns immediately.
- * Incoming packet will be processed later on in the dev loop.
- */
-int pico_stack_recv(struct pico_device *dev, uint8_t *buffer, int len)
-{
-  struct pico_frame *f;
-  int ret;
-  if (len <= 0)
-    return -1;
-  f = pico_frame_alloc(len);
-  if (!f)
-    return -1;
-
-  /* Association to the device that just received the frame. */
-  f->dev = dev;
-
-  /* Setup the start pointer, lenght. */
-  f->start = f->buffer;
-  f->len = f->buffer_len;
-  if (f->len > 8) {
-    int mid_frame = (f->buffer_len >> 2)<<1;
-    mid_frame -= (mid_frame % 4);
-    pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
-  }
-  memcpy(f->buffer, buffer, len);
-  ret = pico_enqueue(dev->q_in, f);
-  if (ret <= 0) {
-    pico_frame_discard(f);
-  }
-  return ret;
-}
-
-int pico_sendto_dev(struct pico_frame *f)
-{
-  if (!f->dev) {
-    pico_frame_discard(f);
-    return -1;
-  } else {
-    if (f->len > 8) {
-      int mid_frame = (f->buffer_len >> 2)<<1;
-      mid_frame -= (mid_frame % 4);
-      pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
-    }
-    return pico_enqueue(f->dev->q_out, f);
-  }
-}
-
-struct pico_timer
-{
-  unsigned long expire;
-  void *arg;
-  void (*timer)(unsigned long timestamp, void *arg);
-};
-
-typedef struct pico_timer pico_timer;
-
-DECLARE_HEAP(pico_timer, expire);
-
-static heap_pico_timer *Timers;
-
-void pico_check_timers(void)
-{
-  struct pico_timer timer;
-  struct pico_timer *t = heap_first(Timers);
-  pico_tick = PICO_TIME_MS();
-  while((t) && (t->expire < pico_tick)) {
-    t->timer(pico_tick, t->arg);
-    heap_peek(Timers, &timer);
-    t = heap_first(Timers);
-  }
-}
-
-
-#define PROTO_DEF_NR      11
-#define PROTO_DEF_AVG_NR  4
-#define PROTO_DEF_SCORE   32
-#define PROTO_MIN_SCORE   32
-#define PROTO_MAX_SCORE   128
-#define PROTO_LAT_IND     1   /* latecy indication 0-3 (lower is better latency performance), x1, x2, x4, x8 */
-#define PROTO_MAX_LOOP    (PROTO_MAX_SCORE<<PROTO_LAT_IND) /* max global loop score, so per tick */
-
-static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret)
-{
-  int temp, i, j, sum;
-  int max_total = PROTO_MAX_LOOP, total = 0;
-
-  //dbg("USED SCORES> "); 
-
-  for (i = 0; i < PROTO_DEF_NR; i++) {
-
-    /* if used looped score */
-    if (ret[i] < score[i]) {
-      temp = score[i] - ret[i]; /* remaining loop score */
-      
-      //dbg("%3d - ",temp);
-
-      if (index[i] >= PROTO_DEF_AVG_NR)
-        index[i] = 0;           /* reset index */
-      j = index[i];
-      avg[i][j] = temp;
-
-      index[i]++; 
-
-      if (ret[i] == 0 && (score[i]<<1 <= PROTO_MAX_SCORE) && ((total+(score[i]<<1)) < max_total) ) {        /* used all loop score -> increase next score directly */
-        score[i] <<= 1;
-        total += score[i];
-        continue;
-      }
-
-      sum = 0;
-      for (j = 0; j < PROTO_DEF_AVG_NR; j++)
-        sum += avg[i][j];       /* calculate sum */
-
-      sum >>= 2;                /* divide by 4 to get average used score */
-
-      /* criterion to increase next loop score */
-      if (sum > (score[i] - (score[i]>>2))  && (score[i]<<1 <= PROTO_MAX_SCORE) && ((total+(score[i]<<1)) < max_total)) { /* > 3/4 */
-        score[i] <<= 1;         /* double loop score */
-        total += score[i];
-        continue;
-      }
-
-      /* criterion to decrease next loop score */
-      if (sum < (score[i]>>2) && (score[i]>>1 >= PROTO_MIN_SCORE)) { /* < 1/4 */
-        score[i] >>= 1;         /* half loop score */
-        total += score[i];
-        continue;
-      }
-
-      /* also add non-changed scores */
-      total += score[i];
-    }
-    else if (ret[i] == score[i]) {
-      /* no used loop score - gradually decrease */
-      
-    //  dbg("%3d - ",0);
-
-      if (index[i] >= PROTO_DEF_AVG_NR)
-        index[i] = 0;           /* reset index */
-      j = index[i];
-      avg[i][j] = 0;
-
-      index[i]++; 
-
-      sum = 0;
-      for (j = 0; j < PROTO_DEF_AVG_NR; j++)
-        sum += avg[i][j];       /* calculate sum */
-
-      sum >>= 2;                /* divide by 4 to get average used score */
-
-      if ((sum == 0) && (score[i]>>1 >= PROTO_MIN_SCORE)) {
-        score[i] >>= 1;         /* half loop score */
-        total += score[i];
-        for (j = 0; j < PROTO_DEF_AVG_NR; j++)
-          avg[i][j] = score[i];
-      }
-      
-    }
-  }
-
-  //dbg("\n");
-
-  return 0;
-}
-
-
-
-/* 
-
-         .                                                               
-       .vS.                                                              
-     <aoSo.                                                              
-    .XoS22.                                                              
-    .S2S22.             ._...              ......            ..._.       
-  :=|2S2X2|=++;      <vSX2XX2z+          |vSSSXSSs>.      :iXXZUZXXe=    
-  )2SS2SS2S2S2I    =oS2S2S2S2X22;.    _vuXS22S2S2S22i  ._wZZXZZZXZZXZX=  
-  )22S2S2S2S2Sl    |S2S2S22S2SSSXc:  .S2SS2S2S22S2SS= .]#XZZZXZXZZZZZZ:  
-  )oSS2SS2S2Sol     |2}!"""!32S22S(. uS2S2Se**12oS2e  ]dXZZXX2?YYXXXZ*   
-   .:2S2So:..-.      .      :]S2S2e;=X2SS2o     .)oc  ]XZZXZ(     =nX:   
-    .S2S22.          ___s_i,.)oS2So(;2SS2So,       `  3XZZZZc,      -    
-    .S2SSo.        =oXXXSSS2XoS2S2o( XS2S2XSos;.      ]ZZZZXXXX|=        
-    .S2S22.      .)S2S2S22S2S2S2S2o( "X2SS2S2S2Sus,,  +3XZZZZZXZZoos_    
-    .S2S22.     .]2S2SS22S222S2SS2o(  ]S22S2S2S222So   :3XXZZZZZZZZXXv   
-    .S2S22.     =u2SS2e"~---"{2S2So(   -"12S2S2SSS2Su.   "?SXXXZXZZZZXo  
-    .S2SSo.     )SS22z;      :S2S2o(       ={vS2S2S22v      .<vXZZZZZZZ; 
-    .S2S2S:     ]oSS2c;      =22S2o(          -"S2SS2n          ~4XXZXZ( 
-    .2S2S2i     )2S2S2[.    .)XS2So(  <;.      .2S2S2o :<.       ]XZZZX( 
-     nX2S2S,,_s_=3oSS2SoaasuXXS2S2o( .oXoasi_aioSSS22l.]dZoaas_aadXZZXZ' 
-     vS2SSSXXX2; )S2S2S2SoS2S2S2S2o( iS2S222XSoSS22So.)nXZZXXXZZXXZZXZo  
-     +32S22S2Sn  -+S2S2S2S2So22S2So( 12S2SS2S2SS22S}- )SXXZZZZZZZZZXX!-  
-      .)S22222i    .i2S2S2o>;:S2S2o(  .<vSoSoSo2S(;     :nXXXXXZXXX(     
-       .-~~~~-        --- .   - -        --~~~--           --^^~~-       
-                                  .                                      
-                                                                         
-
- ... curious about our source code? We are hiring! mailto:<recruiting@tass.be>
-
-
-*/
-
-void pico_stack_tick(void)
-{
-    static int score[PROTO_DEF_NR] = {PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE};
-    static int index[PROTO_DEF_NR] = {0,0,0,0,0,0};
-    static int avg[PROTO_DEF_NR][PROTO_DEF_AVG_NR];
-    static int ret[PROTO_DEF_NR] = {0};
-
-    pico_check_timers();
-
-    //dbg("LOOP_SCORES> %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d\n",score[0],score[1],score[2],score[3],score[4],score[5],score[6],score[7],score[8],score[9],score[10]);
-
-    //score = pico_protocols_loop(100);
-
-    ret[0] = pico_devices_loop(score[0],PICO_LOOP_DIR_IN);
-    pico_rand_feed(ret[0]);
-
-    ret[1] = pico_protocol_datalink_loop(score[1], PICO_LOOP_DIR_IN);
-    pico_rand_feed(ret[1]);
-
-    ret[2] = pico_protocol_network_loop(score[2], PICO_LOOP_DIR_IN);
-    pico_rand_feed(ret[2]);
-
-    ret[3] = pico_protocol_transport_loop(score[3], PICO_LOOP_DIR_IN);
-    pico_rand_feed(ret[3]);
-
-
-    ret[5] = score[5];
-#if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6)
-#if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP)
-    ret[5] = pico_sockets_loop(score[5]); // swapped
-    pico_rand_feed(ret[5]);
-#endif
-#endif
-
-    ret[4] = pico_protocol_socket_loop(score[4], PICO_LOOP_DIR_IN);
-    pico_rand_feed(ret[4]);
-
-
-    ret[6] = pico_protocol_socket_loop(score[6], PICO_LOOP_DIR_OUT);
-    pico_rand_feed(ret[6]);
-
-    ret[7] = pico_protocol_transport_loop(score[7], PICO_LOOP_DIR_OUT);
-    pico_rand_feed(ret[7]);
-
-    ret[8] = pico_protocol_network_loop(score[8], PICO_LOOP_DIR_OUT);
-    pico_rand_feed(ret[8]);
-
-    ret[9] = pico_protocol_datalink_loop(score[9], PICO_LOOP_DIR_OUT);
-    pico_rand_feed(ret[9]);
-
-    ret[10] = pico_devices_loop(score[10],PICO_LOOP_DIR_OUT);
-    pico_rand_feed(ret[10]);
-
-    /* calculate new loop scores for next iteration */
-    calc_score(score, index,(int (*)[]) avg, ret);
-}
-
-void pico_stack_loop(void)
-{
-  while(1) {
-    pico_stack_tick();
-    PICO_IDLE();
-  }
-}
-
-void pico_timer_add(unsigned long expire, void (*timer)(unsigned long, void *), void *arg)
-{
-  pico_timer t;
-  t.expire = PICO_TIME_MS() + expire;
-  t.arg = arg;
-  t.timer = timer;
-  heap_insert(Timers, &t);
-  if (Timers->n > PICO_MAX_TIMERS) {
-    dbg("Warning: I have %d timers\n", Timers->n);
-  }
-}
-
-void pico_stack_init(void)
-{
-
-#ifdef PICO_SUPPORT_IPV4
-  pico_protocol_init(&pico_proto_ipv4);
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  pico_protocol_init(&pico_proto_ipv6);
-#endif
-
-#ifdef PICO_SUPPORT_ICMP4
-  pico_protocol_init(&pico_proto_icmp4);
-#endif
-
-#ifdef PICO_SUPPORT_IGMP
-  pico_protocol_init(&pico_proto_igmp);
-#endif
-
-#ifdef PICO_SUPPORT_UDP
-  pico_protocol_init(&pico_proto_udp);
-#endif
-
-#ifdef PICO_SUPPORT_TCP
-  pico_protocol_init(&pico_proto_tcp);
-#endif
-
-#ifdef PICO_SUPPORT_DNS_CLIENT
-  pico_dns_client_init();
-#endif
-
-  pico_rand_feed(123456);
-
-  /* Initialize timer heap */
-  Timers = heap_init();
-  pico_stack_tick();
-  pico_stack_tick();
-  pico_stack_tick();
-}
-
--- a/stack/pico_tree.c	Sun Jun 16 02:31:38 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,486 +0,0 @@
-/*********************************************************************
-PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
-See LICENSE and COPYING for usage.
-
-Author: Andrei Carp <andrei.carp@tass.be>
-*********************************************************************/
-
-#include "pico_tree.h"
-#include "pico_config.h"
-
-#define RED     0
-#define BLACK 1
-
-// By default the null leafs are black
-struct pico_tree_node LEAF = {
-  NULL, // key
-  &LEAF, &LEAF, &LEAF, // parent, left,right
-  BLACK, // color
-};
-
-#define IS_LEAF(x) (x == &LEAF)
-#define IS_NOT_LEAF(x) (x != &LEAF)
-#define INIT_LEAF (&LEAF)
-
-#define AM_I_LEFT_CHILD(x) (x == x->parent->leftChild)
-#define AM_I_RIGHT_CHILD(x) (x == x->parent->rightChild)
-
-#define PARENT(x) (x->parent)
-#define GRANPA(x) (x->parent->parent)
-
-/*
- * Local Functions
- */
-static struct pico_tree_node * create_node(struct pico_tree * tree,void *key);
-static void rotateToLeft(struct pico_tree* tree, struct pico_tree_node* node);
-static void rotateToRight(struct pico_tree* root, struct pico_tree_node* node);
-static void fix_insert_collisions(struct pico_tree* tree, struct pico_tree_node* node);
-static void fix_delete_collisions(struct pico_tree* tree, struct pico_tree_node * node);
-static void switchNodes(struct pico_tree* tree, struct pico_tree_node* nodeA, struct pico_tree_node* nodeB);
-
-/*
- * Exported functions
- */
-
-struct pico_tree_node *pico_tree_firstNode(struct pico_tree_node * node)
-{
-    while(IS_NOT_LEAF(node->leftChild))
-        node = node->leftChild;
-    return node;
-}
-
-struct pico_tree_node * pico_tree_lastNode(struct pico_tree_node * node)
-{
-    while(IS_NOT_LEAF(node->rightChild))
-        node = node->rightChild;
-    return node;
-}
-
-struct pico_tree_node * pico_tree_next(struct pico_tree_node * node)
-{
-    if(IS_NOT_LEAF(node->rightChild))
-    {
-        node = node->rightChild;
-        while(IS_NOT_LEAF(node->leftChild))
-            node = node->leftChild;
-    }
-    else
-    {
-        if (IS_NOT_LEAF(node->parent) &&  AM_I_LEFT_CHILD(node))
-                  node = node->parent;
-        else {
-            while (IS_NOT_LEAF(node->parent) &&    AM_I_RIGHT_CHILD(node))
-                node = node->parent;
-
-            node = node->parent;
-        }
-    }
-    return node;
-}
-
-struct pico_tree_node * pico_tree_prev(struct pico_tree_node * node)
-{
-    if (IS_NOT_LEAF(node->leftChild)) {
-      node = node->leftChild;
-      while (IS_NOT_LEAF(node->rightChild))
-          node = node->rightChild;
-  } else {
-      if (IS_NOT_LEAF(node->parent) && AM_I_RIGHT_CHILD(node))
-          node = node->parent;
-      else {
-          while (IS_NOT_LEAF(node) &&    AM_I_LEFT_CHILD(node))
-              node = node->parent;
-
-          node = node->parent;
-      }
-  }
-    return node;
-}
-
-void * pico_tree_insert(struct pico_tree* tree, void * key){
-
-    struct pico_tree_node * last_node = INIT_LEAF;
-  struct pico_tree_node * temp = tree->root;
-  struct pico_tree_node * insert;
-  void * LocalKey;
-  int result = 0;
-
-    LocalKey = (IS_NOT_LEAF(tree->root) ? pico_tree_findKey(tree,key) : NULL);
-    // if node already in, bail out
-  if(LocalKey)
-      return LocalKey;
-  else
-      insert = create_node(tree,key);
-
-  // search for the place to insert the new node
-  while(IS_NOT_LEAF(temp))
-  {
-        last_node = temp;
-        result = tree->compare(insert->keyValue,temp->keyValue);
-
-        temp = (result < 0 ? temp->leftChild : temp->rightChild);
-  }
-
-  // make the needed connections
-  insert->parent = last_node;
-
-  if(IS_LEAF(last_node))
-    tree->root = insert;
-  else{
-      result = tree->compare(insert->keyValue,last_node->keyValue);
-    if(result < 0)
-      last_node->leftChild = insert;
-    else
-      last_node->rightChild = insert;
-  }
-
-  // fix colour issues
-  fix_insert_collisions(tree, insert);
-
-    return NULL;
-}
-
-struct pico_tree_node * pico_tree_findNode(struct pico_tree * tree, void * key)
-{
-        struct pico_tree_node *found;
-
-        found = tree->root;
-
-      while(IS_NOT_LEAF(found))
-      {
-          int result;
-          result = tree->compare(found->keyValue, key);
-          if(result == 0)
-          {
-             return found;
-          }
-          else if(result < 0)
-           found = found->rightChild;
-         else
-           found = found->leftChild;
-       }
-
-
-
-      return NULL;
-}
-
-void * pico_tree_findKey(struct pico_tree * tree, void * key)
-{
-  struct pico_tree_node *found;
-
-
-  found = tree->root;
-
-  while(IS_NOT_LEAF(found))
-  {
-      int result;
-
-      result = tree->compare(found->keyValue, key);
-      if(result == 0)
-         return found->keyValue;
-      else if(result < 0)
-       found = found->rightChild;
-     else
-       found = found->leftChild;
-
-   }
-
-  return NULL;
-}
-
-void * pico_tree_first(struct pico_tree * tree)
-{
-    return pico_tree_firstNode(tree->root)->keyValue;
-}
-
-void * pico_tree_last(struct pico_tree * tree)
-{
-    return pico_tree_lastNode(tree->root)->keyValue;
-}
-
-void * pico_tree_delete(struct pico_tree * tree, void * key){
-
-    uint8_t nodeColor; // keeps the color of the node to be deleted
-  void * lkey; // keeps a copy of the key which will be removed
-    struct pico_tree_node * delete; // keeps a copy of the node to be extracted
-    struct pico_tree_node * temp; // temporary
-    struct pico_tree_node * ltemp; // used for switching nodes, as a copy
-
-    delete = pico_tree_findNode(tree, key);
-    ltemp = delete;
-
-  // this key isn't in the tree, bail out
-  if(!delete)
-    return NULL;
-
-  lkey = delete->keyValue;
-  nodeColor = delete->color;
-
-  if(IS_LEAF(delete->leftChild))
-  {
-    temp = ltemp->rightChild;
-    switchNodes(tree, ltemp, ltemp->rightChild);
-  }
-  else
-    if(IS_LEAF(delete->rightChild))
-    {
-        struct pico_tree_node * ltemp = delete;
-      temp = ltemp->leftChild;
-      switchNodes(tree, ltemp, ltemp->leftChild);
-    }
-    else{
-        struct pico_tree_node * min;
-        min = pico_tree_firstNode(delete->rightChild);
-      nodeColor = min->color;
-
-       temp = min->rightChild;
-       if(min->parent == ltemp && IS_NOT_LEAF(temp))
-      temp->parent = min;
-       else{
-           switchNodes(tree, min, min->rightChild);
-           min->rightChild = ltemp->rightChild;
-           if(IS_NOT_LEAF(min->rightChild)) min->rightChild->parent = min;
-       }
-       switchNodes(tree, ltemp, min);
-       min->leftChild = ltemp->leftChild;
-       if(IS_NOT_LEAF(min->leftChild)) min->leftChild->parent = min;
-       min->color = ltemp->color;
-    }
-
-  // deleted node is black, this will mess up the black path property
-  if(nodeColor == BLACK)
-    fix_delete_collisions(tree, temp);
-
-  pico_free(delete);
-
-  return lkey;
-}
-
-int pico_tree_empty(struct pico_tree * tree)
-{
-    return (!tree->root || IS_LEAF(tree->root));
-}
-
-/*
- * Private functions
- */
-static void rotateToLeft(struct pico_tree* tree, struct pico_tree_node* node)
-{
-  struct pico_tree_node* temp;
-
-  temp = node->rightChild;
-
-  if(temp == &LEAF) return;
-
-  node->rightChild = temp->leftChild;
-
-  if(IS_NOT_LEAF(temp->leftChild))
-    temp->leftChild->parent = node;
-
-  temp->parent = node->parent;
-
-  if(IS_LEAF(node->parent))
-    tree->root = temp;
-  else
-    if(node == node->parent->leftChild)
-        node->parent->leftChild = temp;
-    else
-        node->parent->rightChild = temp;
-
-  temp->leftChild = node;
-  node->parent = temp;
-}
-
-
-static void rotateToRight(struct pico_tree * tree, struct pico_tree_node * node)
-{
-  struct pico_tree_node* temp;
-
-  temp = node->leftChild;
-  node->leftChild = temp->rightChild;
-
-  if(temp == &LEAF) return;
-
-  if(IS_NOT_LEAF(temp->rightChild))
-    temp->rightChild->parent = node;
-
-  temp->parent = node->parent;
-
-  if(IS_LEAF(node->parent))
-    tree->root = temp;
-  else
-    if(node == node->parent->rightChild)
-      node->parent->rightChild = temp;
-    else
-      node->parent->leftChild = temp;
-
-  temp->rightChild = node;
-  node->parent = temp;
-  return;
-}
-
-static struct pico_tree_node * create_node(struct pico_tree * tree, void* key)
-{
-  struct pico_tree_node *temp;
-  temp = (struct pico_tree_node *)pico_zalloc(sizeof(struct pico_tree_node));
-
-  if(!temp)
-      return NULL;
-
-  temp->keyValue = key;
-  temp->parent = &LEAF;
-  temp->leftChild = &LEAF;
-  temp->rightChild = &LEAF;
-  // by default every new node is red
-  temp->color = RED;
-  return temp;
-}
-
-/*
- * This function fixes the possible collisions in the tree.
- * Eg. if a node is red his children must be black !
- */
-static void fix_insert_collisions(struct pico_tree* tree, struct pico_tree_node* node)
-{
-  struct pico_tree_node* temp;
-
-  while(node->parent->color == RED)
-  {
-      if(AM_I_RIGHT_CHILD(node->parent))
-     {
-            temp = GRANPA(node)->leftChild;
-            if(temp->color == RED){
-                node->parent->color = BLACK;
-                temp->color = BLACK;
-                GRANPA(node)->color = RED;
-                node = GRANPA(node);
-            }
-            else if(temp->color == BLACK){
-                if(node == node->parent->leftChild){
-                node = node->parent;
-                rotateToRight(tree, node);
-            }
-            node->parent->color = BLACK;
-            GRANPA(node)->color = RED;
-            rotateToLeft(tree, GRANPA(node));
-            }
-        }
-      else if(AM_I_LEFT_CHILD(node->parent))
-    {
-      temp = GRANPA(node)->rightChild;
-      if(temp->color == RED){
-                node->parent->color = BLACK;
-                temp->color = BLACK;
-                GRANPA(node)->color = RED;
-                node = GRANPA(node);
-      }
-      else if(temp->color == BLACK){
-                if(AM_I_RIGHT_CHILD(node)){
-                    node = node->parent;
-                    rotateToLeft(tree, node);
-                }
-                node->parent->color = BLACK;
-                GRANPA(node)->color = RED;
-                rotateToRight(tree, GRANPA(node));
-          }
-    }
-  }
-
-  // make sure that the root of the tree stays black
-  tree->root->color = BLACK;
-}
-
-static void switchNodes(struct pico_tree* tree, struct pico_tree_node* nodeA, struct pico_tree_node* nodeB)
-{
-
-    if(IS_LEAF(nodeA->parent))
-    tree->root = nodeB;
-  else
-  if(IS_NOT_LEAF(nodeA))
-  {    
-    if(AM_I_LEFT_CHILD(nodeA))
-      nodeA->parent->leftChild = nodeB;
-    else
-      nodeA->parent->rightChild = nodeB;
-   }
-
-  if(IS_NOT_LEAF(nodeB))  nodeB->parent = nodeA->parent;
-
-}
-
-/*
- * This function fixes the possible collisions in the tree.
- * Eg. if a node is red his children must be black !
- * In this case the function fixes the constant black path property.
- */
-static void fix_delete_collisions(struct pico_tree* tree, struct pico_tree_node * node)
-{
-  struct pico_tree_node* temp;
-
-  while( node != tree->root && node->color == BLACK && IS_NOT_LEAF(node))
-  {
-      if(AM_I_LEFT_CHILD(node)){
-
-      temp = node->parent->rightChild;
-      if(temp->color == RED)
-      {
-                temp->color = BLACK;
-                node->parent->color = RED;
-                rotateToLeft(tree, node->parent);
-                temp = node->parent->rightChild;
-      }
-      if(temp->leftChild->color == BLACK && temp->rightChild->color == BLACK)
-      {
-                temp->color = RED;
-                node = node->parent;
-      }
-      else
-      {
-                if(temp->rightChild->color == BLACK)
-                {
-                    temp->leftChild->color = BLACK;
-                    temp->color = RED;
-                    rotateToRight(tree, temp);
-                    temp = temp->parent->rightChild;
-                }
-                temp->color = node->parent->color;
-                node->parent->color = BLACK;
-                temp->rightChild->color = BLACK;
-                rotateToLeft(tree, node->parent);
-                node = tree->root;
-      }
-    }
-    else{
-      temp = node->parent->leftChild;
-      if(temp->color == RED)
-      {
-                temp->color = BLACK;
-                node->parent->color = RED;
-                rotateToRight(tree, node->parent);
-                temp = node->parent->leftChild;
-      }
-      if(temp->rightChild->color == BLACK && temp->leftChild->color == BLACK)
-      {
-                temp->color = RED;
-                node = node->parent;
-      }
-      else{
-                if(temp->leftChild->color == BLACK)
-                {
-                    temp->rightChild->color = BLACK;
-                    temp->color = RED;
-                    rotateToLeft(tree, temp);
-                    temp = temp->parent->leftChild;
-                }
-            temp->color = node->parent->color;
-            node->parent->color = BLACK;
-            temp->leftChild->color = BLACK;
-            rotateToRight(tree, node->parent);
-            node = tree->root;
-      }
-    }
-  }
-
-  node->color = BLACK;
-}