Index: uspace/lib/socket/Makefile
===================================================================
--- uspace/lib/socket/Makefile	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/Makefile	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude
+LIBRARY = libsocket
+
+SOURCES = \
+	generic/socket_client.c \
+	generic/socket_core.c \
+	generic/inet.c \
+	generic/net_modules.c \
+	generic/icmp_common.c \
+	generic/icmp_api.c \
+	packet/packet.c \
+	packet/packet_client.c \
+	packet/packet_server.c \
+	adt/dynamic_fifo.c \
+	adt/measured_strings.c \
+	adt/char_map.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/socket/adt/char_map.c
===================================================================
--- uspace/lib/socket/adt/char_map.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/adt/char_map.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,234 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Character string to integer map implementation.
+ *  @see char_map.h
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+#include <adt/char_map.h>
+
+/** Internal magic value for a&nbsp;consistency check.
+ */
+#define CHAR_MAP_MAGIC_VALUE	0x12345611
+
+/** Adds the value with the key to the map.
+ *  Creates new nodes to map the key.
+ *  @param[in,out] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @param[in] value The integral value to be stored for the key character string.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns EEXIST if the key character string is already used.
+ */
+int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value);
+
+/** Returns the node assigned to the key from the map.
+ *  @param[in] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @returns The node holding the integral value assigned to the key character string.
+ *  @returns NULL if the key is not assigned a&nbsp;node.
+ */
+char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, const size_t length);
+
+/** Returns the value assigned to the map.
+ *  @param[in] map The character string to integer map.
+ *  @returns The integral value assigned to the map.
+ *  @returns CHAR_MAP_NULL if the map is not assigned a&nbsp;value.
+ */
+int char_map_get_value(const char_map_ref map);
+
+/** Checks if the map is valid.
+ *  @param[in] map The character string to integer map.
+ *  @returns TRUE if the map is valid.
+ *  @returns FALSE otherwise.
+ */
+int char_map_is_valid(const char_map_ref map);
+
+int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value){
+	if(char_map_is_valid(map) && (identifier) && ((length) || (*identifier))){
+		int index;
+
+		for(index = 0; index < map->next; ++ index){
+			if(map->items[index]->c == * identifier){
+				++ identifier;
+				if((length > 1) || ((length == 0) && (*identifier))){
+					return char_map_add(map->items[index], identifier, length ? length - 1 : 0, value);
+				}else{
+					if(map->items[index]->value != CHAR_MAP_NULL){
+						return EEXISTS;
+					}
+					map->items[index]->value = value;
+					return EOK;
+				}
+			}
+		}
+		return char_map_add_item(map, identifier, length, value);
+	}
+	return EINVAL;
+}
+
+int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value){
+	if(map->next == (map->size - 1)){
+		char_map_ref *tmp;
+
+		tmp = (char_map_ref *) realloc(map->items, sizeof(char_map_ref) * 2 * map->size);
+		if(! tmp){
+			return ENOMEM;
+		}
+		map->size *= 2;
+		map->items = tmp;
+	}
+	map->items[map->next] = (char_map_ref) malloc(sizeof(char_map_t));
+	if(! map->items[map->next]){
+		return ENOMEM;
+	}
+	if(char_map_initialize(map->items[map->next]) != EOK){
+		free(map->items[map->next]);
+		map->items[map->next] = NULL;
+		return ENOMEM;
+	}
+	map->items[map->next]->c = * identifier;
+	++ identifier;
+	++ map->next;
+	if((length > 1) || ((length == 0) && (*identifier))){
+		map->items[map->next - 1]->value = CHAR_MAP_NULL;
+		return char_map_add_item(map->items[map->next - 1], identifier, length ? length - 1 : 0, value);
+	}else{
+		map->items[map->next - 1]->value = value;
+	}
+	return EOK;
+}
+
+void char_map_destroy(char_map_ref map){
+	if(char_map_is_valid(map)){
+		int index;
+
+		map->magic = 0;
+		for(index = 0; index < map->next; ++ index){
+			char_map_destroy(map->items[index]);
+		}
+		free(map->items);
+		map->items = NULL;
+	}
+}
+
+int char_map_exclude(char_map_ref map, const char * identifier, size_t length){
+	char_map_ref node;
+
+	node = char_map_find_node(map, identifier, length);
+	if(node){
+		int value;
+
+		value = node->value;
+		node->value = CHAR_MAP_NULL;
+		return value;
+	}
+	return CHAR_MAP_NULL;
+}
+
+int char_map_find(const char_map_ref map, const char * identifier, size_t length){
+	char_map_ref node;
+
+	node = char_map_find_node(map, identifier, length);
+	return node ? node->value : CHAR_MAP_NULL;
+}
+
+char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, size_t length){
+	if(! char_map_is_valid(map)){
+		return NULL;
+	}
+	if(length || (*identifier)){
+		int index;
+
+		for(index = 0; index < map->next; ++ index){
+			if(map->items[index]->c == * identifier){
+				++ identifier;
+				if(length == 1){
+					return map->items[index];
+				}
+				return char_map_find_node(map->items[index], identifier, length ? length - 1 : 0);
+			}
+		}
+		return NULL;
+	}
+	return map;
+}
+
+int char_map_get_value(const char_map_ref map){
+	return char_map_is_valid(map) ? map->value : CHAR_MAP_NULL;
+}
+
+int char_map_initialize(char_map_ref map){
+	if(! map){
+		return EINVAL;
+	}
+	map->c = '\0';
+	map->value = CHAR_MAP_NULL;
+	map->size = 2;
+	map->next = 0;
+	map->items = malloc(sizeof(char_map_ref) * map->size);
+	if(! map->items){
+		map->magic = 0;
+		return ENOMEM;
+	}
+	map->items[map->next] = NULL;
+	map->magic = CHAR_MAP_MAGIC_VALUE;
+	return EOK;
+}
+
+int char_map_is_valid(const char_map_ref map){
+	return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
+}
+
+int char_map_update(char_map_ref map, const char * identifier, const size_t length, const int value){
+	char_map_ref node;
+
+//	if(! char_map_is_valid(map)) return EINVAL;
+	node = char_map_find_node(map, identifier, length);
+	if(node){
+		node->value = value;
+		return EOK;
+	}else{
+		return char_map_add(map, identifier, length, value);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/socket/adt/dynamic_fifo.c
===================================================================
--- uspace/lib/socket/adt/dynamic_fifo.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/adt/dynamic_fifo.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,151 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Dynamic first in first out positive integer queue implementation.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+
+#include <adt/dynamic_fifo.h>
+
+/** Internal magic value for a&nbsp;consistency check.
+ */
+#define DYN_FIFO_MAGIC_VALUE	0x58627659
+
+/** Returns the next queue index.
+ *  The queue field is circular.
+ *  @param[in] fifo The dynamic queue.
+ *  @param[in] index The actual index to be shifted.
+ */
+#define NEXT_INDEX(fifo, index)	(((index) + 1) % ((fifo)->size + 1))
+
+/** Checks if the queue is valid.
+ *  @param[in] fifo The dynamic queue.
+ *  @returns TRUE if the queue is valid.
+ *  @returns FALSE otherwise.
+ */
+static int dyn_fifo_is_valid(dyn_fifo_ref fifo){
+	return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE);
+}
+
+int dyn_fifo_initialize(dyn_fifo_ref fifo, int size){
+	if(! fifo){
+		return EBADMEM;
+	}
+	if(size <= 0){
+		return EINVAL;
+	}
+	fifo->items = (int *) malloc(sizeof(int) * size + 1);
+	if(! fifo->items){
+		return ENOMEM;
+	}
+	fifo->size = size;
+	fifo->head = 0;
+	fifo->tail = 0;
+	fifo->magic_value = DYN_FIFO_MAGIC_VALUE;
+	return EOK;
+}
+
+int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size){
+	int * new_items;
+
+	if(! dyn_fifo_is_valid(fifo)){
+		return EINVAL;
+	}
+	if(NEXT_INDEX(fifo, fifo->tail) == fifo->head){
+		if((max_size > 0) && ((fifo->size * 2) > max_size)){
+			if(fifo->size >= max_size){
+				return ENOMEM;
+			}
+		}else{
+			max_size = fifo->size * 2;
+		}
+		new_items = realloc(fifo->items, sizeof(int) * max_size + 1);
+		if(! new_items){
+			return ENOMEM;
+		}
+		fifo->items = new_items;
+		if(fifo->tail < fifo->head){
+			if(fifo->tail < max_size - fifo->size){
+				memcpy(fifo->items + fifo->size + 1, fifo->items, fifo->tail * sizeof(int));
+				fifo->tail += fifo->size + 1;
+			}else{
+				memcpy(fifo->items + fifo->size + 1, fifo->items, (max_size - fifo->size) * sizeof(int));
+				memcpy(fifo->items, fifo->items + max_size - fifo->size, fifo->tail - max_size + fifo->size);
+				fifo->tail -= max_size - fifo->size;
+			}
+		}
+		fifo->size = max_size;
+	}
+	fifo->items[fifo->tail] = value;
+	fifo->tail = NEXT_INDEX(fifo, fifo->tail);
+	return EOK;
+}
+
+int dyn_fifo_pop(dyn_fifo_ref fifo){
+	int value;
+
+	if(! dyn_fifo_is_valid(fifo)){
+		return EINVAL;
+	}
+	if(fifo->head == fifo->tail){
+		return ENOENT;
+	}
+	value = fifo->items[fifo->head];
+	fifo->head = NEXT_INDEX(fifo, fifo->head);
+	return value;
+}
+
+int dyn_fifo_value(dyn_fifo_ref fifo){
+	if(! dyn_fifo_is_valid(fifo)){
+		return EINVAL;
+	}
+	if(fifo->head == fifo->tail){
+		return ENOENT;
+	}
+	return fifo->items[fifo->head];
+}
+
+int dyn_fifo_destroy(dyn_fifo_ref fifo){
+	if(! dyn_fifo_is_valid(fifo)){
+		return EINVAL;
+	}
+	free(fifo->items);
+	fifo->magic_value = 0;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/socket/adt/measured_strings.c
===================================================================
--- uspace/lib/socket/adt/measured_strings.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/adt/measured_strings.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,284 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Character string with measured length implementation.
+ *  @see measured_strings.h
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+#include <ipc/ipc.h>
+
+#include <net_err.h>
+#include <net_modules.h>
+#include <adt/measured_strings.h>
+
+measured_string_ref measured_string_create_bulk(const char * string, size_t length){
+	measured_string_ref new;
+
+	if(length == 0){
+		while(string[length]){
+			++ length;
+		}
+	}
+	new = (measured_string_ref) malloc(sizeof(measured_string_t) + (sizeof(char) * (length + 1)));
+	if(! new){
+		return NULL;
+	}
+	new->length = length;
+	new->value = ((char *) new) + sizeof(measured_string_t);
+	// append terminating zero explicitly - to be safe
+	memcpy(new->value, string, new->length);
+	new->value[new->length] = '\0';
+	return new;
+}
+
+measured_string_ref measured_string_copy(measured_string_ref source){
+	measured_string_ref new;
+
+	if(! source){
+		return NULL;
+	}
+	new = (measured_string_ref) malloc(sizeof(measured_string_t));
+	if(new){
+		new->value = (char *) malloc(source->length + 1);
+		if(new->value){
+			new->length = source->length;
+			memcpy(new->value, source->value, new->length);
+			new->value[new->length] = '\0';
+			return new;
+		}else{
+			free(new);
+		}
+	}
+	return NULL;
+}
+
+int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count){
+	ERROR_DECLARE;
+
+	size_t * lengths;
+	size_t index;
+	size_t length;
+	char * next;
+	ipc_callid_t callid;
+
+	if((! strings) || (! data) || (count <= 0)){
+		return EINVAL;
+	}
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if(! lengths){
+		return ENOMEM;
+	}
+	if((! async_data_write_receive(&callid, &length))
+		|| (length != sizeof(size_t) * (count + 1))){
+		free(lengths);
+		return EINVAL;
+	}
+	if(ERROR_OCCURRED(async_data_write_finalize(callid, lengths, sizeof(size_t) * (count + 1)))){
+		free(lengths);
+		return ERROR_CODE;
+	}
+	*data = malloc(lengths[count]);
+	if(!(*data)){
+		return ENOMEM;
+	}
+	(*data)[lengths[count] - 1] = '\0';
+	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) * count);
+	if(!(*strings)){
+		free(lengths);
+		free(*data);
+		return ENOMEM;
+	}
+	next = * data;
+	for(index = 0; index < count; ++ index){
+		(*strings)[index].length = lengths[index];
+		if(lengths[index] > 0){
+			if((! async_data_write_receive(&callid, &length))
+				|| (length != lengths[index])){
+				free(*data);
+				free(*strings);
+				free(lengths);
+				return EINVAL;
+			}
+			ERROR_PROPAGATE(async_data_write_finalize(callid, next, lengths[index]));
+			(*strings)[index].value = next;
+			next += lengths[index];
+			*next = '\0';
+			++ next;
+		}else{
+			(*strings)[index].value = NULL;
+		}
+	}
+	free(lengths);
+	return EOK;
+}
+
+/** Computes the lengths of the measured strings in the given array.
+ *  @param[in] strings The measured strings array to be processed.
+ *  @param[in] count The measured strings array size.
+ *  @returns The computed sizes array.
+ *  @returns NULL if there is not enough memory left.
+ */
+static size_t * prepare_lengths(const measured_string_ref strings, size_t count){
+	size_t * lengths;
+	size_t index;
+	size_t length;
+
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if(! lengths){
+		return NULL;
+	}
+	length = 0;
+	for(index = 0; index < count; ++ index){
+		lengths[index] = strings[index].length;
+		length += lengths[index] + 1;
+	}
+	lengths[count] = length;
+	return lengths;
+}
+
+int measured_strings_reply(const measured_string_ref strings, size_t count){
+	ERROR_DECLARE;
+
+	size_t * lengths;
+	size_t index;
+	size_t length;
+	ipc_callid_t callid;
+
+	if((! strings) || (count <= 0)){
+		return EINVAL;
+	}
+	lengths = prepare_lengths(strings, count);
+	if(! lengths){
+		return ENOMEM;
+	}
+	if((! async_data_read_receive(&callid, &length))
+		|| (length != sizeof(size_t) * (count + 1))){
+		free(lengths);
+		return EINVAL;
+	}
+	if(ERROR_OCCURRED(async_data_read_finalize(callid, lengths, sizeof(size_t) * (count + 1)))){
+		free(lengths);
+		return ERROR_CODE;
+	}
+	free(lengths);
+	for(index = 0; index < count; ++ index){
+		if(strings[index].length > 0){
+			if((! async_data_read_receive(&callid, &length))
+				|| (length != strings[index].length)){
+				return EINVAL;
+			}
+			ERROR_PROPAGATE(async_data_read_finalize(callid, strings[index].value, strings[index].length));
+		}
+	}
+	return EOK;
+}
+
+int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count){
+	ERROR_DECLARE;
+
+	size_t * lengths;
+	size_t index;
+	char * next;
+
+	if((phone <= 0) || (! strings) || (! data) || (count <= 0)){
+		return EINVAL;
+	}
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if(! lengths){
+		return ENOMEM;
+	}
+	if(ERROR_OCCURRED(async_data_read_start(phone, lengths, sizeof(size_t) * (count + 1)))){
+		free(lengths);
+		return ERROR_CODE;
+	}
+	*data = malloc(lengths[count]);
+	if(!(*data)){
+		return ENOMEM;
+	}
+	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) * count);
+	if(!(*strings)){
+		free(lengths);
+		free(*data);
+		return ENOMEM;
+	}
+	next = * data;
+	for(index = 0; index < count; ++ index){
+		(*strings)[index].length = lengths[index];
+		if(lengths[index] > 0){
+			ERROR_PROPAGATE(async_data_read_start(phone, next, lengths[index]));
+			(*strings)[index].value = next;
+			next += lengths[index];
+			*next = '\0';
+			++ next;
+		}else{
+			(*strings)[index].value = NULL;
+		}
+	}
+	free(lengths);
+	return EOK;
+}
+
+int measured_strings_send(int phone, const measured_string_ref strings, size_t count){
+	ERROR_DECLARE;
+
+	size_t * lengths;
+	size_t index;
+
+	if((phone <= 0) || (! strings) || (count <= 0)){
+		return EINVAL;
+	}
+	lengths = prepare_lengths(strings, count);
+	if(! lengths){
+		return ENOMEM;
+	}
+	if(ERROR_OCCURRED(async_data_write_start(phone, lengths, sizeof(size_t) * (count + 1)))){
+		free(lengths);
+		return ERROR_CODE;
+	}
+	free(lengths);
+	for(index = 0; index < count; ++ index){
+		if(strings[index].length > 0){
+			ERROR_PROPAGATE(async_data_write_start(phone, strings[index].value, strings[index].length));
+		}
+	}
+	return EOK;
+}
+
+/** @}
+ */
+
Index: uspace/lib/socket/generic/icmp_api.c
===================================================================
--- uspace/lib/socket/generic/icmp_api.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/icmp_api.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,69 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP application interface implementation.
+ *  @see icmp_api.h
+ */
+
+#include <async.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <sys/types.h>
+
+#include <net_modules.h>
+#include <icmp_api.h>
+#include <inet.h>
+#include <ip_codes.h>
+#include <socket_codes.h>
+#include <icmp_messages.h>
+
+int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
+	aid_t message_id;
+	ipcarg_t result;
+
+	if(addrlen <= 0){
+		return EINVAL;
+	}
+	message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, (ipcarg_t) dont_fragment, NULL);
+	// send the address
+	async_data_write_start(icmp_phone, addr, (size_t) addrlen);
+	// timeout version may cause inconsistency - there is also an inner timer
+	// return async_wait_timeout(message_id, &result, timeout);
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+/** @}
+ */
Index: uspace/lib/socket/generic/icmp_common.c
===================================================================
--- uspace/lib/socket/generic/icmp_common.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/icmp_common.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,56 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP common interface implementation.
+ *  @see icmp_common.h
+ */
+
+#include <async.h>
+#include <ipc/services.h>
+
+#include <net_modules.h>
+#include <icmp_common.h>
+#include <icmp_messages.h>
+
+int icmp_connect_module(services_t service, suseconds_t timeout){
+	int phone;
+
+	phone = connect_to_service_timeout(SERVICE_ICMP, timeout);
+	if(phone >= 0){
+		async_req_0_0(phone, NET_ICMP_INIT);
+	}
+	return phone;
+}
+
+/** @}
+ */
Index: uspace/lib/socket/generic/inet.c
===================================================================
--- uspace/lib/socket/generic/inet.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/inet.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,156 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Internet protocol address conversion functions implementation.
+ */
+
+#include <errno.h>
+#include <mem.h>
+#include <stdio.h>
+#include <str.h>
+
+#include <in.h>
+#include <in6.h>
+#include <inet.h>
+#include <socket_codes.h>
+
+int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){
+	if((! data) || (! address)){
+		return EINVAL;
+	}
+
+	switch(family){
+		case AF_INET:
+			// check the output buffer size
+			if(length < INET_ADDRSTRLEN){
+				return ENOMEM;
+			}
+			// fill the buffer with the IPv4 address
+			snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", data[0], data[1], data[2], data[3]);
+			return EOK;
+		case AF_INET6:
+			// check the output buffer size
+			if(length < INET6_ADDRSTRLEN){
+				return ENOMEM;
+			}
+			// fill the buffer with the IPv6 address
+			snprintf(address, length, "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
+			return EOK;
+		default:
+			return ENOTSUP;
+	}
+}
+
+int inet_pton(uint16_t family, const char * address, uint8_t * data){
+	/** The base number of the values.
+	 */
+	int base;
+	/** The number of bytes per a section.
+	 */
+	size_t bytes;
+	/** The number of bytes of the address data.
+	 */
+	int count;
+
+	const char * next;
+	char * last;
+	int index;
+	size_t shift;
+	unsigned long value;
+
+	if(! data){
+		return EINVAL;
+	}
+
+	// set the processing parameters
+	switch(family){
+		case AF_INET:
+			count = 4;
+			base = 10;
+			bytes = 1;
+			break;
+		case AF_INET6:
+			count = 16;
+			base = 16;
+			bytes = 4;
+			break;
+		default:
+			return ENOTSUP;
+	}
+
+	// erase if no address
+	if(! address){
+		bzero(data, count);
+		return ENOENT;
+	}
+
+	// process the string from the beginning
+	next = address;
+	index = 0;
+	do{
+		// if the actual character is set
+		if(next && (*next)){
+
+			// if not on the first character
+			if(index){
+				// move to the next character
+				++ next;
+			}
+
+			// parse the actual integral value
+			value = strtoul(next, &last, base);
+			// remember the last problematic character
+			// should be either '.' or ':' but is ignored to be more generic
+			next = last;
+
+			// fill the address data byte by byte
+			shift = bytes - 1;
+			do{
+				// like little endian
+				data[index + shift] = value;
+				value >>= 8;
+			}while(shift --);
+
+			index += bytes;
+		}else{
+			// erase the rest of the address
+			bzero(data + index, count - index);
+			return EOK;
+		}
+	}while(index < count);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/socket/generic/net_modules.c
===================================================================
--- uspace/lib/socket/generic/net_modules.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/net_modules.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,198 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Generic module functions implementation.
+ */
+
+#include <async.h>
+#include <malloc.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <sys/time.h>
+
+#include <net_err.h>
+#include <net_modules.h>
+
+/** The time between connect requests in microseconds.
+ */
+#define MODULE_WAIT_TIME	(10 * 1000)
+
+void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count){
+	// choose the most efficient answer function
+	if(answer || (! answer_count)){
+		switch(answer_count){
+			case 0:
+				ipc_answer_0(callid, (ipcarg_t) result);
+				break;
+			case 1:
+				ipc_answer_1(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer));
+				break;
+			case 2:
+				ipc_answer_2(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
+				break;
+			case 3:
+				ipc_answer_3(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer));
+				break;
+			case 4:
+				ipc_answer_4(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
+				break;
+			case 5:
+			default:
+				ipc_answer_5(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
+				break;
+		}
+	}
+}
+
+int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver){
+	return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
+}
+
+int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout){
+	ERROR_DECLARE;
+
+	int phone;
+	ipcarg_t phonehash;
+
+	// connect to the needed service
+	phone = connect_to_service_timeout(need, timeout);
+	// if connected
+	if(phone >= 0){
+		// request the bidirectional connection
+		if(ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash))){
+			ipc_hangup(phone);
+			return ERROR_CODE;
+		}
+		async_new_connection(phonehash, 0, NULL, client_receiver);
+	}
+	return phone;
+}
+
+int connect_to_service(services_t need){
+	return connect_to_service_timeout(need, 0);
+}
+
+int connect_to_service_timeout(services_t need, suseconds_t timeout){
+	int phone;
+
+	// if no timeout is set
+	if (timeout <= 0){
+		return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
+	}
+
+	while(true){
+		phone = async_connect_me_to(PHONE_NS, need, 0, 0);
+		if((phone >= 0) || (phone != ENOENT)){
+			return phone;
+		}
+
+		// end if no time is left
+		if(timeout <= 0){
+			return ETIMEOUT;
+		}
+
+		// wait the minimum of the module wait time and the timeout
+		usleep((timeout <= MODULE_WAIT_TIME) ? timeout : MODULE_WAIT_TIME);
+		timeout -= MODULE_WAIT_TIME;
+	}
+}
+
+int data_receive(void ** data, size_t * length){
+	ERROR_DECLARE;
+
+	ipc_callid_t callid;
+
+	if(!(data && length)){
+		return EBADMEM;
+	}
+
+	// fetch the request
+	if(! async_data_write_receive(&callid, length)){
+		return EINVAL;
+	}
+
+	// allocate the buffer
+	*data = malloc(*length);
+	if(!(*data)){
+		return ENOMEM;
+	}
+
+	// fetch the data
+	if(ERROR_OCCURRED(async_data_write_finalize(callid, * data, * length))){
+		free(data);
+		return ERROR_CODE;
+	}
+	return EOK;
+}
+
+int data_reply(void * data, size_t data_length){
+	size_t length;
+	ipc_callid_t callid;
+
+	// fetch the request
+	if(! async_data_read_receive(&callid, &length)){
+		return EINVAL;
+	}
+
+	// check the requested data size
+	if(length < data_length){
+		async_data_read_finalize(callid, data, length);
+		return EOVERFLOW;
+	}
+
+	// send the data
+	return async_data_read_finalize(callid, data, data_length);
+}
+
+void refresh_answer(ipc_call_t * answer, int * answer_count){
+
+	if(answer_count){
+		*answer_count = 0;
+	}
+
+	if(answer){
+		IPC_SET_RETVAL(*answer, 0);
+		// just to be precize
+		IPC_SET_METHOD(*answer, 0);
+		IPC_SET_ARG1(*answer, 0);
+		IPC_SET_ARG2(*answer, 0);
+		IPC_SET_ARG3(*answer, 0);
+		IPC_SET_ARG4(*answer, 0);
+		IPC_SET_ARG5(*answer, 0);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/socket/generic/socket_client.c
===================================================================
--- uspace/lib/socket/generic/socket_client.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/socket_client.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,882 @@
+/*
+ * 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 application program interface (API) implementation.
+ *  @see socket.h for more information.
+ *  This is a part of the network application library.
+ */
+
+#include <assert.h>
+#include <async.h>
+#include <fibril_synch.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <ipc/services.h>
+
+#include <net_err.h>
+#include <net_modules.h>
+#include <in.h>
+#include <socket.h>
+#include <socket_errno.h>
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+#include <socket_messages.h>
+
+/** Initial received packet queue size.
+ */
+#define SOCKET_INITIAL_RECEIVED_SIZE	4
+
+/** Maximum received packet queue size.
+ */
+#define SOCKET_MAX_RECEIVED_SIZE		0
+
+/** Initial waiting sockets queue size.
+ */
+#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+
+/** Maximum waiting sockets queue size.
+ */
+#define SOCKET_MAX_ACCEPTED_SIZE		0
+
+/** Default timeout for connections in microseconds.
+ */
+#define SOCKET_CONNECT_TIMEOUT	(1 * 1000 * 1000)
+
+/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
+ */
+#define SOCKET_ID_TRIES					100
+
+/** Type definition of the socket specific data.
+ *  @see socket
+ */
+typedef struct socket	socket_t;
+
+/** Type definition of the socket specific data pointer.
+ *  @see socket
+ */
+typedef socket_t *	socket_ref;
+
+/** Socket specific data.
+ *  Each socket lock locks only its structure part and any number of them may be locked simultaneously.
+ */
+struct socket{
+	/** Socket identifier.
+	 */
+	int socket_id;
+	/** Parent module phone.
+	 */
+	int phone;
+	/** Parent module service.
+	 */
+	services_t service;
+	/** Underlying protocol header size.
+	 *  Sending and receiving optimalization.
+	 */
+	size_t header_size;
+	/** Packet data fragment size.
+	 *  Sending optimalization.
+	 */
+	size_t data_fragment_size;
+	/** Sending safety lock.
+	 *  Locks the header_size and data_fragment_size attributes.
+	 */
+	fibril_rwlock_t sending_lock;
+	/** Received packets queue.
+	 */
+	dyn_fifo_t received;
+	/** Received packets safety lock.
+	 *  Used for receiving and receive notifications.
+	 *  Locks the received attribute.
+	 */
+	fibril_mutex_t receive_lock;
+	/** Received packets signaling.
+	 *  Signaled upon receive notification.
+	 */
+	fibril_condvar_t receive_signal;
+	/** Waiting sockets queue.
+	 */
+	dyn_fifo_t accepted;
+	/** Waiting sockets safety lock.
+	 *  Used for accepting and accept notifications.
+	 *  Locks the accepted attribute.
+	 */
+	fibril_mutex_t accept_lock;
+	/** Waiting sockets signaling.
+	 *  Signaled upon accept notification.
+	 */
+	fibril_condvar_t accept_signal;
+	/** The number of blocked functions called.
+	 *  Used while waiting for the received packets or accepted sockets.
+	 */
+	int blocked;
+};
+
+/** Sockets map.
+ *  Maps socket identifiers to the socket specific data.
+ *  @see int_map.h
+ */
+INT_MAP_DECLARE(sockets, socket_t);
+
+/** Socket client library global data.
+ */
+static struct socket_client_globals {
+	/** TCP module phone.
+	 */
+	int tcp_phone;
+	/** UDP module phone.
+	 */
+	int udp_phone;
+//	/** The last socket identifier.
+//	 */
+//	int last_id;
+	/** Active sockets.
+	 */
+	sockets_ref sockets;
+	/** Safety lock.
+	 *  Write lock is used only for adding or removing sockets.
+	 *  When locked for writing, no other socket locks need to be locked.
+	 *  When locked for reading, any other socket locks may be locked.
+	 *  No socket lock may be locked if this lock is unlocked.
+	 */
+	fibril_rwlock_t lock;
+} socket_globals = {
+	.tcp_phone = -1,
+	.udp_phone = -1,
+//	.last_id = 0,
+	.sockets = NULL,
+	.lock = {
+		.readers = 0,
+		.writers = 0,
+		.waiters = {
+			.prev = &socket_globals.lock.waiters,
+			.next = &socket_globals.lock.waiters
+		}
+	}
+};
+
+INT_MAP_IMPLEMENT(sockets, socket_t);
+
+/** Returns the active sockets.
+ *  @returns The active sockets.
+ */
+static sockets_ref socket_get_sockets(void){
+	if(! socket_globals.sockets){
+		socket_globals.sockets = (sockets_ref) malloc(sizeof(sockets_t));
+		if(! socket_globals.sockets){
+			return NULL;
+		}
+		if(sockets_initialize(socket_globals.sockets) != EOK){
+			free(socket_globals.sockets);
+			socket_globals.sockets = NULL;
+		}
+		srand(task_get_id());
+	}
+	return socket_globals.sockets;
+}
+
+/** Default thread for new connections.
+ *  @param[in] iid The initial message identifier.
+ *  @param[in] icall The initial message call structure.
+ */
+static void socket_connection(ipc_callid_t iid, ipc_call_t * icall){
+	ERROR_DECLARE;
+
+	ipc_callid_t callid;
+	ipc_call_t call;
+	socket_ref socket;
+
+	while(true){
+
+		callid = async_get_call(&call);
+		switch(IPC_GET_METHOD(call)){
+			case NET_SOCKET_RECEIVED:
+			case NET_SOCKET_ACCEPTED:
+			case NET_SOCKET_DATA_FRAGMENT_SIZE:
+				fibril_rwlock_read_lock(&socket_globals.lock);
+				// find the socket
+				socket = sockets_find(socket_get_sockets(), SOCKET_GET_SOCKET_ID(call));
+				if(! socket){
+					ERROR_CODE = ENOTSOCK;
+				}else{
+					switch(IPC_GET_METHOD(call)){
+						case NET_SOCKET_RECEIVED:
+							fibril_mutex_lock(&socket->receive_lock);
+							// push the number of received packet fragments
+							if(! ERROR_OCCURRED(dyn_fifo_push(&socket->received, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_MAX_RECEIVED_SIZE))){
+								// signal the received packet
+								fibril_condvar_signal(&socket->receive_signal);
+							}
+							fibril_mutex_unlock(&socket->receive_lock);
+							break;
+						case NET_SOCKET_ACCEPTED:
+							// push the new socket identifier
+							fibril_mutex_lock(&socket->accept_lock);
+							if(! ERROR_OCCURRED(dyn_fifo_push(&socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){
+								// signal the accepted socket
+								fibril_condvar_signal(&socket->accept_signal);
+							}
+							fibril_mutex_unlock(&socket->accept_lock);
+							break;
+						default:
+							ERROR_CODE = ENOTSUP;
+					}
+					if((SOCKET_GET_DATA_FRAGMENT_SIZE(call) > 0)
+						&& (SOCKET_GET_DATA_FRAGMENT_SIZE(call) != socket->data_fragment_size)){
+						fibril_rwlock_write_lock(&socket->sending_lock);
+						// set the data fragment size
+						socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(call);
+						fibril_rwlock_write_unlock(&socket->sending_lock);
+					}
+				}
+				fibril_rwlock_read_unlock(&socket_globals.lock);
+				break;
+			default:
+				ERROR_CODE = ENOTSUP;
+		}
+		ipc_answer_0(callid, (ipcarg_t) ERROR_CODE);
+	}
+}
+
+/** Returns the TCP module phone.
+ *  Connects to the TCP module if necessary.
+ *  @returns The TCP module phone.
+ *  @returns Other error codes as defined for the bind_service_timeout() function.
+ */
+static int socket_get_tcp_phone(void){
+	if(socket_globals.tcp_phone < 0){
+		socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);
+	}
+	return socket_globals.tcp_phone;
+}
+
+/** Returns the UDP module phone.
+ *  Connects to the UDP module if necessary.
+ *  @returns The UDP module phone.
+ *  @returns Other error codes as defined for the bind_service_timeout() function.
+ */
+static int socket_get_udp_phone(void){
+	if(socket_globals.udp_phone < 0){
+		socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);
+	}
+	return socket_globals.udp_phone;
+}
+
+/** Tries to find a new free socket identifier.
+ *	@returns The new socket identifier.
+ *  @returns ELIMIT if there is no socket identifier available.
+ */
+static int socket_generate_new_id(void){
+	sockets_ref sockets;
+	int socket_id;
+	int count;
+
+	sockets = socket_get_sockets();
+	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(sockets_find(sockets, socket_id));
+//	last_id = socket_id
+	return socket_id;
+}
+
+/** Initializes a new socket specific data.
+ *  @param[in,out] socket The socket to be initialized.
+ *  @param[in] socket_id The new socket identifier.
+ *  @param[in] phone The parent module phone.
+ *  @param[in] service The parent module service.
+ */
+static void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){
+	socket->socket_id = socket_id;
+	socket->phone = phone;
+	socket->service = service;
+	dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
+	dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
+	fibril_mutex_initialize(&socket->receive_lock);
+	fibril_condvar_initialize(&socket->receive_signal);
+	fibril_mutex_initialize(&socket->accept_lock);
+	fibril_condvar_initialize(&socket->accept_signal);
+	fibril_rwlock_initialize(&socket->sending_lock);
+}
+
+int socket(int domain, int type, int protocol){
+	ERROR_DECLARE;
+
+	socket_ref socket;
+	int phone;
+	int socket_id;
+	services_t service;
+	ipcarg_t fragment_size;
+	ipcarg_t header_size;
+
+	// find the appropriate service
+	switch(domain){
+		case PF_INET:
+			switch(type){
+				case SOCK_STREAM:
+					if(! protocol){
+						protocol = IPPROTO_TCP;
+					}
+					switch(protocol){
+						case IPPROTO_TCP:
+							phone = socket_get_tcp_phone();
+							service = SERVICE_TCP;
+							break;
+						default:
+							return EPROTONOSUPPORT;
+					}
+					break;
+				case SOCK_DGRAM:
+					if(! protocol){
+						protocol = IPPROTO_UDP;
+					}
+					switch(protocol){
+						case IPPROTO_UDP:
+							phone = socket_get_udp_phone();
+							service = SERVICE_UDP;
+							break;
+						default:
+							return EPROTONOSUPPORT;
+					}
+					break;
+				case SOCK_RAW:
+				default:
+					return ESOCKTNOSUPPORT;
+			}
+			break;
+		// TODO IPv6
+		default:
+			return EPFNOSUPPORT;
+	}
+	if(phone < 0){
+		return phone;
+	}
+	// create a new socket structure
+	socket = (socket_ref) malloc(sizeof(socket_t));
+	if(! socket){
+		return ENOMEM;
+	}
+	bzero(socket, sizeof(*socket));
+	fibril_rwlock_write_lock(&socket_globals.lock);
+	// request a new socket
+	socket_id = socket_generate_new_id();
+	if(socket_id <= 0){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(socket);
+		return socket_id;
+	}
+	if(ERROR_OCCURRED((int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, &fragment_size, &header_size))){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(socket);
+		return ERROR_CODE;
+	}
+	socket->data_fragment_size = (size_t) fragment_size;
+	socket->header_size = (size_t) header_size;
+	// finish the new socket initialization
+	socket_initialize(socket, socket_id, phone, service);
+	// store the new socket
+	ERROR_CODE = sockets_add(socket_get_sockets(), socket_id, socket);
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	if(ERROR_CODE < 0){
+		dyn_fifo_destroy(&socket->received);
+		dyn_fifo_destroy(&socket->accepted);
+		free(socket);
+		async_msg_3(phone, NET_SOCKET_CLOSE, (ipcarg_t) socket_id, 0, service);
+		return ERROR_CODE;
+	}
+
+	return socket_id;
+}
+
+/** Sends message to the socket parent module with specified data.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] message The action message.
+ *  @param[in] arg2 The second message parameter.
+ *  @param[in] data The data to be sent.
+ *  @param[in] datalength The data length.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data parameter is NULL.
+ *  @returns NO_DATA if the datalength parameter is zero (0).
+ *  @returns Other error codes as defined for the spcific message.
+ */
+static int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+
+	if(! data){
+		return EBADMEM;
+	}
+	if(! datalength){
+		return NO_DATA;
+	}
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	// request the message
+	message_id = async_send_3(socket->phone, message, (ipcarg_t) socket->socket_id, arg2, socket->service, NULL);
+	// send the address
+	async_data_write_start(socket->phone, data, datalength);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen){
+	if(addrlen <= 0){
+		return EINVAL;
+	}
+	// send the address
+	return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, (size_t) addrlen);
+}
+
+int listen(int socket_id, int backlog){
+	socket_ref socket;
+	int result;
+
+	if(backlog <= 0){
+		return EINVAL;
+	}
+	fibril_rwlock_read_lock(&socket_globals.lock);
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	// request listen backlog change
+	result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, (ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return result;
+}
+
+int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen){
+	socket_ref socket;
+	socket_ref new_socket;
+	aid_t message_id;
+	ipcarg_t ipc_result;
+	int result;
+	ipc_call_t answer;
+
+	if((! cliaddr) || (! addrlen)){
+		return EBADMEM;
+	}
+
+	fibril_rwlock_write_lock(&socket_globals.lock);
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	fibril_mutex_lock(&socket->accept_lock);
+	// wait for an accepted socket
+	++ socket->blocked;
+	while(dyn_fifo_value(&socket->accepted) <= 0){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock);
+		// drop the accept lock to avoid deadlock
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->accept_lock);
+	}
+	-- socket->blocked;
+
+	// create a new scoket
+	new_socket = (socket_ref) malloc(sizeof(socket_t));
+	if(! new_socket){
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOMEM;
+	}
+	bzero(new_socket, sizeof(*new_socket));
+	socket_id = socket_generate_new_id();
+	if(socket_id <= 0){
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(new_socket);
+		return socket_id;
+	}
+	socket_initialize(new_socket, socket_id, socket->phone, socket->service);
+	result = sockets_add(socket_get_sockets(), new_socket->socket_id, new_socket);
+	if(result < 0){
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(new_socket);
+		return result;
+	}
+
+	// request accept
+	message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, (ipcarg_t) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, &answer);
+	// read address
+	ipc_data_read_start(socket->phone, cliaddr, * addrlen);
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &ipc_result);
+	result = (int) ipc_result;
+	if(result > 0){
+		if(result != socket_id){
+			result = EINVAL;
+		}
+		// dequeue the accepted socket if successful
+		dyn_fifo_pop(&socket->accepted);
+		// set address length
+		*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
+		new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
+	}else if(result == ENOTSOCK){
+		// empty the queue if no accepted sockets
+		while(dyn_fifo_pop(&socket->accepted) > 0);
+	}
+	fibril_mutex_unlock(&socket->accept_lock);
+	return result;
+}
+
+int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen){
+	if(! serv_addr){
+		return EDESTADDRREQ;
+	}
+	if(! addrlen){
+		return EDESTADDRREQ;
+	}
+	// send the address
+	return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen);
+}
+
+/** Clears and destroys the socket.
+ *  @param[in] socket The socket to be destroyed.
+ */
+static void socket_destroy(socket_ref socket){
+	int accepted_id;
+
+	// destroy all accepted sockets
+	while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
+		socket_destroy(sockets_find(socket_get_sockets(), accepted_id));
+	}
+	dyn_fifo_destroy(&socket->received);
+	dyn_fifo_destroy(&socket->accepted);
+	sockets_exclude(socket_get_sockets(), socket->socket_id);
+}
+
+int closesocket(int socket_id){
+	ERROR_DECLARE;
+
+	socket_ref socket;
+
+	fibril_rwlock_write_lock(&socket_globals.lock);
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	if(socket->blocked){
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return EINPROGRESS;
+	}
+	// request close
+	ERROR_PROPAGATE((int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, (ipcarg_t) socket->socket_id, 0, socket->service));
+	// free the socket structure
+	socket_destroy(socket);
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	return EOK;
+}
+
+/** Sends data via the socket to the remote address.
+ *  Binds the socket to a free port if not already connected/bound.
+ *  @param[in] message The action message.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] data The data to be sent.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various send flags.
+ *  @param[in] toaddr The destination address. May be NULL for connected sockets.
+ *  @param[in] addrlen The address length. Used only if toaddr is not NULL.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data or toaddr parameter is NULL.
+ *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
+ */
+static int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+	size_t fragments;
+	ipc_call_t answer;
+
+	if(! data){
+		return EBADMEM;
+	}
+	if(! datalength){
+		return NO_DATA;
+	}
+	fibril_rwlock_read_lock(&socket_globals.lock);
+	// find socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	fibril_rwlock_read_lock(&socket->sending_lock);
+	// compute data fragment count
+	if(socket->data_fragment_size > 0){
+		fragments = (datalength + socket->header_size) / socket->data_fragment_size;
+		if((datalength + socket->header_size) % socket->data_fragment_size) ++ fragments;
+	}else{
+		fragments = 1;
+	}
+	// request send
+	message_id = async_send_5(socket->phone, message, (ipcarg_t) socket->socket_id, (fragments == 1 ? datalength : socket->data_fragment_size), socket->service, (ipcarg_t) flags, fragments, &answer);
+	// send the address if given
+	if((! toaddr) || (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)){
+		if(fragments == 1){
+			// send all if only one fragment
+			async_data_write_start(socket->phone, data, datalength);
+		}else{
+			// send the first fragment
+			async_data_write_start(socket->phone, data, socket->data_fragment_size - socket->header_size);
+			data = ((const uint8_t *) data) + socket->data_fragment_size - socket->header_size;
+			// send the middle fragments
+			while((-- fragments) > 1){
+				async_data_write_start(socket->phone, data, socket->data_fragment_size);
+				data = ((const uint8_t *) data) + socket->data_fragment_size;
+			}
+			// send the last fragment
+			async_data_write_start(socket->phone, data, (datalength + socket->header_size) % socket->data_fragment_size);
+		}
+	}
+	async_wait_for(message_id, &result);
+	if((SOCKET_GET_DATA_FRAGMENT_SIZE(answer) > 0)
+		&& (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != socket->data_fragment_size)){
+		// set the data fragment size
+		socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
+	}
+	fibril_rwlock_read_unlock(&socket->sending_lock);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return (int) result;
+}
+
+int send(int socket_id, void * data, size_t datalength, int flags){
+	// without the address
+	return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0);
+}
+
+int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
+	if(! toaddr){
+		return EDESTADDRREQ;
+	}
+	if(! addrlen){
+		return EDESTADDRREQ;
+	}
+	// with the address
+	return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen);
+}
+
+/** Receives data via the socket.
+ *  @param[in] message The action message.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[out] data The data buffer to be filled.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various receive flags.
+ *  @param[out] fromaddr The source address. May be NULL for connected sockets.
+ *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data parameter is NULL.
+ *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
+ *  @returns Other error codes as defined for the spcific message.
+ */
+static int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t ipc_result;
+	int result;
+	size_t fragments;
+	size_t * lengths;
+	size_t index;
+	ipc_call_t answer;
+
+	if(! data){
+		return EBADMEM;
+	}
+	if(! datalength){
+		return NO_DATA;
+	}
+	if(fromaddr && (! addrlen)){
+		return EINVAL;
+	}
+	fibril_rwlock_read_lock(&socket_globals.lock);
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	fibril_mutex_lock(&socket->receive_lock);
+	// wait for a received packet
+	++ socket->blocked;
+	while((result = dyn_fifo_value(&socket->received)) <= 0){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock);
+		// drop the receive lock to avoid deadlock
+		fibril_mutex_unlock(&socket->receive_lock);
+		fibril_rwlock_read_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->receive_lock);
+	}
+	-- socket->blocked;
+	fragments = (size_t) result;
+	// prepare lengths if more fragments
+	if(fragments > 1){
+		lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
+		if(! lengths){
+			fibril_mutex_unlock(&socket->receive_lock);
+			fibril_rwlock_read_unlock(&socket_globals.lock);
+			return ENOMEM;
+		}
+		// request packet data
+		message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer);
+		// read the address if desired
+		if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){
+		// read the fragment lengths
+			if(async_data_read_start(socket->phone, lengths, sizeof(int) * (fragments + 1)) == EOK){
+				if(lengths[fragments] <= datalength){
+					// read all fragments if long enough
+					for(index = 0; index < fragments; ++ index){
+						async_data_read_start(socket->phone, data, lengths[index]);
+						data = ((uint8_t *) data) + lengths[index];
+					}
+				}
+			}
+		}
+		free(lengths);
+	}else{
+		// request packet data
+		message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer);
+		// read the address if desired
+		if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){
+			// read all if only one fragment
+			async_data_read_start(socket->phone, data, datalength);
+		}
+	}
+	async_wait_for(message_id, &ipc_result);
+	result = (int) ipc_result;
+	// if successful
+	if(result == EOK){
+		// dequeue the received packet
+		dyn_fifo_pop(&socket->received);
+		// return read data length
+		result = SOCKET_GET_READ_DATA_LENGTH(answer);
+		// set address length
+		if(fromaddr && addrlen){
+			*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
+		}
+	}
+	fibril_mutex_unlock(&socket->receive_lock);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return result;
+}
+
+int recv(int socket_id, void * data, size_t datalength, int flags){
+	// without the address
+	return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL);
+}
+
+int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
+	if(! fromaddr){
+		return EBADMEM;
+	}
+	if(! addrlen){
+		return NO_DATA;
+	}
+	// with the address
+	return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen);
+}
+
+int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+
+	if(!(value && optlen)){
+		return EBADMEM;
+	}
+	if(!(*optlen)){
+		return NO_DATA;
+	}
+	fibril_rwlock_read_lock(&socket_globals.lock);
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if(! socket){
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	// request option value
+	message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, (ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service, NULL);
+	// read the length
+	if(async_data_read_start(socket->phone, optlen, sizeof(*optlen)) == EOK){
+		// read the value
+		async_data_read_start(socket->phone, value, * optlen);
+	}
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen){
+	// send the value
+	return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, (ipcarg_t) optname, value, optlen);
+
+}
+
+/** @}
+ */
Index: uspace/lib/socket/generic/socket_core.c
===================================================================
--- uspace/lib/socket/generic/socket_core.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/generic/socket_core.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,476 @@
+/*
+ * 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 <limits.h>
+#include <stdlib.h>
+
+#include <net_err.h>
+#include <in.h>
+#include <inet.h>
+#include <socket_codes.h>
+#include <socket_errno.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(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/adt/char_map.h
===================================================================
--- uspace/lib/socket/include/adt/char_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/char_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,142 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Character string to integer map.
+ */
+
+#ifndef __CHAR_MAP_H__
+#define __CHAR_MAP_H__
+
+/** Invalid assigned value used also if an&nbsp;entry does not exist.
+ */
+#define CHAR_MAP_NULL	(-1)
+
+/** Type definition of the character string to integer map.
+ *  @see char_map
+ */
+typedef struct char_map	char_map_t;
+
+/** Type definition of the character string to integer map pointer.
+ *  @see char_map
+ */
+typedef char_map_t *	char_map_ref;
+
+/** Character string to integer map item.
+ *  This structure recursivelly contains itself as a&nbsp;character by character tree.
+ *  The actually mapped character string consists o fall the parent characters and the actual one.
+ */
+struct	char_map{
+	/** Actually mapped character.
+	 */
+	char c;
+	/** Stored integral value.
+	 */
+	int value;
+	/** Next character array size.
+	 */
+	int size;
+	/** First free position in the next character array.
+	 */
+	int next;
+	/** Next character array.
+	 */
+	char_map_ref * items;
+	/** Consistency check magic value.
+	 */
+	int magic;
+};
+
+/** Adds the value with the key to the map.
+ *  @param[in,out] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @param[in] value The integral value to be stored for the key character string.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the map is not valid.
+ *  @returns EINVAL if the identifier parameter is NULL.
+ *  @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0') character.
+ *  @returns EEXIST if the key character string is already used.
+ *  @returns Other error codes as defined for the char_map_add_item() function.
+ */
+extern int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value);
+
+/** Clears and destroys the map.
+ *  @param[in,out] map The character string to integer map.
+ */
+extern void char_map_destroy(char_map_ref map);
+
+/** Excludes the value assigned to the key from the map.
+ *  The entry is cleared from the map.
+ *  @param[in,out] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @returns The integral value assigned to the key character string.
+ *  @returns CHAR_MAP_NULL if the key is not assigned a&nbsp;value.
+ */
+extern int char_map_exclude(char_map_ref map, const char * identifier, size_t length);
+
+/** Returns the value assigned to the key from the map.
+ *  @param[in] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @returns The integral value assigned to the key character string.
+ *  @returns CHAR_MAP_NULL if the key is not assigned a&nbsp;value.
+ */
+extern int char_map_find(const char_map_ref map, const char * identifier, size_t length);
+
+/** Initializes the map.
+ *  @param[in,out] map The character string to integer map.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the map parameter is NULL.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int char_map_initialize(char_map_ref map);
+
+/** Adds or updates the value with the key to the map.
+ *  @param[in,out] map The character string to integer map.
+ *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
+ *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
+ *  @param[in] value The integral value to be stored for the key character string.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the map is not valid.
+ *  @returns EINVAL if the identifier parameter is NULL.
+ *  @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0) character.
+ *  @returns EEXIST if the key character string is already used.
+ *  @returns Other error codes as defined for the char_map_add_item() function.
+ */
+extern int char_map_update(char_map_ref map, const char * identifier, size_t length, const int value);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/adt/dynamic_fifo.h
===================================================================
--- uspace/lib/socket/include/adt/dynamic_fifo.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/dynamic_fifo.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,119 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Dynamic first in first out positive integer queue.
+ *  Possitive integer values only.
+ */
+
+#ifndef __NET_DYNAMIC_FIFO_H__
+#define __NET_DYNAMIC_FIFO_H__
+
+/** Type definition of the dynamic fifo queue.
+ *  @see dyn_fifo
+ */
+typedef struct dyn_fifo	dyn_fifo_t;
+
+/** Type definition of the dynamic fifo queue pointer.
+ *  @see dyn_fifo
+ */
+typedef dyn_fifo_t *	dyn_fifo_ref;
+
+/** Dynamic first in first out positive integer queue.
+ *  Possitive integer values only.
+ *  The queue automatically resizes if needed.
+ */
+struct dyn_fifo{
+	/** Stored item field.
+	 */
+	int *	items;
+	/** Actual field size.
+	 */
+	int size;
+	/** First item in the queue index.
+	 */
+	int head;
+	/** Last item in the queue index.
+	 */
+	int tail;
+	/** Consistency check magic value.
+	 */
+	int magic_value;
+};
+
+/** Initializes the dynamic queue.
+ *  @param[in,out] fifo The dynamic queue.
+ *  @param[in] size The initial queue size.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the queue is not valid.
+ *  @returns EBADMEM if the fifo parameter is NULL.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int dyn_fifo_initialize(dyn_fifo_ref fifo, int size);
+
+/** Appends a new item to the queue end.
+ *  @param[in,out] fifo The dynamic queue.
+ *  @param[in] value The new item value. Should be positive.
+ *  @param[in] max_size The maximum queue size. The queue is not resized beyound this limit. May be zero or negative (<=0) to indicate no limit.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the queue is not valid.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size);
+
+/** Returns and excludes the first item in the queue.
+ *  @param[in,out] fifo The dynamic queue.
+ *  @returns Value of the first item in the queue.
+ *  @returns EINVAL if the queue is not valid.
+ *  @returns ENOENT if the queue is empty.
+ */
+extern int dyn_fifo_pop(dyn_fifo_ref fifo);
+
+/** Returns and keeps the first item in the queue.
+ *  @param[in,out] fifo The dynamic queue.
+ *  @returns Value of the first item in the queue.
+ *  @returns EINVAL if the queue is not valid.
+ *  @returns ENOENT if the queue is empty.
+ */
+extern int dyn_fifo_value(dyn_fifo_ref fifo);
+
+/** Clears and destroys the queue.
+ *  @param[in,out] fifo The dynamic queue.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the queue is not valid.
+ */
+extern int dyn_fifo_destroy(dyn_fifo_ref fifo);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/adt/generic_char_map.h
===================================================================
--- uspace/lib/socket/include/adt/generic_char_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/generic_char_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,161 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Character string to generic type map.
+ */
+
+#ifndef __GENERIC_CHAR_MAP_H__
+#define __GENERIC_CHAR_MAP_H__
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <net_err.h>
+
+#include <adt/char_map.h>
+#include <adt/generic_field.h>
+
+/** Internal magic value for a&nbsp;map consistency check.
+ */
+#define GENERIC_CHAR_MAP_MAGIC_VALUE	0x12345622
+
+/** Character string to generic type map declaration.
+ *  @param[in] name Name of the map.
+ *  @param[in] type Inner object type.
+ */
+#define GENERIC_CHAR_MAP_DECLARE(name, type)									\
+																				\
+GENERIC_FIELD_DECLARE(name##_items, type)										\
+																				\
+typedef	struct name		name##_t;												\
+typedef	name##_t *		name##_ref;												\
+																				\
+struct	name{																	\
+	char_map_t names;														\
+	name##_items_t values;														\
+	int magic;														\
+};																				\
+																				\
+int name##_add(name##_ref map, const char * name, const size_t length, type * value);	\
+int name##_count(name##_ref map);												\
+void name##_destroy(name##_ref map);											\
+void name##_exclude(name##_ref map, const char * name, const size_t length);	\
+type * name##_find(name##_ref map, const char * name, const size_t length);		\
+int name##_initialize(name##_ref map);											\
+int name##_is_valid(name##_ref map);
+
+/** Character string to generic type map implementation.
+ *  Should follow declaration with the same parameters.
+ *  @param[in] name Name of the map.
+ *  @param[in] type Inner object type.
+ */
+#define GENERIC_CHAR_MAP_IMPLEMENT(name, type)									\
+																				\
+GENERIC_FIELD_IMPLEMENT(name##_items, type)										\
+																				\
+int name##_add(name##_ref map, const char * name, const size_t length, type * value){	\
+	ERROR_DECLARE;																\
+																				\
+	int index;																	\
+																				\
+	if(! name##_is_valid(map)){													\
+		return EINVAL;															\
+	}																			\
+	index = name##_items_add(&map->values, value);								\
+	if(index < 0){																\
+		return index;															\
+	}																			\
+	if(ERROR_OCCURRED(char_map_add(&map->names, name, length, index))){			\
+		name##_items_exclude_index(&map->values, index);						\
+		return ERROR_CODE;														\
+	}																			\
+	return EOK;																	\
+}																				\
+																				\
+int name##_count(name##_ref map){												\
+	return name##_is_valid(map) ? name##_items_count(&map->values) : -1;		\
+}																				\
+																				\
+void name##_destroy(name##_ref map){											\
+	if(name##_is_valid(map)){													\
+		char_map_destroy(&map->names);											\
+		name##_items_destroy(&map->values);										\
+	}																			\
+}																				\
+																				\
+void name##_exclude(name##_ref map, const char * name, const size_t length){	\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		index = char_map_exclude(&map->names, name, length);					\
+		if(index != CHAR_MAP_NULL){												\
+			name##_items_exclude_index(&map->values, index);					\
+		}																		\
+	}																			\
+}																				\
+																				\
+type * name##_find(name##_ref map, const char * name, const size_t length){		\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		index = char_map_find(&map->names, name, length);						\
+		if(index != CHAR_MAP_NULL){												\
+			return name##_items_get_index(&map->values, index);					\
+		}																		\
+	}																			\
+	return NULL;																\
+}																				\
+																				\
+int name##_initialize(name##_ref map){											\
+	ERROR_DECLARE;																\
+																				\
+	if(! map){																	\
+		return EINVAL;															\
+	}																			\
+	ERROR_PROPAGATE(char_map_initialize(&map->names));							\
+	if(ERROR_OCCURRED(name##_items_initialize(&map->values))){					\
+		char_map_destroy(&map->names);											\
+		return ERROR_CODE;														\
+	}																			\
+	map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE;									\
+	return EOK;																	\
+}																				\
+																				\
+int name##_is_valid(name##_ref map){											\
+	return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE);					\
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/adt/generic_field.h
===================================================================
--- uspace/lib/socket/include/adt/generic_field.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/generic_field.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,160 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Generic type field.
+ */
+
+#ifndef __GENERIC_FIELD_H__
+#define __GENERIC_FIELD_H__
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+/** Internal magic value for a&nbsp;field consistency check.
+ */
+#define GENERIC_FIELD_MAGIC_VALUE		0x55667788
+
+/** Generic type field declaration.
+ *  @param[in] name Name of the field.
+ *  @param[in] type Inner object type.
+ */
+#define GENERIC_FIELD_DECLARE(name, type)										\
+																				\
+typedef	struct name		name##_t;												\
+typedef	name##_t *		name##_ref;												\
+																				\
+struct	name{																	\
+	int size;																	\
+	int next;																	\
+	type **	items;																\
+	int magic;																	\
+};																				\
+																				\
+int name##_add(name##_ref field, type * value);									\
+int name##_count(name##_ref field);												\
+void name##_destroy(name##_ref field);											\
+void name##_exclude_index(name##_ref field, int index);							\
+type ** name##_get_field(name##_ref field);										\
+type * name##_get_index(name##_ref field, int index);							\
+int name##_initialize(name##_ref field);										\
+int name##_is_valid(name##_ref field);
+
+/** Generic type field implementation.
+ *  Should follow declaration with the same parameters.
+ *  @param[in] name Name of the field.
+ *  @param[in] type Inner object type.
+ */
+#define GENERIC_FIELD_IMPLEMENT(name, type)										\
+																				\
+int name##_add(name##_ref field, type * value){									\
+	if(name##_is_valid(field)){													\
+		if(field->next == (field->size - 1)){									\
+			type **	tmp;														\
+																				\
+			tmp = (type **) realloc(field->items, sizeof(type *) * 2 * field->size);	\
+			if(! tmp){															\
+				return ENOMEM;													\
+			}																	\
+			field->size *= 2;													\
+			field->items = tmp;													\
+		}																		\
+		field->items[field->next] = value;										\
+		++ field->next;															\
+		field->items[field->next] = NULL;										\
+		return field->next - 1;													\
+	}																			\
+	return EINVAL;																\
+}																				\
+																				\
+int name##_count(name##_ref field){												\
+	return name##_is_valid(field) ? field->next : -1;							\
+}																				\
+																				\
+void name##_destroy(name##_ref field){											\
+	if(name##_is_valid(field)){													\
+		int index;																\
+																				\
+		field->magic = 0;														\
+		for(index = 0; index < field->next; ++ index){							\
+			if(field->items[index]){											\
+				free(field->items[index]);										\
+			}																	\
+		}																		\
+		free(field->items);														\
+	}																			\
+}																				\
+																				\
+void name##_exclude_index(name##_ref field, int index){							\
+	if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){	\
+		free(field->items[index]);												\
+		field->items[index] = NULL;												\
+	}																			\
+}																				\
+																				\
+type * name##_get_index(name##_ref field, int index){							\
+	if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){	\
+		return field->items[index];												\
+	}																			\
+	return NULL;																\
+}																				\
+																				\
+type ** name##_get_field(name##_ref field){										\
+	return name##_is_valid(field) ? field->items : NULL;						\
+}																				\
+																				\
+int name##_initialize(name##_ref field){										\
+	if(! field){																\
+		return EINVAL;															\
+	}																			\
+	field->size = 2;															\
+	field->next = 0;															\
+	field->items = (type **) malloc(sizeof(type *) * field->size);				\
+	if(! field->items){															\
+		return ENOMEM;															\
+	}																			\
+	field->items[field->next] = NULL;											\
+	field->magic = GENERIC_FIELD_MAGIC_VALUE;									\
+	return EOK;																	\
+}																				\
+																				\
+int name##_is_valid(name##_ref field){											\
+	return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE);				\
+}
+
+#endif
+
+/** @}
+ */
+
Index: uspace/lib/socket/include/adt/int_map.h
===================================================================
--- uspace/lib/socket/include/adt/int_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/int_map.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,247 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Integer to generic type map.
+ */
+
+#ifndef __NET_INT_MAP_H__
+#define __NET_INT_MAP_H__
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+/** Internal magic value for a&nbsp;map consistency check.
+ */
+#define INT_MAP_MAGIC_VALUE			0x11223344
+
+/** Internal magic value for an item consistency check.
+ */
+#define INT_MAP_ITEM_MAGIC_VALUE	0x55667788
+
+/** Integer to generic type map declaration.
+ *  @param[in] name Name of the map.
+ *  @param[in] type Inner object type.
+ */
+#define INT_MAP_DECLARE(name, type)												\
+																				\
+typedef	struct name			name##_t;											\
+typedef	name##_t *			name##_ref;											\
+typedef	struct name##_item	name##_item_t;										\
+typedef	name##_item_t *		name##_item_ref;									\
+																				\
+struct	name##_item{															\
+	int key;																\
+	type * value;																\
+	int magic;																\
+};																				\
+																				\
+struct	name{																	\
+	int size;														\
+	int next;														\
+	name##_item_ref items;														\
+	int magic;														\
+};																				\
+																				\
+int name##_add(name##_ref map, int key, type * value);							\
+void name##_clear(name##_ref map);												\
+int name##_count(name##_ref map);												\
+void name##_destroy(name##_ref map);											\
+void name##_exclude(name##_ref map, int key);									\
+void name##_exclude_index(name##_ref map, int index);							\
+type * name##_find(name##_ref map, int key);									\
+int name##_update(name##_ref map, int key, int new_key);						\
+type * name##_get_index(name##_ref map, int index);								\
+int name##_initialize(name##_ref map);											\
+int name##_is_valid(name##_ref map);											\
+void name##_item_destroy(name##_item_ref item);									\
+int name##_item_is_valid(name##_item_ref item);
+
+/** Integer to generic type map implementation.
+ *  Should follow declaration with the same parameters.
+ *  @param[in] name Name of the map.
+ *  @param[in] type Inner object type.
+ */
+#define INT_MAP_IMPLEMENT(name, type)											\
+																				\
+int name##_add(name##_ref map, int key, type * value){							\
+	if(name##_is_valid(map)){													\
+		if(map->next == (map->size - 1)){										\
+			name##_item_ref tmp;												\
+																				\
+			tmp = (name##_item_ref) realloc(map->items, sizeof(name##_item_t) * 2 * map->size);	\
+			if(! tmp){															\
+				return ENOMEM;													\
+			}																	\
+			map->size *= 2;														\
+			map->items = tmp;													\
+		}																		\
+		map->items[map->next].key = key;										\
+		map->items[map->next].value = value;									\
+		map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE;					\
+		++ map->next;															\
+		map->items[map->next].magic = 0;										\
+		return map->next - 1;													\
+	}																			\
+	return EINVAL;																\
+}																				\
+																				\
+void name##_clear(name##_ref map){												\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+/*		map->magic = 0;*/														\
+		for(index = 0; index < map->next; ++ index){							\
+			if(name##_item_is_valid(&(map->items[index]))){						\
+				name##_item_destroy(&(map->items[index]));						\
+			}																	\
+		}																		\
+		map->next = 0;															\
+		map->items[map->next].magic = 0;										\
+/*		map->magic = INT_MAP_MAGIC_VALUE;*/										\
+	}																			\
+}																				\
+																				\
+int name##_count(name##_ref map){												\
+	return name##_is_valid(map) ? map->next : -1;								\
+}																				\
+																				\
+void name##_destroy(name##_ref map){											\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		map->magic = 0;															\
+		for(index = 0; index < map->next; ++ index){							\
+			if(name##_item_is_valid(&(map->items[index]))){						\
+				name##_item_destroy(&(map->items[index]));						\
+			}																	\
+		}																		\
+		free(map->items);														\
+	}																			\
+}																				\
+																				\
+void name##_exclude(name##_ref map, int key){									\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		for(index = 0; index < map->next; ++ index){							\
+			if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){	\
+				name##_item_destroy(&(map->items[index]));						\
+			}																	\
+		}																		\
+	}																			\
+}																				\
+																				\
+void name##_exclude_index(name##_ref map, int index){							\
+	if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){	\
+		name##_item_destroy(&(map->items[index]));								\
+	}																			\
+}																				\
+																				\
+type * name##_find(name##_ref map, int key){									\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		for(index = 0; index < map->next; ++ index){							\
+			if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){	\
+				return map->items[index].value;									\
+			}																	\
+		}																		\
+	}																			\
+	return NULL;																\
+}																				\
+																				\
+int name##_update(name##_ref map, int key, int new_key){						\
+	if(name##_is_valid(map)){													\
+		int index;																\
+																				\
+		for(index = 0; index < map->next; ++ index){							\
+			if(name##_item_is_valid(&(map->items[index]))){						\
+				if(map->items[index].key == new_key){							\
+					return EEXIST;												\
+				}else if(map->items[index].key == key){							\
+					map->items[index].key = new_key;							\
+					return EOK;													\
+				}																\
+			}																	\
+		}																		\
+	}																			\
+	return ENOENT;																\
+}																				\
+																				\
+type * name##_get_index(name##_ref map, int index){								\
+	if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){	\
+		return map->items[index].value;											\
+	}																			\
+	return NULL;																\
+}																				\
+																				\
+int name##_initialize(name##_ref map){											\
+	if(! map){																	\
+		return EINVAL;															\
+	}																			\
+	map->size = 2;																\
+	map->next = 0;																\
+	map->items = (name##_item_ref) malloc(sizeof(name##_item_t) * map->size);	\
+	if(! map->items){															\
+		return ENOMEM;															\
+	}																			\
+	map->items[map->next].magic = 0;											\
+	map->magic = INT_MAP_MAGIC_VALUE;											\
+	return EOK;																	\
+}																				\
+																				\
+int name##_is_valid(name##_ref map){											\
+	return map && (map->magic == INT_MAP_MAGIC_VALUE);							\
+}																				\
+																				\
+void name##_item_destroy(name##_item_ref item){									\
+	if(name##_item_is_valid(item)){												\
+		item->magic = 0;														\
+		if(item->value){														\
+			free(item->value);													\
+			item->value = NULL;													\
+		}																		\
+	}																			\
+}																				\
+																				\
+int name##_item_is_valid(name##_item_ref item){									\
+	return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE);					\
+}
+
+#endif
+
+/** @}
+ */
+
Index: uspace/lib/socket/include/adt/measured_strings.h
===================================================================
--- uspace/lib/socket/include/adt/measured_strings.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/adt/measured_strings.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,144 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Character string with measured length.
+ *  The structure has been designed for serialization of character strings between modules.
+ */
+
+#ifndef __MEASURED_STRINGS_H__
+#define __MEASURED_STRINGS_H__
+
+#include <sys/types.h>
+
+/** Type definition of the character string with measured length.
+ *  @see measured_string
+ */
+typedef struct measured_string	measured_string_t;
+
+/** Type definition of the character string with measured length pointer.
+ *  @see measured_string
+ */
+typedef measured_string_t *		measured_string_ref;
+
+/** Character string with measured length.
+ *  This structure has been designed for serialization of character strings between modules.
+ */
+struct	measured_string{
+	/** Character string data.
+	 */
+	char * value;
+	/** Character string length.
+	 */
+	size_t length;
+};
+
+/** Creates a&nbsp;new measured string bundled with a&nbsp;copy of the given string itself as one memory block.
+ *  If the measured string is being freed, whole memory block is freed.
+ *  The measured string should be used only as a&nbsp;constant.
+ *  @param[in] string The initial character string to be stored.
+ *  @param[in] length The length of the given string without the terminating zero ('/0') character. If the length is zero (0), the actual length is computed. The given length is used and appended with the terminating zero ('\\0') character otherwise.
+ *  @returns The new bundled character string with measured length.
+ *  @returns NULL if there is not enough memory left.
+ */
+extern measured_string_ref measured_string_create_bulk(const char * string, size_t length);
+
+/** Copies the given measured string with separated header and data parts.
+ *  @param[in] source The source measured string to be copied.
+ *  @returns The copy of the given measured string.
+ *  @returns NULL if the source parameter is NULL.
+ *  @returns NULL if there is not enough memory left.
+ */
+extern measured_string_ref measured_string_copy(measured_string_ref source);
+
+/** Receives a&nbsp;measured strings array from a&nbsp;calling module.
+ *  Creates the array and the data memory blocks.
+ *  This method should be used only while processing IPC messages as the array size has to be negotiated in advance.
+ *  @param[out] strings The received measured strings array.
+ *  @param[out] data The measured strings data. This memory block stores the actual character strings.
+ *  @param[in] count The size of the measured strings array.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the strings or data parameter is NULL.
+ *  @returns EINVAL if the count parameter is zero (0).
+ *  @returns EINVAL if the sent array differs in size.
+ *  @returns EINVAL if there is inconsistency in sent measured strings' lengths (should not occur).
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns Other error codes as defined for the async_data_write_finalize() function.
+ */
+extern int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count);
+
+/** Replies the given measured strings array to a&nbsp;calling module.
+ *  This method should be used only while processing IPC messages as the array size has to be negotiated in advance.
+ *  @param[in] strings The measured strings array to be transferred.
+ *  @param[in] count The measured strings array size.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the strings parameter is NULL.
+ *  @returns EINVAL if the count parameter is zero (0).
+ *  @returns EINVAL if the calling module does not accept the given array size.
+ *  @returns EINVAL if there is inconsistency in sent measured strings' lengths (should not occur).
+ *  @returns Other error codes as defined for the async_data_read_finalize() function.
+ */
+extern int measured_strings_reply(const measured_string_ref strings, size_t count);
+
+/** Receives a&nbsp;measured strings array from another module.
+ *  Creates the array and the data memory blocks.
+ *  This method should be used only following other IPC messages as the array size has to be negotiated in advance.
+ *  @param[in] phone The other module phone.
+ *  @param[out] strings The returned measured strings array.
+ *  @param[out] data The measured strings data. This memory block stores the actual character strings.
+ *  @param[in] count The size of the measured strings array.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the strings or data parameter is NULL.
+ *  @returns EINVAL if the phone or count parameter is not positive (<=0).
+ *  @returns EINVAL if the sent array differs in size.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns Other error codes as defined for the async_data_read_start() function.
+ */
+extern int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count);
+
+/** Sends the given measured strings array to another module.
+ *  This method should be used only following other IPC messages as the array size has to be negotiated in advance.
+ *  @param[in] phone The other module phone.
+ *  @param[in] strings The measured strings array to be transferred.
+ *  @param[in] count The measured strings array size.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the strings parameter is NULL.
+ *  @returns EINVAL if the phone or count parameter is not positive (<=0).
+ *  @returns Other error codes as defined for the async_data_write_start() function.
+ */
+extern int measured_strings_send(int phone, const measured_string_ref strings, size_t count);
+
+#endif
+
+/** @}
+ */
+
Index: uspace/lib/socket/include/icmp_api.h
===================================================================
--- uspace/lib/socket/include/icmp_api.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/icmp_api.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,85 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP module application interface.
+ */
+
+#ifndef __NET_ICMP_API_H__
+#define __NET_ICMP_API_H__
+
+#include <sys/types.h>
+
+#include <net_device.h>
+#include <adt/measured_strings.h>
+#include <packet/packet.h>
+#include <inet.h>
+#include <ip_codes.h>
+#include <socket_codes.h>
+#include <icmp_codes.h>
+#include <icmp_common.h>
+
+/** Miliseconds type definition.
+ */
+typedef size_t	mseconds_t;
+
+/** @name ICMP module application interface
+ *  This interface is used by other application modules.
+ */
+/*@{*/
+
+/** Requests an echo message.
+ *  Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout.
+ *  Blocks the caller until the reply or the timeout occurres.
+ *  @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
+ *  @param[in] size The message data length in bytes.
+ *  @param[in] timeout The timeout in miliseconds.
+ *  @param[in] ttl The time to live.
+ *  @param[in] tos The type of service.
+ *  @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery.
+ *  @param[in] addr The target host address.
+ *  @param[in] addrlen The torget host address length.
+ *  @returns ICMP_ECHO on success.
+ *  @returns ETIMEOUT if the reply has not arrived before the timeout.
+ *  @returns ICMP type of the received error notification. 
+ *  @returns EINVAL if the addrlen parameter is less or equal to zero (<=0).
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns EPARTY if there was an internal error.
+ */
+extern int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/icmp_codes.h
===================================================================
--- uspace/lib/socket/include/icmp_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/icmp_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,347 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP types and codes according to the on-line IANA - ICMP Type Numbers - <http://http://www.iana.org/assignments/icmp-parameters>, cited September 14 2009.
+ */
+
+#ifndef __NET_ICMP_CODES_H__
+#define __NET_ICMP_CODES_H__
+
+/** ICMP type type definition.
+ */
+typedef uint8_t	icmp_type_t;
+
+/** ICMP code type definition.
+ */
+typedef uint8_t	icmp_code_t;
+
+/** ICMP parameter type definition.
+ */
+typedef uint16_t	icmp_param_t;
+
+/** @name ICMP types definitions
+ */
+/*@{*/
+
+/** Echo Reply.
+ */
+#define ICMP_ECHOREPLY		0
+
+/** Destination Unreachable.
+ */
+#define ICMP_DEST_UNREACH	3
+
+/** Source Quench.
+ */
+#define ICMP_SOURCE_QUENCH	4
+
+/** Redirect.
+ */
+#define ICMP_REDIRECT		5
+
+/** Alternate Host Address.
+ */
+#define ICMP_ALTERNATE_ADDR	6
+
+/** Echo Request.
+ */
+#define ICMP_ECHO			8
+
+/** Router Advertisement.
+ */
+#define ICMP_ROUTER_ADV		9
+
+/** Router solicitation.
+ */
+#define ICMP_ROUTER_SOL		10
+
+/** Time Exceeded.
+ */
+#define ICMP_TIME_EXCEEDED	11
+
+/** Parameter Problem.
+ */
+#define ICMP_PARAMETERPROB	12
+
+/** Timestamp Request.
+ */
+#define ICMP_TIMESTAMP		13
+
+/** Timestamp Reply.
+ */
+#define ICMP_TIMESTAMPREPLY	14
+
+/** Information Request.
+ */
+#define ICMP_INFO_REQUEST	15
+
+/** Information Reply.
+ */
+#define ICMP_INFO_REPLY		16
+
+/** Address Mask Request.
+ */
+#define ICMP_ADDRESS		17
+
+/** Address Mask Reply.
+ */
+#define ICMP_ADDRESSREPLY	18
+
+/** Traceroute.
+ */
+#define ICMP_TRACEROUTE		30
+
+/** Datagram Conversion Error.
+ */
+#define ICMP_CONVERSION_ERROR	31
+
+/** Mobile Host Redirect.
+ */
+#define ICMP_REDIRECT_MOBILE	32
+
+/** IPv6 Where-Are-You.
+ */
+#define ICMP_IPV6_WHERE_ARE_YOU	33
+
+/** IPv6 I-Am-Here.
+ */
+#define ICMP_IPV6_I_AM_HERE	34
+
+/** Mobile Registration Request.
+ */
+#define ICMP_MOBILE_REQUEST	35
+
+/** Mobile Registration Reply.
+ */
+#define ICMP_MOBILE_REPLY	36
+
+/** Domain name request.
+ */
+#define ICMP_DN_REQUEST		37
+
+/** Domain name reply.
+ */
+#define ICMP_DN_REPLY		38
+
+/** SKIP.
+ */
+#define ICMP_SKIP			39
+
+/** Photuris.
+ */
+#define ICMP_PHOTURIS		40
+
+/*@}*/
+
+/** @name ICMP_DEST_UNREACH codes definitions
+ */
+/*@{*/
+
+/** Network Unreachable.
+ */
+#define ICMP_NET_UNREACH	0
+
+/** Host Unreachable.
+ */
+#define ICMP_HOST_UNREACH	1
+
+/** Protocol Unreachable.
+ */
+#define ICMP_PROT_UNREACH	2
+
+/** Port Unreachable.
+ */
+#define ICMP_PORT_UNREACH	3
+
+/** Fragmentation needed but the Do Not Fragment bit was set.
+ */
+#define ICMP_FRAG_NEEDED	4
+
+/** Source Route failed.
+ */
+#define ICMP_SR_FAILED		5
+
+/** Destination network unknown.
+ */
+#define ICMP_NET_UNKNOWN	6
+
+/** Destination host unknown.
+ */
+#define ICMP_HOST_UNKNOWN	7
+
+/** Source host isolated (obsolete).
+ */
+#define ICMP_HOST_ISOLATED	8
+
+/** Destination network administratively prohibited.
+ */
+#define ICMP_NET_ANO		9
+
+/** Destination host administratively prohibited.
+ */
+#define ICMP_HOST_ANO		10
+
+/** Network unreachable for this type of service.
+ */
+#define ICMP_NET_UNR_TOS	11
+
+/** Host unreachable for this type of service.
+ */
+#define ICMP_HOST_UNR_TOS	12
+
+/** Communication administratively prohibited by filtering.
+ */
+#define ICMP_PKT_FILTERED	13
+
+/** Host precedence violation.
+ */
+#define ICMP_PREC_VIOLATION	14
+
+/** Precedence cutoff in effect.
+ */
+#define ICMP_PREC_CUTOFF	15
+
+/*@}*/
+
+/** @name ICMP_REDIRECT codes definitions
+ */
+/*@{*/
+
+/** Network redirect (or subnet).
+ */
+#define ICMP_REDIR_NET		0
+
+/** Host redirect.
+ */
+#define ICMP_REDIR_HOST		1
+
+/** Network redirect for this type of service.
+ */
+#define ICMP_REDIR_NETTOS	2
+
+/** Host redirect for this type of service.
+ */
+#define ICMP_REDIR_HOSTTOS	3
+
+/*@}*/
+
+/** @name ICMP_ALTERNATE_ADDRESS codes definitions
+ */
+/*@{*/
+
+/** Alternate address for host.
+ */
+#define ICMP_ALTERNATE_HOST	0
+
+/*@}*/
+
+/** @name ICMP_ROUTER_ADV codes definitions
+ */
+/*@{*/
+
+/** Normal router advertisement.
+ */
+#define ICMP_ROUTER_NORMAL	0
+
+/** Does not route common traffic.
+ */
+#define ICMP_ROUTER_NO_NORMAL_TRAFFIC	16
+
+/*@}*/
+
+/** @name ICMP_TIME_EXCEEDED codes definitions
+ */
+/*@{*/
+
+/** Transit TTL exceeded.
+ */
+#define ICMP_EXC_TTL		0
+
+/** Reassembly TTL exceeded.
+ */
+#define ICMP_EXC_FRAGTIME	1
+
+/*@}*/
+
+/** @name ICMP_PARAMETERPROB codes definitions
+ */
+/*@{*/
+
+/** Pointer indicates the error.
+ */
+#define ICMP_PARAM_POINTER	0
+
+/** Missing required option.
+ */
+#define ICMP_PARAM_MISSING	1
+
+/** Bad length.
+ */
+#define ICMP_PARAM_LENGTH	2
+
+/*@}*/
+
+/** @name ICMP_PHOTURIS codes definitions
+ */
+/*@{*/
+
+/** Bad SPI.
+ */
+#define ICMP_PHOTURIS_BAD_SPI	0
+
+/** Authentication failed.
+ */
+#define ICMP_PHOTURIS_AUTHENTICATION	1
+
+/** Decompression failed.
+ */
+#define ICMP_PHOTURIS_DECOMPRESSION		2
+
+/** Decryption failed.
+ */
+#define ICMP_PHOTURIS_DECRYPTION	3
+
+/** Need authentication.
+ */
+#define ICMP_PHOTURIS_NEED_AUTHENTICATION	4
+
+/** Need authorization.
+ */
+#define ICMP_PHOTURIS_NEED_AUTHORIZATION	5
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/icmp_common.h
===================================================================
--- uspace/lib/socket/include/icmp_common.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/icmp_common.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,60 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP module common interface.
+ */
+
+#ifndef __NET_ICMP_COMMON_H__
+#define __NET_ICMP_COMMON_H__
+
+#include <ipc/services.h>
+
+#include <sys/time.h>
+
+/** Default timeout for incoming connections in microseconds.
+ */
+#define ICMP_CONNECT_TIMEOUT	(1 * 1000 * 1000)
+
+/** Connects to the ICMP module.
+ *  @param service The ICMP module service. Ignored parameter.
+ *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
+ *  @returns The ICMP module phone on success.
+ *  @returns The ICMP socket identifier if called by the bundle module.
+ *  @returns ETIMEOUT if the connection timeouted.
+ */
+extern int icmp_connect_module(services_t service, suseconds_t timeout);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/icmp_messages.h
===================================================================
--- uspace/lib/socket/include/icmp_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/icmp_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,132 @@
+/*
+ * 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 icmp
+ *  @{
+ */
+
+/** @file
+ *  ICMP module messages.
+ *  @see icmp_interface.h
+ */
+
+#ifndef __NET_ICMP_MESSAGES__
+#define __NET_ICMP_MESSAGES__
+
+#include <ipc/ipc.h>
+#include <sys/types.h>
+
+#include <icmp_codes.h>
+#include <net_messages.h>
+
+/** ICMP module messages.
+ */
+typedef enum{
+	/** Sends echo request.
+	 *  @see icmp_echo()
+	 */
+	NET_ICMP_ECHO = NET_ICMP_FIRST,
+	/** Sends destination unreachable error message.
+	 *  @see icmp_destination_unreachable_msg()
+	 */
+	NET_ICMP_DEST_UNREACH,
+	/** Sends source quench error message.
+	 *  @see icmp_source_quench_msg()
+	 */
+	NET_ICMP_SOURCE_QUENCH,
+	/** Sends time exceeded error message.
+	 *  @see icmp_time_exceeded_msg()
+	 */
+	NET_ICMP_TIME_EXCEEDED,
+	/** Sends parameter problem error message.
+	 *  @see icmp_parameter_problem_msg()
+	 */
+	NET_ICMP_PARAMETERPROB,
+	/** Initializes new connection.
+	 */
+	NET_ICMP_INIT
+} icmp_messages;
+
+/** @name ICMP specific message parameters definitions
+ */
+/*@{*/
+
+/** Returns the ICMP code message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_CODE(call) \
+	({icmp_code_t code = (icmp_code_t) IPC_GET_ARG1(*call); code;})
+
+/** Returns the ICMP link MTU message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_MTU(call) \
+	({icmp_param_t mtu = (icmp_param_t) IPC_GET_ARG3(*call); mtu;})
+
+/** Returns the pointer message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_POINTER(call) \
+	({icmp_param_t pointer = (icmp_param_t) IPC_GET_ARG3(*call); pointer;})
+
+/** Returns the size message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_SIZE(call) \
+	({size_t size = (size_t) IPC_GET_ARG1(call); size;})
+
+/** Returns the timeout message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_TIMEOUT(call) \
+	(({suseconds_t timeout = (suseconds_t) IPC_GET_ARG2(call); timeout;}))
+
+/** Returns the time to live message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_TTL(call) \
+	({ip_ttl_t ttl = (ip_ttl_t) IPC_GET_ARG3(call); ttl;})
+
+/** Returns the type of service message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_TOS(call) \
+	({ip_tos_t tos = (ip_tos_t) IPC_GET_ARG4(call); tos;})
+
+/** Returns the dont fragment message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define ICMP_GET_DONT_FRAGMENT(call) \
+	({int dont_fragment = (int) IPC_GET_ARG5(call); dont_fragment;})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/in.h
===================================================================
--- uspace/lib/socket/include/in.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/in.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,89 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  INET family common definitions.
+ */
+
+#ifndef __NET_IN_H__
+#define __NET_IN_H__
+
+#include <sys/types.h>
+
+#include <ip_protocols.h>
+#include <inet.h>
+
+/** INET string address maximum length.
+ */
+#define INET_ADDRSTRLEN		(4 * 3 + 3 + 1)
+
+/** Type definition of the INET address.
+ *  @see in_addr
+ */
+typedef struct in_addr		in_addr_t;
+
+/** Type definition of the INET socket address.
+ *  @see sockaddr_in
+ */
+typedef struct sockaddr_in	sockaddr_in_t;
+
+/** INET address.
+ */
+struct in_addr{
+	/** 4 byte IP address.
+	 */
+	uint32_t s_addr;
+};
+
+/** INET socket address.
+ *  @see sockaddr
+ */
+struct sockaddr_in{
+	/** Address family.
+	 *  Should be AF_INET.
+	 */
+	uint16_t sin_family;
+	/** Port number.
+	 */
+	uint16_t sin_port;
+	/** Internet address.
+	 */
+	struct in_addr sin_addr;
+	/** Padding to meet the sockaddr size.
+	 */
+	uint8_t sin_zero[8];
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/in6.h
===================================================================
--- uspace/lib/socket/include/in6.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/in6.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,92 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  INET6 family common definitions.
+ */
+
+#ifndef __NET_IN6_H__
+#define __NET_IN6_H__
+
+#include <sys/types.h>
+
+#include <ip_protocols.h>
+#include <inet.h>
+
+/** INET6 string address maximum length.
+ */
+#define INET6_ADDRSTRLEN	(8 * 4 + 7 + 1)
+
+/** Type definition of the INET6 address.
+ *  @see in6_addr
+ */
+typedef struct in6_addr	in6_addr_t;
+
+/** Type definition of the INET6 socket address.
+ *  @see sockaddr_in6
+ */
+typedef struct sockaddr_in6	sockaddr_in6_t;
+
+/** INET6 address.
+ */
+struct in6_addr{
+	/** 16 byte IPv6 address.
+	 */
+	unsigned char s6_addr[16];
+};
+
+/** INET6 socket address.
+ *  @see sockaddr
+ */
+struct sockaddr_in6{
+	/** Address family.
+	 *  Should be AF_INET6.
+	 */
+	uint16_t sin6_family;
+	/** Port number.
+	 */
+	uint16_t sin6_port;
+	/** IPv6 flow information.
+	 */
+	uint32_t sin6_flowinfo;
+	/** IPv6 address.
+	 */
+	struct in6_addr sin6_addr;
+	/** Scope identifier.
+	 */
+	uint32_t sin6_scope_id;
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/inet.h
===================================================================
--- uspace/lib/socket/include/inet.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/inet.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,115 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Internet common definitions.
+ */
+
+#ifndef __NET_INET_H__
+#define __NET_INET_H__
+
+#include <sys/types.h>
+
+#include <net_byteorder.h>
+
+/** Type definition of the socket address.
+ *  @see sockaddr
+ */
+typedef struct sockaddr		sockaddr_t;
+
+/** Type definition of the address information.
+ *  @see addrinfo
+ */
+typedef struct addrinfo		addrinfo_t;
+
+/** Prints the address into the character buffer.
+ *  @param[in] family The address family.
+ *  @param[in] data The address data.
+ *  @param[out] address The character buffer to be filled.
+ *  @param[in] length The buffer length.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the data or address parameter is NULL.
+ *  @returns ENOMEM if the character buffer is not long enough.
+ *  @returns ENOTSUP if the address family is not supported.
+ */
+extern int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length);
+
+/** Parses the character string into the address.
+ *  If the string is shorter than the full address, zero bytes are added.
+ *  @param[in] family The address family.
+ *  @param[in] address The character buffer to be parsed.
+ *  @param[out] data The address data to be filled.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the data parameter is NULL.
+ *  @returns ENOENT if the address parameter is NULL.
+ *  @returns ENOTSUP if the address family is not supported.
+ */
+extern int inet_pton(uint16_t family, const char * address, uint8_t * data);
+
+/** Socket address.
+ */
+struct sockaddr{
+	/** Address family.
+	 *  @see socket.h
+	 */
+	uint16_t sa_family;
+	/** 14 byte protocol address.
+	 */
+	uint8_t sa_data[14];
+};
+
+// TODO define address information
+// /** Address information.
+// * \todo
+// */
+//struct addrinfo{
+//	int				ai_flags;		// AI_PASSIVE, AI_CANONNAME, etc.
+//	uint16_t		ai_family;		// AF_INET, AF_INET6, AF_UNSPEC
+//	int				ai_socktype;	// SOCK_STREAM, SOCK_DGRAM
+//	int				ai_protocol;	// use 0 for "any"
+//	size_t			ai_addrlen;		// size of ai_addr in bytes
+//	struct sockaddr *	ai_addr;	// struct sockaddr_in or _in6
+//	char *			ai_canonname;	// full canonical hostname
+//	struct addrinfo *	ai_next;	// linked list, next node
+//};
+
+/*int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
+const char *service, // e.g. "http" or port number
+const struct addrinfo *hints,
+struct addrinfo **res);
+getnameinfo
+*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/ip_codes.h
===================================================================
--- uspace/lib/socket/include/ip_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/ip_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,374 @@
+/*
+ * 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 ip
+ *  @{
+ */
+
+/** @file
+ *  IP codes and definitions.
+ */
+
+#ifndef __NET_IP_CODES_H__
+#define __NET_IP_CODES_H__
+
+#include <sys/types.h>
+
+/** IP time to live counter type definition.
+ */
+typedef uint8_t	ip_ttl_t;
+
+/** IP type of service type definition.
+ */
+typedef uint8_t	ip_tos_t;
+
+/** IP transport protocol type definition.
+ */
+typedef uint8_t	ip_protocol_t;
+
+/** Default IPVERSION.
+ */
+#define IPVERSION	4
+
+/** Maximum time to live counter.
+ */
+#define MAXTTL		255
+
+/** Default time to live counter.
+ */
+#define IPDEFTTL	64
+
+/** @name IP type of service definitions
+ */
+/*@{*/
+
+/** IP TOS mask.
+ */
+#define IPTOS_TOS_MASK				0x1E
+
+/** Precedence shift.
+ */
+#define IPTOS_PRECEDENCE_SHIFT		5
+
+/** Delay shift.
+ */
+#define IPTOS_DELAY_SHIFT			4
+
+/** Throughput shift.
+ */
+#define IPTOS_THROUGHPUT_SHIFT		3
+
+/** Reliability shift.
+ */
+#define IPTOS_RELIABILITY_SHIFT		2
+
+/** Cost shift.
+ */
+#define IPTOS_COST_SHIFT			1
+
+/** Normal delay.
+ */
+#define IPTOS_NORMALDELAY			(0x0 << IPTOS_DELAY_SHIFT)
+
+/** Low delay.
+ */
+#define IPTOS_LOWDELAY				(0x1 << IPTOS_DELAY_SHIFT)
+
+/** Normal throughput.
+ */
+#define IPTOS_NORMALTHROUGHPUT		(0x0 << IPTOS_THROUGHPUT_SHIFT)
+
+/** Throughput.
+ */
+#define IPTOS_THROUGHPUT			(0x1 << IPTOS_THROUGHPUT_SHIFT)
+
+/** Normal reliability.
+ */
+#define IPTOS_NORMALRELIABILITY		(0x0 << IPTOS_RELIABILITY_SHIFT)
+
+/** Reliability.
+ */
+#define IPTOS_RELIABILITY			(0x1 << IPTOS_RELIABILITY_SHIFT)
+
+/** Normal cost.
+ */
+#define IPTOS_NORMALCOST			(0x0 << IPTOS_COST_SHIFT)
+
+/** Minimum cost.
+ */
+#define IPTOS_MICNCOST				(0x1 << IPTOS_COST_SHIFT)
+
+/*@}*/
+
+/** @name IP TOS precedence definitions
+ */
+/*@{*/
+
+
+/** Precedence mask.
+ */
+#define IPTOS_PREC_MASK				0xE0
+
+/** Routine precedence.
+ */
+#define IPTOS_PREC_ROUTINE			(0x0 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Priority precedence.
+ */
+#define IPTOS_PREC_PRIORITY			(0x1 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Immediate precedence.
+ */
+#define IPTOS_PREC_IMMEDIATE		(0x2 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Flash precedence.
+ */
+#define IPTOS_PREC_FLASH			(0x3 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Flash override precedence.
+ */
+#define IPTOS_PREC_FLASHOVERRIDE	(0x4 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Critical precedence.
+ */
+#define IPTOS_PREC_CRITIC_ECP		(0x5 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Inter-network control precedence.
+ */
+#define IPTOS_PREC_INTERNETCONTROL	(0x6 << IPTOS_PRECEDENCE_SHIFT)
+
+/** Network control precedence.
+ */
+#define IPTOS_PREC_NETCONTROL		(0x7 << IPTOS_PRECEDENCE_SHIFT)
+
+/*@}*/
+
+/** @name IP options definitions
+ */
+/*@{*/
+
+/** Copy shift.
+ */
+#define IPOPT_COPY_SHIFT			7
+
+/** Class shift.
+ */
+#define IPOPT_CLASS_SHIFT			5
+
+/** Number shift.
+ */
+#define IPOPT_NUMBER_SHIFT			0
+
+/** Class mask.
+ */
+#define IPOPT_CLASS_MASK			0x60
+
+/** Number mask.
+ */
+#define IPOPT_NUMBER_MASK			0x1F
+
+/** Copy flag.
+ */
+#define IPOPT_COPY					(1 << IPOPT_COPY_SHIFT)
+
+/** Returns IP option type.
+ *  @param[in] copy The value indication whether the IP option should be copied.
+ *  @param[in] class The IP option class.
+ *  @param[in] number The IP option number.
+ */
+#define IPOPT_TYPE(copy, class, number)	(((copy) &IPOPT_COPY) | ((class) &IPOPT_CLASS_MASK) | ((number << IPOPT_NUMBER_SHIFT) &IPOPT_NUMBER_MASK))
+
+/** Returns a value indicating whether the IP option should be copied.
+ *  @param[in] o The IP option.
+ */
+#define	IPOPT_COPIED(o)			((o) &IPOPT_COPY)
+
+/** Returns an IP option class.
+ *  @param[in] o The IP option.
+ */
+#define	IPOPT_CLASS(o)			((o) &IPOPT_CLASS_MASK)
+
+/** Returns an IP option number.
+ *  @param[in] o The IP option.
+ */
+#define	IPOPT_NUMBER(o)			((o) &IPOPT_NUMBER_MASK)
+
+/*@}*/
+
+/** @name IP option class definitions
+ */
+/*@{*/
+
+/** Control class.
+ */
+#define	IPOPT_CONTROL				(0 << IPOPT_CLASS_SHIFT)
+
+/** Reserved class 1.
+ */
+#define	IPOPT_RESERVED1				(1 << IPOPT_CLASS_SHIFT)
+
+/** Measurement class.
+ */
+#define	IPOPT_MEASUREMENT			(2 << IPOPT_CLASS_SHIFT)
+
+/** Reserved class 2.
+ */
+#define	IPOPT_RESERVED2				(3 << IPOPT_CLASS_SHIFT)
+
+/*@}*/
+
+/** @name IP option type definitions
+ */
+/*@{*/
+
+/** End of list.
+ */
+//#define IPOPT_END_OF_LIST			0x0
+#define IPOPT_END					IPOPT_TYPE(0, IPOPT_CONTROL, 0)
+
+/** No operation.
+ */
+//#define IPOPT_NO_OPERATION		0x1
+#define IPOPT_NOOP					IPOPT_TYPE(0, IPOPT_CONTROL, 1)
+
+/** Security.
+ */
+//#define IPOPT_SECURITY			0x82
+#define IPOPT_SEC					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 2)
+
+/** Loose source.
+ */
+//#define IPOPT_LOOSE_SOURCE		0x83
+#define IPOPT_LSRR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 3)
+
+/** Strict route.
+ */
+//#define IPOPT_STRICT_SOURCE		0x89
+#define IPOPT_SSRR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 9)
+
+/** Record route.
+ */
+//#define IPOPT_RECORD_ROUTE		0x07
+#define IPOPT_RR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 7)
+
+/** Stream identifier.
+ */
+//#define IPOPT_STREAM_IDENTIFIER	0x88
+#define IPOPT_SID					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 8)
+
+/** Stream identifier length.
+ */
+#define IPOPT_SID_LENGTH			4
+
+/** Internet timestamp.
+ */
+//#define IPOPT_INTERNET_TIMESTAMP	0x44
+#define IPOPT_TIMESTAMP				IPOPT_TYPE(IPOPT_COPY, IPOPT_MEASUREMENT, 4)
+
+/** Commercial IP security option.
+ */
+#define IPOPT_CIPSO					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 5)
+
+/** No operation variant.
+ */
+#define IPOPT_NOP IPOPT_NOOP
+
+/** End of list variant.
+ */
+#define IPOPT_EOL IPOPT_END
+
+/** Timestamp variant.
+ */
+#define IPOPT_TS  IPOPT_TIMESTAMP
+
+/*@}*/
+
+/** @name IP security option definitions
+ */
+/*@{*/
+
+/** Security length.
+ */
+#define IPOPT_SEC_LENGTH			11
+
+/** Unclasified.
+ */
+#define IPOPT_SEC_UNCLASIFIED		0x0
+
+/** Confidential.
+ */
+#define IPOPT_SEC_CONFIDENTIAL		0xF035
+
+/** EFTO.
+ */
+#define IPOPT_SEC_EFTO				0x789A
+
+/** MMMM.
+ */
+#define IPOPT_SEC_MMMM				0xBC4D
+
+/** PROG.
+ */
+#define IPOPT_SEC_PROG				0x5E26
+
+/** Restricted.
+ */
+#define IPOPT_SEC_RESTRICTED		0xAF13
+
+/** Secret.
+ */
+#define IPOPT_SEC_SECRET			0xD788
+
+/** Top secret.
+ */
+#define IPOPT_SEC_TOP_SECRET		0x6BC5
+
+/*@}*/
+
+/** @name IP timestamp option definitions
+ */
+/*@{*/
+
+/** Tiemstamp only.
+ */
+#define	IPOPT_TS_TSONLY		0
+
+/** Timestamps and addresses.
+ */
+#define	IPOPT_TS_TSANDADDR	1
+
+/** Specified modules only.
+ */
+#define	IPOPT_TS_PRESPEC	3
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/ip_protocols.h
===================================================================
--- uspace/lib/socket/include/ip_protocols.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/ip_protocols.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,619 @@
+/*
+ * 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 ip
+ *  @{
+ */
+
+/** @file
+ *  Internet protocol numbers according to the on-line IANA - Assigned Protocol numbers - <http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml>, cited January 14 2009.
+ */
+
+#ifndef __NET_IPPROTOCOLS_H__
+#define __NET_IPPROTOCOLS_H__
+
+/** @name IP protocols definitions
+ */
+/*@{*/
+
+/** IPv6 Hop-by-Hop Option internet protocol number.
+ */
+#define IPPROTO_HOPOPT		0
+
+/** Internet Control Message internet protocol number.
+ */
+#define IPPROTO_ICMP		1
+
+/** Internet Group Management internet protocol number.
+ */
+#define IPPROTO_IGMP		2
+
+/** Gateway-to-Gateway internet protocol number.
+ */
+#define IPPROTO_GGP		3
+
+/** IP in IP (encapsulation) internet protocol number.
+ */
+#define IPPROTO_IP		4
+
+/** Stream internet protocol number.
+ */
+#define IPPROTO_ST		5
+
+/** Transmission Control internet protocol number.
+ */
+#define IPPROTO_TCP		6
+
+/** CBT internet protocol number.
+ */
+#define IPPROTO_CBT		7
+
+/** Exterior Gateway Protocol internet protocol number.
+ */
+#define IPPROTO_EGP		8
+
+/** any private interior gateway             
+(used by Cisco for their IGRP) internet protocol number.
+ */
+#define IPPROTO_IGP		9
+
+/** BBN RCC Monitoring internet protocol number.
+ */
+#define IPPROTO_BBN_RCC_MON		10
+
+/** Network Voice Protocol internet protocol number.
+ */
+#define IPPROTO_NVP_II		11
+
+/** PUP internet protocol number.
+ */
+#define IPPROTO_PUP		12
+
+/** ARGUS internet protocol number.
+ */
+#define IPPROTO_ARGUS		13
+
+/** EMCON internet protocol number.
+ */
+#define IPPROTO_EMCON		14
+
+/** Cross Net Debugger internet protocol number.
+ */
+#define IPPROTO_XNET		15
+
+/** Chaos internet protocol number.
+ */
+#define IPPROTO_CHAOS		16
+
+/** User Datagram internet protocol number.
+ */
+#define IPPROTO_UDP		17
+
+/** Multiplexing internet protocol number.
+ */
+#define IPPROTO_MUX		18
+
+/** DCN Measurement Subsystems internet protocol number.
+ */
+#define IPPROTO_DCN_MEAS		19
+
+/** Host Monitoring internet protocol number.
+ */
+#define IPPROTO_HMP		20
+
+/** Packet Radio Measurement internet protocol number.
+ */
+#define IPPROTO_PRM		21
+
+/** XEROX NS IDP internet protocol number.
+ */
+#define IPPROTO_XNS_IDP		22
+
+/** Trunk-1 internet protocol number.
+ */
+#define IPPROTO_TRUNK_1		23
+
+/** Trunk-2 internet protocol number.
+ */
+#define IPPROTO_TRUNK_2		24
+
+/** Leaf-1 internet protocol number.
+ */
+#define IPPROTO_LEAF_1		25
+
+/** Leaf-2 internet protocol number.
+ */
+#define IPPROTO_LEAF_2		26
+
+/** Reliable Data Protocol internet protocol number.
+ */
+#define IPPROTO_RDP		27
+
+/** Internet Reliable Transaction internet protocol number.
+ */
+#define IPPROTO_IRTP		28
+
+/** ISO Transport Protocol Class 4 internet protocol number.
+ */
+#define IPPROTO_ISO_TP4		29
+
+/** Bulk Data Transfer Protocol internet protocol number.
+ */
+#define IPPROTO_NETBLT		30
+
+/** MFE Network Services Protocol internet protocol number.
+ */
+#define IPPROTO_MFE_NSP		31
+
+/** MERIT Internodal Protocol internet protocol number.
+ */
+#define IPPROTO_MERIT_INP		32
+
+/** Datagram Congestion Control Protocol internet protocol number.
+ */
+#define IPPROTO_DCCP		33
+
+/** Third Party Connect Protocol internet protocol number.
+ */
+#define IPPROTO_3PC		34
+
+/** Inter-Domain Policy Routing Protocol internet protocol number.
+ */
+#define IPPROTO_IDPR		35
+
+/** XTP internet protocol number.
+ */
+#define IPPROTO_XTP		36
+
+/** Datagram Delivery Protocol internet protocol number.
+ */
+#define IPPROTO_DDP		37
+
+/** IDPR Control Message Transport Proto internet protocol number.
+ */
+#define IPPROTO_IDPR_CMTP		38
+
+/** TP++ Transport Protocol internet protocol number.
+ */
+#define IPPROTO_TP		39
+
+/** IL Transport Protocol internet protocol number.
+ */
+#define IPPROTO_IL		40
+
+/** Ipv6 internet protocol number.
+ */
+#define IPPROTO_IPV6		41
+
+/** Source Demand Routing Protocol internet protocol number.
+ */
+#define IPPROTO_SDRP		42
+
+/** Routing Header for IPv6 internet protocol number.
+ */
+#define IPPROTO_IPv6_Route		43
+
+/** Fragment Header for IPv6 internet protocol number.
+ */
+#define IPPROTO_IPv6_Frag		44
+
+/** Inter-Domain Routing Protocol internet protocol number.
+ */
+#define IPPROTO_IDRP		45
+
+/** Reservation Protocol internet protocol number.
+ */
+#define IPPROTO_RSVP		46
+
+/** General Routing Encapsulation internet protocol number.
+ */
+#define IPPROTO_GRE		47
+
+/** Dynamic Source Routing Protocol internet protocol number.
+ */
+#define IPPROTO_DSR		48
+
+/** BNA internet protocol number.
+ */
+#define IPPROTO_BNA		49
+
+/** Encap Security Payload internet protocol number.
+ */
+#define IPPROTO_ESP		50
+
+/** Authentication Header internet protocol number.
+ */
+#define IPPROTO_AH		51
+
+/** Integrated Net Layer Security  TUBA internet protocol number.
+ */
+#define IPPROTO_I_NLSP		52
+
+/** IP with Encryption internet protocol number.
+ */
+#define IPPROTO_SWIPE		53
+
+/** NBMA Address Resolution Protocol internet protocol number.
+ */
+#define IPPROTO_NARP		54
+
+/** IP Mobility internet protocol number.
+ */
+#define IPPROTO_MOBILE		55
+
+/** Transport Layer Security Protocol        
+using Kryptonet key management internet protocol number.
+ */
+#define IPPROTO_TLSP		56
+
+/** SKIP internet protocol number.
+ */
+#define IPPROTO_SKIP		57
+
+/** ICMP for IPv6 internet protocol number.
+ */
+#define IPPROTO_IPv6_ICMP		58
+
+/** No Next Header for IPv6 internet protocol number.
+ */
+#define IPPROTO_IPv6_NoNxt		59
+
+/** Destination Options for IPv6 internet protocol number.
+ */
+#define IPPROTO_IPv6_Opts		60
+
+/** Any host internal protocol internet protocol number.
+ */
+#define IPPROTO_AHIP		61
+
+/** CFTP internet protocol number.
+ */
+#define IPPROTO_CFTP		62
+
+/** Any local network internet protocol number.
+ */
+#define IPPROTO_ALN		63
+
+/** SATNET and Backroom EXPAK internet protocol number.
+ */
+#define IPPROTO_SAT_EXPAK		64
+
+/** Kryptolan internet protocol number.
+ */
+#define IPPROTO_KRYPTOLAN		65
+
+/** MIT Remote Virtual Disk Protocol internet protocol number.
+ */
+#define IPPROTO_RVD		66
+
+/** Internet Pluribus Packet Core internet protocol number.
+ */
+#define IPPROTO_IPPC		67
+
+/** Any distributed file system internet protocol number.
+ */
+#define IPPROTO_ADFS		68
+
+/** SATNET Monitoring internet protocol number.
+ */
+#define IPPROTO_SAT_MON		69
+
+/** VISA Protocol internet protocol number.
+ */
+#define IPPROTO_VISA		70
+
+/** Internet Packet Core Utility internet protocol number.
+ */
+#define IPPROTO_IPCV		71
+
+/** Computer Protocol Network Executive internet protocol number.
+ */
+#define IPPROTO_CPNX		72
+
+/** Computer Protocol Heart Beat internet protocol number.
+ */
+#define IPPROTO_CPHB		73
+
+/** Wang Span Network internet protocol number.
+ */
+#define IPPROTO_WSN		74
+
+/** Packet Video Protocol internet protocol number.
+ */
+#define IPPROTO_PVP		75
+
+/** Backroom SATNET Monitoring internet protocol number.
+ */
+#define IPPROTO_BR_SAT_MON		76
+
+/** SUN ND IPPROTOCOL_Temporary internet protocol number.
+ */
+#define IPPROTO_SUN_ND		77
+
+/** WIDEBAND Monitoring internet protocol number.
+ */
+#define IPPROTO_WB_MON		78
+
+/** WIDEBAND EXPAK internet protocol number.
+ */
+#define IPPROTO_WB_EXPAK		79
+
+/** ISO Internet Protocol internet protocol number.
+ */
+#define IPPROTO_ISO_IP		80
+
+/** VMTP internet protocol number.
+ */
+#define IPPROTO_VMTP		81
+
+/** SECURE-VMTP internet protocol number.
+ */
+#define IPPROTO_SECURE_VMTP		82
+
+/** VINES internet protocol number.
+ */
+#define IPPROTO_VINES		83
+
+/** TTP internet protocol number.
+ */
+#define IPPROTO_TTP		84
+
+/** NSFNET-IGP internet protocol number.
+ */
+#define IPPROTO_NSFNET_IGP		85
+
+/** Dissimilar Gateway Protocol internet protocol number.
+ */
+#define IPPROTO_DGP		86
+
+/** TCF internet protocol number.
+ */
+#define IPPROTO_TCF		87
+
+/** EIGRP internet protocol number.
+ */
+#define IPPROTO_EIGRP		88
+
+/** OSPFIGP internet protocol number.
+ */
+#define IPPROTO_OSPFIGP		89
+
+/** Sprite RPC Protocol internet protocol number.
+ */
+#define IPPROTO_Sprite_RPC		90
+
+/** Locus Address Resolution Protocol internet protocol number.
+ */
+#define IPPROTO_LARP		91
+
+/** Multicast Transport Protocol internet protocol number.
+ */
+#define IPPROTO_MTP		92
+
+/** AX.25 Frames internet protocol number.
+ */
+#define IPPROTO_AX25		93
+
+/** IP-within-IP Encapsulation Protocol internet protocol number.
+ */
+#define IPPROTO_IPIP		94
+
+/** Mobile Internetworking Control Pro. internet protocol number.
+ */
+#define IPPROTO_MICP		95
+
+/** Semaphore Communications Sec. Pro. internet protocol number.
+ */
+#define IPPROTO_SCC_SP		96
+
+/** Ethernet-within-IP Encapsulation internet protocol number.
+ */
+#define IPPROTO_ETHERIP		97
+
+/** Encapsulation Header internet protocol number.
+ */
+#define IPPROTO_ENCAP		98
+
+/** Any private encryption scheme internet protocol number.
+ */
+#define IPPROTO_APES		99
+
+/** GMTP internet protocol number.
+ */
+#define IPPROTO_GMTP		100
+
+/** Ipsilon Flow Management Protocol internet protocol number.
+ */
+#define IPPROTO_IFMP		101
+
+/** PNNI over IP internet protocol number.
+ */
+#define IPPROTO_PNNI		102
+
+/** Protocol Independent Multicast internet protocol number.
+ */
+#define IPPROTO_PIM		103
+
+/** ARIS internet protocol number.
+ */
+#define IPPROTO_ARIS		104
+
+/** SCPS internet protocol number.
+ */
+#define IPPROTO_SCPS		105
+
+/** QNX internet protocol number.
+ */
+#define IPPROTO_QNX		106
+
+/** Active Networks internet protocol number.
+ */
+#define IPPROTO_AN		107
+
+/** IP Payload Compression Protocol internet protocol number.
+ */
+#define IPPROTO_IPComp		108
+
+/** Sitara Networks Protocol internet protocol number.
+ */
+#define IPPROTO_SNP		109
+
+/** Compaq Peer Protocol internet protocol number.
+ */
+#define IPPROTO_Compaq_Peer		110
+
+/** IPX in IP internet protocol number.
+ */
+#define IPPROTO_IPX_in_IP		111
+
+/** Virtual Router Redundancy Protocol internet protocol number.
+ */
+#define IPPROTO_VRRP		112
+
+/** PGM Reliable Transport Protocol internet protocol number.
+ */
+#define IPPROTO_PGM		113
+
+/** Any 0-hop protocol internet protocol number.
+ */
+#define IPPROTO_A0HP		114
+
+/** Layer Two Tunneling Protocol internet protocol number.
+ */
+#define IPPROTO_L2TP		115
+
+/** D-II Data Exchange (DDX) internet protocol number.
+ */
+#define IPPROTO_DDX		116
+
+/** Interactive Agent Transfer Protocol internet protocol number.
+ */
+#define IPPROTO_IATP		117
+
+/** Schedule Transfer Protocol internet protocol number.
+ */
+#define IPPROTO_STP		118
+
+/** SpectraLink Radio Protocol internet protocol number.
+ */
+#define IPPROTO_SRP		119
+
+/** UTI internet protocol number.
+ */
+#define IPPROTO_UTI		120
+
+/** Simple Message Protocol internet protocol number.
+ */
+#define IPPROTO_SMP		121
+
+/** SM internet protocol number.
+ */
+#define IPPROTO_SM		122
+
+/** Performance Transparency Protocol internet protocol number.
+ */
+#define IPPROTO_PTP		123
+
+/** ISIS over IPv4 internet protocol number.
+ */
+#define IPPROTO_ISIS		124
+
+/** FIRE internet protocol number.
+ */
+#define IPPROTO_FIRE		125
+
+/** Combat Radio Transport Protocol internet protocol number.
+ */
+#define IPPROTO_CRTP		126
+
+/** Combat Radio User Datagram internet protocol number.
+ */
+#define IPPROTO_CRUDP		127
+
+/** SSCOPMCE internet protocol number.
+ */
+#define IPPROTO_SSCOPMCE		128
+
+/** IPLT internet protocol number.
+ */
+#define IPPROTO_IPLT		129
+
+/** Secure Packet Shield internet protocol number.
+ */
+#define IPPROTO_SPS		130
+
+/** Private IP Encapsulation within IP internet protocol number.
+ */
+#define IPPROTO_PIPE		131
+
+/** Stream Control Transmission Protocol internet protocol number.
+ */
+#define IPPROTO_SCTP		132
+
+/** Fibre Channel internet protocol number.
+ */
+#define IPPROTO_FC		133
+
+/** RSVP-E2E-IGNORE internet protocol number.
+ */
+#define IPPROTO_RSVP_E2E_IGNORE		134
+
+/** Mobility Header internet protocol number.
+ */
+#define IPPROTO_MH		135
+
+/** UDPLite internet protocol number.
+ */
+#define IPPROTO_UDPLITE		136
+
+/** MPLS-in-IP internet protocol number.
+ */
+#define IPPROTO_MPLS_in_IP		137
+
+/** MANET Protocols internet protocol number.
+ */
+#define IPPROTO_manet		138
+
+/** Host Identity Protocol internet protocol number.
+ */
+#define IPPROTO_HIP		139
+
+/** Raw internet protocol number.
+ */
+#define IPPROTO_RAW		255
+
+/** Maximum internet protocol number.
+ */
+#define IPPROTO_MAX		(IPPROTO_RAW + 1)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/net_byteorder.h
===================================================================
--- uspace/lib/socket/include/net_byteorder.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/net_byteorder.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,71 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Host - network byte order manipulation functions.
+ */
+
+#ifndef __NET_BYTEORDER_H__
+#define __NET_BYTEORDER_H__
+
+#include <byteorder.h>
+#include <sys/types.h>
+
+
+/** Converts the given short number (16 bit) from the host byte order to the network byte order (big endian).
+ *  @param[in] number The number in the host byte order to be converted.
+ *  @returns The number in the network byte order.
+ */
+#define htons(number)		host2uint16_t_be(number)
+
+/** Converts the given long number (32 bit) from the host byte order to the network byte order (big endian).
+ *  @param[in] number The number in the host byte order to be converted.
+ *  @returns The number in the network byte order.
+ */
+#define htonl(number)		host2uint32_t_be(number)
+
+/** Converts the given short number (16 bit) from the network byte order (big endian) to the host byte order.
+ *  @param[in] number The number in the network byte order to be converted.
+ *  @returns The number in the host byte order.
+ */
+#define ntohs(number) 	uint16_t_be2host(number)
+
+/** Converts the given long number (32 bit) from the network byte order (big endian) to the host byte order.
+ *  @param[in] number The number in the network byte order to be converted.
+ *  @returns The number in the host byte order.
+ */
+#define ntohl(number)		uint32_t_be2host(number)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/net_device.h
===================================================================
--- uspace/lib/socket/include/net_device.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/net_device.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,173 @@
+/*
+ * 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 netif
+ *  @{
+ */
+
+/** @file
+ *  Device identifier, state and usage statistics.
+ */
+
+#ifndef __NET_DEVICE_ID_TYPE_H__
+#define __NET_DEVICE_ID_TYPE_H__
+
+#include <adt/int_map.h>
+
+/** Device identifier to generic type map declaration.
+ */
+#define DEVICE_MAP_DECLARE		INT_MAP_DECLARE
+
+/** Device identifier to generic type map implementation.
+ */
+#define DEVICE_MAP_IMPLEMENT	INT_MAP_IMPLEMENT
+
+/** Invalid device identifier.
+ */
+#define DEVICE_INVALID_ID		(-1)
+
+/** Device identifier type.
+ */
+typedef int	device_id_t;
+
+/** Device state type.
+ */
+typedef enum device_state	device_state_t;
+
+/** Type definition of the device usage statistics.
+ *  @see device_stats
+ */
+typedef struct device_stats	device_stats_t;
+
+/** Type definition of the device usage statistics pointer.
+ *  @see device_stats
+ */
+typedef device_stats_t *	device_stats_ref;
+
+/** Device state.
+ */
+enum	device_state{
+	/** Device not present or not initialized.
+	 */
+	NETIF_NULL = 0,
+	/** Device present and stopped.
+	 */
+	NETIF_STOPPED,
+	/** Device present and active.
+	 */
+	NETIF_ACTIVE,
+	/** Device present but unable to transmit.
+	 */
+	NETIF_CARRIER_LOST
+};
+
+/** Device usage statistics.
+ */
+struct	device_stats{
+	/** Total packets received.
+	 */
+	unsigned long receive_packets;
+	/** Total packets transmitted.
+	 */
+	unsigned long send_packets;
+	/** Total bytes received.
+	 */
+	unsigned long receive_bytes;
+	/** Total bytes transmitted.
+	 */
+	unsigned long send_bytes;
+	/** Bad packets received counter.
+	 */
+	unsigned long receive_errors;
+	/** Packet transmition problems counter.
+	 */
+	unsigned long send_errors;
+	/** No space in buffers counter.
+	 */
+	unsigned long receive_dropped;
+	/** No space available counter.
+	 */
+	unsigned long send_dropped;
+	/** Total multicast packets received.
+	 */
+	unsigned long multicast;
+	/** The number of collisions due to congestion on the medium.
+	 */
+	unsigned long collisions;
+
+	/* detailed receive_errors: */
+	/** Received packet length error counter.
+	 */
+	unsigned long receive_length_errors;
+	/** Receiver buffer overflow counter.
+	 */
+	unsigned long receive_over_errors;
+	/** Received packet with crc error counter.
+	 */
+	unsigned long receive_crc_errors;
+	/** Received frame alignment error counter.
+	 */
+	unsigned long receive_frame_errors;
+	/** Receiver fifo overrun counter.
+	 */
+	unsigned long receive_fifo_errors;
+	/** Receiver missed packet counter.
+	 */
+	unsigned long receive_missed_errors;
+
+	/* detailed send_errors */
+	/** Transmitter aborted counter.
+	 */
+	unsigned long send_aborted_errors;
+	/** Transmitter carrier errors counter.
+	 */
+	unsigned long send_carrier_errors;
+	/** Transmitter fifo overrun counter.
+	 */
+	unsigned long send_fifo_errors;
+	/** Transmitter carrier errors counter.
+	 */
+	unsigned long send_heartbeat_errors;
+	/** Transmitter window errors counter.
+	 */
+	unsigned long send_window_errors;
+
+	/* for cslip etc */
+	/** Total compressed packets received.
+	 */
+	unsigned long receive_compressed;
+	/** Total compressed packet transmitted.
+	 */
+	unsigned long send_compressed;
+};
+
+#endif
+
+/** @}
+ */
+
Index: uspace/lib/socket/include/net_err.h
===================================================================
--- uspace/lib/socket/include/net_err.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/net_err.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,83 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Common error processing codes and routines.
+ */
+
+#ifndef __NET_ERR_H__
+#define __NET_ERR_H__
+
+#include <errno.h>
+
+#ifdef CONFIG_DEBUG
+
+#include <stdio.h>
+
+#endif
+
+/** An actual stored error code.
+ */
+#define ERROR_CODE					error_check_return_value
+
+/** An error processing routines declaration.
+ *  This has to be declared in the block where the error processing is desired.
+ */
+#define ERROR_DECLARE				int ERROR_CODE
+
+/** Stores the value as an error code and checks if an error occurred.
+ *  @param[in] value The value to be checked. May be a function call.
+ *  @returns FALSE if the value indicates success (EOK).
+ *  @returns TRUE otherwise.
+ */
+#ifdef CONFIG_DEBUG
+
+#define ERROR_OCCURRED(value)												\
+	(((ERROR_CODE = (value)) != EOK)										\
+	&& ({printf("error at %s:%d %d\n", __FILE__, __LINE__, ERROR_CODE); 1;}))
+
+#else
+
+#define ERROR_OCCURRED(value)		((ERROR_CODE = (value)) != EOK)
+
+#endif
+
+/** Checks if an error occurred and immediately exits the actual function returning the error code.
+ *  @param[in] value The value to be checked. May be a function call.
+ */
+
+#define ERROR_PROPAGATE(value)	if(ERROR_OCCURRED(value)) return ERROR_CODE
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/net_messages.h
===================================================================
--- uspace/lib/socket/include/net_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/net_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,633 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Networking common message definitions.
+ */
+
+#ifndef __NET_MESSAGES_H__
+#define __NET_MESSAGES_H__
+
+#include <async.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <net_device.h>
+#include <adt/measured_strings.h>
+#include <packet/packet.h>
+
+/** Returns a value indicating whether the value is in the interval.
+ *  @param[in] item The value to be checked.
+ *  @param[in] first_inclusive The first value in the interval inclusive.
+ *  @param[in] last_exclusive The first value after the interval.
+ */
+#define IS_IN_INTERVAL(item, first_inclusive, last_exclusive)	(((item) >= (first_inclusive)) && ((item) < (last_exclusive)))
+
+/** @name Networking message counts
+ */
+/*@{*/
+
+/** The number of ARP messages.
+ */
+#define NET_ARP_COUNT		5
+
+/** The number of Ethernet messages.
+ */
+#define NET_ETH_COUNT		0
+
+/** The number of ICMP messages.
+ */
+#define NET_ICMP_COUNT		6
+
+/** The number of inter-network messages.
+ */
+#define NET_IL_COUNT		6
+
+/** The number of IP messages.
+ */
+#define NET_IP_COUNT		4
+
+/** The number of general networking messages.
+ */
+#define NET_NET_COUNT		3
+
+/** The number of network interface driver messages.
+ */
+#define NET_NETIF_COUNT		6
+
+/** The number of network interface layer messages.
+ */
+#define NET_NIL_COUNT		7
+
+/** The number of packet management system messages.
+ */
+#define NET_PACKET_COUNT	5
+
+/** The number of socket messages.
+ */
+#define NET_SOCKET_COUNT	14
+
+/** The number of TCP messages.
+ */
+#define NET_TCP_COUNT		0
+
+/** The number of transport layer messages.
+ */
+#define NET_TL_COUNT		1
+
+/** The number of UDP messages.
+ */
+#define NET_UDP_COUNT		0
+
+/*@}*/
+
+/** @name Networking message intervals
+ */
+/*@{*/
+
+/** The first networking message.
+ */
+#define NET_FIRST			2000
+
+/** The first network interface layer message.
+ */
+#define NET_NETIF_FIRST		NET_FIRST
+
+/** The last network interface layer message.
+ */
+#define NET_NETIF_LAST		(NET_NETIF_FIRST + NET_NETIF_COUNT)
+
+/** The first general networking message.
+ */
+#define NET_NET_FIRST		(NET_NETIF_LAST + 0)
+
+/** The last general networking message.
+ */
+#define NET_NET_LAST		(NET_NET_FIRST + NET_NET_COUNT)
+
+/** The first network interface layer message.
+ */
+#define NET_NIL_FIRST		(NET_NET_LAST + 0)
+
+/** The last network interface layer message.
+ */
+#define NET_NIL_LAST		(NET_NIL_FIRST + NET_NIL_COUNT)
+
+/** The first Ethernet message.
+ */
+#define NET_ETH_FIRST		(NET_NIL_LAST + 0)
+
+/** The last Ethernet message.
+ */
+#define NET_ETH_LAST		(NET_ETH_FIRST + NET_ETH_COUNT)
+
+/** The first inter-network message.
+ */
+#define NET_IL_FIRST		(NET_ETH_LAST + 0)
+
+/** The last inter-network message.
+ */
+#define NET_IL_LAST			(NET_IL_FIRST + NET_IL_COUNT)
+
+/** The first IP message.
+ */
+#define NET_IP_FIRST		(NET_IL_LAST + 0)
+
+/** The last IP message.
+ */
+#define NET_IP_LAST			(NET_IP_FIRST + NET_IP_COUNT)
+
+/** The first ARP message.
+ */
+#define NET_ARP_FIRST		(NET_IP_LAST + 0)
+
+/** The last ARP message.
+ */
+#define NET_ARP_LAST		(NET_ARP_FIRST + NET_ARP_COUNT)
+
+/** The first ICMP message.
+ */
+#define NET_ICMP_FIRST		(NET_ARP_LAST + 0)
+
+/** The last ICMP message.
+ */
+#define NET_ICMP_LAST		(NET_ICMP_FIRST + NET_ICMP_COUNT)
+
+/** The first ICMP message.
+ */
+#define NET_TL_FIRST		(NET_ICMP_LAST + 0)
+
+/** The last ICMP message.
+ */
+#define NET_TL_LAST			(NET_TL_FIRST + NET_TL_COUNT)
+
+/** The first UDP message.
+ */
+#define NET_UDP_FIRST		(NET_TL_LAST + 0)
+
+/** The last UDP message.
+ */
+#define NET_UDP_LAST		(NET_UDP_FIRST + NET_UDP_COUNT)
+
+/** The first TCP message.
+ */
+#define NET_TCP_FIRST		(NET_UDP_LAST + 0)
+
+/** The last TCP message.
+ */
+#define NET_TCP_LAST		(NET_TCP_FIRST + NET_TCP_COUNT)
+
+/** The first socket message.
+ */
+#define NET_SOCKET_FIRST	(NET_TCP_LAST + 0)
+
+/** The last socket message.
+ */
+#define NET_SOCKET_LAST		(NET_SOCKET_FIRST + NET_SOCKET_COUNT)
+
+/** The first packet management system message.
+ */
+#define NET_PACKET_FIRST	(NET_SOCKET_LAST + 0)
+
+/** The last packet management system message.
+ */
+#define NET_PACKET_LAST		(NET_PACKET_FIRST + NET_PACKET_COUNT)
+
+/** The last networking message.
+ */
+#define NET_LAST			NET_PACKET_LAST
+
+/** The number of networking messages.
+ */
+#define NET_COUNT			(NET_LAST - NET_FIRST)
+
+/** Returns a value indicating whether the IPC call is a generic networking message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_FIRST, NET_LAST)
+
+/** Returns a value indicating whether the IPC call is an ARP message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ARP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ARP_FIRST, NET_ARP_LAST)
+
+/** Returns a value indicating whether the IPC call is an Ethernet message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ETH_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ETH_FIRST, NET_ETH_LAST)
+
+/** Returns a value indicating whether the IPC call is an ICMP message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ICMP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST)
+
+/** Returns a value indicating whether the IPC call is an inter-network layer message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_IL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IL_FIRST, NET_IL_LAST)
+
+/** Returns a value indicating whether the IPC call is an IP message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_IP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IP_FIRST, NET_IP_LAST)
+
+/** Returns a value indicating whether the IPC call is a generic networking message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_NET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NET_FIRST, NET_NET_LAST)
+
+/** Returns a value indicating whether the IPC call is a network interface layer message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_NIL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NIL_FIRST, NET_NIL_LAST)
+
+/** Returns a value indicating whether the IPC call is a packet manaagement system message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_PACKET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST)
+
+/** Returns a value indicating whether the IPC call is a socket message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_SOCKET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST)
+
+/** Returns a value indicating whether the IPC call is a TCP message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_TCP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TCP_FIRST, NET_TCP_LAST)
+
+/** Returns a value indicating whether the IPC call is a transport layer message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_TL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TL_FIRST, NET_TL_LAST)
+
+/** Returns a value indicating whether the IPC call is a UDP message.
+ *  @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_UDP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_UDP_FIRST, NET_UDP_LAST)
+
+/*@}*/
+
+/** @name Networking specific message arguments definitions
+ */
+/*@{*/
+
+/** @name First arguments
+ */
+/*@{*/
+
+/** Returns the device identifier message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_DEVICE(call) \
+	({device_id_t device_id = (device_id_t) IPC_GET_ARG1(*call); device_id;})
+
+/*@;})*/
+
+/** @name Second arguments
+ */
+/*@({*/
+
+/** Returns the packet identifier message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_PACKET(call) \
+	({packet_id_t packet_id = (packet_id_t) IPC_GET_ARG2(*call); packet_id;})
+
+/** Returns the count message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_COUNT(call) \
+	({size_t size = (size_t) IPC_GET_ARG2(*call); size;})
+
+/** Returns the device state message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_STATE(call) \
+	({device_state_t device_state = (device_state_t) IPC_GET_ARG2(*call); device_state;})
+
+/** Returns the maximum transmission unit message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_MTU(call) \
+	({size_t size = (size_t) IPC_GET_ARG2(*call); size;})
+
+/*@;})*/
+
+/** @name Third arguments
+ */
+/*@({*/
+
+/** Returns the device driver service message argument.
+ *  @param[in] call The message call structure.
+ */
+ #define IPC_GET_SERVICE(call) \
+	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
+
+/** Returns the target service message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_TARGET(call) \
+	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
+
+/** Returns the sender service message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_SENDER(call) \
+	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
+
+/*@;})*/
+
+/** @name Fourth arguments
+ */
+/*@({*/
+
+/** Returns the error service message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_ERROR(call) \
+	({services_t service = (services_t) IPC_GET_ARG4(*call); service;})
+
+/*@;})*/
+
+/** @name Fifth arguments
+ */
+/*@({*/
+
+/** Returns the phone message argument.
+ *  @param[in] call The message call structure.
+ */
+#define IPC_GET_PHONE(call) \
+	({int phone = (int) IPC_GET_ARG5(*call); phone;})
+
+/*@}*/
+
+/** @name First answers
+ */
+/*@{*/
+
+/** Sets the device identifier in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define IPC_SET_DEVICE(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(*answer, argument);}
+
+/** Sets the minimum address length in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define IPC_SET_ADDR(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(*answer, argument);}
+
+/*@}*/
+
+/** @name Second answers
+ */
+/*@{*/
+
+/** Sets the minimum prefix size in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define IPC_SET_PREFIX(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG2(*answer, argument);}
+
+/*@}*/
+
+/** @name Third answers
+ */
+/*@{*/
+
+/** Sets the maximum content size in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define IPC_SET_CONTENT(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(*answer, argument);}
+
+/*@}*/
+
+/** @name Fourth answers
+ */
+/*@{*/
+
+/** Sets the minimum suffix size in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define IPC_SET_SUFFIX(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG4(*answer, argument);}
+
+/*@}*/
+
+/*@}*/
+
+/** Notifies the module about the device state change.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[in] state The new device state.
+ *  @param[in] target The target module service.
+ *  @returns EOK on success.
+ */
+static inline int generic_device_state_msg(int phone, int message, device_id_t device_id, int state, services_t target){
+	async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) state, target);
+	return EOK;
+}
+
+/** Notifies a module about the device.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[in] arg2 The second argument of the message.
+ *  @param[in] service The device module service.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the specific service message.
+ */
+static inline int generic_device_req(int phone, int message, device_id_t device_id, int arg2, services_t service){
+	return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) arg2, (ipcarg_t) service);
+}
+
+/** Returns the address.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[out] address The desired address.
+ *  @param[out] data The address data container.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the address parameter and/or the data parameter is NULL.
+ *  @returns Other error codes as defined for the specific service message.
+ */
+static inline int generic_get_addr_req(int phone, int message, device_id_t device_id, measured_string_ref * address, char ** data){
+	aid_t message_id;
+	ipcarg_t result;
+	int string;
+
+	if(!(address && data)){
+		return EBADMEM;
+	}
+
+	// request the address
+	message_id = async_send_1(phone, (ipcarg_t) message, (ipcarg_t) device_id, NULL);
+	string = measured_strings_return(phone, address, data, 1);
+	async_wait_for(message_id, &result);
+
+	// if not successful
+	if((string == EOK) && (result != EOK)){
+		// clear the data
+		free(*address);
+		free(*data);
+	}
+	return (int) result;
+}
+
+/** Returns the device packet dimension for sending.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[out] packet_dimension The packet dimension.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the packet_dimension parameter is NULL.
+ *  @returns Other error codes as defined for the specific service message.
+ */
+static inline int generic_packet_size_req(int phone, int message, device_id_t device_id, packet_dimension_ref packet_dimension){
+	ipcarg_t result;
+	ipcarg_t prefix;
+	ipcarg_t content;
+	ipcarg_t suffix;
+	ipcarg_t addr_len;
+
+	if(! packet_dimension){
+		return EBADMEM;
+	}
+	result = async_req_1_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	packet_dimension->prefix = (size_t) prefix;
+	packet_dimension->content = (size_t) content;
+	packet_dimension->suffix = (size_t) suffix;
+	packet_dimension->addr_len = (size_t) addr_len;
+	return (int) result;
+}
+
+/** Passes the packet queue to the module.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[in] packet_id The received packet or the received packet queue identifier.
+ *  @param[in] target The target module service.
+ *  @param[in] error The error module service.
+ *  @returns EOK on success.
+ */
+static inline int generic_received_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target, services_t error){
+	if(error){
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);
+	}else{
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target);
+	}
+	return EOK;
+}
+
+/** Sends the packet queue.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[in] packet_id The packet or the packet queue identifier.
+ *  @param[in] sender The sending module service.
+ *  @param[in] error The error module service.
+ *  @returns EOK on success.
+ */
+static inline int generic_send_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender, services_t error){
+	if(error){
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);
+	}else{
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender);
+	}
+	return EOK;
+}
+
+/** Translates the given strings.
+ *  Allocates and returns the needed memory block as the data parameter.
+ *  @param[in] phone The service module phone.
+ *  @param[in] message The service specific message.
+ *  @param[in] device_id The device identifier.
+ *  @param[in] service The module service.
+ *  @param[in] configuration The key strings.
+ *  @param[in] count The number of configuration keys.
+ *  @param[out] translation The translated values.
+ *  @param[out] data The translation data container.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the configuration parameter is NULL.
+ *  @returns EINVAL if the count parameter is zero (0).
+ *  @returns EBADMEM if the translation or the data parameters are NULL.
+ *  @returns Other error codes as defined for the specific service message.
+ */
+static inline int generic_translate_req(int phone, int message, device_id_t device_id, services_t service, measured_string_ref configuration, size_t count, measured_string_ref * translation, char ** data){
+	aid_t message_id;
+	ipcarg_t result;
+	int string;
+
+	if(!(configuration && (count > 0))){
+		return EINVAL;
+	}
+	if(!(translation && data)){
+		return EBADMEM;
+	}
+
+	// request the translation
+	message_id = async_send_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) count, (ipcarg_t) service, NULL);
+	measured_strings_send(phone, configuration, count);
+	string = measured_strings_return(phone, translation, data, count);
+	async_wait_for(message_id, &result);
+
+	// if not successful
+	if((string == EOK) && (result != EOK)){
+		// clear the data
+		free(*translation);
+		free(*data);
+	}
+
+	return (int) result;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/net_modules.h
===================================================================
--- uspace/lib/socket/include/net_modules.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/net_modules.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,144 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Generic module functions.
+ */
+
+#ifndef __NET_MODULES_H__
+#define __NET_MODULES_H__
+ 
+#include <async.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <sys/time.h>
+
+/** Converts the data length between different types.
+ *	@param[in] type_from The source type.
+ *  @param[in] type_to The destination type.
+ *  @param[in] count The number units of the source type size.
+ */
+#define CONVERT_SIZE(type_from, type_to, count)	((sizeof(type_from) / sizeof(type_to)) * (count))
+
+/** Registers the module service at the name server.
+ *  @param[in] me The module service.
+ *  @param[out] phonehash The created phone hash.
+ */
+#define REGISTER_ME(me, phonehash)	ipc_connect_to_me(PHONE_NS, (me), 0, 0, (phonehash))
+
+/** Connect to the needed module function type definition.
+ *  @param[in] need The needed module service.
+ *  @returns The phone of the needed service.
+ */
+typedef int connect_module_t(services_t need);
+
+/** Answers the call.
+ *  @param[in] callid The call identifier.
+ *  @param[in] result The message processing result.
+ *  @param[in] answer The message processing answer.
+ *  @param[in] answer_count The number of answer parameters.
+ */
+extern void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count);
+
+/** Creates bidirectional connection with the needed module service and registers the message receiver.
+ *  @param[in] need The needed module service.
+ *  @param[in] arg1 The first parameter.
+ *  @param[in] arg2 The second parameter.
+ *  @param[in] arg3 The third parameter.
+ *  @param[in] client_receiver The message receiver.
+ *  @returns The phone of the needed service.
+ *  @returns Other error codes as defined for the ipc_connect_to_me() function.
+ */
+extern int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver);
+
+/** Creates bidirectional connection with the needed module service and registers the message receiver.
+ *  @param[in] need The needed module service.
+ *  @param[in] arg1 The first parameter.
+ *  @param[in] arg2 The second parameter.
+ *  @param[in] arg3 The third parameter.
+ *  @param[in] client_receiver The message receiver.
+ *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
+ *  @returns The phone of the needed service.
+ *  @returns ETIMEOUT if the connection timeouted.
+ *  @returns Other error codes as defined for the ipc_connect_to_me() function.
+ */
+extern int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout);
+
+/** Connects to the needed module.
+ *  @param[in] need The needed module service.
+ *  @returns The phone of the needed service.
+ */
+extern int connect_to_service(services_t need);
+
+/** Connects to the needed module.
+ *  @param[in] need The needed module service.
+ *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
+ *  @returns The phone of the needed service.
+ *  @returns ETIMEOUT if the connection timeouted.
+ */
+extern int connect_to_service_timeout(services_t need, suseconds_t timeout);
+
+/** Receives data from the other party.
+ *  The received data buffer is allocated and returned.
+ *  @param[out] data The data buffer to be filled.
+ *  @param[out] length The buffer length.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the data or the length parameter is NULL.
+ *  @returns EINVAL if the client does not send data.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns Other error codes as defined for the async_data_write_finalize() function.
+ */
+extern int data_receive(void ** data, size_t * length);
+
+/** Replies the data to the other party.
+ *  @param[in] data The data buffer to be sent.
+ *  @param[in] data_length The buffer length.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the client does not expect the data.
+ *  @returns EOVERFLOW if the client does not expect all the data. Only partial data are transfered.
+ *  @returns Other error codes as defined for the async_data_read_finalize() function.
+ */
+extern int data_reply(void * data, size_t data_length);
+
+/** Refreshes answer structure and parameters count.
+ *  Erases all attributes.
+ *  @param[in,out] answer The message processing answer structure.
+ *  @param[in,out] answer_count The number of answer parameters.
+ */
+extern void refresh_answer(ipc_call_t * answer, int * answer_count);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/netdb.h
===================================================================
--- uspace/lib/socket/include/netdb.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/netdb.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,109 @@
+/*
+ * 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 netdb
+ *  @{
+ */
+
+/** @file
+ *  Structures and interfaces according to the BSD netdb.h file.
+ */
+
+#ifndef __NET_NETDB_H__
+#define __NET_NETDB_H__
+
+#include <sys/types.h>
+
+/** Structure returned by network data base library.
+ *  All addresses are supplied in host order, and returned in network order (suitable for use in system calls).
+ */
+struct	hostent {
+	/** Official host name.
+	 */
+	char * h_name;
+	/** Alias list.
+	 */
+	char **	h_aliases;
+	/** Host address type.
+	 */
+	int h_addrtype;
+	/** Address length.
+	 */
+	int h_length;
+	/** List of addresses from name server.
+	 */
+	char **	h_addr_list;
+	/** Address, for backward compatiblity.
+	 */
+#define	h_addr	h_addr_list[0]
+};
+
+/** @name Host entry address types definitions.
+ */
+/*@{*/
+
+/** Authoritative Answer Host not found address type.
+ */
+#define	HOST_NOT_FOUND	1
+
+/** Non-Authoritive Host not found, or SERVERFAIL address type.
+ */
+#define	TRY_AGAIN	2
+
+/** Non recoverable errors, FORMERR, REFUSED, NOTIMP address type.
+ */
+#define	NO_RECOVERY	3
+
+/** Valid name, no data record of requested type address type.
+ */
+#define	NO_DATA		4
+
+/** No address, look for MX record address type.
+ */
+#define	NO_ADDRESS	NO_DATA
+
+/*@}*/
+
+/** Returns host entry by the host address.
+ *  @param[in] address The host address.
+ *  @param[in] len The address length.
+ *  @param[in] type The address type.
+ *  @returns Host entry information.
+ */
+//struct hostent *	gethostbyaddr(const void * address, int len, int type);
+
+/** Returns host entry by the host name.
+ *  @param[in] name The host name.
+ *  @returns Host entry information.
+ */
+//struct hostent *	gethostbyname(const char * name);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/packet/packet.h
===================================================================
--- uspace/lib/socket/include/packet/packet.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/packet/packet.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,196 @@
+/*
+ * 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 map and queue.
+ */
+
+#ifndef __NET_PACKET_H__
+#define __NET_PACKET_H__
+
+/** Packet identifier type.
+ *  Value zero (0) is used as an invalid identifier.
+ */
+typedef int	packet_id_t;
+
+/** Type definition of the packet.
+ *  @see packet
+ */
+typedef struct packet *	packet_t;
+
+/** Type definition of the packet pointer.
+ *  @see packet
+ */
+typedef packet_t *		packet_ref;
+
+/** Type definition of the packet dimension.
+ *  @see packet_dimension
+ */
+typedef struct packet_dimension	packet_dimension_t;
+
+/** Type definition of the packet dimension pointer.
+ *  @see packet_dimension
+ */
+typedef packet_dimension_t *	packet_dimension_ref;
+
+/** Packet dimension.
+ */
+struct packet_dimension{
+	/** Reserved packet prefix length.
+	 */
+	size_t prefix;
+	/** Maximal packet content length.
+	 */
+	size_t content;
+	/** Reserved packet suffix length.
+	 */
+	size_t suffix;
+	/** Maximal packet address length.
+	 */
+	size_t addr_len;
+};
+
+/** @name Packet management system interface
+ */
+/*@{*/
+
+/** Finds the packet mapping.
+ *  @param[in] packet_id The packet identifier to be found.
+ *  @returns The found packet reference.
+ *  @returns NULL if the mapping does not exist.
+ */
+extern packet_t pm_find(packet_id_t packet_id);
+
+/** Adds the packet mapping.
+ *  @param[in] packet The packet to be remembered.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns EINVAL if the packet map is not initialized.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int pm_add(packet_t packet);
+
+/** Initializes the packet map.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int pm_init(void);
+
+/** Releases the packet map.
+ */
+extern void pm_destroy(void);
+
+/** Add packet to the sorted queue.
+ *  The queue is sorted in the ascending order.
+ *  The packet is inserted right before the packets of the same order value.
+ *  @param[in,out] first The first packet of the queue. Sets the first packet of the queue. The original first packet may be shifted by the new packet.
+ *  @param[in] packet The packet to be added.
+ *  @param[in] order The packet order value.
+ *  @param[in] metric The metric value of the packet.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the first parameter is NULL.
+ *  @returns EINVAL if the packet is not valid.
+ */
+extern int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric);
+
+/** Finds the packet with the given order.
+ *  @param[in] first The first packet of the queue.
+ *  @param[in] order The packet order value.
+ *  @returns The packet with the given order.
+ *  @returns NULL if the first packet is not valid.
+ *  @returns NULL if the packet is not found.
+ */
+extern packet_t pq_find(packet_t first, size_t order);
+
+/** Inserts packet after the given one.
+ *  @param[in] packet The packet in the queue.
+ *  @param[in] new_packet The new packet to be inserted.
+ *  @returns EOK on success.
+ *  @returns EINVAL if etiher of the packets is invalid.
+ */
+extern int pq_insert_after(packet_t packet, packet_t new_packet);
+
+/** Detach the packet from the queue.
+ *  @param[in] packet The packet to be detached.
+ *  @returns The next packet in the queue. If the packet is the first one of the queue, this becomes the new first one.
+ *  @returns NULL if there is no packet left.
+ *  @returns NULL if the packet is not valid.
+ */
+extern packet_t pq_detach(packet_t packet);
+
+/** Sets the packet order and metric attributes.
+ *  @param[in] packet The packet to be set.
+ *  @param[in] order The packet order value.
+ *  @param[in] metric The metric value of the packet.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is invalid..
+ */
+extern int pq_set_order(packet_t packet, size_t order, size_t metric);
+
+/** Sets the packet order and metric attributes.
+ *  @param[in] packet The packet to be set.
+ *  @param[out] order The packet order value.
+ *  @param[out] metric The metric value of the packet.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is invalid..
+ */
+extern int pq_get_order(packet_t packet, size_t * order, size_t * metric);
+
+/** Releases the whole queue.
+ *  Detaches all packets of the queue and calls the packet_release() for each of them.
+ *  @param[in] first The first packet of the queue.
+ *  @param[in] packet_release The releasing function called for each of the packets after its detachment.
+ */
+extern void pq_destroy(packet_t first, void (*packet_release)(packet_t packet));
+
+/** Returns the next packet in the queue.
+ *  @param[in] packet The packet queue member.
+ *  @returns The next packet in the queue.
+ *  @returns NULL if there is no next packet.
+ *  @returns NULL if the packet is not valid.
+ */
+extern packet_t pq_next(packet_t packet);
+
+/** Returns the previous packet in the queue.
+ *  @param[in] packet The packet queue member.
+ *  @returns The previous packet in the queue.
+ *  @returns NULL if there is no previous packet.
+ *  @returns NULL if the packet is not valid.
+ */
+extern packet_t pq_previous(packet_t packet);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/packet/packet_client.h
===================================================================
--- uspace/lib/socket/include/packet/packet_client.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/packet/packet_client.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -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.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(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(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(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(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_header.h
===================================================================
--- uspace/lib/socket/include/packet/packet_header.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/packet/packet_header.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,123 @@
+/*
+ * 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 header.
+ */
+
+#ifndef __NET_PACKET_HEADER_H__
+#define __NET_PACKET_HEADER_H__
+
+#include <packet/packet.h>
+
+/** Returns the actual packet data length.
+ *  @param[in] header The packet header.
+ */
+#define PACKET_DATA_LENGTH(header)		((header)->data_end - (header)->data_start)
+
+/** Returns the maximum packet address length.
+ *  @param[in] header The packet header.
+ */
+#define PACKET_MAX_ADDRESS_LENGTH(header)		((header)->dest_addr - (header)->src_addr)
+
+/** Returns the minimum packet suffix.
+ *  @param[in] header The packet header.
+ */
+#define PACKET_MIN_SUFFIX(header)		((header)->length - (header)->data_start - (header)->max_content)
+
+/** Packet integrity check magic value.
+ */
+#define PACKET_MAGIC_VALUE	0x11227788
+
+/** Packet header.
+ */
+struct packet{
+	/** Packet identifier.
+	 */
+	packet_id_t packet_id;
+	/** Packet queue sorting value.
+	 *  The packet queue is sorted the ascending order.
+	 */
+	size_t order;
+	/** Packet metric.
+	 */
+	size_t metric;
+	/** Previous packet in the queue.
+	 */
+	packet_id_t previous;
+	/** Next packet in the queue.
+	 */
+	packet_id_t next;
+	/** Total length of the packet.
+	 *  Contains the header, the addresses and the data of the packet.
+	 *  Corresponds to the mapped sharable memory block.
+	 */
+	size_t length;
+	/** Stored source and destination addresses length.
+	 */
+	size_t addr_len;
+	/** Souce address offset in bytes from the beginning of the packet header.
+	 */
+	size_t src_addr;
+	/** Destination address offset in bytes from the beginning of the packet header.
+	 */
+	size_t dest_addr;
+	/** Reserved data prefix length in bytes.
+	 */
+	size_t max_prefix;
+	/** Reserved content length in bytes.
+	 */
+	size_t max_content;
+	/** Actual data start offset in bytes from the beginning of the packet header.
+	 */
+	size_t data_start;
+	/** Actual data end offset in bytes from the beginning of the packet header.
+	 */
+	size_t data_end;
+	/** Integrity check magic value.
+	 */
+	int magic_value;
+};
+
+/** Returns whether the packet is valid.
+ *  @param[in] packet The packet to be checked.
+ *  @returns true if the packet is not NULL and the magic value is correct.
+ *  @returns false otherwise.
+ */
+static inline int packet_is_valid(const packet_t packet){
+	return packet && (packet->magic_value == PACKET_MAGIC_VALUE);
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/packet/packet_messages.h
===================================================================
--- uspace/lib/socket/include/packet/packet_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/packet/packet_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,96 @@
+/*
+ * 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 server module messages.
+ */
+
+#ifndef __NET_PACKET_MESSAGES__
+#define __NET_PACKET_MESSAGES__
+
+#include <ipc/ipc.h>
+
+#include <net_messages.h>
+
+/** Packet server module messages.
+ */
+typedef enum {
+	/** Create packet message with specified content length.
+	 *  @see packet_get_1()
+	 */
+	NET_PACKET_CREATE_1 = NET_PACKET_FIRST,
+	/** Create packet message with specified address length, prefix, content and suffix.
+	 *  @see packet_get_4()
+	 */
+	NET_PACKET_CREATE_4,
+	/** Get packet message.
+	 *  @see packet_return()
+	 */
+	NET_PACKET_GET,
+	/** Get packet size message.
+	 *  @see packet_translate()
+	 */
+	NET_PACKET_GET_SIZE,
+	/** Release packet message.
+	 *  @see pq_release()
+	 */
+	NET_PACKET_RELEASE
+} packet_messages;
+
+/** Returns the protocol service message parameter.
+ */
+#define ARP_GET_PROTO(call)		(services_t) IPC_GET_ARG2(*call)
+
+/** Returns the packet identifier message parameter.
+ */
+#define IPC_GET_ID(call)			(packet_id_t) IPC_GET_ARG1(*call)
+
+/** Returns the maximal content length message parameter.
+ */
+#define IPC_GET_CONTENT(call)		(size_t) IPC_GET_ARG1(*call)
+
+/** Returns the maximal address length message parameter.
+ */
+#define IPC_GET_ADDR_LEN(call)	(size_t) IPC_GET_ARG2(*call)
+
+/** Returns the maximal prefix length message parameter.
+ */
+#define IPC_GET_PREFIX(call)		(size_t) IPC_GET_ARG3(*call)
+
+/** Returns the maximal suffix length message parameter.
+ */
+#define IPC_GET_SUFFIX(call)		(size_t) IPC_GET_ARG4(*call)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/packet/packet_server.h
===================================================================
--- uspace/lib/socket/include/packet/packet_server.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/packet/packet_server.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,63 @@
+/*
+ * 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 server.
+ *  The hosting module has to be compiled with both the packet.c and the packet_server.c source files.
+ *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
+ *  Then the packet messages have to be processed by the packet_server_message() function.
+ *  The packet map should be released by the pm_destroy() function during the module termination.
+ *  @see IS_NET_PACKET_MESSAGE()
+ */
+
+#ifndef __NET_PACKET_SERVER_H__
+#define __NET_PACKET_SERVER_H__
+
+#include <ipc/ipc.h>
+
+/** Processes the packet server message.
+ *  @param[in] callid The message identifier.
+ *  @param[in] call The message parameters.
+ *  @param[out] answer The message answer parameters.
+ *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns ENOENT if there is no such packet as in the packet message parameter..
+ *  @returns ENOTSUP if the message is not known.
+ *  @returns Other error codes as defined for the packet_release_wrapper() function.
+ */
+extern int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/socket.h
===================================================================
--- uspace/lib/socket/include/socket.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/socket.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,214 @@
+/*
+ * 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 application program interface (API).
+ *  This is a part of the network application library.
+ *  Based on the BSD socket interface.
+ */
+
+#ifndef __NET_SOCKET_H__
+#define __NET_SOCKET_H__
+
+#include <net_byteorder.h>
+#include <in.h>
+#include <in6.h>
+#include <inet.h>
+#include <socket_codes.h>
+#include <socket_errno.h>
+
+/** @name Socket application programming interface
+ */
+/*@{*/
+
+/** Creates a new socket.
+ *  @param[in] domain The socket protocol family.
+ *  @param[in] type Socket type.
+ *  @param[in] protocol Socket protocol.
+ *  @returns The socket identifier on success.
+ *  @returns EPFNOTSUPPORT if the protocol family is not supported.
+ *  @returns ESOCKNOTSUPPORT if the socket type is not supported.
+ *  @returns EPROTONOSUPPORT if the protocol is not supported.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns ELIMIT if there was not a free socket identifier found this time.
+ *  @returns Other error codes as defined for the NET_SOCKET message.
+ *  @returns Other error codes as defined for the bind_service_timeout() function.
+ */
+extern int socket(int domain, int type, int protocol);
+
+/** Binds the socket to a port address.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] my_addr The port address.
+ *  @param[in] addrlen The address length.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the my_addr parameter is NULL.
+ *  @returns NO_DATA if the addlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_BIND message.
+ */
+extern int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen);
+
+/** Sets the number of connections waiting to be accepted.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] backlog The maximum number of waiting sockets to be accepted.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the backlog parameter is not positive (<=0).
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns Other error codes as defined for the NET_SOCKET_LISTEN message.
+ */
+extern int listen(int socket_id, int backlog);
+
+/** Accepts waiting socket.
+ *  Blocks until such a socket exists.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[out] cliaddr The remote client address.
+ *  @param[in] addrlen The address length.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the cliaddr or addrlen parameter is NULL.
+ *  @returns EINVAL if the backlog parameter is not positive (<=0).
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns Other error codes as defined for the NET_SOCKET_ACCEPT message.
+ */
+extern int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen);
+
+/** Connects socket to the remote server.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] serv_addr The remote server address.
+ *  @param[in] addrlen The address length.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the serv_addr parameter is NULL.
+ *  @returns NO_DATA if the addlen parameter is zero (0).
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns Other error codes as defined for the NET_SOCKET_CONNECT message.
+ */
+extern int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen);
+
+/** Closes the socket.
+ *  @param[in] socket_id Socket identifier.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EINPROGRESS if there is another blocking function in progress.
+ *  @returns Other error codes as defined for the NET_SOCKET_CLOSE message.
+ */
+extern int closesocket(int socket_id);
+
+/** Sends data via the socket.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] data The data to be sent.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various send flags.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data parameter is NULL.
+ *  @returns NO_DATA if the datalength parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_SEND message.
+ */
+extern int send(int socket_id, void * data, size_t datalength, int flags);
+
+/** Sends data via the socket to the remote address.
+ *  Binds the socket to a free port if not already connected/bound.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] data The data to be sent.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various send flags.
+ *  @param[in] toaddr The destination address.
+ *  @param[in] addrlen The address length.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data or toaddr parameter is NULL.
+ *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
+ */
+extern int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);
+
+/** Receives data via the socket.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[out] data The data buffer to be filled.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various receive flags.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data parameter is NULL.
+ *  @returns NO_DATA if the datalength parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_RECV message.
+ */
+extern int recv(int socket_id, void * data, size_t datalength, int flags);
+
+/** Receives data via the socket.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[out] data The data buffer to be filled.
+ *  @param[in] datalength The data length.
+ *  @param[in] flags Various receive flags.
+ *  @param[out] fromaddr The source address.
+ *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the data or fromaddr parameter is NULL.
+ *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_RECVFROM message.
+ */
+extern int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);
+
+/** Gets socket option.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] level The socket options level.
+ *  @param[in] optname The socket option to be get.
+ *  @param[out] value The value buffer to be filled.
+ *  @param[in,out] optlen The value buffer length. The maximum length is read. The actual length is set.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the value or optlen parameter is NULL.
+ *  @returns NO_DATA if the optlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_GETSOCKOPT message.
+ */
+extern int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen);
+
+/** Sets socket option.
+ *  @param[in] socket_id Socket identifier.
+ *  @param[in] level The socket options level.
+ *  @param[in] optname The socket option to be set.
+ *  @param[in] value The value to be set.
+ *  @param[in] optlen The value length.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ *  @returns EBADMEM if the value parameter is NULL.
+ *  @returns NO_DATA if the optlen parameter is zero (0).
+ *  @returns Other error codes as defined for the NET_SOCKET_SETSOCKOPT message.
+ */
+extern int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/socket_codes.h
===================================================================
--- uspace/lib/socket/include/socket_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/socket_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,460 @@
+/*
+ * 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 codes and definitions.
+ *  This is a part of the network application library.
+ */
+
+#ifndef __NET_SOCKET_CODES_H__
+#define __NET_SOCKET_CODES_H__
+
+#include <sys/types.h>
+
+/** @name Address families definitions
+ */
+/*@{*/
+
+/** Unspecified address family.
+ */
+#define AF_UNSPEC	0
+
+/** Unix domain sockets address family.
+ */
+#define AF_UNIXL	1
+
+/** POSIX name for AF_UNIX address family.
+ */
+#define AF_LOCAL	1
+
+/** Internet IP Protocol address family.
+ */
+#define AF_INET		2
+
+/** Amateur Radio AX.25 address family.
+ */
+#define AF_AX25		3
+
+/** Novell IPX address family.
+ */
+#define AF_IPX		4
+
+/** AppleTalk DDP address family.
+ */
+#define AF_APPLETALK	5
+
+/** Amateur Radio NET/ROM address family.
+ */
+#define AF_NETROM	6
+
+/** Multiprotocol bridge address family.
+ */
+#define AF_BRIDGE	7
+
+/** ATM PVCs address family.
+ */
+#define AF_ATMPVC	8
+
+/** Reserved for X.25 project address family.
+ */
+#define AF_X25		9
+
+/** IP version 6 address family.
+ */
+#define AF_INET6	10
+
+/** Amateur Radio X.25 PLP address family.
+ */
+#define AF_ROSE		11
+
+/** Reserved for DECnet project address family.
+ */
+#define AF_DECnet	12
+
+/** Reserved for 802.2LLC project address family.
+ */
+#define AF_NETBEUI	13
+
+/** Security callback pseudo AF address family.
+ */
+#define AF_SECURITY	14
+
+/** PF_KEY key management API address family.
+ */
+#define AF_KEY		15
+
+/** Alias to emulate 4.4BSD address family.
+ */
+#define AF_NETLINK	16
+
+/** Packet family address family.
+ */
+#define AF_PACKET	17
+
+/** Ash address family.
+ */
+#define AF_ASH		18
+
+/** Acorn Econet address family.
+ */
+#define AF_ECONET	19
+
+/** ATM SVCs address family.
+ */
+#define AF_ATMSVC	20
+
+/** Linux SNA Project (nutters!) address family.
+ */
+#define AF_SNA		22
+
+/** IRDA sockets address family.
+ */
+#define AF_IRDA		23
+
+/** PPPoX sockets address family.
+ */
+#define AF_PPPOX	24
+
+/** Wanpipe API Sockets address family.
+ */
+#define AF_WANPIPE	25
+
+/** Linux LLC address family.
+ */
+#define AF_LLC		26
+
+/** Controller Area Network address family.
+ */
+#define AF_CAN		29
+
+/** TIPC sockets address family.
+ */
+#define AF_TIPC		30
+
+/** Bluetooth sockets address family.
+ */
+#define AF_BLUETOOTH	31
+
+/** IUCV sockets address family.
+ */
+#define AF_IUCV		32
+
+/** RxRPC sockets address family.
+ */
+#define AF_RXRPC	33
+
+/** Maximum address family.
+ */
+#define AF_MAX		34
+
+/*@}*/
+
+/** @name Protocol families definitions
+ *  Same as address families.
+ */
+/*@{*/
+
+/** Unspecified protocol family.
+ */
+#define PF_UNSPEC	AF_UNSPEC
+
+/** Unix domain sockets protocol family.
+ */
+#define PF_UNIXL	AF_UNIXL
+
+/** POSIX name for AF_UNIX protocol family.
+ */
+#define PF_LOCAL	AF_LOCAL
+
+/** Internet IP Protocol protocol family.
+ */
+#define PF_INET		AF_INET
+
+/** Amateur Radio AX.25 protocol family.
+ */
+#define PF_AX25		AF_AX25
+
+/** Novell IPX protocol family.
+ */
+#define PF_IPX		AF_IPX
+
+/** AppleTalk DDP protocol family.
+ */
+#define PF_APPLETALK	AF_APPLETALK
+
+/** Amateur Radio NET/ROM protocol family.
+ */
+#define PF_NETROM	AF_NETROM
+
+/** Multiprotocol bridge protocol family.
+ */
+#define PF_BRIDGE	AF_BRIDGE
+
+/** ATM PVCs protocol family.
+ */
+#define PF_ATMPVC	AF_ATMPVC
+
+/** Reserved for X.25 project protocol family.
+ */
+#define PF_X25		AF_X25
+
+/** IP version 6 protocol family.
+ */
+#define PF_INET6	AF_INET6
+
+/** Amateur Radio X.25 PLP protocol family.
+ */
+#define PF_ROSE		AF_ROSE
+
+/** Reserved for DECnet project protocol family.
+ */
+#define PF_DECnet	AF_DECnet
+
+/** Reserved for 802.2LLC project protocol family.
+ */
+#define PF_NETBEUI	AF_NETBEUI
+
+/** Security callback pseudo AF protocol family.
+ */
+#define PF_SECURITY	AF_SECURITY
+
+/** PF_KEY key management API protocol family.
+ */
+#define PF_KEY		AF_KEY
+
+/** Alias to emulate 4.4BSD protocol family.
+ */
+#define PF_NETLINK	AF_NETLINK
+
+/** Packet family protocol family.
+ */
+#define PF_PACKET	AF_PACKET
+
+/** Ash protocol family.
+ */
+#define PF_ASH		AF_ASH
+
+/** Acorn Econet protocol family.
+ */
+#define PF_ECONET	AF_ECONET
+
+/** ATM SVCs protocol family.
+ */
+#define PF_ATMSVC	AF_ATMSVC
+
+/** Linux SNA Project (nutters!) protocol family.
+ */
+#define PF_SNA		AF_SNA
+
+/** IRDA sockets protocol family.
+ */
+#define PF_IRDA		AF_IRDA
+
+/** PPPoX sockets protocol family.
+ */
+#define PF_PPPOX	AF_PPPOX
+
+/** Wanpipe API Sockets protocol family.
+ */
+#define PF_WANPIPE	AF_WANPIPE
+
+/** Linux LLC protocol family.
+ */
+#define PF_LLC		AF_LLC
+
+/** Controller Area Network protocol family.
+ */
+#define PF_CAN		AF_CAN
+
+/** TIPC sockets protocol family.
+ */
+#define PF_TIPC		AF_TIPC
+
+/** Bluetooth sockets protocol family.
+ */
+#define PF_BLUETOOTH	AF_BLUETOOTH
+
+/** IUCV sockets protocol family.
+ */
+#define PF_IUCV		AF_IUCV
+
+/** RxRPC sockets protocol family.
+ */
+#define PF_RXRPC	AF_RXRPC
+
+/** Maximum protocol family.
+ */
+#define PF_MAX		AF_MAX
+
+/*@}*/
+
+/** @name Socket option levels definitions
+ *  Thanks to BSD these must match IPPROTO_xxx
+ */
+/*@{*/
+
+/** IP socket option level.
+ */
+#define SOL_IP		0
+
+/** ICMP socket option level.
+ */
+#define SOL_ICMP	1
+
+/** TCP socket option level.
+ */
+#define SOL_TCP		6
+
+/** UDP socket option level.
+ */
+#define SOL_UDP		17
+
+/** IPV socket option level.
+ */
+#define SOL_IPV6	41
+
+/** ICMPV socket option level.
+ */
+#define SOL_ICMPV6	58
+
+/** SCTP socket option level.
+ */
+#define SOL_SCTP	132
+
+/** UDP-Lite (RFC 3828) socket option level.
+ */
+#define SOL_UDPLITE	136
+
+/** RAW socket option level.
+ */
+#define SOL_RAW		255
+
+/** IPX socket option level.
+ */
+#define SOL_IPX		256
+
+/** AX socket option level.
+ */
+#define SOL_AX25	257
+
+/** ATALK socket option level.
+ */
+#define SOL_ATALK	258
+
+/** NETROM socket option level.
+ */
+#define SOL_NETROM	259
+
+/** ROSE socket option level.
+ */
+#define SOL_ROSE	260
+
+/** DECNET socket option level.
+ */
+#define SOL_DECNET	261
+
+/** X25 socket option level.
+ */
+#define	SOL_X25		262
+
+/** PACKET socket option level.
+ */
+#define SOL_PACKET	263
+
+/** ATM layer (cell level) socket option level.
+ */
+#define SOL_ATM		264
+
+/** ATM Adaption Layer (packet level) socket option level.
+ */
+#define SOL_AAL		265
+
+/** IRDA socket option level.
+ */
+#define SOL_IRDA	266
+
+/** NETBEUI socket option level.
+ */
+#define SOL_NETBEUI	267
+
+/** LLC socket option level.
+ */
+#define SOL_LLC		268
+
+/** DCCP socket option level.
+ */
+#define SOL_DCCP	269
+
+/** NETLINK socket option level.
+ */
+#define SOL_NETLINK	270
+
+/** TIPC socket option level.
+ */
+#define SOL_TIPC	271
+
+/** RXRPC socket option level.
+ */
+#define SOL_RXRPC	272
+
+/** PPPOL socket option level.
+ */
+#define SOL_PPPOL2TP	273
+
+/** BLUETOOTH socket option level.
+ */
+#define SOL_BLUETOOTH	274
+
+/*@}*/
+
+/** Socket types.
+ */
+typedef enum sock_type{
+	/** Stream (connection oriented) socket.
+	 */
+	SOCK_STREAM = 1,
+	/** Datagram (connectionless oriented) socket.
+	 */
+	SOCK_DGRAM = 2,
+	/** Raw socket.
+	 */
+	SOCK_RAW = 3
+} sock_type_t;
+
+/** Type definition of the socket length.
+ */
+typedef int32_t	socklen_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/socket_core.h
===================================================================
--- uspace/lib/socket/include/socket_core.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/socket_core.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+#ifndef __NET_SOCKET_CORE_H__
+#define __NET_SOCKET_CORE_H__
+
+#include <sys/types.h>
+
+#include <in.h>
+#include <net_device.h>
+#include <adt/generic_char_map.h>
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+#include <packet/packet.h>
+
+/** Initial size of the received packet queue.
+ */
+#define SOCKET_INITIAL_RECEIVED_SIZE	4
+
+/** Maximum size of the received packet queue.
+ */
+#define SOCKET_MAX_RECEIVED_SIZE		0
+
+/** Initial size of the sockets for acceptance queue.
+ */
+#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+
+/** Maximum size of the sockets for acceptance queue.
+ */
+#define SOCKET_MAX_ACCEPTEDED_SIZE		0
+
+/** Listening sockets' port map key.
+ */
+#define SOCKET_MAP_KEY_LISTENING	"L"
+
+/** Type definition of the socket core.
+ *  @see socket_core
+ */
+typedef struct socket_core	socket_core_t;
+
+/** Type definition of the socket core pointer.
+ *  @see socket_core
+ */
+typedef socket_core_t *	socket_core_ref;
+
+/** Type definition of the socket port.
+ *  @see socket_port
+ */
+typedef struct socket_port	socket_port_t;
+
+/** Type definition of the socket port pointer.
+ *  @see socket_port
+ */
+typedef socket_port_t *	socket_port_ref;
+
+/** Socket core.
+ */
+struct socket_core{
+	/** Socket identifier.
+	 */
+	int socket_id;
+	/** Client application phone.
+	 */
+	int phone;
+	/** Bound port.
+	 */
+	int port;
+	/** Received packets queue.
+	 */
+	dyn_fifo_t received;
+	/** Sockets for acceptance queue.
+	 */
+	dyn_fifo_t accepted;
+	/** Protocol specific data.
+	 */
+	void * specific_data;
+	/** Socket ports map key.
+	 */
+	const char * key;
+	/** Length of the Socket ports map key.
+	 */
+	size_t key_length;
+};
+
+/** Sockets map.
+ *  The key is the socket identifier.
+ */
+INT_MAP_DECLARE(socket_cores, socket_core_t);
+
+/** Bount port sockets map.
+ *  The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas the other use the remote addresses.
+ */
+GENERIC_CHAR_MAP_DECLARE(socket_port_map, socket_core_ref);
+
+/** Ports map.
+ *  The key is the port number.
+ */
+INT_MAP_DECLARE(socket_ports, socket_port_t);
+
+/** Destroys local sockets.
+ *  Releases all buffered packets and calls the release function for each of the sockets.
+ *  @param[in] packet_phone The packet server phone to release buffered packets.
+ *  @param[in] local_sockets The local sockets to be destroyed.
+ *  @param[in,out] global_sockets The global sockets to be updated.
+ *  @param[in] socket_release The client release callback function.
+ */
+extern void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket));
+
+/** Binds the socket to the port.
+ *  The address port is used if set, a free port is used if not.
+ *  @param[in] local_sockets The local sockets to be searched.
+ *  @param[in,out] global_sockets The global sockets to be updated.
+ *  @param[in] socket_id The new socket identifier.
+ *  @param[in] addr The address to be bound to.
+ *  @param[in] addrlen The address length.
+ *  @param[in] free_ports_start The minimum free port.
+ *  @param[in] free_ports_end The maximum free port.
+ *  @param[in] last_used_port The last used free port.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket was not found.
+ *  @returns EAFNOSUPPORT if the address family is not supported.
+ *  @returns EADDRINUSE if the port is already in use.
+ *  @returns Other error codes as defined for the socket_bind_free_port() function.
+ *  @returns Other error codes as defined for the socket_bind_insert() function.
+ */
+extern 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);
+
+/** Binds the socket to a free port.
+ *  The first free port is used.
+ *  @param[in,out] global_sockets The global sockets to be updated.
+ *  @param[in,out] socket The socket to be bound.
+ *  @param[in] free_ports_start The minimum free port.
+ *  @param[in] free_ports_end The maximum free port.
+ *  @param[in] last_used_port The last used free port.
+ *  @returns EOK on success.
+ *  @returns ENOTCONN if no free port was found.
+ *  @returns Other error codes as defined for the socket_bind_insert() function.
+ */
+extern 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);
+
+/** Creates a new socket.
+ *  @param[in,out] local_sockets The local sockets to be updated.
+ *  @param[in] app_phone The application phone.
+ *  @param[in] specific_data The socket specific data.
+ *  @param[in,out] socket_id The new socket identifier. A new identifier is chosen if set to zero (0) or negative. A negative identifier is chosen if set to negative.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the socket_id parameter is NULL.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
+extern int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id);
+
+/** 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_id The socket identifier.
+ *  @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.
+ *  @returns EOK on success.
+ *  @returns ENOTSOCK if the socket is not found.
+ */
+extern 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));
+
+/** Replies the packet or the packet queue data to the application via the socket.
+ *  Uses the current message processing fibril.
+ *  @param[in] packet The packet to be transfered.
+ *  @param[out] length The total data length.
+ *  @returns EOK on success.
+ *  @returns EBADMEM if the length parameter is NULL.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns Other error codes as defined for the data_reply() function.
+ */
+extern int socket_reply_packets(packet_t packet, size_t * length);
+
+/** Finds the bound port socket.
+ *  @param[in] global_sockets The global sockets to be searched.
+ *  @param[in] port The port number.
+ *  @param[in] key The socket key identifier.
+ *  @param[in] key_length The socket key length.
+ *  @returns The found socket.
+ *  @returns NULL if no socket was found.
+ */
+extern socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length);
+
+/** Releases the socket port.
+ *  If the socket is bound the port entry is released.
+ *  If there are no more port entries the port is release.
+ *  @param[in] global_sockets The global sockets to be updated.
+ *  @param[in] socket The socket to be unbound.
+ */
+extern void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket);
+
+/** Adds the socket to an already bound port.
+ *  @param[in] global_sockets The global sockets to be updated.
+ *  @param[in] port The port number to be bound to.
+ *  @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 ENOENT if the port is not already used.
+ *  @returns Other error codes as defined for the socket_port_add_core() function.
+ */
+extern int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/socket_errno.h
===================================================================
--- uspace/lib/socket/include/socket_errno.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/socket_errno.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,136 @@
+/*
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Socket error codes.
+ *  Based on BSD.
+ */
+
+#ifndef __NET_SOCKET_ERR_H__
+#define __NET_SOCKET_ERR_H__
+
+#include <errno.h>
+
+/** @name Socket error codes definitions
+ */
+/*@{*/
+
+////#define EINTR			(-10004)
+////#define EBADF			(-10009)
+//#define EACCES			(-10013)
+//#define EFAULT			(-10014)
+////#define EINVAL			(-10022)
+////#define EMFILE			(-10024)
+//#define EWOULDBLOCK		(-10035)
+
+/** An API function is called while another blocking function is in progress.
+ */
+#define EINPROGRESS		(-10036)
+
+//#define EALREADY		(-10037)
+
+/** The socket identifier is not valid.
+ */
+#define ENOTSOCK		(-10038)
+
+/** The destination address required.
+ */
+#define EDESTADDRREQ	(-10039)
+
+//#define EMSGSIZE		(-10040)
+//#define EPROTOTYPE		(-10041)
+//#define ENOPROTOOPT		(-10042)
+
+/** Protocol is not supported.
+ */
+#define EPROTONOSUPPORT	(-10043)
+
+/** Socket type is not supported.
+ */
+#define ESOCKTNOSUPPORT	(-10044)
+
+//#define EOPNOTSUPP		(-10045)
+
+/** Protocol family is not supported.
+ */
+#define EPFNOSUPPORT	(-10046)
+
+/** Address family is not supported.
+ */
+#define EAFNOSUPPORT	(-10047)
+
+/** Address is already in use.
+ */
+#define EADDRINUSE		(-10048)
+
+//#define EADDRNOTAVAIL	(-10049)
+/* May be reported at any time if the implementation detects an underlying failure.
+ */
+//#define ENETDOWN		(-10050)
+//#define ENETUNREACH		(-10051)
+//#define ENETRESET		(-10052)
+//#define ECONNABORTED	(-10053)
+//#define ECONNRESET		(-10054)
+//#define ENOBUFS			(-10055)
+//#define EISCONN			(-10056)
+
+/** The socket is not connected or bound.
+ */
+#define ENOTCONN		(-10057)
+
+//#define ESHUTDOWN		(-10058)
+//#define ETOOMANYREFS	(-10059)
+//#define ETIMEDOUT		(-10060)
+//#define ECONNREFUSED	(-10061)
+//#define ELOOP			(-10062)
+////#define ENAMETOOLONG	(-10063)
+//#define EHOSTDOWN		(-10064)
+//#define EHOSTUNREACH	(-10065)
+//#define HOST_NOT_FOUND	(-11001)
+
+/** The requested operation was not performed.
+ *  Try again later.
+ */
+#define TRY_AGAIN		(-11002)
+
+//#define NO_RECOVERY		(-11003)
+
+/** No data.
+ */
+#define NO_DATA			(-11004)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/socket_messages.h
===================================================================
--- uspace/lib/socket/include/socket_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/socket_messages.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,215 @@
+/*
+ * 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 messages.
+ *  @see socket.h
+ */
+
+
+#ifndef __NET_SOCKET_MESSAGES_H__
+#define __NET_SOCKET_MESSAGES_H__
+
+#include <ipc/ipc.h>
+
+#include <net_messages.h>
+#include <socket_codes.h>
+
+/** Socket client messages.
+ */
+typedef enum{
+	/** Creates a new socket.
+	 *  @see socket()
+	 */
+	NET_SOCKET = NET_SOCKET_FIRST,
+	/** Binds the socket.
+	 *  @see bind()
+	 */
+	NET_SOCKET_BIND,
+	/** Creates a new socket.
+	 *  @see socket()
+	 */
+	NET_SOCKET_LISTEN,
+	/** Accepts an incomming connection.
+	 *  @see accept()
+	 */
+	NET_SOCKET_ACCEPT,
+	/** Connects the socket.
+	 *  @see connect()
+	 */
+	NET_SOCKET_CONNECT,
+	/** Closes the socket.
+	 *  @see closesocket()
+	 */
+	NET_SOCKET_CLOSE,
+	/** Sends data via the stream socket.
+	 *  @see send()
+	 */
+	NET_SOCKET_SEND,
+	/** Sends data via the datagram socket.
+	 *  @see sendto()
+	 */
+	NET_SOCKET_SENDTO,
+	/** Receives data from the stream socket.
+	 *  @see socket()
+	 */
+	NET_SOCKET_RECV,
+	/** Receives data from the datagram socket.
+	 *  @see socket()
+	 */
+	NET_SOCKET_RECVFROM,
+	/** Gets the socket option.
+	 *  @see getsockopt()
+	 */
+	NET_SOCKET_GETSOCKOPT,
+	/** Sets the socket option.
+	 *  @see setsockopt()
+	 */
+	NET_SOCKET_SETSOCKOPT,
+	/** New socket for acceptence notification message.
+	 */
+	NET_SOCKET_ACCEPTED,
+	/** New data received notification message.
+	 */
+	NET_SOCKET_RECEIVED,
+	/** New socket data fragment size notification message.
+	 */
+	NET_SOCKET_DATA_FRAGMENT_SIZE
+} socket_messages;
+
+/** @name Socket specific message parameters definitions
+ */
+/*@{*/
+
+/** Sets the socket identifier in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define SOCKET_SET_SOCKET_ID(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(answer, argument);}
+
+/** Returns the socket identifier message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_SOCKET_ID(call) \
+	({int socket_id = (int) IPC_GET_ARG1(call); socket_id;})
+
+/** Sets the read data length in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define SOCKET_SET_READ_DATA_LENGTH(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(answer, argument);}
+
+/** Returns the read data length message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_READ_DATA_LENGTH(call) \
+	({int data_length = (int) IPC_GET_ARG1(call); data_length;})
+
+/** Returns the backlog message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_BACKLOG(call) \
+	({int backlog = (int) IPC_GET_ARG2(call); backlog;})
+
+/** Returns the option level message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_OPT_LEVEL(call) \
+	({int opt_level = (int) IPC_GET_ARG2(call); opt_level;})
+
+/** Returns the data fragment size message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_DATA_FRAGMENT_SIZE(call) \
+	({size_t size = (size_t) IPC_GET_ARG2(call); size;})
+
+/** Sets the data fragment size in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define SOCKET_SET_DATA_FRAGMENT_SIZE(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG2(answer, argument);}
+
+/** Sets the address length in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define SOCKET_SET_ADDRESS_LENGTH(answer, value) \
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(answer, argument);}
+
+/** Returns the address length message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_ADDRESS_LENGTH(call) \
+	({socklen_t address_length = (socklen_t) IPC_GET_ARG3(call); address_length;})
+
+/** Sets the header size in the message answer.
+ *  @param[out] answer The message answer structure.
+ */
+#define SOCKET_SET_HEADER_SIZE(answer, value) \
+	\
+	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(answer, argument);}
+
+/** Returns the header size message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_HEADER_SIZE(call) \
+	({size_t size = (size_t) IPC_GET_ARG3(call); size;})
+
+/** Returns the flags message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_FLAGS(call) \
+	({int flags = (int) IPC_GET_ARG4(call); flags;})
+
+/** Returns the option name message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_OPT_NAME(call) \
+	({int opt_name = (int) IPC_GET_ARG4(call); opt_name;})
+
+/** Returns the data fragments message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_DATA_FRAGMENTS(call) \
+	({int fragments = (int) IPC_GET_ARG5(call); fragments;})
+
+/** Returns the new socket identifier message parameter.
+ *  @param[in] call The message call structure.
+ */
+#define SOCKET_GET_NEW_SOCKET_ID(call) \
+	({int socket_id = (int) IPC_GET_ARG5(call); socket_id;})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/include/tcp_codes.h
===================================================================
--- uspace/lib/socket/include/tcp_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/include/tcp_codes.h	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,88 @@
+/*
+ * 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 tcp
+ *  @{
+ */
+
+/** @file
+ *  TCP options definitions.
+ */
+
+#ifndef __NET_TCP_CODES_H__
+#define __NET_TCP_CODES_H__
+
+/** End of list TCP option.
+ */
+#define TCPOPT_END_OF_LIST				0x0
+
+/** No operation TCP option.
+ */
+#define TCPOPT_NO_OPERATION				0x1
+
+/** Maximum segment size TCP option.
+ */
+#define TCPOPT_MAX_SEGMENT_SIZE			0x2
+
+/** Maximum segment size TCP option length.
+ */
+#define TCPOPT_MAX_SEGMENT_SIZE_LENGTH	4
+
+/** Window scale TCP option.
+ */
+#define TCPOPT_WINDOW_SCALE				0x3
+
+/** Window scale TCP option length.
+ */
+#define TCPOPT_WINDOW_SCALE_LENGTH		3
+
+/** Selective acknowledgement permitted TCP option.
+ */
+#define TCPOPT_SACK_PERMITTED			0x4
+
+/** Selective acknowledgement permitted TCP option length.
+ */
+#define TCPOPT_SACK_PERMITTED_LENGTH	2
+
+/** Selective acknowledgement TCP option.
+ *  Has variable length.
+ */
+#define TCPOPT_SACK						0x5
+
+/** Timestamp TCP option.
+ */
+#define TCPOPT_TIMESTAMP				0x8
+
+/** Timestamp TCP option length.
+ */
+#define TCPOPT_TIMESTAMP_LENGTH			10
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/socket/packet/packet.c
===================================================================
--- uspace/lib/socket/packet/packet.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/packet/packet.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,330 @@
+/*
+ * 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 map and queue implementation.
+ *  This file has to be compiled with both the packet server and the client.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <fibril_synch.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#include <net_err.h>
+#include <adt/generic_field.h>
+#include <packet/packet.h>
+#include <packet/packet_header.h>
+
+/** Packet map page size.
+ */
+#define PACKET_MAP_SIZE	100
+
+/** Returns the packet map page index.
+ *  @param[in] packet_id The packet identifier.
+ */
+#define PACKET_MAP_PAGE(packet_id)	(((packet_id) - 1) / PACKET_MAP_SIZE)
+
+/** Returns the packet index in the corresponding packet map page.
+ *  @param[in] packet_id The packet identifier.
+ */
+#define PACKET_MAP_INDEX(packet_id)	(((packet_id) - 1) % PACKET_MAP_SIZE)
+
+/** Type definition of the packet map page.
+ */
+typedef packet_t packet_map_t[PACKET_MAP_SIZE];
+/** Type definition of the packet map page pointer.
+ */
+typedef packet_map_t * packet_map_ref;
+
+/** Packet map.
+ *  Maps packet identifiers to the packet references.
+ *  @see generic_field.h
+ */
+GENERIC_FIELD_DECLARE(gpm, packet_map_t);
+
+/** Releases the packet.
+ *  @param[in] packet The packet to be released.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ */
+int packet_destroy(packet_t packet);
+
+/** Packet map global data.
+ */
+static struct{
+	/** Safety lock.
+	 */
+	fibril_rwlock_t lock;
+	/** Packet map.
+	 */
+	gpm_t packet_map;
+} pm_globals;
+
+GENERIC_FIELD_IMPLEMENT(gpm, packet_map_t);
+
+int packet_destroy(packet_t packet){
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	return munmap(packet, packet->length);
+}
+
+int pm_init(void){
+	ERROR_DECLARE;
+
+	fibril_rwlock_initialize(&pm_globals.lock);
+	fibril_rwlock_write_lock(&pm_globals.lock);
+	ERROR_PROPAGATE(gpm_initialize(&pm_globals.packet_map));
+	fibril_rwlock_write_unlock(&pm_globals.lock);
+	return EOK;
+}
+
+packet_t pm_find(packet_id_t packet_id){
+	packet_map_ref map;
+	packet_t packet;
+
+	if(! packet_id){
+		return NULL;
+	}
+	fibril_rwlock_read_lock(&pm_globals.lock);
+	if(packet_id > PACKET_MAP_SIZE * gpm_count(&pm_globals.packet_map)){
+		fibril_rwlock_read_unlock(&pm_globals.lock);
+		return NULL;
+	}
+	map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet_id));
+	if(! map){
+		fibril_rwlock_read_unlock(&pm_globals.lock);
+		return NULL;
+	}
+	packet = (*map)[PACKET_MAP_INDEX(packet_id)];
+	fibril_rwlock_read_unlock(&pm_globals.lock);
+	return packet;
+}
+
+int pm_add(packet_t packet){
+	ERROR_DECLARE;
+
+	packet_map_ref map;
+
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	fibril_rwlock_write_lock(&pm_globals.lock);
+	if(PACKET_MAP_PAGE(packet->packet_id) < gpm_count(&pm_globals.packet_map)){
+		map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet->packet_id));
+	}else{
+		do{
+			map = (packet_map_ref) malloc(sizeof(packet_map_t));
+			if(! map){
+				fibril_rwlock_write_unlock(&pm_globals.lock);
+				return ENOMEM;
+			}
+			bzero(map, sizeof(packet_map_t));
+			if((ERROR_CODE = gpm_add(&pm_globals.packet_map, map)) < 0){
+				fibril_rwlock_write_unlock(&pm_globals.lock);
+				free(map);
+				return ERROR_CODE;
+			}
+		}while(PACKET_MAP_PAGE(packet->packet_id) >= gpm_count(&pm_globals.packet_map));
+	}
+	(*map)[PACKET_MAP_INDEX(packet->packet_id)] = packet;
+	fibril_rwlock_write_unlock(&pm_globals.lock);
+	return EOK;
+}
+
+void pm_destroy(void){
+	int count;
+	int index;
+	packet_map_ref map;
+	packet_t packet;
+
+	fibril_rwlock_write_lock(&pm_globals.lock);
+	count = gpm_count(&pm_globals.packet_map);
+	while(count > 0){
+		map = gpm_get_index(&pm_globals.packet_map, count - 1);
+		for(index = PACKET_MAP_SIZE - 1; index >= 0; -- index){
+			packet = (*map)[index];
+			if(packet_is_valid(packet)){
+				munmap(packet, packet->length);
+			}
+		}
+	}
+	gpm_destroy(&pm_globals.packet_map);
+	// leave locked
+}
+
+int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric){
+	packet_t item;
+
+	if((! first) || (! packet_is_valid(packet))){
+		return EINVAL;
+	}
+	pq_set_order(packet, order, metric);
+	if(packet_is_valid(*first)){
+		item = * first;
+		do{
+			if(item->order < order){
+				if(item->next){
+					item = pm_find(item->next);
+				}else{
+					item->next = packet->packet_id;
+					packet->previous = item->packet_id;
+					return EOK;
+				}
+			}else{
+				packet->previous = item->previous;
+				packet->next = item->packet_id;
+				item->previous = packet->packet_id;
+				item = pm_find(packet->previous);
+				if(item){
+					item->next = packet->packet_id;
+				}else{
+					*first = packet;
+				}
+				return EOK;
+			}
+		}while(packet_is_valid(item));
+	}
+	*first = packet;
+	return EOK;
+}
+
+packet_t pq_find(packet_t packet, size_t order){
+	packet_t item;
+
+	if(! packet_is_valid(packet)){
+		return NULL;
+	}
+	item = packet;
+	do{
+		if(item->order == order){
+			return item;
+		}
+		item = pm_find(item->next);
+	}while(item && (item != packet) && packet_is_valid(item));
+	return NULL;
+}
+
+int pq_insert_after(packet_t packet, packet_t new_packet){
+	packet_t item;
+
+	if(!(packet_is_valid(packet) && packet_is_valid(new_packet))){
+		return EINVAL;
+	}
+	new_packet->previous = packet->packet_id;
+	new_packet->next = packet->next;
+	item = pm_find(packet->next);
+	if(item){
+		item->previous = new_packet->packet_id;
+	}
+	packet->next = new_packet->packet_id;
+	return EOK;
+}
+
+packet_t pq_detach(packet_t packet){
+	packet_t next;
+	packet_t previous;
+
+	if(! packet_is_valid(packet)){
+		return NULL;
+	}
+	next = pm_find(packet->next);
+	if(next){
+		next->previous = packet->previous;
+		previous = pm_find(next->previous);
+		if(previous){
+			previous->next = next->packet_id;
+		}
+	}
+	packet->previous = 0;
+	packet->next = 0;
+	return next;
+}
+
+int pq_set_order(packet_t packet, size_t order, size_t metric){
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	packet->order = order;
+	packet->metric = metric;
+	return EOK;
+}
+
+int pq_get_order(packet_t packet, size_t * order, size_t * metric){
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	if(order){
+		*order = packet->order;
+	}
+	if(metric){
+		*metric = packet->metric;
+	}
+	return EOK;
+}
+
+void pq_destroy(packet_t first, void (*packet_release)(packet_t packet)){
+	packet_t actual;
+	packet_t next;
+
+	actual = first;
+	while(packet_is_valid(actual)){
+		next = pm_find(actual->next);
+		actual->next = 0;
+		actual->previous = 0;
+		if(packet_release){
+			packet_release(actual);
+		}
+		actual = next;
+	}
+}
+
+packet_t pq_next(packet_t packet){
+	if(! packet_is_valid(packet)){
+		return NULL;
+	}
+	return pm_find(packet->next);
+}
+
+packet_t pq_previous(packet_t packet){
+	if(! packet_is_valid(packet)){
+		return NULL;
+	}
+	return pm_find(packet->previous);
+}
+
+/** @}
+ */
Index: uspace/lib/socket/packet/packet_client.c
===================================================================
--- uspace/lib/socket/packet/packet_client.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/packet/packet_client.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,186 @@
+/*
+ * 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;
+	uint8_t * dest;
+	size_t addrlen;
+
+	if(! packet_is_valid(packet)){
+		return NULL;
+	}
+	// get a new packet
+	copy = packet_get_4(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(phone, copy->packet_id);
+		return NULL;
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/socket/packet/packet_server.c
===================================================================
--- uspace/lib/socket/packet/packet_server.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
+++ uspace/lib/socket/packet/packet_server.c	(revision 849ed54afbef3ad0ec3af831e93a1353f9eaaf0f)
@@ -0,0 +1,321 @@
+/*
+ * 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 server implementation.
+ */
+
+#include <align.h>
+#include <assert.h>
+#include <async.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <unistd.h>
+
+#include <ipc/ipc.h>
+#include <sys/mman.h>
+
+#include <net_err.h>
+#include <net_messages.h>
+#include <packet/packet.h>
+#include <packet/packet_client.h>
+#include <packet/packet_header.h>
+#include <packet/packet_messages.h>
+#include <packet/packet_server.h>
+
+#define FREE_QUEUES_COUNT	7
+
+/** The default address length reserved for new packets.
+ */
+#define DEFAULT_ADDR_LEN	32
+
+/** The default prefix reserved for new packets.
+ */
+#define DEFAULT_PREFIX		64
+
+/** The default suffix reserved for new packets.
+ */
+#define DEFAULT_SUFFIX		64
+
+/** Packet server global data.
+ */
+static struct{
+	/** Safety lock.
+	 */
+	fibril_mutex_t lock;
+	/** Free packet queues.
+	 */
+	packet_t free[FREE_QUEUES_COUNT];
+	/** Packet length upper bounds of the free packet queues.
+	 *  The maximal lengths of packets in each queue in the ascending order.
+	 *  The last queue is not limited.
+	 */
+	size_t sizes[FREE_QUEUES_COUNT];
+	/** Total packets allocated.
+	 */
+	unsigned int count;
+} ps_globals = {
+	.lock = {
+		.counter = 1,
+		.waiters = {
+			.prev = &ps_globals.lock.waiters,
+			.next = &ps_globals.lock.waiters,
+		}
+	},
+	.free = {NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	.sizes = {PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 4, PAGE_SIZE * 8, PAGE_SIZE * 16, PAGE_SIZE * 32, PAGE_SIZE * 64},
+	.count = 0
+};
+
+int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){
+	if(! packet){
+		return EINVAL;
+	}
+	*packet = pm_find(packet_id);
+	return (*packet) ? EOK : ENOENT;
+}
+
+/** Clears and initializes the packet according to the given dimensions.
+ *  @param[in] packet The packet to be initialized.
+ *  @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.
+ */
+static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
+	// clear the packet content
+	bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet));
+	// clear the packet header
+	packet->order = 0;
+	packet->metric = 0;
+	packet->previous = 0;
+	packet->next = 0;
+	packet->addr_len = 0;
+	packet->src_addr = sizeof(struct packet);
+	packet->dest_addr = packet->src_addr + addr_len;
+	packet->max_prefix = max_prefix;
+	packet->max_content = max_content;
+	packet->data_start = packet->dest_addr + addr_len + packet->max_prefix;
+	packet->data_end = packet->data_start;
+}
+
+/** Creates a&nbsp;new packet of dimensions at least as given.
+ *  Should be used only when the global data are locked.
+ *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
+ *  @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 of dimensions at least as given.
+ *  @returns NULL if there is not enough memory left.
+ */
+static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
+	ERROR_DECLARE;
+
+	packet_t packet;
+
+	// already locked
+	packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+	if(packet == MAP_FAILED){
+		return NULL;
+	}
+	++ ps_globals.count;
+	packet->packet_id = ps_globals.count;
+	packet->length = length;
+	packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
+	packet->magic_value = PACKET_MAGIC_VALUE;
+	if(ERROR_OCCURRED(pm_add(packet))){
+		munmap(packet, packet->length);
+		return NULL;
+	}
+	return packet;
+}
+
+/** Returns the packet of dimensions at least as given.
+ *  Tries to reuse free packets first.
+ *  Creates a&nbsp;new packet aligned to the memory page size if none available.
+ *  Locks the global data during its processing.
+ *  @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 of dimensions at least as given.
+ *  @returns NULL if there is not enough memory left.
+ */
+static packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
+	int index;
+	packet_t packet;
+	size_t length;
+
+	length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE);
+	fibril_mutex_lock(&ps_globals.lock);
+	for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){
+		if(length <= ps_globals.sizes[index]){
+			packet = ps_globals.free[index];
+			while(packet_is_valid(packet) && (packet->length < length)){
+				packet = pm_find(packet->next);
+			}
+			if(packet_is_valid(packet)){
+				if(packet == ps_globals.free[index]){
+					ps_globals.free[index] = pq_detach(packet);
+				}else{
+					pq_detach(packet);
+				}
+				packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
+				fibril_mutex_unlock(&ps_globals.lock);
+				// remove debug dump
+//				printf("packet %d got\n", packet->packet_id);
+				return packet;
+			}
+		}
+	}
+	packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix);
+	fibril_mutex_unlock(&ps_globals.lock);
+	// remove debug dump
+//	printf("packet %d created\n", packet->packet_id);
+	return packet;
+}
+
+packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){
+	return packet_get(addr_len, max_prefix, max_content, max_suffix);
+}
+
+packet_t packet_get_1(int phone, size_t content){
+	return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX);
+}
+
+/** Releases the packet and returns it to the appropriate free packet queue.
+ *  Should be used only when the global data are locked.
+ *  @param[in] packet The packet to be released.
+ */
+static void packet_release(packet_t packet){
+	int index;
+	int result;
+
+	// remove debug dump
+//	printf("packet %d released\n", packet->packet_id);
+	for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
+	result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
+	assert(result == EOK);
+}
+
+/** Releases the packet queue.
+ *  @param[in] packet_id The first packet identifier.
+ *  @returns EOK on success.
+ *  @returns ENOENT if there is no such packet.
+ */
+static int packet_release_wrapper(packet_id_t packet_id){
+	packet_t packet;
+
+	packet = pm_find(packet_id);
+	if(! packet_is_valid(packet)){
+		return ENOENT;
+	}
+	fibril_mutex_lock(&ps_globals.lock);
+	pq_destroy(packet, packet_release);
+	fibril_mutex_unlock(&ps_globals.lock);
+	return EOK;
+}
+
+void pq_release(int phone, packet_id_t packet_id){
+	(void) packet_release_wrapper(packet_id);
+}
+
+/** Shares the packet memory block.
+ *  @param[in] packet The packet to be shared.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns EINVAL if the calling module does not accept the memory.
+ *  @returns ENOMEM if the desired and actual sizes differ.
+ *  @returns Other error codes as defined for the async_share_in_finalize() function.
+ */
+static int packet_reply(const packet_t packet){
+	ipc_callid_t callid;
+	size_t size;
+
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	if(async_share_in_receive(&callid, &size) <= 0) return EINVAL;
+	if(size != packet->length){
+		return ENOMEM;
+	}
+	return async_share_in_finalize(callid, packet, PROTO_READ | PROTO_WRITE);
+}
+
+int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	packet_t packet;
+
+	*answer_count = 0;
+	switch(IPC_GET_METHOD(*call)){
+		case IPC_M_PHONE_HUNGUP:
+			return EOK;
+		case NET_PACKET_CREATE_1:
+			packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
+			if(! packet){
+				return ENOMEM;
+			}
+			*answer_count = 2;
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
+			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
+			return EOK;
+		case NET_PACKET_CREATE_4:
+			packet = packet_get(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
+			if(! packet){
+				return ENOMEM;
+			}
+			*answer_count = 2;
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
+			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
+			return EOK;
+		case NET_PACKET_GET:
+			packet = pm_find(IPC_GET_ID(call));
+			if(! packet_is_valid(packet)){
+				return ENOENT;
+			}
+			return packet_reply(packet);
+		case NET_PACKET_GET_SIZE:
+			packet = pm_find(IPC_GET_ID(call));
+			if(! packet_is_valid(packet)){
+				return ENOENT;
+			}
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
+			*answer_count = 1;
+			return EOK;
+		case NET_PACKET_RELEASE:
+			return packet_release_wrapper(IPC_GET_ID(call));
+	}
+	return ENOTSUP;
+}
+
+/** @}
+ */
