Index: uspace/lib/net/Makefile
===================================================================
--- uspace/lib/net/Makefile	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/Makefile	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -35,5 +35,7 @@
 	generic/net_remote.c \
 	generic/net_checksum.c \
+	generic/packet_client.c \
 	generic/packet_remote.c \
+	generic/socket_core.c \
 	adt/module_map.c \
 	netif/netif_local.c \
Index: uspace/lib/net/generic/packet_client.c
===================================================================
--- uspace/lib/net/generic/packet_client.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
+++ uspace/lib/net/generic/packet_client.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup packet
+ *  @{
+ */
+
+/** @file
+ *  Packet client implementation.
+ */
+
+#include <errno.h>
+#include <mem.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#include <packet_client.h>
+
+#include <net_messages.h>
+#include <packet/packet.h>
+#include <packet/packet_header.h>
+
+int packet_copy_data(packet_t packet, const void * data, size_t length)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	if (packet->data_start + length >= packet->length)
+		return ENOMEM;
+
+	memcpy((void *) packet + packet->data_start, data, length);
+	if (packet->data_start + length > packet->data_end) 
+		packet->data_end = packet->data_start + length;
+
+	return EOK;
+}
+
+void *packet_prefix(packet_t packet, size_t length)
+{
+	if ((!packet_is_valid(packet)) ||
+	    (packet->data_start - sizeof(struct packet) -
+	    2 * (packet->dest_addr - packet->src_addr) < length)) {
+		return NULL;
+	}
+
+	packet->data_start -= length;
+	return (void *) packet + packet->data_start;
+}
+
+void *packet_suffix(packet_t packet, size_t length)
+{
+	if ((!packet_is_valid(packet)) ||
+	    (packet->data_end + length >= packet->length)) {
+		return NULL;
+	}
+
+	packet->data_end += length;
+	return (void *) packet + packet->data_end - length;
+}
+
+int packet_trim(packet_t packet, size_t prefix, size_t suffix)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	if (prefix + suffix > PACKET_DATA_LENGTH(packet))
+		return ENOMEM;
+
+	packet->data_start += prefix;
+	packet->data_end -= suffix;
+	return EOK;
+}
+
+packet_id_t packet_get_id(const packet_t packet)
+{
+	return packet_is_valid(packet) ? packet->packet_id : 0;
+}
+
+int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+	if (!packet->addr_len)
+		return 0;
+	if (src)
+		*src = (void *) packet + packet->src_addr;
+	if (dest)
+		*dest = (void *) packet + packet->dest_addr;
+
+	return packet->addr_len;
+}
+
+size_t packet_get_data_length(const packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return 0;
+
+	return PACKET_DATA_LENGTH(packet);
+}
+
+void *packet_get_data(const packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	return (void *) packet + packet->data_start;
+}
+
+int
+packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest,
+    size_t addr_len)
+{
+	size_t padding;
+	size_t allocated;
+
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
+	if (allocated < addr_len)
+		return ENOMEM;
+
+	padding = allocated - addr_len;
+	packet->addr_len = addr_len;
+
+	if (src) {
+		memcpy((void *) packet + packet->src_addr, src, addr_len);
+		if (padding)
+			bzero((void *) packet + packet->src_addr + addr_len,
+			    padding);
+	} else {
+		bzero((void *) packet + packet->src_addr, allocated);
+	}
+
+	if (dest) {
+		memcpy((void *) packet + packet->dest_addr, dest, addr_len);
+		if (padding)
+			bzero((void *) packet + packet->dest_addr + addr_len,
+			    padding);
+	} else {
+		bzero((void *) packet + packet->dest_addr, allocated);
+	}
+
+	return EOK;
+}
+
+packet_t packet_get_copy(int phone, packet_t packet)
+{
+	packet_t copy;
+	uint8_t * src = NULL;
+	uint8_t * dest = NULL;
+	size_t addrlen;
+
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	// get a new packet
+	copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
+	    PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
+	    PACKET_MIN_SUFFIX(packet));
+	if (!copy)
+		return NULL;
+
+	// get addresses
+	addrlen = packet_get_addr(packet, &src, &dest);
+	// copy data
+	if ((packet_copy_data(copy, packet_get_data(packet),
+	    PACKET_DATA_LENGTH(packet)) == EOK) &&
+	    // copy addresses if present
+	    ((addrlen <= 0) ||
+	    (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
+		copy->order = packet->order;
+		copy->metric = packet->metric;
+		return copy;
+	} else {
+		pq_release_remote(phone, copy->packet_id);
+		return NULL;
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/generic/packet_remote.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -44,8 +44,9 @@
 
 #include <net_messages.h>
+#include <packet_client.h>
+#include <packet_remote.h>
+
 #include <packet/packet.h>
-#include <packet/packet_client.h>
 #include <packet/packet_header.h>
-#include <packet_remote.h>
 
 /** Obtain the packet from the packet server as the shared memory block.
Index: uspace/lib/net/generic/socket_core.c
===================================================================
--- uspace/lib/net/generic/socket_core.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
+++ uspace/lib/net/generic/socket_core.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup socket
+ *  @{
+ */
+
+/** @file
+ *  Socket common core implementation.
+ */
+
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/inet.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+#include <packet/packet.h>
+#include <packet_client.h>
+#include <packet_remote.h>
+#include <net/modules.h>
+#include <socket_core.h>
+
+/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
+ */
+#define SOCKET_ID_TRIES					100
+
+/** Bound port sockets.
+ */
+struct socket_port{
+	/** The bound sockets map.
+	 */
+	socket_port_map_t map;
+	/** The bound sockets count.
+	 */
+	int count;
+};
+
+INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
+
+GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
+
+INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
+
+/** Destroys the socket.
+ *  If the socket is bound, the port is released.
+ *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
+ *  @param[in] packet_phone The packet server phone to release buffered packets.
+ *  @param[in] socket The socket to be destroyed.
+ *  @param[in,out] local_sockets The local sockets to be updated.
+ *  @param[in,out] global_sockets The global sockets to be updated.
+ *  @param[in] socket_release The client release callback function.
+ */
+static void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
+	int packet_id;
+
+	// if bound
+	if(socket->port){
+		// release the port
+		socket_port_release(global_sockets, socket);
+	}
+	// release all received packets
+	while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
+		pq_release_remote(packet_phone, packet_id);
+	}
+	dyn_fifo_destroy(&socket->received);
+	dyn_fifo_destroy(&socket->accepted);
+	if(socket_release){
+		socket_release(socket);
+	}
+	socket_cores_exclude(local_sockets, socket->socket_id);
+}
+
+void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
+	if(socket_cores_is_valid(local_sockets)){
+		int index;
+
+		local_sockets->magic = 0;
+		for(index = 0; index < local_sockets->next; ++ index){
+			if(socket_cores_item_is_valid(&(local_sockets->items[index]))){
+				local_sockets->items[index].magic = 0;
+				if(local_sockets->items[index].value){
+					socket_destroy_core(packet_phone, local_sockets->items[index].value, local_sockets, global_sockets, socket_release);
+					free(local_sockets->items[index].value);
+					local_sockets->items[index].value = NULL;
+				}
+			}
+		}
+		free(local_sockets->items);
+	}
+}
+
+/** Adds the socket to a socket port.
+ *  @param[in,out] socket_port The socket port structure.
+ *  @param[in] socket The socket to be added.
+ *  @param[in] key The socket key identifier.
+ *  @param[in] key_length The socket key length.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
+	ERROR_DECLARE;
+
+	socket_core_ref * socket_ref;
+
+	// create a wrapper
+	socket_ref = malloc(sizeof(*socket_ref));
+	if(! socket_ref){
+		return ENOMEM;
+	}
+	*socket_ref = socket;
+	// add the wrapper
+	if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
+		free(socket_ref);
+		return ERROR_CODE;
+	}
+	++ socket_port->count;
+	socket->key = key;
+	socket->key_length = key_length;
+	return EOK;
+}
+
+/** Binds the socket to the port.
+ *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
+ *  @param[in] global_sockets The global sockets to be updated.
+ *  @param[in] socket The socket to be added.
+ *  @param[in] port The port number to be bound to.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns Other error codes as defined for the socket_ports_add() function.
+ */
+static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
+	ERROR_DECLARE;
+
+	socket_port_ref socket_port;
+
+	// create a wrapper
+	socket_port = malloc(sizeof(*socket_port));
+	if(! socket_port){
+		return ENOMEM;
+	}
+	socket_port->count = 0;
+	if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
+		|| ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
+		socket_port_map_destroy(&socket_port->map);
+		free(socket_port);
+		return ERROR_CODE;
+	}
+	// register the incomming port
+	ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
+	if(ERROR_CODE < 0){
+		socket_port_map_destroy(&socket_port->map);
+		free(socket_port);
+		return ERROR_CODE;
+	}
+	socket->port = port;
+	return EOK;
+}
+
+int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port){
+	socket_core_ref socket;
+	socket_port_ref socket_port;
+	struct sockaddr * address;
+	struct sockaddr_in * address_in;
+
+	if(addrlen < sizeof(struct sockaddr)){
+		return EINVAL;
+	}
+	address = (struct sockaddr *) addr;
+	switch(address->sa_family){
+		case AF_INET:
+			if(addrlen != sizeof(struct sockaddr_in)){
+				return EINVAL;
+			}
+			address_in = (struct sockaddr_in *) addr;
+			// find the socket
+			socket = socket_cores_find(local_sockets, socket_id);
+			if(! socket){
+				return ENOTSOCK;
+			}
+			// bind a free port?
+			if(address_in->sin_port <= 0){
+				return socket_bind_free_port(global_sockets, socket, free_ports_start, free_ports_end, last_used_port);
+			}
+			// try to find the port
+			socket_port = socket_ports_find(global_sockets, ntohs(address_in->sin_port));
+			if(socket_port){
+				// already used
+				return EADDRINUSE;
+			}
+			// if bound
+			if(socket->port){
+				// release the port
+				socket_port_release(global_sockets, socket);
+			}
+			socket->port = -1;
+			return socket_bind_insert(global_sockets, socket, ntohs(address_in->sin_port));
+			break;
+		// TODO IPv6
+	}
+	return EAFNOSUPPORT;
+}
+
+int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){
+	int index;
+
+	// from the last used one
+	index = last_used_port;
+	do{
+		++ index;
+		// til the range end
+		if(index >= free_ports_end){
+			// start from the range beginning
+			index = free_ports_start - 1;
+			do{
+				++ index;
+				// til the last used one
+				if(index >= last_used_port){
+					// none found
+					return ENOTCONN;
+				}
+			}while(socket_ports_find(global_sockets, index) != NULL);
+			// found, break immediately
+			break;
+		}
+	}while(socket_ports_find(global_sockets, index) != NULL);
+	return socket_bind_insert(global_sockets, socket, index);
+}
+
+/** Tries to find a new free socket identifier.
+ *  @param[in] local_sockets The local sockets to be searched.
+ *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
+ *	@returns The new socket identifier.
+ *  @returns ELIMIT if there is no socket identifier available.
+ */
+static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){
+	int socket_id;
+	int count;
+
+	count = 0;
+//	socket_id = socket_globals.last_id;
+	do{
+		if(count < SOCKET_ID_TRIES){
+			socket_id = rand() % INT_MAX;
+			++ count;
+		}else if(count == SOCKET_ID_TRIES){
+			socket_id = 1;
+			++ count;
+		// only this branch for last_id
+		}else{
+			if(socket_id < INT_MAX){
+				++ socket_id;
+/*			}else if(socket_globals.last_id){
+*				socket_globals.last_id = 0;
+*				socket_id = 1;
+*/			}else{
+				return ELIMIT;
+			}
+		}
+	}while(socket_cores_find(local_sockets, ((positive ? 1 : -1) * socket_id)));
+//	last_id = socket_id
+	return socket_id;
+}
+
+int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){
+	ERROR_DECLARE;
+
+	socket_core_ref socket;
+	int res;
+	int positive;
+
+	if(! socket_id){
+		return EINVAL;
+	}
+	// store the socket
+	if(*socket_id <= 0){
+		positive = (*socket_id == 0);
+		*socket_id = socket_generate_new_id(local_sockets, positive);
+		if(*socket_id <= 0){
+			return * socket_id;
+		}
+		if(! positive){
+			*socket_id *= -1;
+		}
+	}else if(socket_cores_find(local_sockets, * socket_id)){
+		return EEXIST;
+	}
+	socket = (socket_core_ref) malloc(sizeof(*socket));
+	if(! socket){
+		return ENOMEM;
+	}
+	// initialize
+	socket->phone = app_phone;
+	socket->port = -1;
+	socket->key = NULL;
+	socket->key_length = 0;
+	socket->specific_data = specific_data;
+	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){
+		free(socket);
+		return ERROR_CODE;
+	}
+	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){
+		dyn_fifo_destroy(&socket->received);
+		free(socket);
+		return ERROR_CODE;
+	}
+	socket->socket_id = * socket_id;
+	res = socket_cores_add(local_sockets, socket->socket_id, socket);
+	if(res < 0){
+		dyn_fifo_destroy(&socket->received);
+		dyn_fifo_destroy(&socket->accepted);
+		free(socket);
+		return res;
+	}
+	return EOK;
+}
+
+int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
+	socket_core_ref socket;
+	int accepted_id;
+
+	// find the socket
+	socket = socket_cores_find(local_sockets, socket_id);
+	if(! socket){
+		return ENOTSOCK;
+	}
+	// destroy all accepted sockets
+	while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
+		socket_destroy(packet_phone, accepted_id, local_sockets, global_sockets, socket_release);
+	}
+	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, socket_release);
+	return EOK;
+}
+
+int socket_reply_packets(packet_t packet, size_t * length){
+	ERROR_DECLARE;
+
+	packet_t next_packet;
+	size_t fragments;
+	size_t * lengths;
+	size_t index;
+
+	if(! length){
+		return EBADMEM;
+	}
+	next_packet = pq_next(packet);
+	if(! next_packet){
+		// write all if only one fragment
+		ERROR_PROPAGATE(data_reply(packet_get_data(packet), packet_get_data_length(packet)));
+		// store the total length
+		*length = packet_get_data_length(packet);
+	}else{
+		// count the packet fragments
+		fragments = 1;
+		next_packet = pq_next(packet);
+		while((next_packet = pq_next(next_packet))){
+			++ fragments;
+		}
+		// compute and store the fragment lengths
+		lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
+		if(! lengths){
+			return ENOMEM;
+		}
+		lengths[0] = packet_get_data_length(packet);
+		lengths[fragments] = lengths[0];
+		next_packet = pq_next(packet);
+		for(index = 1; index < fragments; ++ index){
+			lengths[index] = packet_get_data_length(next_packet);
+			lengths[fragments] += lengths[index];
+			next_packet = pq_next(packet);
+		}while(next_packet);
+		// write the fragment lengths
+		ERROR_PROPAGATE(data_reply(lengths, sizeof(int) * (fragments + 1)));
+		next_packet = packet;
+		// write the fragments
+		for(index = 0; index < fragments; ++ index){
+			ERROR_PROPAGATE(data_reply(packet_get_data(next_packet), lengths[index]));
+			next_packet = pq_next(next_packet);
+		}while(next_packet);
+		// store the total length
+		*length = lengths[fragments];
+		free(lengths);
+	}
+	return EOK;
+}
+
+socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length){
+	socket_port_ref socket_port;
+	socket_core_ref * socket_ref;
+
+	socket_port = socket_ports_find(global_sockets, port);
+	if(socket_port && (socket_port->count > 0)){
+		socket_ref = socket_port_map_find(&socket_port->map, key, key_length);
+		if(socket_ref){
+			return * socket_ref;
+		}
+	}
+	return NULL;
+}
+
+void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket){
+	socket_port_ref socket_port;
+	socket_core_ref * socket_ref;
+
+	if(socket->port){
+		// find ports
+		socket_port = socket_ports_find(global_sockets, socket->port);
+		if(socket_port){
+			// find the socket
+			socket_ref = socket_port_map_find(&socket_port->map, socket->key, socket->key_length);
+			if(socket_ref){
+				-- socket_port->count;
+				// release if empty
+				if(socket_port->count <= 0){
+					// destroy the map
+					socket_port_map_destroy(&socket_port->map);
+					// release the port
+					socket_ports_exclude(global_sockets, socket->port);
+				}else{
+					// remove
+					socket_port_map_exclude(&socket_port->map, socket->key, socket->key_length);
+				}
+			}
+		}
+		socket->port = 0;
+		socket->key = NULL;
+		socket->key_length = 0;
+	}
+}
+
+int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){
+	ERROR_DECLARE;
+
+	socket_port_ref socket_port;
+
+	// find ports
+	socket_port = socket_ports_find(global_sockets, port);
+	if(! socket_port){
+		return ENOENT;
+	}
+	// add the socket
+	ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, key_length));
+	socket->port = port;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/net/il/ip_client.c
===================================================================
--- uspace/lib/net/il/ip_client.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/il/ip_client.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -40,7 +40,8 @@
 
 #include <ip_client.h>
+#include <packet_client.h>
+#include <ip_header.h>
+
 #include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <ip_header.h>
 
 size_t ip_client_header_length(packet_t packet){
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/il/ip_remote.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -47,5 +47,5 @@
 #include <net/inet.h>
 #include <ip_interface.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <il_messages.h>
 #include <ip_messages.h>
Index: uspace/lib/net/include/il_interface.h
===================================================================
--- uspace/lib/net/include/il_interface.h	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/include/il_interface.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -46,5 +46,5 @@
 #include <net_device.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <il_messages.h>
 
Index: uspace/lib/net/include/netif_interface.h
===================================================================
--- uspace/lib/net/include/netif_interface.h	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/include/netif_interface.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -53,5 +53,5 @@
 
 #include <netif_remote.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 
 #define netif_module_message    netif_module_message_standalone
Index: uspace/lib/net/include/packet_client.h
===================================================================
--- uspace/lib/net/include/packet_client.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
+++ uspace/lib/net/include/packet_client.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup packet
+ *  @{
+ */
+
+/** @file
+ *  Packet client.
+ *  The hosting module has to be compiled with both the packet.c and the packet_client.c source files.
+ *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
+ *  The module should not send the packet messages to the packet server but use the functions provided.
+ *  The packet map should be released by the pm_destroy() function during the module termination.
+ *  The packets and the packet queues can't be locked at all.
+ *  The processing modules should process them sequentially -&nbsp;by passing the packets to the next module and stopping using the passed ones.
+ *  @see packet.h
+ */
+
+#ifndef __NET_PACKET_CLIENT_H__
+#define __NET_PACKET_CLIENT_H__
+
+#include <packet/packet.h>
+
+/** @name Packet client interface
+ */
+/*@{*/
+
+/** Allocates the specified type right before the actual packet content and returns its pointer.
+ *  The wrapper of the packet_prepend() function.
+ *  @param[in] packet The packet to be used.
+ *  @param[in] type The type to be allocated at the beginning of the packet content.
+ *  @returns The typed pointer to the allocated memory.
+ *  @returns NULL if the packet is not valid.
+ *  @returns NULL if there is not enough memory left.
+ */
+#define PACKET_PREFIX(packet, type)	(type *) packet_prefix((packet), sizeof(type))
+
+/** Allocates the specified type right after the actual packet content and returns its pointer.
+ *  The wrapper of the packet_append() function.
+ *  @param[in] packet The packet to be used.
+ *  @param[in] type The type to be allocated at the end of the packet content.
+ *  @returns The typed pointer to the allocated memory.
+ *  @returns NULL if the packet is not valid.
+ *  @returns NULL if there is not enough memory left.
+ */
+#define PACKET_SUFFIX(packet, type)	(type *) packet_suffix((packet), sizeof(type))
+
+/** Trims the actual packet content by the specified prefix and suffix types.
+ *  The wrapper of the packet_trim() function.
+ *  @param[in] packet The packet to be trimmed.
+ *  @param[in] prefix The type of the prefix to be removed from the beginning of the packet content.
+ *  @param[in] suffix The type of the suffix to be removed from the end of the packet content.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+#define PACKET_TRIM(packet, prefix, suffix)	packet_trim((packet), sizeof(prefix), sizeof(suffix))
+
+/** Allocates the specified space right before the actual packet content and returns its pointer.
+ *  @param[in] packet The packet to be used.
+ *  @param[in] length The space length to be allocated at the beginning of the packet content.
+ *  @returns The pointer to the allocated memory.
+ *  @returns NULL if there is not enough memory left.
+ */
+extern void * packet_prefix(packet_t packet, size_t length);
+
+/** Allocates the specified space right after the actual packet content and returns its pointer.
+ *  @param[in] packet The packet to be used.
+ *  @param[in] length The space length to be allocated at the end of the packet content.
+ *  @returns The pointer to the allocated memory.
+ *  @returns NULL if there is not enough memory left.
+ */
+extern void * packet_suffix(packet_t packet, size_t length);
+
+/** Trims the actual packet content by the specified prefix and suffix lengths.
+ *  @param[in] packet The packet to be trimmed.
+ *  @param[in] prefix The prefix length to be removed from the beginning of the packet content.
+ *  @param[in] suffix The suffix length to be removed from the end of the packet content.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int packet_trim(packet_t packet, size_t prefix, size_t suffix);
+
+/** Copies the specified data to the beginning of the actual packet content.
+ *  Pushes the content end if needed.
+ *  @param[in] packet The packet to be filled.
+ *  @param[in] data The data to be copied.
+ *  @param[in] length The length of the copied data.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int packet_copy_data(packet_t packet, const void * data, size_t length);
+
+/** Returns the packet identifier.
+ *  @param[in] packet The packet.
+ *  @returns The packet identifier.
+ *  @returns Zero (0) if the packet is not valid.
+ */
+extern packet_id_t packet_get_id(const packet_t packet);
+
+/** Returns the packet content length.
+ *  @param[in] packet The packet.
+ *  @returns The packet content length in bytes.
+ *  @returns Zero (0) if the packet is not valid.
+ */
+extern size_t packet_get_data_length(const packet_t packet);
+
+/** Returns the pointer to the beginning of the packet content.
+ *  @param[in] packet The packet.
+ *  @returns The pointer to the beginning of the packet content.
+ *  @returns NULL if the packet is not valid.
+ */
+extern void * packet_get_data(const packet_t packet);
+
+/** Returns the stored packet addresses and their length.
+ *  @param[in] packet The packet.
+ *  @param[out] src The source address. May be NULL if not desired.
+ *  @param[out] dest The destination address. May be NULL if not desired.
+ *  @returns The stored addresses length.
+ *  @returns Zero (0) if the addresses are not present.
+ *  @returns EINVAL if the packet is not valid.
+ */
+extern int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest);
+
+/** Sets the packet addresses.
+ *  @param[in] packet The packet.
+ *  @param[in] src The new source address. May be NULL.
+ *  @param[in] dest The new destination address. May be NULL.
+ *  @param[in] addr_len The addresses length.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len);
+
+/** Translates the packet identifier to the packet reference.
+ *  Tries to find mapping first.
+ *  Contacts the packet server to share the packet if the mapping is not present.
+ *  @param[in] phone The packet server module phone.
+ *  @param[out] packet The packet reference.
+ *  @param[in] packet_id The packet identifier.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet parameter is NULL.
+ *  @returns Other error codes as defined for the NET_PACKET_GET_SIZE message.
+ *  @returns Other error codes as defined for the packet_return() function.
+ */
+extern int packet_translate_remote(int phone, packet_ref packet, packet_id_t packet_id);
+
+/** Obtains the packet of the given dimensions.
+ *  Contacts the packet server to return the appropriate packet.
+ *  @param[in] phone The packet server module phone.
+ *  @param[in] addr_len The source and destination addresses maximal length in bytes.
+ *  @param[in] max_prefix The maximal prefix length in bytes.
+ *  @param[in] max_content The maximal content length in bytes.
+ *  @param[in] max_suffix The maximal suffix length in bytes.
+ *  @returns The packet reference.
+ *  @returns NULL on error.
+ */
+extern packet_t packet_get_4_remote(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);
+
+/** Obtains the packet of the given content size.
+ *  Contacts the packet server to return the appropriate packet.
+ *  @param[in] phone The packet server module phone.
+ *  @param[in] content The maximal content length in bytes.
+ *  @returns The packet reference.
+ *  @returns NULL on error.
+ */
+extern packet_t packet_get_1_remote(int phone, size_t content);
+
+/** Releases the packet queue.
+ *  All packets in the queue are marked as free for use.
+ *  The packet queue may be one packet only.
+ *  The module should not use the packets after this point until they are received or obtained again.
+ *  @param[in] phone The packet server module phone.
+ *  @param[in] packet_id The packet identifier.
+ */
+extern void pq_release_remote(int phone, packet_id_t packet_id);
+
+/** Returns the packet copy.
+ *  Copies the addresses, data, order and metric values.
+ *  Does not copy the queue placement.
+ *  @param[in] phone The packet server module phone.
+ *  @param[in] packet The original packet.
+ *  @returns The packet copy.
+ *  @returns NULL on error.
+ */
+extern packet_t packet_get_copy(int phone, packet_t packet);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/tl_interface.h
===================================================================
--- uspace/lib/net/include/tl_interface.h	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/include/tl_interface.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -44,5 +44,5 @@
 #include <net_device.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <tl_messages.h>
 
Index: uspace/lib/net/netif/netif_local.c
===================================================================
--- uspace/lib/net/netif/netif_local.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/netif/netif_local.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -47,5 +47,5 @@
 #include <net/modules.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet/packet_server.h>
 #include <packet_remote.h>
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/netif/netif_remote.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -40,5 +40,5 @@
 #include <adt/measured_strings.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <net_device.h>
 #include <netif_remote.h>
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/nil/nil_remote.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -40,5 +40,5 @@
 #include <nil_interface.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <nil_messages.h>
 #include <nil_remote.h>
Index: uspace/lib/net/tl/icmp_client.c
===================================================================
--- uspace/lib/net/tl/icmp_client.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/tl/icmp_client.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -46,5 +46,5 @@
 #include <icmp_client.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <icmp_header.h>
 
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/tl/icmp_remote.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -45,5 +45,5 @@
 #include <net/modules.h>
 #include <icmp_interface.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <icmp_messages.h>
 
Index: uspace/lib/net/tl/tl_common.c
===================================================================
--- uspace/lib/net/tl/tl_common.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/net/tl/tl_common.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -46,5 +46,5 @@
 
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_device.h>
Index: uspace/lib/socket/Makefile
===================================================================
--- uspace/lib/socket/Makefile	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/socket/Makefile	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -33,9 +33,7 @@
 
 SOURCES = \
-	generic/socket_core.c \
 	generic/icmp_common.c \
 	generic/icmp_api.c \
 	packet/packet.c \
-	packet/packet_client.c \
 	packet/packet_server.c 
 
Index: uspace/lib/socket/generic/socket_core.c
===================================================================
--- uspace/lib/socket/generic/socket_core.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ 	(revision )
@@ -1,477 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup socket
- *  @{
- */
-
-/** @file
- *  Socket common core implementation.
- */
-
-#include <net/socket_codes.h>
-#include <net/in.h>
-#include <net/inet.h>
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <err.h>
-
-#include <adt/dynamic_fifo.h>
-#include <adt/int_map.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <net/modules.h>
-#include <socket_core.h>
-
-/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
- */
-#define SOCKET_ID_TRIES					100
-
-/** Bound port sockets.
- */
-struct socket_port{
-	/** The bound sockets map.
-	 */
-	socket_port_map_t map;
-	/** The bound sockets count.
-	 */
-	int count;
-};
-
-INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
-
-GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
-
-INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
-
-/** Destroys the socket.
- *  If the socket is bound, the port is released.
- *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
- *  @param[in] packet_phone The packet server phone to release buffered packets.
- *  @param[in] socket The socket to be destroyed.
- *  @param[in,out] local_sockets The local sockets to be updated.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in] socket_release The client release callback function.
- */
-static void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	int packet_id;
-
-	// if bound
-	if(socket->port){
-		// release the port
-		socket_port_release(global_sockets, socket);
-	}
-	// release all received packets
-	while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
-		pq_release_local(packet_phone, packet_id);
-	}
-	dyn_fifo_destroy(&socket->received);
-	dyn_fifo_destroy(&socket->accepted);
-	if(socket_release){
-		socket_release(socket);
-	}
-	socket_cores_exclude(local_sockets, socket->socket_id);
-}
-
-void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	if(socket_cores_is_valid(local_sockets)){
-		int index;
-
-		local_sockets->magic = 0;
-		for(index = 0; index < local_sockets->next; ++ index){
-			if(socket_cores_item_is_valid(&(local_sockets->items[index]))){
-				local_sockets->items[index].magic = 0;
-				if(local_sockets->items[index].value){
-					socket_destroy_core(packet_phone, local_sockets->items[index].value, local_sockets, global_sockets, socket_release);
-					free(local_sockets->items[index].value);
-					local_sockets->items[index].value = NULL;
-				}
-			}
-		}
-		free(local_sockets->items);
-	}
-}
-
-/** Adds the socket to a socket port.
- *  @param[in,out] socket_port The socket port structure.
- *  @param[in] socket The socket to be added.
- *  @param[in] key The socket key identifier.
- *  @param[in] key_length The socket key length.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
-	ERROR_DECLARE;
-
-	socket_core_ref * socket_ref;
-
-	// create a wrapper
-	socket_ref = malloc(sizeof(*socket_ref));
-	if(! socket_ref){
-		return ENOMEM;
-	}
-	*socket_ref = socket;
-	// add the wrapper
-	if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
-		free(socket_ref);
-		return ERROR_CODE;
-	}
-	++ socket_port->count;
-	socket->key = key;
-	socket->key_length = key_length;
-	return EOK;
-}
-
-/** Binds the socket to the port.
- *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
- *  @param[in] global_sockets The global sockets to be updated.
- *  @param[in] socket The socket to be added.
- *  @param[in] port The port number to be bound to.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the socket_ports_add() function.
- */
-static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
-	ERROR_DECLARE;
-
-	socket_port_ref socket_port;
-
-	// create a wrapper
-	socket_port = malloc(sizeof(*socket_port));
-	if(! socket_port){
-		return ENOMEM;
-	}
-	socket_port->count = 0;
-	if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
-		|| ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
-		socket_port_map_destroy(&socket_port->map);
-		free(socket_port);
-		return ERROR_CODE;
-	}
-	// register the incomming port
-	ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
-	if(ERROR_CODE < 0){
-		socket_port_map_destroy(&socket_port->map);
-		free(socket_port);
-		return ERROR_CODE;
-	}
-	socket->port = port;
-	return EOK;
-}
-
-int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port){
-	socket_core_ref socket;
-	socket_port_ref socket_port;
-	struct sockaddr * address;
-	struct sockaddr_in * address_in;
-
-	if(addrlen < sizeof(struct sockaddr)){
-		return EINVAL;
-	}
-	address = (struct sockaddr *) addr;
-	switch(address->sa_family){
-		case AF_INET:
-			if(addrlen != sizeof(struct sockaddr_in)){
-				return EINVAL;
-			}
-			address_in = (struct sockaddr_in *) addr;
-			// find the socket
-			socket = socket_cores_find(local_sockets, socket_id);
-			if(! socket){
-				return ENOTSOCK;
-			}
-			// bind a free port?
-			if(address_in->sin_port <= 0){
-				return socket_bind_free_port(global_sockets, socket, free_ports_start, free_ports_end, last_used_port);
-			}
-			// try to find the port
-			socket_port = socket_ports_find(global_sockets, ntohs(address_in->sin_port));
-			if(socket_port){
-				// already used
-				return EADDRINUSE;
-			}
-			// if bound
-			if(socket->port){
-				// release the port
-				socket_port_release(global_sockets, socket);
-			}
-			socket->port = -1;
-			return socket_bind_insert(global_sockets, socket, ntohs(address_in->sin_port));
-			break;
-		// TODO IPv6
-	}
-	return EAFNOSUPPORT;
-}
-
-int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){
-	int index;
-
-	// from the last used one
-	index = last_used_port;
-	do{
-		++ index;
-		// til the range end
-		if(index >= free_ports_end){
-			// start from the range beginning
-			index = free_ports_start - 1;
-			do{
-				++ index;
-				// til the last used one
-				if(index >= last_used_port){
-					// none found
-					return ENOTCONN;
-				}
-			}while(socket_ports_find(global_sockets, index) != NULL);
-			// found, break immediately
-			break;
-		}
-	}while(socket_ports_find(global_sockets, index) != NULL);
-	return socket_bind_insert(global_sockets, socket, index);
-}
-
-/** Tries to find a new free socket identifier.
- *  @param[in] local_sockets The local sockets to be searched.
- *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
- *	@returns The new socket identifier.
- *  @returns ELIMIT if there is no socket identifier available.
- */
-static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){
-	int socket_id;
-	int count;
-
-	count = 0;
-//	socket_id = socket_globals.last_id;
-	do{
-		if(count < SOCKET_ID_TRIES){
-			socket_id = rand() % INT_MAX;
-			++ count;
-		}else if(count == SOCKET_ID_TRIES){
-			socket_id = 1;
-			++ count;
-		// only this branch for last_id
-		}else{
-			if(socket_id < INT_MAX){
-				++ socket_id;
-/*			}else if(socket_globals.last_id){
-*				socket_globals.last_id = 0;
-*				socket_id = 1;
-*/			}else{
-				return ELIMIT;
-			}
-		}
-	}while(socket_cores_find(local_sockets, ((positive ? 1 : -1) * socket_id)));
-//	last_id = socket_id
-	return socket_id;
-}
-
-int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){
-	ERROR_DECLARE;
-
-	socket_core_ref socket;
-	int res;
-	int positive;
-
-	if(! socket_id){
-		return EINVAL;
-	}
-	// store the socket
-	if(*socket_id <= 0){
-		positive = (*socket_id == 0);
-		*socket_id = socket_generate_new_id(local_sockets, positive);
-		if(*socket_id <= 0){
-			return * socket_id;
-		}
-		if(! positive){
-			*socket_id *= -1;
-		}
-	}else if(socket_cores_find(local_sockets, * socket_id)){
-		return EEXIST;
-	}
-	socket = (socket_core_ref) malloc(sizeof(*socket));
-	if(! socket){
-		return ENOMEM;
-	}
-	// initialize
-	socket->phone = app_phone;
-	socket->port = -1;
-	socket->key = NULL;
-	socket->key_length = 0;
-	socket->specific_data = specific_data;
-	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){
-		free(socket);
-		return ERROR_CODE;
-	}
-	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){
-		dyn_fifo_destroy(&socket->received);
-		free(socket);
-		return ERROR_CODE;
-	}
-	socket->socket_id = * socket_id;
-	res = socket_cores_add(local_sockets, socket->socket_id, socket);
-	if(res < 0){
-		dyn_fifo_destroy(&socket->received);
-		dyn_fifo_destroy(&socket->accepted);
-		free(socket);
-		return res;
-	}
-	return EOK;
-}
-
-int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	socket_core_ref socket;
-	int accepted_id;
-
-	// find the socket
-	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
-		return ENOTSOCK;
-	}
-	// destroy all accepted sockets
-	while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
-		socket_destroy(packet_phone, accepted_id, local_sockets, global_sockets, socket_release);
-	}
-	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, socket_release);
-	return EOK;
-}
-
-int socket_reply_packets(packet_t packet, size_t * length){
-	ERROR_DECLARE;
-
-	packet_t next_packet;
-	size_t fragments;
-	size_t * lengths;
-	size_t index;
-
-	if(! length){
-		return EBADMEM;
-	}
-	next_packet = pq_next(packet);
-	if(! next_packet){
-		// write all if only one fragment
-		ERROR_PROPAGATE(data_reply(packet_get_data(packet), packet_get_data_length(packet)));
-		// store the total length
-		*length = packet_get_data_length(packet);
-	}else{
-		// count the packet fragments
-		fragments = 1;
-		next_packet = pq_next(packet);
-		while((next_packet = pq_next(next_packet))){
-			++ fragments;
-		}
-		// compute and store the fragment lengths
-		lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
-		if(! lengths){
-			return ENOMEM;
-		}
-		lengths[0] = packet_get_data_length(packet);
-		lengths[fragments] = lengths[0];
-		next_packet = pq_next(packet);
-		for(index = 1; index < fragments; ++ index){
-			lengths[index] = packet_get_data_length(next_packet);
-			lengths[fragments] += lengths[index];
-			next_packet = pq_next(packet);
-		}while(next_packet);
-		// write the fragment lengths
-		ERROR_PROPAGATE(data_reply(lengths, sizeof(int) * (fragments + 1)));
-		next_packet = packet;
-		// write the fragments
-		for(index = 0; index < fragments; ++ index){
-			ERROR_PROPAGATE(data_reply(packet_get_data(next_packet), lengths[index]));
-			next_packet = pq_next(next_packet);
-		}while(next_packet);
-		// store the total length
-		*length = lengths[fragments];
-		free(lengths);
-	}
-	return EOK;
-}
-
-socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length){
-	socket_port_ref socket_port;
-	socket_core_ref * socket_ref;
-
-	socket_port = socket_ports_find(global_sockets, port);
-	if(socket_port && (socket_port->count > 0)){
-		socket_ref = socket_port_map_find(&socket_port->map, key, key_length);
-		if(socket_ref){
-			return * socket_ref;
-		}
-	}
-	return NULL;
-}
-
-void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket){
-	socket_port_ref socket_port;
-	socket_core_ref * socket_ref;
-
-	if(socket->port){
-		// find ports
-		socket_port = socket_ports_find(global_sockets, socket->port);
-		if(socket_port){
-			// find the socket
-			socket_ref = socket_port_map_find(&socket_port->map, socket->key, socket->key_length);
-			if(socket_ref){
-				-- socket_port->count;
-				// release if empty
-				if(socket_port->count <= 0){
-					// destroy the map
-					socket_port_map_destroy(&socket_port->map);
-					// release the port
-					socket_ports_exclude(global_sockets, socket->port);
-				}else{
-					// remove
-					socket_port_map_exclude(&socket_port->map, socket->key, socket->key_length);
-				}
-			}
-		}
-		socket->port = 0;
-		socket->key = NULL;
-		socket->key_length = 0;
-	}
-}
-
-int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){
-	ERROR_DECLARE;
-
-	socket_port_ref socket_port;
-
-	// find ports
-	socket_port = socket_ports_find(global_sockets, port);
-	if(! socket_port){
-		return ENOENT;
-	}
-	// add the socket
-	ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, key_length));
-	socket->port = port;
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/lib/socket/include/packet/packet_client.h
===================================================================
--- uspace/lib/socket/include/packet/packet_client.h	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ 	(revision )
@@ -1,221 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup packet
- *  @{
- */
-
-/** @file
- *  Packet client.
- *  The hosting module has to be compiled with both the packet.c and the packet_client.c source files.
- *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
- *  The module should not send the packet messages to the packet server but use the functions provided.
- *  The packet map should be released by the pm_destroy() function during the module termination.
- *  The packets and the packet queues can't be locked at all.
- *  The processing modules should process them sequentially -&nbsp;by passing the packets to the next module and stopping using the passed ones.
- *  @see packet.h
- */
-
-#ifndef __NET_PACKET_CLIENT_H__
-#define __NET_PACKET_CLIENT_H__
-
-#include <packet/packet.h>
-
-/** @name Packet client interface
- */
-/*@{*/
-
-/** Allocates the specified type right before the actual packet content and returns its pointer.
- *  The wrapper of the packet_prepend() function.
- *  @param[in] packet The packet to be used.
- *  @param[in] type The type to be allocated at the beginning of the packet content.
- *  @returns The typed pointer to the allocated memory.
- *  @returns NULL if the packet is not valid.
- *  @returns NULL if there is not enough memory left.
- */
-#define PACKET_PREFIX(packet, type)	(type *) packet_prefix((packet), sizeof(type))
-
-/** Allocates the specified type right after the actual packet content and returns its pointer.
- *  The wrapper of the packet_append() function.
- *  @param[in] packet The packet to be used.
- *  @param[in] type The type to be allocated at the end of the packet content.
- *  @returns The typed pointer to the allocated memory.
- *  @returns NULL if the packet is not valid.
- *  @returns NULL if there is not enough memory left.
- */
-#define PACKET_SUFFIX(packet, type)	(type *) packet_suffix((packet), sizeof(type))
-
-/** Trims the actual packet content by the specified prefix and suffix types.
- *  The wrapper of the packet_trim() function.
- *  @param[in] packet The packet to be trimmed.
- *  @param[in] prefix The type of the prefix to be removed from the beginning of the packet content.
- *  @param[in] suffix The type of the suffix to be removed from the end of the packet content.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-#define PACKET_TRIM(packet, prefix, suffix)	packet_trim((packet), sizeof(prefix), sizeof(suffix))
-
-/** Allocates the specified space right before the actual packet content and returns its pointer.
- *  @param[in] packet The packet to be used.
- *  @param[in] length The space length to be allocated at the beginning of the packet content.
- *  @returns The pointer to the allocated memory.
- *  @returns NULL if there is not enough memory left.
- */
-extern void * packet_prefix(packet_t packet, size_t length);
-
-/** Allocates the specified space right after the actual packet content and returns its pointer.
- *  @param[in] packet The packet to be used.
- *  @param[in] length The space length to be allocated at the end of the packet content.
- *  @returns The pointer to the allocated memory.
- *  @returns NULL if there is not enough memory left.
- */
-extern void * packet_suffix(packet_t packet, size_t length);
-
-/** Trims the actual packet content by the specified prefix and suffix lengths.
- *  @param[in] packet The packet to be trimmed.
- *  @param[in] prefix The prefix length to be removed from the beginning of the packet content.
- *  @param[in] suffix The suffix length to be removed from the end of the packet content.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_trim(packet_t packet, size_t prefix, size_t suffix);
-
-/** Copies the specified data to the beginning of the actual packet content.
- *  Pushes the content end if needed.
- *  @param[in] packet The packet to be filled.
- *  @param[in] data The data to be copied.
- *  @param[in] length The length of the copied data.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_copy_data(packet_t packet, const void * data, size_t length);
-
-/** Returns the packet identifier.
- *  @param[in] packet The packet.
- *  @returns The packet identifier.
- *  @returns Zero (0) if the packet is not valid.
- */
-extern packet_id_t packet_get_id(const packet_t packet);
-
-/** Returns the packet content length.
- *  @param[in] packet The packet.
- *  @returns The packet content length in bytes.
- *  @returns Zero (0) if the packet is not valid.
- */
-extern size_t packet_get_data_length(const packet_t packet);
-
-/** Returns the pointer to the beginning of the packet content.
- *  @param[in] packet The packet.
- *  @returns The pointer to the beginning of the packet content.
- *  @returns NULL if the packet is not valid.
- */
-extern void * packet_get_data(const packet_t packet);
-
-/** Returns the stored packet addresses and their length.
- *  @param[in] packet The packet.
- *  @param[out] src The source address. May be NULL if not desired.
- *  @param[out] dest The destination address. May be NULL if not desired.
- *  @returns The stored addresses length.
- *  @returns Zero (0) if the addresses are not present.
- *  @returns EINVAL if the packet is not valid.
- */
-extern int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest);
-
-/** Sets the packet addresses.
- *  @param[in] packet The packet.
- *  @param[in] src The new source address. May be NULL.
- *  @param[in] dest The new destination address. May be NULL.
- *  @param[in] addr_len The addresses length.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len);
-
-/** Translates the packet identifier to the packet reference.
- *  Tries to find mapping first.
- *  Contacts the packet server to share the packet if the mapping is not present.
- *  @param[in] phone The packet server module phone.
- *  @param[out] packet The packet reference.
- *  @param[in] packet_id The packet identifier.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet parameter is NULL.
- *  @returns Other error codes as defined for the NET_PACKET_GET_SIZE message.
- *  @returns Other error codes as defined for the packet_return() function.
- */
-extern int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id);
-
-/** Obtains the packet of the given dimensions.
- *  Contacts the packet server to return the appropriate packet.
- *  @param[in] phone The packet server module phone.
- *  @param[in] addr_len The source and destination addresses maximal length in bytes.
- *  @param[in] max_prefix The maximal prefix length in bytes.
- *  @param[in] max_content The maximal content length in bytes.
- *  @param[in] max_suffix The maximal suffix length in bytes.
- *  @returns The packet reference.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);
-
-/** Obtains the packet of the given content size.
- *  Contacts the packet server to return the appropriate packet.
- *  @param[in] phone The packet server module phone.
- *  @param[in] content The maximal content length in bytes.
- *  @returns The packet reference.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_1_local(int phone, size_t content);
-
-/** Releases the packet queue.
- *  All packets in the queue are marked as free for use.
- *  The packet queue may be one packet only.
- *  The module should not use the packets after this point until they are received or obtained again.
- *  @param[in] phone The packet server module phone.
- *  @param[in] packet_id The packet identifier.
- */
-extern void pq_release_local(int phone, packet_id_t packet_id);
-
-/** Returns the packet copy.
- *  Copies the addresses, data, order and metric values.
- *  Does not copy the queue placement.
- *  @param[in] phone The packet server module phone.
- *  @param[in] packet The original packet.
- *  @returns The packet copy.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_copy(int phone, packet_t packet);
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: uspace/lib/socket/include/packet/packet_local.h
===================================================================
--- uspace/lib/socket/include/packet/packet_local.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
+++ uspace/lib/socket/include/packet/packet_local.h	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup packet
+ *  @{
+ */
+
+/** @file
+ */
+
+#ifndef __NET_PACKET_LOCAL_H__
+#define __NET_PACKET_LOCAL_H__
+
+#include <packet/packet.h>
+
+/** @name Packet local interface
+ */
+/*@{*/
+
+extern int packet_translate_local(int, packet_ref, packet_id_t);
+extern packet_t packet_get_4_local(int, size_t, size_t, size_t, size_t);
+extern packet_t packet_get_1_local(int, size_t);
+extern void pq_release_local(int, packet_id_t);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/packet/packet_client.c
===================================================================
--- uspace/lib/socket/packet/packet_client.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ 	(revision )
@@ -1,207 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup packet
- *  @{
- */
-
-/** @file
- *  Packet client implementation.
- */
-
-#include <errno.h>
-#include <mem.h>
-#include <unistd.h>
-
-#include <sys/mman.h>
-
-#include <net_messages.h>
-#include <packet/packet.h>
-#include <packet/packet_header.h>
-#include <packet/packet_client.h>
-
-int packet_copy_data(packet_t packet, const void * data, size_t length)
-{
-	if (!packet_is_valid(packet))
-		return EINVAL;
-
-	if (packet->data_start + length >= packet->length)
-		return ENOMEM;
-
-	memcpy((void *) packet + packet->data_start, data, length);
-	if (packet->data_start + length > packet->data_end) 
-		packet->data_end = packet->data_start + length;
-
-	return EOK;
-}
-
-void *packet_prefix(packet_t packet, size_t length)
-{
-	if ((!packet_is_valid(packet)) ||
-	    (packet->data_start - sizeof(struct packet) -
-	    2 * (packet->dest_addr - packet->src_addr) < length)) {
-		return NULL;
-	}
-
-	packet->data_start -= length;
-	return (void *) packet + packet->data_start;
-}
-
-void *packet_suffix(packet_t packet, size_t length)
-{
-	if ((!packet_is_valid(packet)) ||
-	    (packet->data_end + length >= packet->length)) {
-		return NULL;
-	}
-
-	packet->data_end += length;
-	return (void *) packet + packet->data_end - length;
-}
-
-int packet_trim(packet_t packet, size_t prefix, size_t suffix)
-{
-	if (!packet_is_valid(packet))
-		return EINVAL;
-
-	if (prefix + suffix > PACKET_DATA_LENGTH(packet))
-		return ENOMEM;
-
-	packet->data_start += prefix;
-	packet->data_end -= suffix;
-	return EOK;
-}
-
-packet_id_t packet_get_id(const packet_t packet)
-{
-	return packet_is_valid(packet) ? packet->packet_id : 0;
-}
-
-int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest)
-{
-	if (!packet_is_valid(packet))
-		return EINVAL;
-	if (!packet->addr_len)
-		return 0;
-	if (src)
-		*src = (void *) packet + packet->src_addr;
-	if (dest)
-		*dest = (void *) packet + packet->dest_addr;
-
-	return packet->addr_len;
-}
-
-size_t packet_get_data_length(const packet_t packet)
-{
-	if (!packet_is_valid(packet))
-		return 0;
-
-	return PACKET_DATA_LENGTH(packet);
-}
-
-void *packet_get_data(const packet_t packet)
-{
-	if (!packet_is_valid(packet))
-		return NULL;
-
-	return (void *) packet + packet->data_start;
-}
-
-int
-packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest,
-    size_t addr_len)
-{
-	size_t padding;
-	size_t allocated;
-
-	if (!packet_is_valid(packet))
-		return EINVAL;
-
-	allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
-	if (allocated < addr_len)
-		return ENOMEM;
-
-	padding = allocated - addr_len;
-	packet->addr_len = addr_len;
-
-	if (src) {
-		memcpy((void *) packet + packet->src_addr, src, addr_len);
-		if (padding)
-			bzero((void *) packet + packet->src_addr + addr_len,
-			    padding);
-	} else {
-		bzero((void *) packet + packet->src_addr, allocated);
-	}
-
-	if (dest) {
-		memcpy((void *) packet + packet->dest_addr, dest, addr_len);
-		if (padding)
-			bzero((void *) packet + packet->dest_addr + addr_len,
-			    padding);
-	} else {
-		bzero((void *) packet + packet->dest_addr, allocated);
-	}
-
-	return EOK;
-}
-
-packet_t packet_get_copy(int phone, packet_t packet)
-{
-	packet_t copy;
-	uint8_t * src = NULL;
-	uint8_t * dest = NULL;
-	size_t addrlen;
-
-	if (!packet_is_valid(packet))
-		return NULL;
-
-	// get a new packet
-	copy = packet_get_4_local(phone, PACKET_DATA_LENGTH(packet),
-	    PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
-	    PACKET_MIN_SUFFIX(packet));
-	if (!copy)
-		return NULL;
-
-	// get addresses
-	addrlen = packet_get_addr(packet, &src, &dest);
-	// copy data
-	if ((packet_copy_data(copy, packet_get_data(packet),
-	    PACKET_DATA_LENGTH(packet)) == EOK) &&
-	    // copy addresses if present
-	    ((addrlen <= 0) ||
-	    (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
-		copy->order = packet->order;
-		copy->metric = packet->metric;
-		return copy;
-	} else {
-		pq_release_local(phone, copy->packet_id);
-		return NULL;
-	}
-}
-
-/** @}
- */
Index: uspace/lib/socket/packet/packet_server.c
===================================================================
--- uspace/lib/socket/packet/packet_server.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/lib/socket/packet/packet_server.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -49,5 +49,5 @@
 #include <net_messages.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet/packet_local.h>
 #include <packet/packet_header.h>
 #include <packet/packet_server.h>
Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -39,5 +39,5 @@
 #include <netif_local.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 
 #include "dp8390_drv.h"
Index: uspace/srv/hw/netif/dp8390/dp8390_module.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -46,5 +46,5 @@
 #include <net_messages.h>
 #include <net/modules.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <adt/measured_strings.h>
 #include <net_device.h>
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/il/arp/arp.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -56,5 +56,5 @@
 #include <adt/measured_strings.h>
 #include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <il_messages.h>
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/il/ip/ip.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -68,5 +68,5 @@
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <nil_messages.h>
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/netif/lo/lo.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -47,5 +47,5 @@
 #include <net/modules.h>
 #include <adt/measured_strings.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <net_device.h>
 #include <nil_interface.h>
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/nil/eth/eth.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -59,5 +59,5 @@
 #include <il_interface.h>
 #include <adt/measured_strings.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <nil_local.h>
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -56,5 +56,5 @@
 #include <net_messages.h>
 #include <net/modules.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_checksum.h>
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -58,5 +58,5 @@
 #include <net_messages.h>
 #include <adt/dynamic_fifo.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_checksum.h>
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision d52fbaf59e7bccbf3e5d682f5fafb0146f625e9f)
+++ uspace/srv/net/tl/udp/udp.c	(revision 0a866eebd91749e0380adb6b7af11e95a433af59)
@@ -55,5 +55,5 @@
 #include <net_messages.h>
 #include <adt/dynamic_fifo.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_checksum.h>
