Index: uspace/srv/net/app/echo/echo.c
===================================================================
--- uspace/srv/net/app/echo/echo.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/echo/echo.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -55,4 +55,8 @@
 #define NAME	"Echo"
 
+/** Prints the application help.
+ */
+void echo_print_help(void);
+
 /** Module entry point.
  *  Reads command line parameters and starts listenning.
@@ -62,22 +66,4 @@
  */
 int main(int argc, char * argv[]);
-
-/** Prints the application help.
- */
-void echo_print_help(void);
-
-/** Translates the character string to the protocol family number.
- *  @param[in] name The protocol family name.
- *  @returns The corresponding protocol family number.
- *  @returns EPFNOSUPPORTED if the protocol family is not supported.
- */
-int echo_parse_protocol_family(const char * name);
-
-/** Translates the character string to the socket type number.
- *  @param[in] name The socket type name.
- *  @returns The corresponding socket type number.
- *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
- */
-int echo_parse_socket_type(const char * name);
 
 void echo_print_help(void){
@@ -115,22 +101,4 @@
 }
 
-int echo_parse_protocol_family(const char * name){
-	if(str_lcmp(name, "PF_INET", 7) == 0){
-		return PF_INET;
-	}else if(str_lcmp(name, "PF_INET6", 8) == 0){
-		return PF_INET6;
-	}
-	return EPFNOSUPPORT;
-}
-
-int echo_parse_socket_type(const char * name){
-	if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
-		return SOCK_DGRAM;
-	}else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
-		return SOCK_STREAM;
-	}
-	return ESOCKTNOSUPPORT;
-}
-
 int main(int argc, char * argv[]){
 	ERROR_DECLARE;
@@ -138,14 +106,14 @@
 	size_t size			= 1024;
 	int verbose			= 0;
-	char * reply			= NULL;
-	sock_type_t type			= SOCK_DGRAM;
+	char * reply		= NULL;
+	sock_type_t type	= SOCK_DGRAM;
 	int count			= -1;
 	int family			= PF_INET;
-	uint16_t port			= 7;
+	uint16_t port		= 7;
 	int backlog			= 3;
 
-	socklen_t max_length		= sizeof(struct sockaddr_in6);
+	socklen_t max_length				= sizeof(struct sockaddr_in6);
 	uint8_t address_data[max_length];
-	struct sockaddr * address		= (struct sockaddr *) address_data;
+	struct sockaddr * address			= (struct sockaddr *) address_data;
 	struct sockaddr_in * address_in		= (struct sockaddr_in *) address;
 	struct sockaddr_in6 * address_in6	= (struct sockaddr_in6 *) address;
@@ -155,5 +123,5 @@
 	int socket_id;
 	int listening_id;
-	char * 				data;
+	char * data;
 	size_t length;
 	int index;
@@ -161,7 +129,9 @@
 	int value;
 
+	// print the program label
 	printf("Task %d - ", task_get_id());
 	printf("%s\n", NAME);
 
+	// parse the command line arguments
 	for(index = 1; index < argc; ++ index){
 		if(argv[index][0] == '-'){
@@ -174,5 +144,5 @@
 					break;
 				case 'f':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));
+					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
 					break;
 				case 'h':
@@ -192,5 +162,5 @@
 					break;
 				case 't':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));
+					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
 					type = (sock_type_t) value;
 					break;
@@ -198,4 +168,5 @@
 					verbose = 1;
 					break;
+				// long options with the double minus sign ('-')
 				case '-':
 					if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
@@ -204,5 +175,5 @@
 						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
 					}else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));
+						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
 						echo_print_help();
@@ -217,5 +188,5 @@
 						size = (value >= 0) ? (size_t) value : 0;
 					}else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));
+						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
 						type = (sock_type_t) value;
 					}else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
@@ -239,9 +210,10 @@
 	}
 
+	// check the buffer size
 	if(size <= 0){
 		fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
 		size = 1024;
 	}
-	// size plus terminating null (\0)
+	// size plus the terminating null (\0)
 	data = (char *) malloc(size + 1);
 	if(! data){
@@ -250,12 +222,8 @@
 	}
 
+	// set the reply size if set
 	reply_length = reply ? str_length(reply) : 0;
 
-	listening_id = socket(family, type, 0);
-	if(listening_id < 0){
-		socket_print_error(stderr, listening_id, "Socket create: ", "\n");
-		return listening_id;
-	}
-
+	// prepare the address buffer
 	bzero(address_data, max_length);
 	switch(family){
@@ -275,4 +243,5 @@
 	}
 
+	// get a listening socket
 	listening_id = socket(family, type, 0);
 	if(listening_id < 0){
@@ -281,9 +250,12 @@
 	}
 
+	// if the stream socket is used
 	if(type == SOCK_STREAM){
+		// check the backlog
 		if(backlog <= 0){
 			fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
 			backlog = 3;
 		}
+		// set the backlog
 		if(ERROR_OCCURRED(listen(listening_id, backlog))){
 			socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
@@ -292,4 +264,5 @@
 	}
 
+	// bind the listenning socket
 	if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
 		socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
@@ -303,7 +276,11 @@
 	socket_id = listening_id;
 
+	// do count times
+	// or indefinitely if set to a negative value
 	while(count){
+
 		addrlen = max_length;
 		if(type == SOCK_STREAM){
+			// acceept a socket if the stream socket is used
 			socket_id = accept(listening_id, address, &addrlen);
 			if(socket_id <= 0){
@@ -315,5 +292,9 @@
 			}
 		}
+
+		// if the datagram socket is used or the stream socked was accepted
 		if(socket_id > 0){
+
+			// receive an echo request
 			value = recvfrom(socket_id, data, size, 0, address, &addrlen);
 			if(value < 0){
@@ -322,4 +303,7 @@
 				length = (size_t) value;
 				if(verbose){
+					// print the header
+
+					// get the source port and prepare the address buffer
 					address_start = NULL;
 					switch(address->sa_family){
@@ -335,4 +319,5 @@
 							fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
 					}
+					// parse the source address
 					if(address_start){
 						if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
@@ -344,8 +329,13 @@
 					}
 				}
+
+				// answer the request either with the static reply or the original data
 				if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
 					socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
 				}
-			}
+
+			}
+
+			// close the accepted stream socket
 			if(type == SOCK_STREAM){
 				if(ERROR_OCCURRED(closesocket(socket_id))){
@@ -353,5 +343,8 @@
 				}
 			}
-		}
+
+		}
+
+		// decrease the count if positive
 		if(count > 0){
 			-- count;
@@ -366,4 +359,5 @@
 	}
 
+	// close the listenning socket
 	if(ERROR_OCCURRED(closesocket(listening_id))){
 		socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
Index: uspace/srv/net/app/nettest.c
===================================================================
--- uspace/srv/net/app/nettest.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
+++ uspace/srv/net/app/nettest.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -0,0 +1,202 @@
+/*
+ * 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 nettest
+ *  @{
+ */
+
+/** @file
+ *  Networking test support functions implementation.
+ */
+
+#include <stdio.h>
+
+#include "../include/socket.h"
+
+#include "../err.h"
+
+#include "nettest.h"
+#include "print_error.h"
+
+int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
+	int index;
+
+	if(verbose){
+		printf("Create\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		socket_ids[index] = socket(family, type, 0);
+		if(socket_ids[index] < 0){
+			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
+			socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
+			return socket_ids[index];
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+int sockets_close(int verbose, int * socket_ids, int sockets){
+	ERROR_DECLARE;
+
+	int index;
+
+	if(verbose){
+		printf("\tClose\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
+			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
+			socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
+			return ERROR_CODE;
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
+	ERROR_DECLARE;
+
+	int index;
+
+	if(verbose){
+		printf("\tConnect\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
+			socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
+			return ERROR_CODE;
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
+	ERROR_DECLARE;
+
+	int index;
+	int message;
+
+	if(verbose){
+		printf("\tSendto\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		for(message = 0; message < messages; ++ message){
+			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
+				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
+				return ERROR_CODE;
+			}
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
+	int value;
+	int index;
+	int message;
+
+	if(verbose){
+		printf("\tRecvfrom\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		for(message = 0; message < messages; ++ message){
+			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
+			if(value < 0){
+				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				socket_print_error(stderr, value, "Socket receive: ", "\n");
+				return value;
+			}
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
+	ERROR_DECLARE;
+
+	int value;
+	int index;
+	int message;
+
+	if(verbose){
+		printf("\tSendto and recvfrom\t");
+	}
+	fflush(stdout);
+	for(index = 0; index < sockets; ++ index){
+		for(message = 0; message < messages; ++ message){
+			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
+				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
+				return ERROR_CODE;
+			}
+			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
+			if(value < 0){
+				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				socket_print_error(stderr, value, "Socket receive: ", "\n");
+				return value;
+			}
+		}
+		if(verbose){
+			print_mark(index);
+		}
+	}
+	return EOK;
+}
+
+void print_mark(int index){
+	if((index + 1) % 10){
+		printf("*");
+	}else{
+		printf("|");
+	}
+	fflush(stdout);
+}
+
+/** @}
+ */
Index: uspace/srv/net/app/nettest.h
===================================================================
--- uspace/srv/net/app/nettest.h	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
+++ uspace/srv/net/app/nettest.h	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -0,0 +1,126 @@
+/*
+ * 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 nettest
+ *  @{
+ */
+
+/** @file
+ *  Networking test support functions.
+ */
+
+#ifndef __NET_TEST__
+#define __NET_TEST__
+
+#include "../include/socket.h"
+
+/** Prints a mark.
+ *  If the index is a multiple of ten, a different mark is printed.
+ *  @param[in] index The index of the mark to be printed.
+ */
+void print_mark(int index);
+
+/** Creates new sockets.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[out] socket_ids A field to store the socket identifiers.
+ *  @param[in] sockets The number of sockets to create. Should be at most the size of the field.
+ *  @param[in] family The socket address family.
+ *  @param[in] type The socket type.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the socket() function.
+ */
+int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type);
+
+/** Closes sockets.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[in] socket_ids A field of stored socket identifiers.
+ *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the closesocket() function.
+ */
+int sockets_close(int verbose, int * socket_ids, int sockets);
+
+/** Connects sockets.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[in] socket_ids A field of stored socket identifiers.
+ *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
+ *  @param[in] address The destination host address to connect to.
+ *  @param[in] addrlen The length of the destination address in bytes.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the connect() function.
+ */
+int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen);
+
+/** Sends data via sockets.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[in] socket_ids A field of stored socket identifiers.
+ *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
+ *  @param[in] address The destination host address to send data to.
+ *  @param[in] addrlen The length of the destination address in bytes.
+ *  @param[in] data The data to be sent.
+ *  @param[in] size The data size in bytes.
+ *  @param[in] messages The number of datagrams per socket to be sent.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the sendto() function.
+ */
+int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages);
+
+/** Receives data via sockets.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[in] socket_ids A field of stored socket identifiers.
+ *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
+ *  @param[in] address The source host address of received datagrams.
+ *  @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
+ *  @param[out] data The received data.
+ *  @param[in] size The maximum data size in bytes.
+ *  @param[in] messages The number of datagrams per socket to be received.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the recvfrom() function.
+ */
+int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
+
+/** Sends and receives data via sockets.
+ *  Each datagram is sent and a reply read consequently.
+ *  The next datagram is sent after the reply is received.
+ *  @param[in] verbose A value indicating whether to print out verbose information.
+ *  @param[in] socket_ids A field of stored socket identifiers.
+ *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
+ *  @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
+ *  @param[in] addrlen The length of the destination address in bytes.
+ *  @param[in,out] data The data to be sent. The received data are set instead.
+ *  @param[in] size The data size in bytes.
+ *  @param[in] messages The number of datagrams per socket to be received.
+ *  @returns EOK on success.
+ *  @returns Other error codes as defined for the recvfrom() function.
+ */
+int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/app/nettest1/Makefile
===================================================================
--- uspace/srv/net/app/nettest1/Makefile	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/nettest1/Makefile	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -40,4 +40,5 @@
 SOURCES = \
 	$(NAME).c \
+	$(NET_BASE)app/nettest.c \
 	$(NET_BASE)app/parse.c \
 	$(NET_BASE)app/print_error.c
Index: uspace/srv/net/app/nettest1/nettest1.c
===================================================================
--- uspace/srv/net/app/nettest1/nettest1.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/nettest1/nettest1.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -48,4 +48,5 @@
 #include "../../err.h"
 
+#include "../nettest.h"
 #include "../parse.h"
 #include "../print_error.h"
@@ -69,19 +70,5 @@
 /** Prints the application help.
  */
-void print_help(void);
-
-/** Translates the character string to the protocol family number.
- *  @param[in] name The protocol family name.
- *  @returns The corresponding protocol family number.
- *  @returns EPFNOSUPPORTED if the protocol family is not supported.
- */
-int parse_protocol_family(const char * name);
-
-/** Translates the character string to the socket type number.
- *  @param[in] name The socket type name.
- *  @returns The corresponding socket type number.
- *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
- */
-int parse_socket_type(const char * name);
+void nettest1_print_help(void);
 
 /** Refreshes the data.
@@ -90,300 +77,5 @@
  *  @param[in] size The data block size in bytes.
  */
-void refresh_data(char * data, size_t size);
-
-/** Creates new sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[out] socket_ids A field to store the socket identifiers.
- *  @param[in] sockets The number of sockets to create. Should be at most the size of the field.
- *  @param[in] family The socket address family.
- *  @param[in] type The socket type.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the socket() function.
- */
-int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type);
-
-/** Closes sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the closesocket() function.
- */
-int sockets_close(int verbose, int * socket_ids, int sockets);
-
-/** Connects sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The destination host address to connect to.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the connect() function.
- */
-int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen);
-
-/** Sends data via sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The destination host address to send data to.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @param[in] data The data to be sent.
- *  @param[in] size The data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be sent.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the sendto() function.
- */
-int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages);
-
-/** Receives data via sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The source host address of received datagrams.
- *  @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
- *  @param[out] data The received data.
- *  @param[in] size The maximum data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be received.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the recvfrom() function.
- */
-int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
-
-/** Sends and receives data via sockets.
- *  Each datagram is sent and a reply read consequently.
- *  The next datagram is sent after the reply is received.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @param[in,out] data The data to be sent. The received data are set instead.
- *  @param[in] size The data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be received.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the recvfrom() function.
- */
-int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
-
-/** Prints a mark.
- *  If the index is a multiple of ten, a different mark is printed.
- *  @param[in] index The index of the mark to be printed.
- */
-void print_mark(int index);
-
-void print_help(void){
-	printf(
-		"Network Networking test 1 aplication - sockets\n" \
-		"Usage: echo [options] numeric_address\n" \
-		"Where options are:\n" \
-		"-f protocol_family | --family=protocol_family\n" \
-		"\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
-		"\n" \
-		"-h | --help\n" \
-		"\tShow this application help.\n"
-		"\n" \
-		"-m count | --messages=count\n" \
-		"\tThe number of messages to send and receive per socket. The default is 10.\n" \
-		"\n" \
-		"-n sockets | --sockets=count\n" \
-		"\tThe number of sockets to use. The default is 10.\n" \
-		"\n" \
-		"-p port_number | --port=port_number\n" \
-		"\tThe port number the application should send messages to. The default is 7.\n" \
-		"\n" \
-		"-s packet_size | --size=packet_size\n" \
-		"\tThe packet data size the application sends. The default is 28 bytes.\n" \
-		"\n" \
-		"-v | --verbose\n" \
-		"\tShow all output messages.\n"
-	);
-}
-
-int parse_protocol_family(const char * name){
-	if(str_lcmp(name, "PF_INET", 7) == 0){
-		return PF_INET;
-	}else if(str_lcmp(name, "PF_INET6", 8) == 0){
-		return PF_INET6;
-	}
-	return EPFNOSUPPORT;
-}
-
-int parse_socket_type(const char * name){
-	if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
-		return SOCK_DGRAM;
-	}else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
-		return SOCK_STREAM;
-	}
-	return ESOCKTNOSUPPORT;
-}
-
-void refresh_data(char * data, size_t size){
-	size_t length;
-
-	// fill the data
-	length = 0;
-	while(size > length + sizeof(NETTEST1_TEXT) - 1){
-		memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
-		length += sizeof(NETTEST1_TEXT) - 1;
-	}
-	memcpy(data + length, NETTEST1_TEXT, size - length);
-	data[size] = '\0';
-}
-
-int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
-	int index;
-
-	if(verbose){
-		printf("Create\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		socket_ids[index] = socket(family, type, 0);
-		if(socket_ids[index] < 0){
-			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
-			socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
-			return socket_ids[index];
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_close(int verbose, int * socket_ids, int sockets){
-	ERROR_DECLARE;
-
-	int index;
-
-	if(verbose){
-		printf("\tClose\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
-			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
-			socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
-			return ERROR_CODE;
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
-	ERROR_DECLARE;
-
-	int index;
-
-	if(verbose){
-		printf("\tConnect\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
-			socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
-			return ERROR_CODE;
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
-	ERROR_DECLARE;
-
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tSendto\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
-				return ERROR_CODE;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
-	int value;
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tRecvfrom\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
-			if(value < 0){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, value, "Socket receive: ", "\n");
-				return value;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
-	ERROR_DECLARE;
-
-	int value;
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tSendto and recvfrom\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
-				return ERROR_CODE;
-			}
-			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
-			if(value < 0){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, value, "Socket receive: ", "\n");
-				return value;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-void print_mark(int index){
-	if((index + 1) % 10){
-		printf("*");
-	}else{
-		printf("|");
-	}
-	fflush(stdout);
-}
+void nettest1_refresh_data(char * data, size_t size);
 
 int main(int argc, char * argv[]){
@@ -392,21 +84,21 @@
 	size_t size			= 27;
 	int verbose			= 0;
-	sock_type_t type			= SOCK_DGRAM;
+	sock_type_t type	= SOCK_DGRAM;
 	int sockets			= 10;
 	int messages		= 10;
 	int family			= PF_INET;
-	uint16_t port			= 7;
-
-	socklen_t max_length		= sizeof(struct sockaddr_in6);
+	uint16_t port		= 7;
+
+	socklen_t max_length				= sizeof(struct sockaddr_in6);
 	uint8_t address_data[max_length];
-	struct sockaddr * address		= (struct sockaddr *) address_data;
+	struct sockaddr * address			= (struct sockaddr *) address_data;
 	struct sockaddr_in * address_in		= (struct sockaddr_in *) address;
 	struct sockaddr_in6 * address_in6	= (struct sockaddr_in6 *) address;
 	socklen_t addrlen;
-//	char				address_string[INET6_ADDRSTRLEN];
+//	char address_string[INET6_ADDRSTRLEN];
 	uint8_t * address_start;
 
 	int * socket_ids;
-	char * 				data;
+	char * data;
 	int value;
 	int index;
@@ -414,20 +106,20 @@
 	struct timeval time_after;
 
+	// print the program label
 	printf("Task %d - ", task_get_id());
 	printf("%s\n", NAME);
 
-	if(argc <= 1){
-		print_help();
-		return EINVAL;
-	}
-
-	for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
+	// parse the command line arguments
+	// stop before the last argument if it does not start with the minus sign ('-')
+	for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
+		// options should start with the minus sign ('-')
 		if(argv[index][0] == '-'){
 			switch(argv[index][1]){
+				// short options with only one letter
 				case 'f':
 					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
 					break;
 				case 'h':
-					print_help();
+					nettest1_print_help();
 					return EOK;
 					break;
@@ -453,9 +145,10 @@
 					verbose = 1;
 					break;
+				// long options with the double minus sign ('-')
 				case '-':
 					if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
 						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
-						print_help();
+						nettest1_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
@@ -473,5 +166,5 @@
 					}else{
 						print_unrecognized(index, argv[index] + 2);
-						print_help();
+						nettest1_print_help();
 						return EINVAL;
 					}
@@ -479,14 +172,22 @@
 				default:
 					print_unrecognized(index, argv[index] + 1);
-					print_help();
+					nettest1_print_help();
 					return EINVAL;
 			}
 		}else{
 			print_unrecognized(index, argv[index]);
-			print_help();
+			nettest1_print_help();
 			return EINVAL;
 		}
 	}
 
+	// if not before the last argument containing the address
+	if(index >= argc){
+		printf("Command line error: missing address\n");
+		nettest1_print_help();
+		return EINVAL;
+	}
+
+	// prepare the address buffer
 	bzero(address_data, max_length);
 	switch(family){
@@ -508,4 +209,5 @@
 	}
 
+	// parse the last argument which should contain the address
 	if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
 		fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
@@ -513,9 +215,12 @@
 	}
 
+	// check the buffer size
 	if(size <= 0){
 		fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
 		size = 1024;
 	}
-	// size plus terminating null (\0)
+
+	// prepare the buffer
+	// size plus the terminating null (\0)
 	data = (char *) malloc(size + 1);
 	if(! data){
@@ -523,11 +228,14 @@
 		return ENOMEM;
 	}
-	refresh_data(data, size);
-
+	nettest1_refresh_data(data, size);
+
+	// check the socket count
 	if(sockets <= 0){
 		fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
 		sockets = 2;
 	}
-	// count plus terminating null (\0)
+
+	// prepare the socket buffer
+	// count plus the terminating null (\0)
 	socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
 	if(! socket_ids){
@@ -673,4 +381,45 @@
 }
 
+void nettest1_print_help(void){
+	printf(
+		"Network Networking test 1 aplication - sockets\n" \
+		"Usage: echo [options] numeric_address\n" \
+		"Where options are:\n" \
+		"-f protocol_family | --family=protocol_family\n" \
+		"\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
+		"\n" \
+		"-h | --help\n" \
+		"\tShow this application help.\n"
+		"\n" \
+		"-m count | --messages=count\n" \
+		"\tThe number of messages to send and receive per socket. The default is 10.\n" \
+		"\n" \
+		"-n sockets | --sockets=count\n" \
+		"\tThe number of sockets to use. The default is 10.\n" \
+		"\n" \
+		"-p port_number | --port=port_number\n" \
+		"\tThe port number the application should send messages to. The default is 7.\n" \
+		"\n" \
+		"-s packet_size | --size=packet_size\n" \
+		"\tThe packet data size the application sends. The default is 28 bytes.\n" \
+		"\n" \
+		"-v | --verbose\n" \
+		"\tShow all output messages.\n"
+	);
+}
+
+void nettest1_refresh_data(char * data, size_t size){
+	size_t length;
+
+	// fill the data
+	length = 0;
+	while(size > length + sizeof(NETTEST1_TEXT) - 1){
+		memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
+		length += sizeof(NETTEST1_TEXT) - 1;
+	}
+	memcpy(data + length, NETTEST1_TEXT, size - length);
+	data[size] = '\0';
+}
+
 /** @}
  */
Index: uspace/srv/net/app/nettest2/Makefile
===================================================================
--- uspace/srv/net/app/nettest2/Makefile	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/nettest2/Makefile	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -40,4 +40,5 @@
 SOURCES = \
 	$(NAME).c \
+	$(NET_BASE)app/nettest.c \
 	$(NET_BASE)app/parse.c \
 	$(NET_BASE)app/print_error.c
Index: uspace/srv/net/app/nettest2/nettest2.c
===================================================================
--- uspace/srv/net/app/nettest2/nettest2.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/nettest2/nettest2.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -48,4 +48,5 @@
 #include "../../err.h"
 
+#include "../nettest.h"
 #include "../parse.h"
 #include "../print_error.h"
@@ -69,19 +70,5 @@
 /** Prints the application help.
  */
-void print_help(void);
-
-/** Translates the character string to the protocol family number.
- *  @param[in] name The protocol family name.
- *  @returns The corresponding protocol family number.
- *  @returns EPFNOSUPPORTED if the protocol family is not supported.
- */
-int parse_protocol_family(const char * name);
-
-/** Translates the character string to the socket type number.
- *  @param[in] name The socket type name.
- *  @returns The corresponding socket type number.
- *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
- */
-int parse_socket_type(const char * name);
+void nettest2_print_help(void);
 
 /** Refreshes the data.
@@ -90,300 +77,5 @@
  *  @param[in] size The data block size in bytes.
  */
-void refresh_data(char * data, size_t size);
-
-/** Creates new sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[out] socket_ids A field to store the socket identifiers.
- *  @param[in] sockets The number of sockets to create. Should be at most the size of the field.
- *  @param[in] family The socket address family.
- *  @param[in] type The socket type.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the socket() function.
- */
-int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type);
-
-/** Closes sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the closesocket() function.
- */
-int sockets_close(int verbose, int * socket_ids, int sockets);
-
-/** Connects sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The destination host address to connect to.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the connect() function.
- */
-int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen);
-
-/** Sends data via sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The destination host address to send data to.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @param[in] data The data to be sent.
- *  @param[in] size The data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be sent.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the sendto() function.
- */
-int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages);
-
-/** Receives data via sockets.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in] address The source host address of received datagrams.
- *  @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
- *  @param[out] data The received data.
- *  @param[in] size The maximum data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be received.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the recvfrom() function.
- */
-int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
-
-/** Sends and receives data via sockets.
- *  Each datagram is sent and a reply read consequently.
- *  The next datagram is sent after the reply is received.
- *  @param[in] verbose A value indicating whether to print out verbose information.
- *  @param[in] socket_ids A field of stored socket identifiers.
- *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
- *  @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
- *  @param[in] addrlen The length of the destination address in bytes.
- *  @param[in,out] data The data to be sent. The received data are set instead.
- *  @param[in] size The data size in bytes.
- *  @param[in] messages The number of datagrams per socket to be received.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the recvfrom() function.
- */
-int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
-
-/** Prints a mark.
- *  If the index is a multiple of ten, a different mark is printed.
- *  @param[in] index The index of the mark to be printed.
- */
-void print_mark(int index);
-
-void print_help(void){
-	printf(
-		"Network Networking test 2 aplication - UDP transfer\n" \
-		"Usage: echo [options] numeric_address\n" \
-		"Where options are:\n" \
-		"-f protocol_family | --family=protocol_family\n" \
-		"\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
-		"\n" \
-		"-h | --help\n" \
-		"\tShow this application help.\n"
-		"\n" \
-		"-m count | --messages=count\n" \
-		"\tThe number of messages to send and receive per socket. The default is 10.\n" \
-		"\n" \
-		"-n sockets | --sockets=count\n" \
-		"\tThe number of sockets to use. The default is 10.\n" \
-		"\n" \
-		"-p port_number | --port=port_number\n" \
-		"\tThe port number the application should send messages to. The default is 7.\n" \
-		"\n" \
-		"-s packet_size | --size=packet_size\n" \
-		"\tThe packet data size the application sends. The default is 29 bytes.\n" \
-		"\n" \
-		"-v | --verbose\n" \
-		"\tShow all output messages.\n"
-	);
-}
-
-int parse_protocol_family(const char * name){
-	if(str_lcmp(name, "PF_INET", 7) == 0){
-		return PF_INET;
-	}else if(str_lcmp(name, "PF_INET6", 8) == 0){
-		return PF_INET6;
-	}
-	return EPFNOSUPPORT;
-}
-
-int parse_socket_type(const char * name){
-	if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
-		return SOCK_DGRAM;
-	}else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
-		return SOCK_STREAM;
-	}
-	return ESOCKTNOSUPPORT;
-}
-
-void refresh_data(char * data, size_t size){
-	size_t length;
-
-	// fill the data
-	length = 0;
-	while(size > length + sizeof(NETTEST2_TEXT) - 1){
-		memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
-		length += sizeof(NETTEST2_TEXT) - 1;
-	}
-	memcpy(data + length, NETTEST2_TEXT, size - length);
-	data[size] = '\0';
-}
-
-int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
-	int index;
-
-	if(verbose){
-		printf("Create\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		socket_ids[index] = socket(family, type, 0);
-		if(socket_ids[index] < 0){
-			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
-			socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
-			return socket_ids[index];
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_close(int verbose, int * socket_ids, int sockets){
-	ERROR_DECLARE;
-
-	int index;
-
-	if(verbose){
-		printf("\tClose\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
-			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
-			socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
-			return ERROR_CODE;
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
-	ERROR_DECLARE;
-
-	int index;
-
-	if(verbose){
-		printf("\tConnect\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
-			socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
-			return ERROR_CODE;
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
-	ERROR_DECLARE;
-
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tSendto\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
-				return ERROR_CODE;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
-	int value;
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tRecvfrom\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
-			if(value < 0){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, value, "Socket receive: ", "\n");
-				return value;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
-	ERROR_DECLARE;
-
-	int value;
-	int index;
-	int message;
-
-	if(verbose){
-		printf("\tSendto and recvfrom\t");
-	}
-	fflush(stdout);
-	for(index = 0; index < sockets; ++ index){
-		for(message = 0; message < messages; ++ message){
-			if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
-				return ERROR_CODE;
-			}
-			value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
-			if(value < 0){
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
-				socket_print_error(stderr, value, "Socket receive: ", "\n");
-				return value;
-			}
-		}
-		if(verbose){
-			print_mark(index);
-		}
-	}
-	return EOK;
-}
-
-void print_mark(int index){
-	if((index + 1) % 10){
-		printf("*");
-	}else{
-		printf("|");
-	}
-	fflush(stdout);
-}
+void nettest2_refresh_data(char * data, size_t size);
 
 int main(int argc, char * argv[]){
@@ -392,21 +84,21 @@
 	size_t size			= 28;
 	int verbose			= 0;
-	sock_type_t type			= SOCK_DGRAM;
+	sock_type_t type	= SOCK_DGRAM;
 	int sockets			= 10;
 	int messages		= 10;
 	int family			= PF_INET;
-	uint16_t port			= 7;
-
-	socklen_t max_length		= sizeof(struct sockaddr_in6);
+	uint16_t port		= 7;
+
+	socklen_t max_length				= sizeof(struct sockaddr_in6);
 	uint8_t address_data[max_length];
-	struct sockaddr * address		= (struct sockaddr *) address_data;
+	struct sockaddr * address			= (struct sockaddr *) address_data;
 	struct sockaddr_in * address_in		= (struct sockaddr_in *) address;
 	struct sockaddr_in6 * address_in6	= (struct sockaddr_in6 *) address;
 	socklen_t addrlen;
-//	char				address_string[INET6_ADDRSTRLEN];
+//	char address_string[INET6_ADDRSTRLEN];
 	uint8_t * address_start;
 
 	int * socket_ids;
-	char * 				data;
+	char * data;
 	int value;
 	int index;
@@ -417,17 +109,16 @@
 	printf("%s\n", NAME);
 
-	if(argc <= 1){
-		print_help();
-		return EINVAL;
-	}
-
-	for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
+	// parse the command line arguments
+	// stop before the last argument if it does not start with the minus sign ('-')
+	for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
+		// options should start with the minus sign ('-')
 		if(argv[index][0] == '-'){
 			switch(argv[index][1]){
+				// short options with only one letter
 				case 'f':
 					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
 					break;
 				case 'h':
-					print_help();
+					nettest2_print_help();
 					return EOK;
 					break;
@@ -453,9 +144,10 @@
 					verbose = 1;
 					break;
+				// long options with the double minus sign ('-')
 				case '-':
 					if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
 						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
-						print_help();
+						nettest2_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
@@ -473,5 +165,5 @@
 					}else{
 						print_unrecognized(index, argv[index] + 2);
-						print_help();
+						nettest2_print_help();
 						return EINVAL;
 					}
@@ -479,14 +171,22 @@
 				default:
 					print_unrecognized(index, argv[index] + 1);
-					print_help();
+					nettest2_print_help();
 					return EINVAL;
 			}
 		}else{
 			print_unrecognized(index, argv[index]);
-			print_help();
+			nettest2_print_help();
 			return EINVAL;
 		}
 	}
 
+	// if not before the last argument containing the address
+	if(index >= argc){
+		printf("Command line error: missing address\n");
+		nettest2_print_help();
+		return EINVAL;
+	}
+
+	// prepare the address buffer
 	bzero(address_data, max_length);
 	switch(family){
@@ -508,4 +208,5 @@
 	}
 
+	// parse the last argument which should contain the address
 	if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
 		fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
@@ -513,8 +214,11 @@
 	}
 
+	// check the buffer size
 	if(size <= 0){
 		fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
 		size = 1024;
 	}
+
+	// prepare the buffer
 	// size plus terminating null (\0)
 	data = (char *) malloc(size + 1);
@@ -523,11 +227,14 @@
 		return ENOMEM;
 	}
-	refresh_data(data, size);
-
+	nettest2_refresh_data(data, size);
+
+	// check the socket count
 	if(sockets <= 0){
 		fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
 		sockets = 2;
 	}
-	// count plus terminating null (\0)
+
+	// prepare the socket buffer
+	// count plus the terminating null (\0)
 	socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
 	if(! socket_ids){
@@ -597,4 +304,45 @@
 }
 
+void nettest2_print_help(void){
+	printf(
+		"Network Networking test 2 aplication - UDP transfer\n" \
+		"Usage: echo [options] numeric_address\n" \
+		"Where options are:\n" \
+		"-f protocol_family | --family=protocol_family\n" \
+		"\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
+		"\n" \
+		"-h | --help\n" \
+		"\tShow this application help.\n"
+		"\n" \
+		"-m count | --messages=count\n" \
+		"\tThe number of messages to send and receive per socket. The default is 10.\n" \
+		"\n" \
+		"-n sockets | --sockets=count\n" \
+		"\tThe number of sockets to use. The default is 10.\n" \
+		"\n" \
+		"-p port_number | --port=port_number\n" \
+		"\tThe port number the application should send messages to. The default is 7.\n" \
+		"\n" \
+		"-s packet_size | --size=packet_size\n" \
+		"\tThe packet data size the application sends. The default is 29 bytes.\n" \
+		"\n" \
+		"-v | --verbose\n" \
+		"\tShow all output messages.\n"
+	);
+}
+
+void nettest2_refresh_data(char * data, size_t size){
+	size_t length;
+
+	// fill the data
+	length = 0;
+	while(size > length + sizeof(NETTEST2_TEXT) - 1){
+		memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
+		length += sizeof(NETTEST2_TEXT) - 1;
+	}
+	memcpy(data + length, NETTEST2_TEXT, size - length);
+	data[size] = '\0';
+}
+
 /** @}
  */
Index: uspace/srv/net/app/parse.c
===================================================================
--- uspace/srv/net/app/parse.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/parse.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -38,7 +38,18 @@
 #include <string.h>
 
+#include "../include/socket.h"
+
 #include "../err.h"
 
 #include "parse.h"
+
+int parse_address_family(const char * name){
+	if(str_lcmp(name, "AF_INET", 7) == 0){
+		return AF_INET;
+	}else if(str_lcmp(name, "AF_INET6", 8) == 0){
+		return AF_INET6;
+	}
+	return EAFNOSUPPORT;
+}
 
 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset){
@@ -61,17 +72,4 @@
 }
 
-int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){
-	if(offset){
-		*value = argv[*index] + offset;
-	}else if((*index) + 1 < argc){
-		++ (*index);
-		*value = argv[*index];
-	}else{
-		fprintf(stderr, "Command line error: missing %s\n", name);
-		return EINVAL;
-	}
-	return EOK;
-}
-
 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)){
 	ERROR_DECLARE;
@@ -88,6 +86,37 @@
 }
 
+int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){
+	if(offset){
+		*value = argv[*index] + offset;
+	}else if((*index) + 1 < argc){
+		++ (*index);
+		*value = argv[*index];
+	}else{
+		fprintf(stderr, "Command line error: missing %s\n", name);
+		return EINVAL;
+	}
+	return EOK;
+}
+
+int parse_protocol_family(const char * name){
+	if(str_lcmp(name, "PF_INET", 7) == 0){
+		return PF_INET;
+	}else if(str_lcmp(name, "PF_INET6", 8) == 0){
+		return PF_INET6;
+	}
+	return EPFNOSUPPORT;
+}
+
+int parse_socket_type(const char * name){
+	if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
+		return SOCK_DGRAM;
+	}else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
+		return SOCK_STREAM;
+	}
+	return ESOCKTNOSUPPORT;
+}
+
 void print_unrecognized(int index, const char * parameter){
-	fprintf(stderr, "Command line error - unrecognized parameter (%d: %s)\n", index, parameter);
+	fprintf(stderr, "Command line error: unrecognized argument (%d: %s)\n", index, parameter);
 }
 
Index: uspace/srv/net/app/parse.h
===================================================================
--- uspace/srv/net/app/parse.h	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/parse.h	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -38,9 +38,12 @@
 #define __NET_APP_PARSE__
 
-/** Prints the parameter unrecognized message and the application help.
- *  @param[in] index The index of the parameter.
- *  @param[in] parameter The parameter name.
+#include "../include/socket.h"
+
+/** Translates the character string to the address family number.
+ *  @param[in] name The address family name.
+ *  @returns The corresponding address family number.
+ *  @returns EAFNOSUPPORTED if the address family is not supported.
  */
-void print_unrecognized(int index, const char * parameter);
+int parse_address_family(const char * name);
 
 /** Parses the next parameter as an integral number.
@@ -58,19 +61,4 @@
  */
 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset);
-
-/** Parses the next parameter as a character string.
- *  The actual parameter is pointed by the index.
- *  Uses the offseted actual parameter value if the offset is set or the next one if not.
- *  Increments the actual index by the number of processed parameters.
- *  @param[in] argc The total number of the parameters.
- *  @param[in] argv The parameters.
- *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
- *  @param[out] value The parsed parameter value.
- *  @param[in] name The parameter name to be printed on errors.
- *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
- *  @returns EOK on success.
- *  @returns EINVAL if the parameter is missing.
- */
-int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);
 
 /** Parses the next named parameter as an integral number.
@@ -92,4 +80,39 @@
 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value));
 
+/** Parses the next parameter as a character string.
+ *  The actual parameter is pointed by the index.
+ *  Uses the offseted actual parameter value if the offset is set or the next one if not.
+ *  Increments the actual index by the number of processed parameters.
+ *  @param[in] argc The total number of the parameters.
+ *  @param[in] argv The parameters.
+ *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
+ *  @param[out] value The parsed parameter value.
+ *  @param[in] name The parameter name to be printed on errors.
+ *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the parameter is missing.
+ */
+int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);
+
+/** Translates the character string to the protocol family number.
+ *  @param[in] name The protocol family name.
+ *  @returns The corresponding protocol family number.
+ *  @returns EPFNOSUPPORTED if the protocol family is not supported.
+ */
+int parse_protocol_family(const char * name);
+
+/** Translates the character string to the socket type number.
+ *  @param[in] name The socket type name.
+ *  @returns The corresponding socket type number.
+ *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
+ */
+int parse_socket_type(const char * name);
+
+/** Prints the parameter unrecognized message and the application help.
+ *  @param[in] index The index of the parameter.
+ *  @param[in] parameter The parameter name.
+ */
+void print_unrecognized(int index, const char * parameter);
+
 #endif
 
Index: uspace/srv/net/app/ping/ping.c
===================================================================
--- uspace/srv/net/app/ping/ping.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/ping/ping.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -39,4 +39,5 @@
 #include <task.h>
 #include <time.h>
+#include <ipc/ipc.h>
 #include <ipc/services.h>
 
@@ -67,56 +68,5 @@
 /** Prints the application help.
  */
-void print_help(void);
-
-/** Translates the character string to the address family number.
- *  @param[in] name The address family name.
- *  @returns The corresponding address family number.
- *  @returns EAFNOSUPPORTED if the address family is not supported.
- */
-int parse_address_family(const char * name);
-
-void print_help(void){
-	printf(
-		"Network Ping aplication\n" \
-		"Usage: ping [options] numeric_address\n" \
-		"Where options are:\n" \
-		"\n" \
-		"-c request_count | --count=request_count\n" \
-		"\tThe number of packets the application sends. The default is three (3).\n" \
-		"\n" \
-		"--dont_fragment\n" \
-		"\tDisable packet fragmentation.\n"
-		"\n" \
-		"-f address_family | --family=address_family\n" \
-		"\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
-		"\n" \
-		"-h | --help\n" \
-		"\tShow this application help.\n"
-		"\n" \
-		"-s packet_size | --size=packet_size\n" \
-		"\tThe packet data size the application sends. The default is 38 bytes.\n" \
-		"\n" \
-		"-t timeout | --timeout=timeout\n" \
-		"\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
-		"\n" \
-		"--tos=tos\n" \
-		"\tThe type of service to be used.\n" \
-		"\n" \
-		"--ttl=ttl\n" \
-		"\tThe time to live to be used.\n" \
-		"\n" \
-		"-v | --verbose\n" \
-		"\tShow all output messages.\n"
-	);
-}
-
-int parse_address_family(const char * name){
-	if(str_lcmp(name, "AF_INET", 7) == 0){
-		return AF_INET;
-	}else if(str_lcmp(name, "AF_INET6", 8) == 0){
-		return AF_INET6;
-	}
-	return EAFNOSUPPORT;
-}
+void ping_print_help(void);
 
 int main(int argc, char * argv[]){
@@ -126,13 +76,13 @@
 	int verbose			= 0;
 	int dont_fragment	= 0;
-	ip_ttl_t ttl				= 0;
-	ip_tos_t tos				= 0;
+	ip_ttl_t ttl		= 0;
+	ip_tos_t tos		= 0;
 	int count			= 3;
-	suseconds_t timeout			= 3000;
+	suseconds_t timeout	= 3000;
 	int family			= AF_INET;
 
-	socklen_t max_length		= sizeof(struct sockaddr_in6);
+	socklen_t max_length				= sizeof(struct sockaddr_in6);
 	uint8_t address_data[max_length];
-	struct sockaddr * address		= (struct sockaddr *) address_data;
+	struct sockaddr * address			= (struct sockaddr *) address_data;
 	struct sockaddr_in * address_in		= (struct sockaddr_in *) address;
 	struct sockaddr_in6 * address_in6	= (struct sockaddr_in6 *) address;
@@ -147,15 +97,15 @@
 	int index;
 
+	// print the program label
 	printf("Task %d - ", task_get_id());
 	printf("%s\n", NAME);
 
-	if(argc <= 1){
-		print_help();
-		return EINVAL;
-	}
-
-	for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
+	// parse the command line arguments
+	// stop before the last argument if it does not start with the minus sign ('-')
+	for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
+		// options should start with the minus sign ('-')
 		if(argv[index][0] == '-'){
 			switch(argv[index][1]){
+				// short options with only one letter
 				case 'c':
 					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0));
@@ -165,5 +115,5 @@
 					break;
 				case 'h':
-					print_help();
+					ping_print_help();
 					return EOK;
 					break;
@@ -179,4 +129,5 @@
 					verbose = 1;
 					break;
+				// long options with the double minus sign ('-')
 				case '-':
 					if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
@@ -187,5 +138,5 @@
 						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
-						print_help();
+						ping_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
@@ -205,5 +156,5 @@
 					}else{
 						print_unrecognized(index, argv[index] + 2);
-						print_help();
+						ping_print_help();
 						return EINVAL;
 					}
@@ -211,14 +162,22 @@
 				default:
 					print_unrecognized(index, argv[index] + 1);
-					print_help();
+					ping_print_help();
 					return EINVAL;
 			}
 		}else{
 			print_unrecognized(index, argv[index]);
-			print_help();
+			ping_print_help();
 			return EINVAL;
 		}
 	}
 
+	// if not before the last argument containing the address
+	if(index >= argc){
+		printf("Command line error: missing address\n");
+		ping_print_help();
+		return EINVAL;
+	}
+
+	// prepare the address buffer
 	bzero(address_data, max_length);
 	switch(family){
@@ -238,4 +197,5 @@
 	}
 
+	// parse the last argument which should contain the address
 	if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
 		fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
@@ -243,4 +203,5 @@
 	}
 
+	// connect to the ICMP module
 	icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
 	if(icmp_phone < 0){
@@ -249,4 +210,5 @@
 	}
 
+	// print the ping header
 	printf("PING %d bytes of data\n", size);
 	if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
@@ -256,14 +218,27 @@
 	}
 
+	// do count times
 	while(count > 0){
+
+		// get the starting time
 		if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
 			fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
+			// release the ICMP phone
+			ipc_hangup(icmp_phone);
 			return ERROR_CODE;
 		}
+
+		// request the ping
 		result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen);
+
+		// get the ending time
 		if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
 			fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
+			// release the ICMP phone
+			ipc_hangup(icmp_phone);
 			return ERROR_CODE;
 		}
+
+		// print the result
 		switch(result){
 			case ICMP_ECHO:
@@ -283,7 +258,45 @@
 	}
 
+	// release the ICMP phone
+	ipc_hangup(icmp_phone);
+
 	return EOK;
 }
 
+void ping_print_help(void){
+	printf(
+		"Network Ping aplication\n" \
+		"Usage: ping [options] numeric_address\n" \
+		"Where options are:\n" \
+		"\n" \
+		"-c request_count | --count=request_count\n" \
+		"\tThe number of packets the application sends. The default is three (3).\n" \
+		"\n" \
+		"--dont_fragment\n" \
+		"\tDisable packet fragmentation.\n"
+		"\n" \
+		"-f address_family | --family=address_family\n" \
+		"\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
+		"\n" \
+		"-h | --help\n" \
+		"\tShow this application help.\n"
+		"\n" \
+		"-s packet_size | --size=packet_size\n" \
+		"\tThe packet data size the application sends. The default is 38 bytes.\n" \
+		"\n" \
+		"-t timeout | --timeout=timeout\n" \
+		"\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
+		"\n" \
+		"--tos=tos\n" \
+		"\tThe type of service to be used.\n" \
+		"\n" \
+		"--ttl=ttl\n" \
+		"\tThe time to live to be used.\n" \
+		"\n" \
+		"-v | --verbose\n" \
+		"\tShow all output messages.\n"
+	);
+}
+
 /** @}
  */
Index: uspace/srv/net/app/print_error.c
===================================================================
--- uspace/srv/net/app/print_error.c	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/print_error.c	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -41,12 +41,4 @@
 
 #include "print_error.h"
-
-void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
-	if(IS_ICMP_ERROR(error_code)){
-		icmp_print_error(output, error_code, prefix, suffix);
-	}else if(IS_SOCKET_ERROR(error_code)){
-		socket_print_error(output, error_code, prefix, suffix);
-	}
-}
 
 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
@@ -101,4 +93,12 @@
 }
 
+void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
+	if(IS_ICMP_ERROR(error_code)){
+		icmp_print_error(output, error_code, prefix, suffix);
+	}else if(IS_SOCKET_ERROR(error_code)){
+		socket_print_error(output, error_code, prefix, suffix);
+	}
+}
+
 void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
 	if(output){
Index: uspace/srv/net/app/print_error.h
===================================================================
--- uspace/srv/net/app/print_error.h	(revision a8a13d06144cd1b2fb793e67554e75be33860ac2)
+++ uspace/srv/net/app/print_error.h	(revision 3be62bc8cd08888b403d5c582327281b0683ccc5)
@@ -50,4 +50,12 @@
 #define IS_SOCKET_ERROR(error_code)	((error_code) < 0)
 
+/** Prints the specific ICMP error description.
+ *  @param[in] output The description output stream. May be NULL.
+ *  @param[in] error_code The ICMP error code.
+ *  @param[in] prefix The error description prefix. May be NULL.
+ *  @param[in] suffix The error description suffix. May be NULL.
+ */
+void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
+
 /** Prints the error description.
  *  Supports ICMP and socket error codes.
@@ -58,12 +66,4 @@
  */
 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
-
-/** Prints the specific ICMP error description.
- *  @param[in] output The description output stream. May be NULL.
- *  @param[in] error_code The ICMP error code.
- *  @param[in] prefix The error description prefix. May be NULL.
- *  @param[in] suffix The error description suffix. May be NULL.
- */
-void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
 
 /** Prints the specific socket error description.
