Index: rnel/genarch/include/genarch/drivers/amdm37x_uart/amdm37x_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/amdm37x_uart/amdm37x_uart.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ 	(revision )
@@ -1,459 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Texas Instruments AMDM37x on-chip interrupt controller driver.
- */
-
-#ifndef KERN_AMDM37x_UART_H_
-#define KERN_AMDM37x_UART_H_
-
-#include <typedefs.h>
-#include <console/chardev.h>
-#include <ddi/irq.h>
-
-/* AMDM37x TRM p. 2950 */
-#define AMDM37x_UART1_BASE_ADDRESS   0x4806a000
-#define AMDM37x_UART1_SIZE   1024
-#define AMDM37x_UART1_IRQ   72 /* AMDM37x TRM p. 2418 */
-
-#define AMDM37x_UART2_BASE_ADDRESS   0x4806b000
-#define AMDM37x_UART2_SIZE   1024
-#define AMDM37x_UART2_IRQ   73 /* AMDM37x TRM p. 2418 */
-
-#define AMDM37x_UART3_BASE_ADDRESS   0x49020000
-#define AMDM37x_UART3_SIZE   1024
-#define AMDM37x_UART3_IRQ   74 /* AMDM37x TRM p. 2418 */
-
-#define AMDM37x_UART4_BASE_ADDRESS   0x49042000
-#define AMDM37x_UART4_SIZE   1024
-#define AMDM37x_UART4_IRQ   80 /* AMDM37x TRM p. 2418 */
-
-typedef struct {
-	union {
-		/** Stores lower part of the 14-bit baud divisor */
-		ioport32_t dll;
-#define AMDM37x_UART_DLL_MASK   (0xff)
-
-		/** Receive holding register */
-		const ioport32_t rhr;
-#define AMDM37x_UART_RHR_MASK   (0xff)
-
-		/** Transmit holding register */
-		ioport32_t thr;
-#define AMDM37x_UART_THR_MASK   (0xff)
-	};
-
-	union {
-		/** Stores higher part of the 14-bit baud divisor */
-		ioport32_t dlh;
-#define AMDM37x_UART_DLH_MASK   (0x1f)
-
-		/** Interrupt enable registers */
-		ioport32_t ier;
-#define AMDM37x_UART_IER_RHR_IRQ_FLAG   (1 << 0)
-#define AMDM37x_UART_IER_THR_IRQ_FLAG   (1 << 1)
-#define AMDM37x_UART_IER_LINE_STS_IRQ_FLAG   (1 << 2)
-#define AMDM37x_UART_IER_MODEM_STS_IRQ_FLAG   (1 << 3)
-#define AMDM37x_UART_IER_SLEEP_MODE_FLAG   (1 << 4)
-#define AMDM37x_UART_IER_XOFF_IRQ_FLAG   (1 << 5)
-#define AMDM37x_UART_IER_RTS_IRQ_FLAG   (1 << 6)
-#define AMDM37x_UART_IER_CTS_IRQ_FLAG   (1 << 7)
-
-#define AMDM37x_CIR_IER_RHR_IRQ_FLAG   (1 << 0)
-#define AMDM37x_CIR_IER_THR_IRQ_FLAG   (1 << 1)
-#define AMDM37x_CIR_IER_RX_STOP_IRQ_FLAG   (1 << 2)
-#define AMDM37x_CIR_IER_RX_OVERRUN_IRQ_FLAG   (1 << 3)
-#define AMDM37x_CIR_IER_TX_STS_IRQ_FLAG   (1 << 5)
-
-#define AMDM37x_IRDA_IER_RHR_IRQ_FLAG   (1 << 0)
-#define AMDM37x_IRDA_IER_THR_IRQ_FLAG   (1 << 1)
-#define AMDM37x_IRDA_IER_LAST_RX_BYTE_IRQ_FLAG   (1 << 2)
-#define AMDM37x_IRDA_IER_RX_OVERRUN_IRQ_FLAG   (1 << 3)
-#define AMDM37x_IRDA_IER_STS_FIFO_TRIG_IRQ_FLAG   (1 << 4)
-#define AMDM37x_IRDA_IER_TX_STS_IRQ_FLAG   (1 << 5)
-#define AMDM37x_IRDA_IER_LINE_STS_IRQ_FLAG   (1 << 6)
-#define AMDM37x_IRDA_IER_EOF_IRQ_FLAG   (1 << 7)
-	};
-
-	union {
-		/** Interrupt identification register */
-		const ioport32_t iir;
-#define AMDM37x_UART_IIR_IRQ_PENDING_FLAG   (1 << 0)
-#define AMDM37x_UART_IIR_TYPE_MASK   (0x1f)
-#define AMDM37x_UART_IIR_TYPE_SHIFT   (1)
-#define AMDM37x_UART_IIR_FCR_MASK   (0x3)
-#define AMDM37x_UART_IIR_FCR_SHIFT   (6)
-
-#define AMDM37x_CIR_IIR_RHR_IRQ_FLAG   (1 << 0)
-#define AMDM37x_CIR_IIR_THR_IRQ_FLAG   (1 << 1)
-#define AMDM37x_CIR_IIR_RX_STOP_IRQ_FLAG   (1 << 2)
-#define AMDM37x_CIR_IIR_RX_OE_IRQ_FLAG   (1 << 3)
-#define AMDM37x_CIR_IIR_TX_STS_IRQ_FLAG   (1 << 5)
-
-#define AMDM37x_IRDA_IIR_RHR_IRQ_FLAG   (1 << 0)
-#define AMDM37x_IRDA_IIR_THR_IRQ_FLAG   (1 << 1)
-#define AMDM37x_IRDA_IIR_RX_FIFO_LB_IRQ_FLAG   (1 << 2)
-#define AMDM37x_IRDA_IIR_RX_OE_IRQ_FLAG   (1 << 3)
-#define AMDM37x_IRDA_IIR_STS_FIFO_IRQ_FLAG   (1 << 4)
-#define AMDM37x_IRDA_IIR_TX_STS_IRQ_FLAG   (1 << 5)
-#define AMDM37x_IRDA_IIR_LINE_STS_IRQ_FLAG   (1 << 6)
-#define AMDM37x_IRDA_IIR_EOF_IRQ_FLAG   (1 << 7)
-
-		/** FIFO control register */
-		ioport32_t fcr;
-#define AMDM37x_UART_FCR_FIFO_EN_FLAG   (1 << 0)
-#define AMDM37x_UART_FCR_RX_FIFO_CLR_FLAG   (1 << 1)
-#define AMDM37x_UART_FCR_TX_FIFO_CLR_FLAG   (1 << 3)
-#define AMDM37x_UART_FCR_DMA_MODE_FLAG   (1 << 4)
-
-#define AMDM37x_UART_FCR_TX_FIFO_TRIG_MASK   (0x3)
-#define AMDM37x_UART_FCR_TX_FIFO_TRIG_SHIFT   (4)
-
-#define AMDM37x_UART_FCR_RX_FIFO_TRIG_MASK   (0x3)
-#define AMDM37x_UART_FCR_RX_FIFO_TRIG_SHIFT   (6)
-
-		/** Enhanced feature register */
-		ioport32_t efr;
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_RX_MASK   (0x3)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_RX_SHIFT   (0)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_TX_MASK   (0x3)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_TX_SHIFT   (2)
-
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_NONE   (0x0)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_X2   (0x1)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_X1   (0x2)
-#define AMDM37x_UART_EFR_SW_FLOW_CTRL_XBOTH   (0x3)
-
-#define AMDM37x_UART_EFR_ENH_FLAG   (1 << 4)
-#define AMDM37x_UART_EFR_SPEC_CHAR_FLAG   (1 << 5)
-#define AMDM37x_UART_EFR_AUTO_RTS_EN_FLAG   (1 << 6)
-#define AMDM37x_UART_EFR_AUTO_CTS_EN_FLAG   (1 << 7)
-	};
-
-	/** Line control register */
-	ioport32_t lcr;
-#define AMDM37x_UART_LCR_CHAR_LENGTH_MASK   (0x3)
-#define AMDM37x_UART_LCR_CHAR_LENGTH_SHIFT   (0)
-#define AMDM37x_UART_LCR_CHAR_LENGTH_5BITS   (0x0)
-#define AMDM37x_UART_LCR_CHAR_LENGTH_6BITS   (0x1)
-#define AMDM37x_UART_LCR_CHAR_LENGTH_7BITS   (0x2)
-#define AMDM37x_UART_LCR_CHAR_LENGTH_8BITS   (0x3)
-#define AMDM37x_UART_LCR_NB_STOP_FLAG   (1 << 2)
-#define AMDM37x_UART_LCR_PARITY_EN_FLAG   (1 << 3)
-#define AMDM37x_UART_LCR_PARITY_TYPE1_FLAG   (1 << 4)
-#define AMDM37x_UART_LCR_PARITY_TYPE2_FLAG   (1 << 5)
-#define AMDM37x_UART_LCR_BREAK_EN_FLAG   (1 << 6)
-#define AMDM37x_UART_LCR_DIV_EN_FLAG   (1 << 7)
-
-
-	union {
-		/** Modem control register */
-		ioport32_t mcr;
-#define AMDM37x_UART_MCR_DTR_FLAG   (1 << 0)
-#define AMDM37x_UART_MCR_RTS_FLAG   (1 << 1)
-#define AMDM37x_UART_MCR_RI_STS_CH_FLAG   (1 << 2)
-#define AMDM37x_UART_MCR_CD_STS_CH_FLAG   (1 << 3)
-#define AMDM37x_UART_MCR_LOOPBACK_EN_FLAG   (1 << 4)
-#define AMDM37x_UART_MCR_XON_EN_FLAG   (1 << 5)
-#define AMDM37x_UART_MCR_TCR_TLR_FLAG   (1 << 6)
-
-		/** UART: XON1 char, IRDA: ADDR1 address */
-		ioport32_t xon1_addr1;
-#define AMDM37x_UART_XON1_ADDR1_MASK   (0xff)
-	};
-
-	union {
-		/** Line status register */
-		const ioport32_t lsr;
-#define AMDM37x_UART_LSR_RX_FIFO_E_FLAG   (1 << 0)
-#define AMDM37x_UART_LSR_RX_OE_FLAG   (1 << 1)
-#define AMDM37x_UART_LSR_RX_PE_FLAG   (1 << 2)
-#define AMDM37x_UART_LSR_RX_FE_FLAG   (1 << 3)
-#define AMDM37x_UART_LSR_RX_BI_FLAG   (1 << 4)
-#define AMDM37x_UART_LSR_TX_FIFO_E_FLAG   (1 << 5)
-#define AMDM37x_UART_LSR_TX_SR_E_FLAG   (1 << 6)
-#define AMDM37x_UART_LSR_RX_FIFO_STS_FLAG   (1 << 7)
-
-#define AMDM37x_CIR_LSR_RX_FIFO_E_FLAG   (1 << 0)
-#define AMDM37x_CIR_LSR_RX_STOP_FLAG   (1 << 5)
-#define AMDM37x_CIR_LSR_THR_EMPTY_FLAG   (1 << 7)
-
-#define AMDM37x_IRDA_LSR_RX_FIFO_E_FLAG   (1 << 0)
-#define AMDM37x_IRDA_LSR_STS_FIFO_E_FLAG   (1 << 1)
-#define AMDM37x_IRDA_LSR_CRC_FLAG   (1 << 2)
-#define AMDM37x_IRDA_LSR_ABORT_FLAG   (1 << 3)
-#define AMDM37x_IRDA_LSR_FTL_FLAG   (1 << 4)
-#define AMDM37x_IRDA_LSR_RX_LAST_FLAG   (1 << 5)
-#define AMDM37x_IRDA_LSR_STS_FIFO_FULL_FLAG   (1 << 6)
-#define AMDM37x_IRDA_LSR_THR_EMPTY_FLAG   (1 << 7)
-
-		/** UART: XON2 char, IRDA: ADDR2 address */
-		ioport32_t xon2_addr2;
-	};
-
-	union {
-		/** Modem status register */
-		const ioport32_t msr;
-#define AMDM37x_UART_MSR_CTS_STS_FLAG   (1 << 0)
-#define AMDM37x_UART_MSR_DSR_STS_FLAG   (1 << 1)
-#define AMDM37x_UART_MSR_RI_STS_FLAG   (1 << 2)
-#define AMDM37x_UART_MSR_DCD_STS_FLAG   (1 << 3)
-#define AMDM37x_UART_MSR_NCTS_STS_FLAG   (1 << 4)
-#define AMDM37x_UART_MSR_NDSR_STS_FLAG   (1 << 5)
-#define AMDM37x_UART_MSR_NRI_STS_FLAG   (1 << 6)
-#define AMDM37x_UART_MSR_NCD_STS_FLAG   (1 << 7)
-
-		/** Transmission control register */
-		ioport32_t tcr;
-#define AMDM37x_UART_TCR_FIFO_TRIG_MASK   (0xf)
-#define AMDM37x_UART_TCR_FIFO_TRIG_HALT_SHIFT   (0)
-#define AMDM37x_UART_TCR_FIFO_TRIG_START_SHIFT   (4)
-
-		/** UART: XOFF1 char */
-		ioport32_t xoff1;
-#define AMDM37x_UART_XOFF1_MASK   (0xff)
-	};
-
-	union {
-		/* Scratchpad register, does nothing */
-		ioport32_t spr;
-#define AMDM37x_UART_SPR_MASK   (0xff)
-
-		/* Trigger level register */
-		ioport32_t tlr;
-#define AMDM37x_UART_TLR_LEVEL_MASK   (0xf)
-#define AMDM37x_UART_TLR_TX_FIFO_TRIG_SHIFT   (0)
-#define AMDM37x_UART_TLR_RX_FIFO_TRIG_SHIFT   (4)
-
-		/** UART: XOFF2 char */
-		ioport32_t xoff2;
-#define AMDM37x_UART_XOFF2_MASK   (0xff)
-	};
-
-	/** Mode definition register. */
-	ioport32_t mdr1;
-#define AMDM37x_UART_MDR_MS_MASK   (0x7)
-#define AMDM37x_UART_MDR_MS_SHIFT   (0)
-#define AMDM37x_UART_MDR_MS_UART16   (0x0)
-#define AMDM37x_UART_MDR_MS_SIR   (0x1)
-#define AMDM37x_UART_MDR_MS_UART16_AUTO   (0x2)
-#define AMDM37x_UART_MDR_MS_UART13   (0x3)
-#define AMDM37x_UART_MDR_MS_MIR   (0x4)
-#define AMDM37x_UART_MDR_MS_FIR   (0x5)
-#define AMDM37x_UART_MDR_MS_CIR   (0x6)
-#define AMDM37x_UART_MDR_MS_DISABLE   (0x7)
-
-#define AMDM37x_UART_MDR_IR_SLEEP_FLAG   (1 << 3)
-#define AMDM37x_UART_MDR_SET_TXIR_FLAG   (1 << 4)
-#define AMDM37x_UART_MDR_SCT_FLAG   (1 << 5)
-#define AMDM37x_UART_MDR_SIP_FLAG   (1 << 6)
-#define AMDM37x_UART_MDR_FRAME_END_MODE_FLAG   (1 << 7)
-
-	/** Mode definition register */
-	ioport32_t mdr2;
-#define AMDM37x_UART_MDR_IRTX_UNDERRUN_FLAG   (1 << 0)
-#define AMDM37x_UART_MDR_STS_FIFO_TRIG_MASK   (0x3)
-#define AMDM37x_UART_MDR_STS_FIFO_TRIG_SHIFT   (1)
-#define AMDM37x_UART_MDR_PULSE_SHAPING_FLAG   (1 << 3)
-#define AMDM37x_UART_MDR_CIR_PULSE_MODE_MASK   (0x3)
-#define AMDM37x_UART_MDR_CIR_PULSE_MODE_SHIFT   (4)
-#define AMDM37x_UART_MDR_IRRXINVERT_FLAG   (1 << 6)
-
-
-	/* UART3 specific */
-	union {
-		/** Status FIFO line status register (IrDA only) */
-		const ioport32_t sflsr;
-#define AMDM37x_IRDA_SFLSR_CRC_ERROR_FLAG   (1 << 1)
-#define AMDM37x_IRDA_SFLSR_ABORT_FLAG   (1 << 2)
-#define AMDM37x_IRDA_SFLSR_FTL_FLAG   (1 << 3)
-#define AMDM37x_IRDA_SFLSR_OE_FLAG   (1 << 4)
-
-		/** Transmit frame length low (IrDA only) */
-		ioport32_t txfll;
-#define AMDM37x_UART_TXFLL_MASK   (0xff)
-	};
-
-	/* UART3 specific */
-	union {
-		/** Dummy register to restart TX or RX (IrDA only) */
-		const ioport32_t resume;
-		/** Transmit frame length high (IrDA only) */
-		ioport32_t txflh;
-#define AMDM37x_UART_TXFLH_MASK   (0xff)
-	};
-
-	/* UART3 specific */
-	union {
-		/** Status FIFO register low (IrDA only) */
-		const ioport32_t sfregl;
-#define AMDM37x_UART_SFREGL_MASK   (0xff)
-		/** Received frame length low (IrDA only) */
-		ioport32_t rxfll;
-#define AMDM37x_UART_RXFLL_MASK   (0xff)
-	};
-
-	/* UART3 specific */
-	union {
-		/** Status FIFO register high (IrDA only) */
-		const ioport32_t sfregh;
-#define AMDM37x_UART_SFREGH_MASK   (0xf)
-		/** Received frame length high (IrDA only) */
-		ioport32_t rxflh;
-#define AMDM37x_UART_RXFLH_MASK   (0xf)
-	};
-
-	union {
-		/** UART autobauding status register */
-		const ioport32_t uasr;
-#define AMDM37x_UART_UASR_SPEED_MASK   (0x1f)
-#define AMDM37x_UART_UASR_SPEED_SHIFT   (0)
-#define AMDM37x_UART_UASR_8BIT_CHAR_FLAG   (1 << 5)
-#define AMDM37x_UART_UASR_PARITY_MASK   (0x3)
-#define AMDM37x_UART_UASR_PARITY_SHIFT   (6)
-
-		/** BOF control register (IrDA only) */
-		ioport32_t blr; /* UART3 sepcific */
-#define AMDM37x_IRDA_BLR_XBOF_TYPE_FLAG   (1 << 6)
-#define AMDM37x_IRDA_BLR_STS_FIFO_RESET   (1 << 7)
-	};
-
-	/** Auxiliary control register (IrDA only) */
-	ioport32_t acreg; /* UART3 specific */
-#define AMDM37x_IRDA_ACREG_EOT_EN_FLAG   (1 << 0)
-#define AMDM37x_IRDA_ACREG_ABORT_EN_FLAG   (1 << 1)
-#define AMDM37x_IRDA_ACREG_SCTX_EN_FLAG   (1 << 2)
-#define AMDM37x_IRDA_ACREG_SEND_SIP_FLAG   (1 << 3)
-#define AMDM37x_IRDA_ACREG_DIS_TX_UNDERRUN_FLAG   (1 << 4)
-#define AMDM37x_IRDA_ACREG_DIS_IR_RX_FLAG   (1 << 5)
-#define AMDM37x_IRDA_ACREG_SD_MOD_FLAG   (1 << 6)
-#define AMDM37x_IRDA_ACREG_PULSE_TYPE_FLAG   (1 << 7)
-
-	/** Supplementary control register */
-	ioport32_t scr;
-#define AMDM37x_UART_SCR_DMA_MODE_CTL_FLAG   (1 << 0)
-#define AMDM37x_UART_SCR_DMA_MODE_MASK   (0x3)
-#define AMDM37x_UART_SCR_DMA_MODE_SHIFT   (1)
-#define AMDM37x_UART_SCR_TX_EMPTY_CTL_IRQ_FLAG   (1 << 3)
-#define AMDM37x_UART_SCR_RX_CTS_WU_EN_FLAG   (1 << 4)
-#define AMDM37x_UART_SCR_TX_TRIG_GRANU1_FLAG   (1 << 6)
-#define AMDM37x_UART_SCR_RX_TRIG_GRANU1_FLAG   (1 << 7)
-
-	/** Supplementary status register */
-	const ioport32_t ssr;
-#define AMDM37x_UART_SSR_TX_FIFO_FULL_FLAG   (1 << 0)
-#define AMDM37x_UART_SSR_RX_CTS_WU_STS_FLAG   (1 << 1)
-#define AMDM37x_UART_SSR_DMA_COUNTER_RESET_FLAG   (1 << 2)
-
-	/** BOF Length register (IrDA only)*/
-	ioport32_t eblr; /* UART3 specific */
-#define AMDM37x_IRDA_EBLR_DISABLED   (0x00)
-#define AMDM37x_IRDA_EBLR_RX_STOP_BITS(bits)   (bits & 0xff)
-
-	uint32_t padd0_;
-
-	/** Module version register */
-	const ioport32_t mvr;
-#define AMDM37x_UART_MVR_MINOR_MASK   (0xf)
-#define AMDM37x_UART_MVR_MINOR_SHIFT   (0)
-#define AMDM37x_UART_MVR_MAJOR_MASK   (0xf)
-#define AMDM37x_UART_MVR_MAJOR_SHIFT   (4)
-
-	/** System configuration register */
-	ioport32_t sysc;
-#define AMDM37x_UART_SYSC_AUTOIDLE_FLAG   (1 << 0)
-#define AMDM37x_UART_SYSC_SOFTRESET_FLAG   (1 << 1)
-#define AMDM37x_UART_SYSC_ENWAKEUP_FLAG   (1 << 2)
-#define AMDM37x_UART_SYSC_IDLE_MODE_MASK   (0x3)
-#define AMDM37x_UART_SYSC_IDLE_MODE_SHIFT   (3)
-#define AMDM37x_UART_SYSC_IDLE_MODE_FORCE   (0x0)
-#define AMDM37x_UART_SYSC_IDLE_MODE_NO   (0x1)
-#define AMDM37x_UART_SYSC_IDLE_MODE_SMART   (0x2)
-
-	/** System status register */
-	const ioport32_t syss;
-#define AMDM37x_UART_SYSS_RESETDONE_FLAG   (1 << 0)
-
-	/** Wake-up enable register */
-	ioport32_t wer;
-#define AMDM37x_UART_WER_CTS_ACTIVITY_FLAG  (1 << 0)
-#define AMDM37x_UART_WER_RI_ACTIVITY_FLAG  (1 << 2)
-#define AMDM37x_UART_WER_RX_ACTIVITY_FLAG  (1 << 4)
-#define AMDM37x_UART_WER_RHR_IRQ_FLAG  (1 << 5)
-#define AMDM37x_UART_WER_RLS_IRQ_FLAG  (1 << 6)
-#define AMDM37x_UART_WER_TX_WAKEUP_EN_FLAG  (1 << 7)
-
-	/** Carrier frequency prescaler */
-	ioport32_t cfps;	/* UART3 specific */
-#define AMDM37x_UART_CFPS_MASK   (0xff)
-
-	/** Number of bytes in RX fifo */
-	const ioport32_t rx_fifo_lvl;
-#define AMDM37x_UART_RX_FIFO_LVL_MASK   (0xff)
-
-	/** Number of bytes in TX fifo */
-	const ioport32_t tx_fifo_lvl;
-#define AMDM37x_UART_TX_FIFO_LVL_MASK   (0xff)
-
-	/** RX/TX empty interrupts */
-	ioport32_t ier2;
-#define AMDM37x_UART_IER2_RX_FIFO_EMPTY_IRQ_EN_FLAG  (1 << 0)
-#define AMDM37x_UART_IER2_TX_FIFO_EMPTY_IRQ_EN_FLAG  (1 << 1)
-
-	/** RX/TX empty status */
-	ioport32_t isr2;
-#define AMDM37x_UART_ISR2_RX_FIFO_EMPTY_FLAG  (1 << 0)
-#define AMDM37x_UART_ISR2_TX_FIFO_EMPTY_FLAG  (1 << 1)
-
-	uint32_t padd2_[3];
-
-	/** Mode definition register 3 */
-	ioport32_t mdr3;
-#define AMDM37x_UART_MDR3_DIS_CIR_RX_DEMOD_FLAG   (1 << 0)
-} amdm37x_uart_regs_t;
-
-typedef struct {
-	amdm37x_uart_regs_t *regs;
-	indev_t *indev;
-	outdev_t outdev;
-	irq_t irq;
-} amdm37x_uart_t;
-
-
-bool amdm37x_uart_init(amdm37x_uart_t *, inr_t, uintptr_t, size_t);
-void amdm37x_uart_input_wire(amdm37x_uart_t *, indev_t *);
-
-#endif
-
-/**
- * @}
- */
Index: rnel/genarch/include/genarch/fb/logo-196x66.h
===================================================================
--- kernel/genarch/include/genarch/fb/logo-196x66.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2008 Martin Decky
- * 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 genarch
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_LOGO_196X66_H_
-#define KERN_LOGO_196X66_H_
-
-#define LOGO_WIDTH   196
-#define LOGO_HEIGHT  66
-#define LOGO_COLOR   0xffffff
-
-#include <typedefs.h>
-
-extern uint32_t fb_logo[LOGO_WIDTH * LOGO_HEIGHT];
-
-#endif
-
-/** @}
- */
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -63,4 +63,7 @@
 static bool should_quit = false;
 static bool dash_represents_stdin = false;
+static unsigned int lineno = 0;
+static bool number = false;
+static bool last_char_was_newline = false;
 
 static console_ctrl_t *console = NULL;
@@ -75,4 +78,5 @@
 	{ "hex", no_argument, 0, 'x' },
 	{ "stdin", no_argument, 0, 's' },
+	{ "number", no_argument, 0, 'n' },
 	{ 0, 0, 0, 0 }
 };
@@ -95,5 +99,6 @@
 		"  -m, --more       Pause after each screen full\n"
 		"  -x, --hex        Print bytes as hex values\n"
-		"  -s  --stdin      Treat `-' in file list as standard input\n"
+		"  -s, --stdin      Treat `-' in file list as standard input\n"
+		"  -n, --number     Number all output lines\n"
 		"Currently, %s is under development, some options don't work.\n",
 		cmdname, cmdname);
@@ -153,5 +158,10 @@
 static void paged_char(wchar_t c)
 {
+	if (last_char_was_newline && number) {
+		lineno++;
+		printf("%6u  ", lineno);
+	}
 	putchar(c);
+	last_char_was_newline = c == '\n';
 	if (paging_enabled) {
 		chars_remaining--;
@@ -306,9 +316,14 @@
 	should_quit = false;
 	console = console_init(stdin, stdout);
+	number = false;
+	lineno = 0;
+	/* This enables printing of the first number. */
+	last_char_was_newline = true;
+
 
 	argc = cli_count_args(argv);
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind);
+		c = getopt_long(argc, argv, "xhvmH:t:b:s:n", long_options, &opt_ind);
 		switch (c) {
 		case 'h':
@@ -347,4 +362,7 @@
 			dash_represents_stdin = true;
 			break;
+		case 'n':
+			number = true;
+			break;
 		}
 	}
Index: uspace/app/dnsres/dnsres.c
===================================================================
--- uspace/app/dnsres/dnsres.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/dnsres/dnsres.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -36,49 +36,71 @@
 #include <inet/addr.h>
 #include <inet/dnsr.h>
+#include <net/socket_codes.h>
 #include <stdio.h>
 #include <stdlib.h>
 
-#define NAME "dnsres"
+#define NAME  "dnsres"
 
 static void print_syntax(void)
 {
-	printf("syntax: " NAME " <host-name>\n");
+	printf("Syntax: %s [-4|-6] <host-name>\n", NAME);
 }
 
 int main(int argc, char *argv[])
 {
-	int rc;
-	dnsr_hostinfo_t *hinfo;
-	char *hname;
-	char *saddr;
-
-	if (argc != 2) {
+	if ((argc < 2) || (argc > 3)) {
 		print_syntax();
 		return 1;
 	}
-
-	hname = argv[1];
-
-	rc = dnsr_name2host(hname, &hinfo);
+	
+	uint16_t af;
+	char *hname;
+	
+	if (str_cmp(argv[1], "-4") == 0) {
+		if (argc < 3) {
+			print_syntax();
+			return 1;
+		}
+		
+		af = AF_INET;
+		hname = argv[2];
+	} else if (str_cmp(argv[1], "-6") == 0) {
+		if (argc < 3) {
+			print_syntax();
+			return 1;
+		}
+		
+		af = AF_INET6;
+		hname = argv[2];
+	} else {
+		af = 0;
+		hname = argv[1];
+	}
+	
+	dnsr_hostinfo_t *hinfo;
+	int rc = dnsr_name2host(hname, &hinfo, af);
 	if (rc != EOK) {
-		printf(NAME ": Error resolving '%s'.\n", argv[1]);
-		return 1;
+		printf("%s: Error resolving '%s'.\n", NAME, hname);
+		return rc;
 	}
-
+	
+	char *saddr;
 	rc = inet_addr_format(&hinfo->addr, &saddr);
 	if (rc != EOK) {
 		dnsr_hostinfo_destroy(hinfo);
-		printf(NAME ": Out of memory.\n");
-		return 1;
+		printf("%s: Error formatting address.\n", NAME);
+		return rc;
 	}
-
+	
 	printf("Host name: %s\n", hname);
+	
 	if (str_cmp(hname, hinfo->cname) != 0)
 		printf("Canonical name: %s\n", hinfo->cname);
+	
 	printf("Address: %s\n", saddr);
-
+	
 	dnsr_hostinfo_destroy(hinfo);
 	free(saddr);
-
+	
 	return 0;
 }
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/netecho/netecho.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -225,5 +225,5 @@
 	uint8_t address_buf[sizeof(struct sockaddr_in6)];
 
-	socklen_t addrlen;
+	socklen_t addrlen = sizeof(struct sockaddr_in6);
 	int socket_id;
 	ssize_t rcv_size;
@@ -240,5 +240,4 @@
 	if (type == SOCK_STREAM) {
 		/* Accept a socket if a stream socket is used */
-		addrlen = sizeof(address_buf);
 		if (verbose)
 			printf("accept()\n");
@@ -280,5 +279,5 @@
 				case AF_INET6:
 					port = ntohs(address_in6->sin6_port);
-					address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
+					address_start = (uint8_t *) address_in6->sin6_addr.s6_addr;
 					break;
 				default:
Index: uspace/app/nettest1/nettest.c
===================================================================
--- uspace/app/nettest1/nettest.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nettest1/nettest.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -41,5 +41,4 @@
 #include "print_error.h"
 
-
 /** Creates new sockets.
  *
@@ -52,20 +51,20 @@
  * @return 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)
-{
-	int index;
-
+int sockets_create(int verbose, int *socket_ids, unsigned int sockets,
+    uint16_t family, sock_type_t type)
+{
 	if (verbose)
 		printf("Create\t");
-		
-	fflush(stdout);
-	
-	for (index = 0; index < sockets; index++) {
+	
+	fflush(stdout);
+	
+	for (unsigned int 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]);
+			printf("Socket %u (%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);
@@ -83,21 +82,19 @@
  * @return Other error codes as defined for the closesocket() function.
  */
-int sockets_close(int verbose, int *socket_ids, int sockets)
-{
-	int index;
-	int rc;
-
+int sockets_close(int verbose, int *socket_ids, unsigned int sockets)
+{
 	if (verbose)
 		printf("\tClose\t");
-
-	fflush(stdout);
-	
-	for (index = 0; index < sockets; index++) {
-		rc = closesocket(socket_ids[index]);
+	
+	fflush(stdout);
+	
+	for (unsigned int index = 0; index < sockets; index++) {
+		int rc = closesocket(socket_ids[index]);
 		if (rc != EOK) {
-			printf("Socket %d (%d) error:\n", index, socket_ids[index]);
+			printf("Socket %u (%d) error:\n", index, socket_ids[index]);
 			socket_print_error(stderr, rc, "Socket close: ", "\n");
 			return rc;
 		}
+		
 		if (verbose)
 			print_mark(index);
@@ -117,9 +114,7 @@
  * @return 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)
-{
-	int index;
-	int rc;
-
+int sockets_connect(int verbose, int *socket_ids, unsigned int sockets,
+    struct sockaddr *address, socklen_t addrlen)
+{
 	if (verbose)
 		printf("\tConnect\t");
@@ -127,76 +122,93 @@
 	fflush(stdout);
 	
-	for (index = 0; index < sockets; index++) {
-		rc = connect(socket_ids[index], address, addrlen);
+	for (unsigned int index = 0; index < sockets; index++) {
+		int rc = connect(socket_ids[index], address, addrlen);
 		if (rc != EOK) {
 			socket_print_error(stderr, rc, "Socket connect: ", "\n");
 			return rc;
 		}
-		if (verbose)
-			print_mark(index);
-	}
-	
-	return EOK;
-}
-
-/** 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.
+		
+		if (verbose)
+			print_mark(index);
+	}
+	
+	return EOK;
+}
+
+/** Send data via sockets.
+ *
+ * @param[in] verbose    Print out verbose information.
+ * @param[in] socket_ids Stored socket identifiers.
+ * @param[in] sockets    Number of sockets.
+ * @param[in] address    Destination host address to send data to.
+ * @param[in] addrlen    Length of the destination address in bytes.
+ * @param[in] data       Data to be sent.
+ * @param[in] size       Size of the data in bytes.
+ * @param[in] messages   Number of datagrams per socket to be sent.
+ * @param[in] type       Socket type.
+ *
  * @return EOK on success.
  * @return 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)
-{
-	int index;
-	int message;
-	int rc;
-
+ *
+ */
+int sockets_sendto(int verbose, int *socket_ids, unsigned int sockets,
+    struct sockaddr *address, socklen_t addrlen, char *data, size_t size,
+    unsigned int messages, sock_type_t type)
+{
 	if (verbose)
 		printf("\tSendto\t");
-
-	fflush(stdout);
-	
-	for (index = 0; index < sockets; index++) {
-		for (message = 0; message < messages; message++) {
-			rc = sendto(socket_ids[index], data, size, 0, address, addrlen);
+	
+	fflush(stdout);
+	
+	for (unsigned int index = 0; index < sockets; index++) {
+		for (unsigned int message = 0; message < messages; message++) {
+			int rc;
+			
+			switch (type) {
+			case SOCK_STREAM:
+				rc = send(socket_ids[index], data, size, 0);
+				break;
+			case SOCK_DGRAM:
+				rc = sendto(socket_ids[index], data, size, 0, address, addrlen);
+				break;
+			default:
+				rc = EINVAL;
+			}
+			
 			if (rc != EOK) {
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				printf("Socket %u (%d), message %u error:\n",
+				    index, socket_ids[index], message);
 				socket_print_error(stderr, rc, "Socket send: ", "\n");
 				return rc;
 			}
 		}
-		if (verbose)
-			print_mark(index);
-	}
-	
-	return EOK;
-}
-
-/** 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.
+		
+		if (verbose)
+			print_mark(index);
+	}
+	
+	return EOK;
+}
+
+/** Receive data via sockets.
+ *
+ * @param[in]     verbose    Print out verbose information.
+ * @param[in]     socket_ids Stored socket identifiers.
+ * @param[in]     sockets    Number of sockets.
+ * @param[in]     address    Source host address of received datagrams.
+ * @param[in,out] addrlen    Maximum length of the source address in bytes.
+ *                           The actual size of the source address is set.
+ * @param[out]    data       Received data.
+ * @param[in]     size       Maximum data size in bytes.
+ * @param[in]     messages   Number of datagrams per socket to be received.
+ *
  * @return EOK on success.
  * @return 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)
-{
-	int value;
-	int index;
-	int message;
-
+ *
+ */
+int sockets_recvfrom(int verbose, int *socket_ids, unsigned int sockets,
+    struct sockaddr *address, socklen_t *addrlen, char *data, size_t size,
+    unsigned int messages)
+{
 	if (verbose)
 		printf("\tRecvfrom\t");
@@ -204,62 +216,82 @@
 	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;
-}
-
-/** Sends and receives data via sockets.
+	for (unsigned int index = 0; index < sockets; index++) {
+		for (unsigned int message = 0; message < messages; message++) {
+			int rc = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
+			if (rc < 0) {
+				printf("Socket %u (%d), message %u error:\n",
+				    index, socket_ids[index], message);
+				socket_print_error(stderr, rc, "Socket receive: ", "\n");
+				return rc;
+			}
+		}
+		
+		if (verbose)
+			print_mark(index);
+	}
+	
+	return EOK;
+}
+
+/** Send and receive 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.
+ * @param[in]     verbose    Print out verbose information.
+ * @param[in]     socket_ids Stored socket identifiers.
+ * @param[in]     sockets    Number of sockets.
+ * @param[in,out] address    Destination host address to send data to.
+ *                           The source host address of received datagrams is set.
+ * @param[in]     addrlen    Length of the destination address in bytes.
+ * @param[in,out] data       Data to be sent. The received data are set.
+ * @param[in]     size       Size of the data in bytes.
+ * @param[in]     messages   Number of datagrams per socket to be received.
+ * @param[in]     type       Socket type.
+ *
  * @return EOK on success.
  * @return 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)
-{
-	int value;
-	int index;
-	int message;
-	int rc;
-
+ *
+ */
+int sockets_sendto_recvfrom(int verbose, int *socket_ids, unsigned int sockets,
+    struct sockaddr *address, socklen_t *addrlen, char *data,
+    size_t size, unsigned int messages, sock_type_t type)
+{
 	if (verbose)
 		printf("\tSendto and recvfrom\t");
-
-	fflush(stdout);
-	
-	for (index = 0; index < sockets; index++) {
-		for (message = 0; message < messages; message++) {
-			rc = sendto(socket_ids[index], data, size, 0, address, *addrlen);
+	
+	fflush(stdout);
+	
+	for (unsigned int index = 0; index < sockets; index++) {
+		for (unsigned int message = 0; message < messages; message++) {
+			int rc;
+			
+			switch (type) {
+			case SOCK_STREAM:
+				rc = send(socket_ids[index], data, size, 0);
+				break;
+			case SOCK_DGRAM:
+				rc = sendto(socket_ids[index], data, size, 0, address, *addrlen);
+				break;
+			default:
+				rc = EINVAL;
+			}
+			
 			if (rc != EOK) {
-				printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
+				printf("Socket %u (%d), message %u error:\n",
+				    index, socket_ids[index], message);
 				socket_print_error(stderr, rc, "Socket send: ", "\n");
 				return rc;
 			}
-			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;
-			}
-		}
+			
+			rc = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
+			if (rc < 0) {
+				printf("Socket %u (%d), message %u error:\n",
+				    index, socket_ids[index], message);
+				socket_print_error(stderr, rc, "Socket receive: ", "\n");
+				return rc;
+			}
+		}
+		
 		if (verbose)
 			print_mark(index);
@@ -274,6 +306,7 @@
  *
  * @param[in] index The index of the mark to be printed.
- */
-void print_mark(int index)
+ *
+ */
+void print_mark(unsigned int index)
 {
 	if ((index + 1) % 10)
@@ -281,4 +314,5 @@
 	else
 		printf("|");
+	
 	fflush(stdout);
 }
Index: uspace/app/nettest1/nettest.h
===================================================================
--- uspace/app/nettest1/nettest.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nettest1/nettest.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -40,11 +40,15 @@
 #include <net/socket.h>
 
-extern void print_mark(int);
-extern int sockets_create(int, int *, int, int, sock_type_t);
-extern int sockets_close(int, int *, int);
-extern int sockets_connect(int, int *, int, struct sockaddr *, socklen_t);
-extern int sockets_sendto(int, int *, int, struct sockaddr *, socklen_t, char *, int, int);
-extern int sockets_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int);
-extern int sockets_sendto_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int);
+extern void print_mark(unsigned int);
+extern int sockets_create(int, int *, unsigned int, uint16_t, sock_type_t);
+extern int sockets_close(int, int *, unsigned int);
+extern int sockets_connect(int, int *, unsigned int, struct sockaddr *,
+    socklen_t);
+extern int sockets_sendto(int, int *, unsigned int, struct sockaddr *,
+    socklen_t, char *, size_t, unsigned int, sock_type_t);
+extern int sockets_recvfrom(int, int *, unsigned int, struct sockaddr *,
+    socklen_t *, char *, size_t, unsigned int);
+extern int sockets_sendto_recvfrom(int, int *, unsigned int, struct sockaddr *,
+    socklen_t *, char *, size_t, unsigned int, sock_type_t);
 
 #endif
Index: uspace/app/nettest1/nettest1.c
===================================================================
--- uspace/app/nettest1/nettest1.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nettest1/nettest1.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -253,5 +253,5 @@
 	
 	rc = sockets_sendto_recvfrom(verbose, socket_ids, nsockets, address,
-	    &addrlen, data, size, nmessages);
+	    &addrlen, data, size, nmessages, type);
 	if (rc != EOK)
 		return rc;
@@ -278,5 +278,5 @@
 	
 	rc = sockets_sendto(verbose, socket_ids, nsockets, address, addrlen,
-	    data, size, nmessages);
+	    data, size, nmessages, type);
 	if (rc != EOK)
 		return rc;
@@ -335,5 +335,5 @@
 		/* Interpret as a host name */
 		dnsr_hostinfo_t *hinfo = NULL;
-		rc = dnsr_name2host(addr_s, &hinfo);
+		rc = dnsr_name2host(addr_s, &hinfo, family);
 		
 		if (rc != EOK) {
Index: uspace/app/nettest2/nettest2.c
===================================================================
--- uspace/app/nettest2/nettest2.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nettest2/nettest2.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -271,5 +271,5 @@
 		/* Interpret as a host name */
 		dnsr_hostinfo_t *hinfo = NULL;
-		rc = dnsr_name2host(addr_s, &hinfo);
+		rc = dnsr_name2host(addr_s, &hinfo, family);
 		
 		if (rc != EOK) {
@@ -375,5 +375,5 @@
 	
 	rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address,
-	    &addrlen, data, size, messages);
+	    &addrlen, data, size, messages, type);
 	if (rc != EOK)
 		return rc;
@@ -399,5 +399,5 @@
 	
 	rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen,
-	    data, size, messages);
+	    data, size, messages, type);
 	if (rc != EOK)
 		return rc;
Index: uspace/app/nettest3/nettest3.c
===================================================================
--- uspace/app/nettest3/nettest3.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nettest3/nettest3.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -78,5 +78,5 @@
 		if (rc != EOK) {
 			/* Try interpreting as a host name */
-			rc = dnsr_name2host(argv[1], &hinfo);
+			rc = dnsr_name2host(argv[1], &hinfo, AF_INET);
 			if (rc != EOK) {
 				printf("Error resolving host '%s'.\n", argv[1]);
Index: uspace/app/nterm/conn.c
===================================================================
--- uspace/app/nterm/conn.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/nterm/conn.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -84,5 +84,5 @@
 		/* Interpret as a host name */
 		dnsr_hostinfo_t *hinfo = NULL;
-		rc = dnsr_name2host(addr_s, &hinfo);
+		rc = dnsr_name2host(addr_s, &hinfo, 0);
 		
 		if (rc != EOK) {
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/ping/ping.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -42,6 +42,9 @@
 #include <inet/inetping.h>
 #include <io/console.h>
+#include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
+#include <str_error.h>
 #include <sys/types.h>
 
@@ -54,9 +57,19 @@
 #define PING_TIMEOUT (1000 * 1000)
 
+typedef enum {
+	RECEIVED_NONE,
+	RECEIVED_SUCCESS,
+	RECEIVED_INTERRUPT
+} received_t;
+
+static received_t received;
+static FIBRIL_CONDVAR_INITIALIZE(received_cv);
+static FIBRIL_MUTEX_INITIALIZE(received_lock);
+
+static bool quit = false;
+static FIBRIL_CONDVAR_INITIALIZE(quit_cv);
+static FIBRIL_MUTEX_INITIALIZE(quit_lock);
+
 static int ping_ev_recv(inetping_sdu_t *);
-
-static bool done = false;
-static FIBRIL_CONDVAR_INITIALIZE(done_cv);
-static FIBRIL_MUTEX_INITIALIZE(done_lock);
 
 static inetping_ev_ops_t ev_ops = {
@@ -67,17 +80,28 @@
 static addr32_t dest;
 
-static bool ping_repeat = false;
+static bool repeat_forever = false;
+static size_t repeat_count = 1;
+
+static const char *short_options = "rn:";
 
 static void print_syntax(void)
 {
-	printf("syntax: " NAME " [-r] <host>\n");
-}
-
-static void ping_signal_done(void)
-{
-	fibril_mutex_lock(&done_lock);
-	done = true;
-	fibril_mutex_unlock(&done_lock);
-	fibril_condvar_broadcast(&done_cv);
+	printf("Syntax: %s [-n <count>|-r] <host>\n", NAME);
+}
+
+static void ping_signal_received(received_t value)
+{
+	fibril_mutex_lock(&received_lock);
+	received = value;
+	fibril_mutex_unlock(&received_lock);
+	fibril_condvar_broadcast(&received_cv);
+}
+
+static void ping_signal_quit(void)
+{
+	fibril_mutex_lock(&quit_lock);
+	quit = true;
+	fibril_mutex_unlock(&quit_lock);
+	fibril_condvar_broadcast(&quit_cv);
 }
 
@@ -105,6 +129,5 @@
 	    "payload size %zu\n", asrc, adest, sdu->seq_no, sdu->size);
 	
-	if (!ping_repeat)
-		ping_signal_done();
+	ping_signal_received(RECEIVED_SUCCESS);
 	
 	free(asrc);
@@ -116,6 +139,5 @@
 {
 	inetping_sdu_t sdu;
-	int rc;
-
+	
 	sdu.src = src;
 	sdu.dest = dest;
@@ -123,12 +145,11 @@
 	sdu.data = (void *) "foo";
 	sdu.size = 3;
-
-	rc = inetping_send(&sdu);
-	if (rc != EOK) {
-		printf(NAME ": Failed sending echo request (%d).\n", rc);
-		return rc;
-	}
-
-	return EOK;
+	
+	int rc = inetping_send(&sdu);
+	if (rc != EOK)
+		printf("Failed sending echo request: %s (%d).\n",
+		    str_error(rc), rc);
+	
+	return rc;
 }
 
@@ -136,43 +157,60 @@
 {
 	uint16_t seq_no = 0;
-
+	
+	while ((repeat_count--) || (repeat_forever)) {
+		fibril_mutex_lock(&received_lock);
+		received = RECEIVED_NONE;
+		fibril_mutex_unlock(&received_lock);
+		
+		(void) ping_send(++seq_no);
+		
+		fibril_mutex_lock(&received_lock);
+		int rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
+		    PING_TIMEOUT);
+		received_t recv = received;
+		fibril_mutex_unlock(&received_lock);
+		
+		if ((rc == ETIMEOUT) || (recv == RECEIVED_NONE))
+			printf("Echo request timed out (seq. no %u)\n", seq_no);
+		
+		if (recv == RECEIVED_INTERRUPT)
+			break;
+		
+		if ((repeat_count > 0) || (repeat_forever)) {
+			fibril_mutex_lock(&received_lock);
+			rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
+			    PING_DELAY);
+			recv = received;
+			fibril_mutex_unlock(&received_lock);
+			
+			if (recv == RECEIVED_INTERRUPT)
+				break;
+		}
+	}
+	
+	ping_signal_quit();
+	return 0;
+}
+
+static int input_fibril(void *arg)
+{
+	console_ctrl_t *con = console_init(stdin, stdout);
+	
 	while (true) {
-		fibril_mutex_lock(&done_lock);
-		if (done) {
-			fibril_mutex_unlock(&done_lock);
-			return 0;
-		}
-		fibril_mutex_unlock(&done_lock);
-
-		(void) ping_send(++seq_no);
-		async_usleep(PING_DELAY);
-	}
-
-	return 0;
-}
-
-static int input_fibril(void *arg)
-{
-	console_ctrl_t *con;
-	cons_event_t ev;
-
-	con = console_init(stdin, stdout);
-	printf("[Press Ctrl-Q to quit]\n");
-
-	while (true) {
+		cons_event_t ev;
 		if (!console_get_event(con, &ev))
 			break;
-
-		if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS &&
-		    (ev.ev.key.mods & (KM_ALT | KM_SHIFT)) ==
-		    0 && (ev.ev.key.mods & KM_CTRL) != 0) {
+		
+		if ((ev.type == CEV_KEY) && (ev.ev.key.type == KEY_PRESS) &&
+		    ((ev.ev.key.mods & (KM_ALT | KM_SHIFT)) == 0) &&
+		    ((ev.ev.key.mods & KM_CTRL) != 0)) {
 			/* Ctrl+key */
 			if (ev.ev.key.key == KC_Q) {
-				ping_signal_done();
-				return 0;
+				ping_signal_received(RECEIVED_INTERRUPT);
+				break;
 			}
 		}
 	}
-
+	
 	return 0;
 }
@@ -184,35 +222,47 @@
 	char *adest = NULL;
 	char *sdest = NULL;
-	int rc;
-	int argi;
-
-	rc = inetping_init(&ev_ops);
-	if (rc != EOK) {
-		printf(NAME ": Failed connecting to internet ping service "
-		    "(%d).\n", rc);
-		goto error;
-	}
-
-	argi = 1;
-	if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
-		ping_repeat = true;
-		++argi;
-	} else {
-		ping_repeat = false;
-	}
-
-	if (argc - argi != 1) {
+	
+	int rc = inetping_init(&ev_ops);
+	if (rc != EOK) {
+		printf("Failed connecting to internet ping service: "
+		    "%s (%d).\n", str_error(rc), rc);
+		goto error;
+	}
+	
+	int c;
+	while ((c = getopt(argc, argv, short_options)) != -1) {
+		switch (c) {
+		case 'r':
+			repeat_forever = true;
+			break;
+		case 'n':
+			rc = str_size_t(optarg, NULL, 10, true, &repeat_count);
+			if (rc != EOK) {
+				printf("Invalid repeat count.\n");
+				print_syntax();
+				goto error;
+			}
+			break;
+		default:
+			printf("Unknown option passed.\n");
+			print_syntax();
+			goto error;
+		}
+	}
+	
+	if (optind >= argc) {
+		printf("IP address or host name not supplied.\n");
 		print_syntax();
 		goto error;
 	}
-
+	
 	/* Parse destination address */
 	inet_addr_t dest_addr;
-	rc = inet_addr_parse(argv[argi], &dest_addr);
+	rc = inet_addr_parse(argv[optind], &dest_addr);
 	if (rc != EOK) {
 		/* Try interpreting as a host name */
-		rc = dnsr_name2host(argv[argi], &hinfo);
+		rc = dnsr_name2host(argv[optind], &hinfo, AF_INET);
 		if (rc != EOK) {
-			printf(NAME ": Error resolving host '%s'.\n", argv[argi]);
+			printf("Error resolving host '%s'.\n", argv[optind]);
 			goto error;
 		}
@@ -223,6 +273,6 @@
 	uint16_t af = inet_addr_get(&dest_addr, &dest, NULL);
 	if (af != AF_INET) {
-		printf(NAME ": Destination '%s' is not an IPv4 address.\n",
-		    argv[argi]);
+		printf("Destination '%s' is not an IPv4 address.\n",
+		    argv[optind]);
 		goto error;
 	}
@@ -231,5 +281,5 @@
 	rc = inetping_get_srcaddr(dest, &src);
 	if (rc != EOK) {
-		printf(NAME ": Failed determining source address.\n");
+		printf("Failed determining source address.\n");
 		goto error;
 	}
@@ -240,5 +290,5 @@
 	rc = inet_addr_format(&src_addr, &asrc);
 	if (rc != EOK) {
-		printf(NAME ": Out of memory.\n");
+		printf("Out of memory.\n");
 		goto error;
 	}
@@ -246,5 +296,5 @@
 	rc = inet_addr_format(&dest_addr, &adest);
 	if (rc != EOK) {
-		printf(NAME ": Out of memory.\n");
+		printf("Out of memory.\n");
 		goto error;
 	}
@@ -253,5 +303,5 @@
 		rc = asprintf(&sdest, "%s (%s)", hinfo->cname, adest);
 		if (rc < 0) {
-			printf(NAME ": Out of memory.\n");
+			printf("Out of memory.\n");
 			goto error;
 		}
@@ -260,43 +310,29 @@
 		adest = NULL;
 	}
-
-	printf("Sending ICMP echo request from %s to %s.\n",
+	
+	printf("Sending ICMP echo request from %s to %s (Ctrl+Q to quit)\n",
 	    asrc, sdest);
-
-	fid_t fid;
-
-	if (ping_repeat) {
-		fid = fibril_create(transmit_fibril, NULL);
-		if (fid == 0) {
-			printf(NAME ": Failed creating transmit fibril.\n");
-			goto error;
-		}
-
-		fibril_add_ready(fid);
-
-		fid = fibril_create(input_fibril, NULL);
-		if (fid == 0) {
-			printf(NAME ": Failed creating input fibril.\n");
-			goto error;
-		}
-
-		fibril_add_ready(fid);
-	} else {
-		ping_send(1);
-	}
-
-	fibril_mutex_lock(&done_lock);
-	rc = EOK;
-	while (!done && rc != ETIMEOUT) {
-		rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
-			ping_repeat ? 0 : PING_TIMEOUT);
-	}
-	fibril_mutex_unlock(&done_lock);
-
-	if (rc == ETIMEOUT) {
-		printf(NAME ": Echo request timed out.\n");
-		goto error;
-	}
-
+	
+	fid_t fid = fibril_create(transmit_fibril, NULL);
+	if (fid == 0) {
+		printf("Failed creating transmit fibril.\n");
+		goto error;
+	}
+	
+	fibril_add_ready(fid);
+	
+	fid = fibril_create(input_fibril, NULL);
+	if (fid == 0) {
+		printf("Failed creating input fibril.\n");
+		goto error;
+	}
+	
+	fibril_add_ready(fid);
+	
+	fibril_mutex_lock(&quit_lock);
+	while (!quit)
+		fibril_condvar_wait(&quit_cv, &quit_lock);
+	fibril_mutex_unlock(&quit_lock);
+	
 	free(asrc);
 	free(adest);
Index: uspace/app/ping6/ping6.c
===================================================================
--- uspace/app/ping6/ping6.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/app/ping6/ping6.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -42,6 +42,9 @@
 #include <inet/inetping6.h>
 #include <io/console.h>
+#include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
+#include <str_error.h>
 #include <sys/types.h>
 
@@ -54,9 +57,19 @@
 #define PING_TIMEOUT (1000 * 1000)
 
+typedef enum {
+	RECEIVED_NONE,
+	RECEIVED_SUCCESS,
+	RECEIVED_INTERRUPT
+} received_t;
+
+static received_t received;
+static FIBRIL_CONDVAR_INITIALIZE(received_cv);
+static FIBRIL_MUTEX_INITIALIZE(received_lock);
+
+static bool quit = false;
+static FIBRIL_CONDVAR_INITIALIZE(quit_cv);
+static FIBRIL_MUTEX_INITIALIZE(quit_lock);
+
 static int ping_ev_recv(inetping6_sdu_t *);
-
-static bool done = false;
-static FIBRIL_CONDVAR_INITIALIZE(done_cv);
-static FIBRIL_MUTEX_INITIALIZE(done_lock);
 
 static inetping6_ev_ops_t ev_ops = {
@@ -67,17 +80,28 @@
 static addr128_t dest;
 
-static bool ping_repeat = false;
+static bool repeat_forever = false;
+static size_t repeat_count = 1;
+
+static const char *short_options = "rn:";
 
 static void print_syntax(void)
 {
-	printf("syntax: " NAME " [-r] <host>\n");
-}
-
-static void ping_signal_done(void)
-{
-	fibril_mutex_lock(&done_lock);
-	done = true;
-	fibril_mutex_unlock(&done_lock);
-	fibril_condvar_broadcast(&done_cv);
+	printf("Syntax: %s [-n <count>|-r] <host>\n", NAME);
+}
+
+static void ping_signal_received(received_t value)
+{
+	fibril_mutex_lock(&received_lock);
+	received = value;
+	fibril_mutex_unlock(&received_lock);
+	fibril_condvar_broadcast(&received_cv);
+}
+
+static void ping_signal_quit(void)
+{
+	fibril_mutex_lock(&quit_lock);
+	quit = true;
+	fibril_mutex_unlock(&quit_lock);
+	fibril_condvar_broadcast(&quit_cv);
 }
 
@@ -102,9 +126,8 @@
 	}
 	
-	printf("Received ICMP echo reply: from %s to %s, seq. no %u, "
+	printf("Received ICMPv6 echo reply: from %s to %s, seq. no %u, "
 	    "payload size %zu\n", asrc, adest, sdu->seq_no, sdu->size);
 	
-	if (!ping_repeat)
-		ping_signal_done();
+	ping_signal_received(RECEIVED_SUCCESS);
 	
 	free(asrc);
@@ -116,6 +139,5 @@
 {
 	inetping6_sdu_t sdu;
-	int rc;
-
+	
 	addr128(src, sdu.src);
 	addr128(dest, sdu.dest);
@@ -123,12 +145,11 @@
 	sdu.data = (void *) "foo";
 	sdu.size = 3;
-
-	rc = inetping6_send(&sdu);
-	if (rc != EOK) {
-		printf(NAME ": Failed sending echo request (%d).\n", rc);
-		return rc;
-	}
-
-	return EOK;
+	
+	int rc = inetping6_send(&sdu);
+	if (rc != EOK)
+		printf("Failed sending echo request: %s (%d).\n",
+		    str_error(rc), rc);
+	
+	return rc;
 }
 
@@ -136,43 +157,60 @@
 {
 	uint16_t seq_no = 0;
-
+	
+	while ((repeat_count--) || (repeat_forever)) {
+		fibril_mutex_lock(&received_lock);
+		received = RECEIVED_NONE;
+		fibril_mutex_unlock(&received_lock);
+		
+		(void) ping_send(++seq_no);
+		
+		fibril_mutex_lock(&received_lock);
+		int rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
+		    PING_TIMEOUT);
+		received_t recv = received;
+		fibril_mutex_unlock(&received_lock);
+		
+		if ((rc == ETIMEOUT) || (recv == RECEIVED_NONE))
+			printf("Echo request timed out (seq. no %u)\n", seq_no);
+		
+		if (recv == RECEIVED_INTERRUPT)
+			break;
+		
+		if ((repeat_count > 0) || (repeat_forever)) {
+			fibril_mutex_lock(&received_lock);
+			rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
+			    PING_DELAY);
+			recv = received;
+			fibril_mutex_unlock(&received_lock);
+			
+			if (recv == RECEIVED_INTERRUPT)
+				break;
+		}
+	}
+	
+	ping_signal_quit();
+	return 0;
+}
+
+static int input_fibril(void *arg)
+{
+	console_ctrl_t *con = console_init(stdin, stdout);
+	
 	while (true) {
-		fibril_mutex_lock(&done_lock);
-		if (done) {
-			fibril_mutex_unlock(&done_lock);
-			return 0;
-		}
-		fibril_mutex_unlock(&done_lock);
-
-		(void) ping_send(++seq_no);
-		async_usleep(PING_DELAY);
-	}
-
-	return 0;
-}
-
-static int input_fibril(void *arg)
-{
-	console_ctrl_t *con;
-	cons_event_t ev;
-
-	con = console_init(stdin, stdout);
-	printf("[Press Ctrl-Q to quit]\n");
-
-	while (true) {
+		cons_event_t ev;
 		if (!console_get_event(con, &ev))
 			break;
-
-		if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS &&
-		    (ev.ev.key.mods & (KM_ALT | KM_SHIFT)) ==
-		    0 && (ev.ev.key.mods & KM_CTRL) != 0) {
+		
+		if ((ev.type == CEV_KEY) && (ev.ev.key.type == KEY_PRESS) &&
+		    ((ev.ev.key.mods & (KM_ALT | KM_SHIFT)) == 0) &&
+		    ((ev.ev.key.mods & KM_CTRL) != 0)) {
 			/* Ctrl+key */
 			if (ev.ev.key.key == KC_Q) {
-				ping_signal_done();
-				return 0;
+				ping_signal_received(RECEIVED_INTERRUPT);
+				break;
 			}
 		}
 	}
-
+	
 	return 0;
 }
@@ -184,35 +222,47 @@
 	char *adest = NULL;
 	char *sdest = NULL;
-	int rc;
-	int argi;
-
-	rc = inetping6_init(&ev_ops);
-	if (rc != EOK) {
-		printf(NAME ": Failed connecting to internet ping service "
-		    "(%d).\n", rc);
-		goto error;
-	}
-
-	argi = 1;
-	if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
-		ping_repeat = true;
-		++argi;
-	} else {
-		ping_repeat = false;
-	}
-
-	if (argc - argi != 1) {
+	
+	int rc = inetping6_init(&ev_ops);
+	if (rc != EOK) {
+		printf("Failed connecting to internet ping service: "
+		    "%s (%d).\n", str_error(rc), rc);
+		goto error;
+	}
+	
+	int c;
+	while ((c = getopt(argc, argv, short_options)) != -1) {
+		switch (c) {
+		case 'r':
+			repeat_forever = true;
+			break;
+		case 'n':
+			rc = str_size_t(optarg, NULL, 10, true, &repeat_count);
+			if (rc != EOK) {
+				printf("Invalid repeat count.\n");
+				print_syntax();
+				goto error;
+			}
+			break;
+		default:
+			printf("Unknown option passed.\n");
+			print_syntax();
+			goto error;
+		}
+	}
+	
+	if (optind >= argc) {
+		printf("IP address or host name not supplied.\n");
 		print_syntax();
 		goto error;
 	}
-
+	
 	/* Parse destination address */
 	inet_addr_t dest_addr;
-	rc = inet_addr_parse(argv[argi], &dest_addr);
+	rc = inet_addr_parse(argv[optind], &dest_addr);
 	if (rc != EOK) {
 		/* Try interpreting as a host name */
-		rc = dnsr_name2host(argv[argi], &hinfo);
+		rc = dnsr_name2host(argv[optind], &hinfo, AF_INET);
 		if (rc != EOK) {
-			printf(NAME ": Error resolving host '%s'.\n", argv[argi]);
+			printf("Error resolving host '%s'.\n", argv[optind]);
 			goto error;
 		}
@@ -223,6 +273,6 @@
 	uint16_t af = inet_addr_get(&dest_addr, NULL, &dest);
 	if (af != AF_INET6) {
-		printf(NAME ": Destination '%s' is not an IPv6 address.\n",
-		    argv[argi]);
+		printf("Destination '%s' is not an IPv6 address.\n",
+		    argv[optind]);
 		goto error;
 	}
@@ -231,5 +281,5 @@
 	rc = inetping6_get_srcaddr(dest, src);
 	if (rc != EOK) {
-		printf(NAME ": Failed determining source address.\n");
+		printf("Failed determining source address.\n");
 		goto error;
 	}
@@ -240,5 +290,5 @@
 	rc = inet_addr_format(&src_addr, &asrc);
 	if (rc != EOK) {
-		printf(NAME ": Out of memory.\n");
+		printf("Out of memory.\n");
 		goto error;
 	}
@@ -246,5 +296,5 @@
 	rc = inet_addr_format(&dest_addr, &adest);
 	if (rc != EOK) {
-		printf(NAME ": Out of memory.\n");
+		printf("Out of memory.\n");
 		goto error;
 	}
@@ -253,5 +303,5 @@
 		rc = asprintf(&sdest, "%s (%s)", hinfo->cname, adest);
 		if (rc < 0) {
-			printf(NAME ": Out of memory.\n");
+			printf("Out of memory.\n");
 			goto error;
 		}
@@ -260,43 +310,29 @@
 		adest = NULL;
 	}
-
-	printf("Sending ICMP echo request from %s to %s.\n",
+	
+	printf("Sending ICMP echo request from %s to %s (Ctrl+Q to quit)\n",
 	    asrc, sdest);
-
-	fid_t fid;
-
-	if (ping_repeat) {
-		fid = fibril_create(transmit_fibril, NULL);
-		if (fid == 0) {
-			printf(NAME ": Failed creating transmit fibril.\n");
-			goto error;
-		}
-
-		fibril_add_ready(fid);
-
-		fid = fibril_create(input_fibril, NULL);
-		if (fid == 0) {
-			printf(NAME ": Failed creating input fibril.\n");
-			goto error;
-		}
-
-		fibril_add_ready(fid);
-	} else {
-		ping_send(1);
-	}
-
-	fibril_mutex_lock(&done_lock);
-	rc = EOK;
-	while (!done && rc != ETIMEOUT) {
-		rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
-			ping_repeat ? 0 : PING_TIMEOUT);
-	}
-	fibril_mutex_unlock(&done_lock);
-
-	if (rc == ETIMEOUT) {
-		printf(NAME ": Echo request timed out.\n");
-		goto error;
-	}
-
+	
+	fid_t fid = fibril_create(transmit_fibril, NULL);
+	if (fid == 0) {
+		printf("Failed creating transmit fibril.\n");
+		goto error;
+	}
+	
+	fibril_add_ready(fid);
+	
+	fid = fibril_create(input_fibril, NULL);
+	if (fid == 0) {
+		printf("Failed creating input fibril.\n");
+		goto error;
+	}
+	
+	fibril_add_ready(fid);
+	
+	fibril_mutex_lock(&quit_lock);
+	while (!quit)
+		fibril_condvar_wait(&quit_cv, &quit_lock);
+	fibril_mutex_unlock(&quit_lock);
+	
 	free(asrc);
 	free(adest);
Index: uspace/lib/c/generic/dnsr.c
===================================================================
--- uspace/lib/c/generic/dnsr.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/c/generic/dnsr.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -67,5 +67,5 @@
 }
 
-int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo)
+int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo, uint16_t af)
 {
 	dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
@@ -76,5 +76,6 @@
 	
 	ipc_call_t answer;
-	aid_t req = async_send_0(exch, DNSR_NAME2HOST, &answer);
+	aid_t req = async_send_1(exch, DNSR_NAME2HOST, (sysarg_t) af,
+	    &answer);
 	
 	int rc = async_data_write_start(exch, name, str_size(name));
Index: uspace/lib/c/generic/inet/addr.c
===================================================================
--- uspace/lib/c/generic/inet/addr.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/c/generic/inet/addr.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -52,4 +52,8 @@
 };
 
+static const addr48_t inet_addr48_solicited_node = {
+	0x33, 0x33, 0xff, 0, 0, 0
+};
+
 static const inet_addr_t inet_addr_any_addr = {
 	.family = AF_INET,
@@ -72,7 +76,24 @@
 }
 
+int addr48_compare(const addr48_t a, const addr48_t b)
+{
+	return memcmp(a, b, 6);
+}
+
 int addr128_compare(const addr128_t a, const addr128_t b)
 {
 	return memcmp(a, b, 16);
+}
+
+/** Compute solicited node MAC multicast address from target IPv6 address
+ *
+ * @param ip  Target IPv6 address
+ * @param mac Solicited MAC address to be assigned
+ *
+ */
+void addr48_solicited_node(const addr128_t ip, addr48_t mac)
+{
+	memcpy(mac, inet_addr48_solicited_node, 3);
+	memcpy(mac + 3, ip + 13, 3);
 }
 
@@ -260,4 +281,19 @@
 }
 
+int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
+{
+	if (naddr->family != addr->family)
+		return 0;
+	
+	switch (naddr->family) {
+	case AF_INET:
+		return (naddr->addr == addr->addr);
+	case AF_INET6:
+		return addr128_compare(naddr->addr6, addr->addr6);
+	default:
+		return 0;
+	}
+}
+
 int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
 {
Index: uspace/lib/c/generic/net/socket_parse.c
===================================================================
--- uspace/lib/c/generic/net/socket_parse.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/c/generic/net/socket_parse.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -53,11 +53,11 @@
 int socket_parse_address_family(const char *name, int *af)
 {
-	if (str_lcmp(name, "AF_INET", 7) == 0) {
-		*af = AF_INET;
+	if (str_lcmp(name, "AF_INET6", 8) == 0) {
+		*af = AF_INET6;
 		return EOK;
 	}
 	
-	if (str_lcmp(name, "AF_INET6", 8) == 0) {
-		*af = AF_INET6;
+	if (str_lcmp(name, "AF_INET", 7) == 0) {
+		*af = AF_INET;
 		return EOK;
 	}
Index: uspace/lib/c/include/inet/addr.h
===================================================================
--- uspace/lib/c/include/inet/addr.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/c/include/inet/addr.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -73,5 +73,8 @@
 extern void addr128(const addr128_t, addr128_t);
 
+extern int addr48_compare(const addr48_t, const addr48_t);
 extern int addr128_compare(const addr128_t, const addr128_t);
+
+extern void addr48_solicited_node(const addr128_t, addr48_t);
 
 extern void host2addr128_t_be(const addr128_t, addr128_t);
@@ -97,4 +100,5 @@
 extern int inet_addr_is_any(const inet_addr_t *);
 
+extern int inet_naddr_compare(const inet_naddr_t *, const inet_addr_t *);
 extern int inet_naddr_compare_mask(const inet_naddr_t *, const inet_addr_t *);
 
Index: uspace/lib/c/include/inet/dnsr.h
===================================================================
--- uspace/lib/c/include/inet/dnsr.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/c/include/inet/dnsr.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -51,5 +51,5 @@
 
 extern int dnsr_init(void);
-extern int dnsr_name2host(const char *, dnsr_hostinfo_t **);
+extern int dnsr_name2host(const char *, dnsr_hostinfo_t **, uint16_t);
 extern void dnsr_hostinfo_destroy(dnsr_hostinfo_t *);
 extern int dnsr_get_srvaddr(inet_addr_t *);
Index: uspace/lib/posix/include/posix/stdio.h
===================================================================
--- uspace/lib/posix/include/posix/stdio.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/include/posix/stdio.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -65,7 +65,4 @@
 
 #define BUFSIZ  4096
-#define SEEK_SET  0
-#define SEEK_CUR  1
-#define SEEK_END  2
 
 typedef struct _IO_FILE FILE;
Index: uspace/lib/posix/include/posix/stdlib.h
===================================================================
--- uspace/lib/posix/include/posix/stdlib.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/include/posix/stdlib.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -46,4 +46,6 @@
 	#define NULL  ((void *) 0)
 #endif
+
+#define RAND_MAX  714025
 
 /* Process Termination */
@@ -122,4 +124,8 @@
 extern int __POSIX_DEF__(mkstemp)(char *tmpl);
 
+/* Pseudo-random number generator */
+extern int __POSIX_DEF__(rand)(void);
+extern void __POSIX_DEF__(srand)(unsigned int seed);
+
 /* Legacy Declarations */
 extern char *__POSIX_DEF__(mktemp)(char *tmpl);
Index: uspace/lib/posix/include/posix/time.h
===================================================================
--- uspace/lib/posix/include/posix/time.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/include/posix/time.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -87,4 +87,7 @@
 extern void __POSIX_DEF__(tzset)(void);
 
+/* Time */
+extern time_t __POSIX_DEF__(time)(time_t *t);
+
 /* Broken-down Time */
 extern struct tm *__POSIX_DEF__(gmtime_r)(const time_t *restrict timer,
Index: uspace/lib/posix/include/posix/unistd.h
===================================================================
--- uspace/lib/posix/include/posix/unistd.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/include/posix/unistd.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -44,4 +44,8 @@
 #include "stddef.h"
 
+#define SEEK_SET  0
+#define SEEK_CUR  1
+#define SEEK_END  2
+
 /* Process Termination */
 #define _exit exit
@@ -77,4 +81,6 @@
 extern ssize_t __POSIX_DEF__(read)(int fildes, void *buf, size_t nbyte);
 extern ssize_t __POSIX_DEF__(write)(int fildes, const void *buf, size_t nbyte);
+extern __POSIX_DEF__(off_t) __POSIX_DEF__(lseek)(int fildes,
+    __POSIX_DEF__(off_t) offset, int whence);
 extern int __POSIX_DEF__(fsync)(int fildes);
 extern int __POSIX_DEF__(ftruncate)(int fildes, __POSIX_DEF__(off_t) length);
Index: uspace/lib/posix/source/stdlib.c
===================================================================
--- uspace/lib/posix/source/stdlib.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/source/stdlib.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -394,4 +394,24 @@
 
 /**
+ * Generate a pseudo random integer in the range 0 to RAND_MAX inclusive.
+ *
+ * @return The pseudo random integer.
+ */
+int posix_rand(void)
+{
+	return (int) random();
+}
+
+/**
+ * Initialize a new sequence of pseudo-random integers.
+ *
+ * @param seed The seed of the new sequence.
+ */
+void posix_srand(unsigned int seed)
+{
+	srandom(seed);
+}
+
+/**
  * Creates and opens an unique temporary file from template.
  *
Index: uspace/lib/posix/source/time.c
===================================================================
--- uspace/lib/posix/source/time.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/source/time.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -74,4 +74,17 @@
 	posix_daylight = 0;
 	posix_timezone = 0;
+}
+
+/**
+ * Get the time in seconds
+ *
+ * @param t If t is non-NULL, the return value is also stored in the memory
+ *          pointed to by t.
+ * @return  On success, the value of time in seconds since the Epoch
+ *          is returned. On error, (time_t)-1 is returned.
+ */
+time_t posix_time(time_t *t)
+{
+	return time(t);
 }
 
Index: uspace/lib/posix/source/unistd.c
===================================================================
--- uspace/lib/posix/source/unistd.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/lib/posix/source/unistd.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -221,4 +221,18 @@
 {
 	return errnify(write, fildes, buf, nbyte);
+}
+
+/**
+ * Reposition read/write file offset
+ *
+ * @param fildes File descriptor of the opened file.
+ * @param offset New offset in the file.
+ * @param whence The position from which the offset argument is specified.
+ * @return Upon successful completion, returns the resulting offset
+ *         as measured in bytes from the beginning of the file, -1 otherwise.
+ */
+posix_off_t posix_lseek(int fildes, posix_off_t offset, int whence)
+{
+	return errnify(lseek, fildes, offset, whence);
 }
 
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -296,13 +296,20 @@
 uint32_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
 {
-	uint32_t w;
 	assert(buf_size >= 4);
-
-	w = ((uint32_t) buf[0] << 24) +
+	
+	uint32_t w = ((uint32_t) buf[0] << 24) +
 	    ((uint32_t) buf[1] << 16) +
 	    ((uint32_t) buf[2] << 8) +
 	    buf[3];
-
+	
 	return w;
+}
+
+/** Decode unaligned big-endian 128-bit integer */
+void dns_addr128_t_decode(uint8_t *buf, size_t buf_size, addr128_t addr)
+{
+	assert(buf_size >= 16);
+	
+	addr128_t_be2host(buf, addr);
 }
 
@@ -400,5 +407,5 @@
 	int rc;
 
-	rr = calloc(1, sizeof (dns_rr_t));
+	rr = calloc(1, sizeof(dns_rr_t));
 	if (rr == NULL)
 		return ENOMEM;
@@ -427,14 +434,18 @@
 
 	rr->rtype = dns_uint16_t_decode(bp, bsz);
-	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	bp += sizeof(uint16_t);
+	bsz -= sizeof(uint16_t);
 
 	rr->rclass = dns_uint16_t_decode(bp, bsz);
-	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	bp += sizeof(uint16_t);
+	bsz -= sizeof(uint16_t);
 
 	rr->ttl = dns_uint32_t_decode(bp, bsz);
-	bp += sizeof(uint32_t); bsz -= sizeof(uint32_t);
+	bp += sizeof(uint32_t);
+	bsz -= sizeof(uint32_t);
 
 	rdlength = dns_uint16_t_decode(bp, bsz);
-	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	bp += sizeof(uint16_t);
+	bsz -= sizeof(uint16_t);
 
 	if (rdlength > bsz) {
Index: uspace/srv/net/dnsrsrv/dns_msg.h
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/dns_msg.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -40,4 +40,5 @@
 #include <stdbool.h>
 #include <stdint.h>
+#include <inet/addr.h>
 #include "dns_std.h"
 #include "dns_type.h"
@@ -49,4 +50,5 @@
 extern int dns_name_decode(dns_pdu_t *, size_t, char **, size_t *);
 extern uint32_t dns_uint32_t_decode(uint8_t *, size_t);
+extern void dns_addr128_t_decode(uint8_t *, size_t, addr128_t);
 
 #endif
Index: uspace/srv/net/dnsrsrv/dns_std.h
===================================================================
--- uspace/srv/net/dnsrsrv/dns_std.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/dns_std.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -65,4 +65,5 @@
 	DTYPE_MX	= 15,
 	DTYPE_TXT	= 16,
+	DTYPE_AAAA	= 28,
 	DQTYPE_AXFR	= 252,
 	DQTYPE_MAILB	= 253,
Index: uspace/srv/net/dnsrsrv/dnsrsrv.c
===================================================================
--- uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -89,4 +89,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
 	
+	uint16_t af = IPC_GET_ARG1(*icall);
+	
 	char *name;
 	int rc = async_data_write_accept((void **) &name, true, 0,
@@ -98,5 +100,5 @@
 	
 	dns_host_info_t *hinfo;
-	rc = dns_name2host(name, &hinfo);
+	rc = dns_name2host(name, &hinfo, af);
 	if (rc != EOK) {
 		async_answer_0(iid, rc);
Index: uspace/srv/net/dnsrsrv/query.c
===================================================================
--- uspace/srv/net/dnsrsrv/query.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/query.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -39,5 +39,5 @@
 #include <stdlib.h>
 #include <str.h>
-
+#include <net/socket_codes.h>
 #include "dns_msg.h"
 #include "dns_std.h"
@@ -48,28 +48,37 @@
 static uint16_t msg_id;
 
-int dns_name2host(const char *name, dns_host_info_t **rinfo)
+static int dns_name_query(const char *name, dns_qtype_t qtype,
+    dns_host_info_t *info)
 {
-	dns_message_t *msg;
-	dns_message_t *amsg;
-	dns_question_t *question;
-	dns_host_info_t *info;
-	char *sname, *cname;
-	size_t eoff;
-	int rc;
-
-	question = calloc(1, sizeof(dns_question_t));
-	if (question == NULL)
-		return ENOMEM;
-
-	question->qname = (char *)name;
-	question->qtype = DTYPE_A;
+	/* Start with the caller-provided name */
+	char *sname = str_dup(name);
+	if (sname == NULL)
+		return ENOMEM;
+	
+	char *qname = str_dup(name);
+	if (qname == NULL) {
+		free(sname);
+		return ENOMEM;
+	}
+	
+	dns_question_t *question = calloc(1, sizeof(dns_question_t));
+	if (question == NULL) {
+		free(qname);
+		free(sname);
+		return ENOMEM;
+	}
+	
+	question->qname = qname;
+	question->qtype = qtype;
 	question->qclass = DC_IN;
-
-	msg = dns_message_new();
-	if (msg == NULL)
-		return ENOMEM;
-
-	list_append(&question->msg, &msg->question);
-
+	
+	dns_message_t *msg = dns_message_new();
+	if (msg == NULL) {
+		free(question);
+		free(qname);
+		free(sname);
+		return ENOMEM;
+	}
+	
 	msg->id = msg_id++;
 	msg->qr = QR_QUERY;
@@ -79,53 +88,63 @@
 	msg->rd = true;
 	msg->ra = false;
-
-	rc = dns_request(msg, &amsg);
+	
+	list_append(&question->msg, &msg->question);
+	
+	dns_message_t *amsg;
+	int rc = dns_request(msg, &amsg);
 	if (rc != EOK) {
+		dns_message_destroy(msg);
+		free(sname);
 		return rc;
 	}
-
-	/* Start with the caller-provided name */
-	sname = str_dup(name);
-
+	
 	list_foreach(amsg->answer, link) {
 		dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
-
+		
 		log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu",
-			rr->name, rr->rtype, rr->rclass, rr->rdata_size);
-
-		if (rr->rtype == DTYPE_CNAME && rr->rclass == DC_IN &&
-		    str_cmp(rr->name, sname) == 0) {
+		    rr->name, rr->rtype, rr->rclass, rr->rdata_size);
+		
+		if ((rr->rtype == DTYPE_CNAME) && (rr->rclass == DC_IN) &&
+		    (str_cmp(rr->name, sname) == 0)) {
+			
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
 			    amsg->pdu.data, amsg->pdu.size, rr->roff);
+			
+			char *cname;
+			size_t eoff;
 			rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
 			if (rc != EOK) {
-				log_msg(LOG_DEFAULT, LVL_DEBUG,
-				    "error decoding cname");
-				assert(rc == EINVAL || rc == ENOMEM);
+				assert((rc == EINVAL) || (rc == ENOMEM));
+				
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding cname");
+				
 				dns_message_destroy(msg);
 				dns_message_destroy(amsg);
+				free(sname);
+				
 				return rc;
 			}
-
+			
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
 			    "cname = '%s'", sname, cname);
-
+			
+			/* Continue looking for the more canonical name */
 			free(sname);
-			/* Continue looking for the more canonical name */
 			sname = cname;
 		}
-
-		if (rr->rtype == DTYPE_A && rr->rclass == DC_IN &&
-			rr->rdata_size == sizeof(uint32_t) &&
-			    str_cmp(rr->name, sname) == 0) {
-
-			info = calloc(1, sizeof(dns_host_info_t));
-			if (info == NULL) {
+		
+		if ((qtype == DTYPE_A) && (rr->rtype == DTYPE_A) &&
+		    (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr32_t)) &&
+		    (str_cmp(rr->name, sname) == 0)) {
+			
+			info->cname = str_dup(rr->name);
+			if (info->cname == NULL) {
 				dns_message_destroy(msg);
 				dns_message_destroy(amsg);
+				free(sname);
+				
 				return ENOMEM;
 			}
-
-			info->cname = str_dup(rr->name);
+			
 			inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size),
 			    &info->addr);
@@ -133,14 +152,76 @@
 			dns_message_destroy(msg);
 			dns_message_destroy(amsg);
-			*rinfo = info;
+			free(sname);
+			
 			return EOK;
 		}
-	}
-
+		
+		if ((qtype == DTYPE_AAAA) && (rr->rtype == DTYPE_AAAA) &&
+		    (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr128_t)) &&
+		    (str_cmp(rr->name, sname) == 0)) {
+		
+			info->cname = str_dup(rr->name);
+			if (info->cname == NULL) {
+				dns_message_destroy(msg);
+				dns_message_destroy(amsg);
+				free(sname);
+				
+				return ENOMEM;
+			}
+			
+			addr128_t addr;
+			dns_addr128_t_decode(rr->rdata, rr->rdata_size, addr);
+			
+			inet_addr_set6(addr, &info->addr);
+			
+			dns_message_destroy(msg);
+			dns_message_destroy(amsg);
+			free(sname);
+			
+			return EOK;
+		}
+	}
+	
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
+	
 	dns_message_destroy(msg);
 	dns_message_destroy(amsg);
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
-
+	free(sname);
+	
 	return EIO;
+}
+
+int dns_name2host(const char *name, dns_host_info_t **rinfo, uint16_t af)
+{
+	dns_host_info_t *info = calloc(1, sizeof(dns_host_info_t));
+	if (info == NULL)
+		return ENOMEM;
+	
+	int rc;
+	
+	switch (af) {
+	case AF_NONE:
+		rc = dns_name_query(name, DTYPE_AAAA, info);
+		
+		if (rc != EOK)
+			rc = dns_name_query(name, DTYPE_A, info);
+		
+		break;
+	case AF_INET:
+		rc = dns_name_query(name, DTYPE_A, info);
+		break;
+	case AF_INET6:
+		rc = dns_name_query(name, DTYPE_AAAA, info);
+		break;
+	default:
+		rc = EINVAL;
+	}
+	
+	if (rc == EOK)
+		*rinfo = info;
+	else
+		free(info);
+	
+	return rc;
 }
 
Index: uspace/srv/net/dnsrsrv/query.h
===================================================================
--- uspace/srv/net/dnsrsrv/query.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/dnsrsrv/query.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -39,5 +39,5 @@
 #include "dns_type.h"
 
-extern int dns_name2host(const char *, dns_host_info_t **);
+extern int dns_name2host(const char *, dns_host_info_t **, uint16_t);
 extern void dns_hostinfo_destroy(dns_host_info_t *);
 
Index: uspace/srv/net/ethip/ethip.h
===================================================================
--- uspace/srv/net/ethip/ethip.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/ethip/ethip.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -46,10 +46,10 @@
 
 typedef struct {
-	link_t addr_list;
+	link_t link;
 	inet_addr_t addr;
 } ethip_link_addr_t;
 
 typedef struct ethip_nic {
-	link_t nic_list;
+	link_t link;
 	service_id_t svc_id;
 	char *svc_name;
@@ -61,6 +61,10 @@
 	/** MAC address */
 	addr48_t mac_addr;
-	/** List of IP addresses configured on this link */
-	list_t addr_list; /* of ethip_link_addr_t */
+	
+	/**
+	 * List of IP addresses configured on this link
+	 * (of the type ethip_link_addr_t)
+	 */
+	list_t addr_list;
 } ethip_nic_t;
 
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -45,5 +45,6 @@
 #include <device/nic.h>
 #include <stdlib.h>
-
+#include <net/socket_codes.h>
+#include <mem.h>
 #include "ethip.h"
 #include "ethip_nic.h"
@@ -83,7 +84,7 @@
 		already_known = false;
 
-		list_foreach(ethip_nic_list, nic_link) {
-			ethip_nic_t *nic = list_get_instance(nic_link,
-			    ethip_nic_t, nic_list);
+		list_foreach(ethip_nic_list, link) {
+			ethip_nic_t *nic = list_get_instance(link,
+			    ethip_nic_t, link);
 			if (nic->svc_id == svcs[i]) {
 				already_known = true;
@@ -108,5 +109,4 @@
 {
 	ethip_nic_t *nic = calloc(1, sizeof(ethip_nic_t));
-
 	if (nic == NULL) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC structure. "
@@ -114,8 +114,8 @@
 		return NULL;
 	}
-
-	link_initialize(&nic->nic_list);
+	
+	link_initialize(&nic->link);
 	list_initialize(&nic->addr_list);
-
+	
 	return nic;
 }
@@ -130,5 +130,5 @@
 	}
 	
-	link_initialize(&laddr->addr_list);
+	link_initialize(&laddr->link);
 	laddr->addr = *addr;
 	
@@ -140,4 +140,5 @@
 	if (nic->svc_name != NULL)
 		free(nic->svc_name);
+	
 	free(nic);
 }
@@ -180,5 +181,5 @@
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened NIC '%s'", nic->svc_name);
-	list_append(&nic->nic_list, &ethip_nic_list);
+	list_append(&nic->link, &ethip_nic_list);
 	in_list = true;
 
@@ -209,7 +210,9 @@
 error:
 	if (in_list)
-		list_remove(&nic->nic_list);
+		list_remove(&nic->link);
+	
 	if (nic->sess != NULL)
 		async_hangup(nic->sess);
+	
 	ethip_nic_delete(nic);
 	return rc;
@@ -312,6 +315,5 @@
 	list_foreach(ethip_nic_list, link) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
-		ethip_nic_t *nic = list_get_instance(link, ethip_nic_t,
-		    nic_list);
+		ethip_nic_t *nic = list_get_instance(link, ethip_nic_t, link);
 
 		if (nic->iplink_sid == iplink_sid) {
@@ -334,4 +336,80 @@
 }
 
+/** Setup accepted multicast addresses
+ *
+ * Currently the set of accepted multicast addresses is
+ * determined only based on IPv6 addresses.
+ *
+ */
+static int ethip_nic_setup_multicast(ethip_nic_t *nic)
+{
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_setup_multicast()");
+	
+	/* Count the number of multicast addresses */
+	
+	size_t count = 0;
+	
+	list_foreach(nic->addr_list, link) {
+		ethip_link_addr_t *laddr = list_get_instance(link,
+		    ethip_link_addr_t, link);
+		
+		uint16_t af = inet_addr_get(&laddr->addr, NULL, NULL);
+		if (af == AF_INET6)
+			count++;
+	}
+	
+	if (count == 0)
+		return nic_multicast_set_mode(nic->sess, NIC_MULTICAST_BLOCKED,
+		    NULL, 0);
+	
+	nic_address_t *mac_list = calloc(count, sizeof(nic_address_t));
+	if (mac_list == NULL)
+		return ENOMEM;
+	
+	/* Create the multicast MAC list */
+	
+	size_t i = 0;
+	
+	list_foreach(nic->addr_list, link) {
+		assert(i < count);
+		
+		ethip_link_addr_t *laddr = list_get_instance(link,
+		    ethip_link_addr_t, link);
+		
+		addr128_t v6;
+		uint16_t af = inet_addr_get(&laddr->addr, NULL, &v6);
+		if (af != AF_INET6)
+			continue;
+		
+		addr48_t mac;
+		addr48_solicited_node(v6, mac);
+		
+		/* Avoid duplicate addresses in the list */
+		
+		bool found = false;
+		
+		for (size_t j = 0; j < i; j++) {
+			if (addr48_compare(mac_list[j].address, mac)) {
+				found = true;
+				break;
+			}
+		}
+		
+		if (!found) {
+			addr48(mac, mac_list[i].address);
+			i++;
+		} else
+			count--;
+	}
+	
+	/* Setup the multicast MAC list */
+	
+	int rc = nic_multicast_set_mode(nic->sess, NIC_MULTICAST_LIST,
+	    mac_list, count);
+	
+	free(mac_list);
+	return rc;
+}
+
 int ethip_nic_addr_add(ethip_nic_t *nic, inet_addr_t *addr)
 {
@@ -342,6 +420,7 @@
 		return ENOMEM;
 	
-	list_append(&laddr->addr_list, &nic->addr_list);
-	return EOK;
+	list_append(&laddr->link, &nic->addr_list);
+	
+	return ethip_nic_setup_multicast(nic);
 }
 
@@ -354,7 +433,8 @@
 		return ENOENT;
 	
-	list_remove(&laddr->addr_list);
+	list_remove(&laddr->link);
 	ethip_link_addr_delete(laddr);
-	return EOK;
+	
+	return ethip_nic_setup_multicast(nic);
 }
 
@@ -366,5 +446,5 @@
 	list_foreach(nic->addr_list, link) {
 		ethip_link_addr_t *laddr = list_get_instance(link,
-		    ethip_link_addr_t, addr_list);
+		    ethip_link_addr_t, link);
 		
 		if (inet_addr_compare(addr, &laddr->addr))
Index: uspace/srv/net/ethip/pdu.c
===================================================================
--- uspace/srv/net/ethip/pdu.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/ethip/pdu.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -46,6 +46,4 @@
 #include "pdu.h"
 
-#define MAC48_BYTES 6
-
 /** Encode Ethernet PDU. */
 int eth_pdu_encode(eth_frame_t *frame, void **rdata, size_t *rsize)
Index: uspace/srv/net/inetsrv/addrobj.c
===================================================================
--- uspace/srv/net/inetsrv/addrobj.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/addrobj.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -119,9 +119,21 @@
 		    inet_addrobj_t, addr_list);
 		
-		if (inet_naddr_compare_mask(&naddr->naddr, addr)) {
-			fibril_mutex_unlock(&addr_list_lock);
-			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
-			    naddr);
-			return naddr;
+		switch (find) {
+		case iaf_net:
+			if (inet_naddr_compare_mask(&naddr->naddr, addr)) {
+				fibril_mutex_unlock(&addr_list_lock);
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
+				    naddr);
+				return naddr;
+			}
+			break;
+		case iaf_addr:
+			if (inet_naddr_compare(&naddr->naddr, addr)) {
+				fibril_mutex_unlock(&addr_list_lock);
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
+				    naddr);
+				return naddr;
+			}
+			break;
 		}
 	}
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/icmp.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -153,5 +153,5 @@
 		return ENOMEM;
 	
-	icmp_echo_t *request = (icmp_echo_t *)rdata;
+	icmp_echo_t *request = (icmp_echo_t *) rdata;
 	
 	request->type = ICMP_ECHO_REQUEST;
Index: uspace/srv/net/inetsrv/icmpv6.c
===================================================================
--- uspace/srv/net/inetsrv/icmpv6.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/icmpv6.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -78,5 +78,5 @@
 	inet_dgram_t rdgram;
 	
-	rdgram.src = dgram->dest;
+	inet_get_srcaddr(&dgram->src, 0, &rdgram.src);
 	rdgram.dest = dgram->src;
 	rdgram.tos = 0;
@@ -150,7 +150,5 @@
 	case ICMPV6_NEIGHBOUR_SOLICITATION:
 	case ICMPV6_NEIGHBOUR_ADVERTISEMENT:
-#ifdef ACCEPT_RA
 	case ICMPV6_ROUTER_ADVERTISEMENT:
-#endif
 		return ndp_received(dgram);
 	default:
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -51,4 +51,7 @@
 static bool first_link = true;
 static bool first_link6 = true;
+
+static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
+static uint16_t ip_ident = 0;
 
 static int inet_link_open(service_id_t);
@@ -335,5 +338,19 @@
 }
 
-/** Send IPv4 datagram over Internet link */
+/** Send IPv4 datagram over Internet link
+ *
+ * @param ilink Internet link
+ * @param lsrc  Source IPv4 address
+ * @param ldest Destination IPv4 address
+ * @param dgram IPv4 datagram body
+ * @param proto Protocol
+ * @param ttl   Time-to-live
+ * @param df    Do-not-Fragment flag
+ *
+ * @return EOK on success
+ * @return ENOMEM when not enough memory to create the datagram
+ * @return ENOTSUP if networking mode is not supported
+ *
+ */
 int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest,
     inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
@@ -366,10 +383,16 @@
 	packet.proto = proto;
 	packet.ttl = ttl;
+	
+	/* Allocate identifier */
+	fibril_mutex_lock(&ip_ident_lock);
+	packet.ident = ++ip_ident;
+	fibril_mutex_unlock(&ip_ident_lock);
+	
 	packet.df = df;
 	packet.data = dgram->data;
 	packet.size = dgram->size;
 	
+	int rc;
 	size_t offs = 0;
-	int rc;
 	
 	do {
@@ -392,5 +415,17 @@
 }
 
-/** Send IPv6 datagram over Internet link */
+/** Send IPv6 datagram over Internet link
+ *
+ * @param ilink Internet link
+ * @param ldest Destination MAC address
+ * @param dgram IPv6 datagram body
+ * @param proto Next header
+ * @param ttl   Hop limit
+ * @param df    Do-not-Fragment flag (unused)
+ *
+ * @return EOK on success
+ * @return ENOMEM when not enough memory to create the datagram
+ *
+ */
 int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest,
     inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
@@ -421,4 +456,10 @@
 	packet.proto = proto;
 	packet.ttl = ttl;
+	
+	/* Allocate identifier */
+	fibril_mutex_lock(&ip_ident_lock);
+	packet.ident = ++ip_ident;
+	fibril_mutex_unlock(&ip_ident_lock);
+	
 	packet.df = df;
 	packet.data = dgram->data;
Index: uspace/srv/net/inetsrv/inet_std.h
===================================================================
--- uspace/srv/net/inetsrv/inet_std.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/inet_std.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -40,4 +40,6 @@
 #include <sys/types.h>
 
+#define IP6_NEXT_FRAGMENT  44
+
 /** IPv4 Datagram header (fixed part) */
 typedef struct {
@@ -48,5 +50,5 @@
 	/** Total Length */
 	uint16_t tot_len;
-	/** Identification */
+	/** Identifier */
 	uint16_t id;
 	/** Flags, Fragment Offset */
@@ -90,4 +92,14 @@
 };
 
+/** Bits in ip6_header_fragment_t.offsmf */
+enum flags_offsmt_bits {
+	/** More fragments */
+	OF_FLAG_M = 0,
+	/** Fragment offset, highest bit */
+	OF_FRAGOFF_h = 15,
+	/** Fragment offset, lowest bit */
+	OF_FRAGOFF_l = 3
+};
+
 /** IPv6 Datagram header (fixed part) */
 typedef struct {
@@ -114,7 +126,7 @@
 	/** Reserved */
 	uint8_t reserved;
-	/** Fragment Offset, Flags */
-	uint16_t foff_flags;
-	/** Identification */
+	/** Fragmentation offset, reserved and M flag */
+	uint16_t offsmf;
+	/** Identifier */
 	uint32_t id;
 } ip6_header_fragment_t;
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -62,4 +62,15 @@
 #define NAME "inetsrv"
 
+static inet_naddr_t solicited_node_mask = {
+	.family = AF_INET6,
+	.addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0},
+	.prefix = 104
+};
+
+static inet_addr_t multicast_all_nodes = {
+	.family = AF_INET6,
+	.addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
+};
+
 static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 
@@ -514,5 +525,7 @@
 
 	addr = inet_addrobj_find(&packet->dest, iaf_addr);
-	if (addr != NULL) {
+	if ((addr != NULL) ||
+	    (inet_naddr_compare_mask(&solicited_node_mask, &packet->dest)) ||
+	    (inet_addr_compare(&multicast_all_nodes, &packet->dest))) {
 		/* Destined for one of the local addresses */
 
Index: uspace/srv/net/inetsrv/inetsrv.h
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.h	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/inetsrv.h	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -113,5 +113,5 @@
 	uint8_t ttl;
 	/** Identifier */
-	uint16_t ident;
+	uint32_t ident;
 	/** Do not fragment */
 	bool df;
Index: uspace/srv/net/inetsrv/ndp.c
===================================================================
--- uspace/srv/net/inetsrv/ndp.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/ndp.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -38,4 +38,5 @@
 #include <mem.h>
 #include <malloc.h>
+#include <io/log.h>
 #include <net/socket_codes.h>
 #include "ntrans.h"
@@ -48,16 +49,13 @@
 #define NDP_REQUEST_TIMEOUT  (3 * 1000 * 1000)
 
-static addr48_t solicited_node_mac =
-    {0x33, 0x33, 0xff, 0, 0, 0};
-
 static addr128_t solicited_node_ip =
     {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0};
 
-static void ndp_solicited_node_mac(addr128_t ip_addr, addr48_t mac_addr)
-{
-	memcpy(mac_addr, solicited_node_mac, 3);
-	memcpy(mac_addr + 3, ip_addr + 13, 3);
-}
-
+/** Compute solicited node IPv6 multicast address from target IPv6 address
+ *
+ * @param ip_addr      Target IPv6 address
+ * @param ip_solicited Solicited IPv6 address to be assigned
+ *
+ */
 static void ndp_solicited_node_ip(addr128_t ip_addr,
     addr128_t ip_solicited)
@@ -88,4 +86,6 @@
 int ndp_received(inet_dgram_t *dgram)
 {
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ndp_received()");
+	
 	ndp_packet_t packet;
 	int rc = ndp_pdu_decode(dgram, &packet);
@@ -100,4 +100,7 @@
 	
 	inet_addrobj_t *laddr;
+	
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "NDP PDU decoded; opcode: %d",
+	    packet.opcode);
 	
 	switch (packet.opcode) {
@@ -138,4 +141,15 @@
 }
 
+/** Translate IPv6 to MAC address
+ *
+ * @param src  Source IPv6 address
+ * @param dest Destination IPv6 address
+ * @param mac  Target MAC address to be assigned
+ * @param link Network interface
+ *
+ * @return EOK on success
+ * @return ENOENT when NDP translation failed
+ *
+ */
 int ndp_translate(addr128_t src_addr, addr128_t ip_addr, addr48_t mac_addr,
     inet_link_t *ilink)
@@ -157,5 +171,5 @@
 	addr128(src_addr, packet.sender_proto_addr);
 	addr128(ip_addr, packet.solicited_ip);
-	ndp_solicited_node_mac(ip_addr, packet.target_hw_addr);
+	addr48_solicited_node(ip_addr, packet.target_hw_addr);
 	ndp_solicited_node_ip(ip_addr, packet.target_proto_addr);
 	
Index: uspace/srv/net/inetsrv/ntrans.c
===================================================================
--- uspace/srv/net/inetsrv/ntrans.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/ntrans.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -47,4 +47,11 @@
 static FIBRIL_CONDVAR_INITIALIZE(ntrans_cv);
 
+/** Look for address in translation table
+ *
+ * @param ip_addr IPv6 address
+ *
+ * @return inet_ntrans_t with the address on success
+ * @return NULL if nothing found
+ */
 static inet_ntrans_t *ntrans_find(addr128_t ip_addr)
 {
@@ -60,4 +67,13 @@
 }
 
+/** Add entry to translation table
+ *
+ * @param ip_addr  IPv6 address of the new entry
+ * @param mac_addr MAC address of the new entry
+ *
+ * @return EOK on success
+ * @return ENOMEM if not enough memory
+ *
+ */
 int ntrans_add(addr128_t ip_addr, addr48_t mac_addr)
 {
@@ -86,4 +102,12 @@
 }
 
+/** Remove entry from translation table
+ *
+ * @param ip_addr IPv6 address of the entry to be removed
+ *
+ * @return EOK on success
+ * @return ENOENT when no such address found
+ *
+ */
 int ntrans_remove(addr128_t ip_addr)
 {
@@ -104,4 +128,13 @@
 }
 
+/** Translate IPv6 address to MAC address using the translation table
+ *
+ * @param ip_addr  IPv6 address to be translated
+ * @param mac_addr MAC address to be assigned
+ *
+ * @return EOK on success
+ * @return ENOENT when no such address found
+ *
+ */
 int ntrans_lookup(addr128_t ip_addr, addr48_t mac_addr)
 {
@@ -118,4 +151,12 @@
 }
 
+/** Wait on translation table CV for some time
+ *
+ * @param timeout Timeout in microseconds
+ *
+ * @return EOK if woken up by another fibril
+ * @return ETIMEDOUT if timed out
+ *
+ */
 int ntrans_wait_timeout(suseconds_t timeout)
 {
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/pdu.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -49,7 +49,4 @@
 #include "pdu.h"
 
-static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
-static uint16_t ip_ident = 0;
-
 /** One's complement addition.
  *
@@ -107,5 +104,5 @@
  */
 int inet_pdu_encode(inet_packet_t *packet, addr32_t src, addr32_t dest,
-   size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs)
+    size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs)
 {
 	/* Upper bound for fragment offset field */
@@ -117,7 +114,8 @@
 	
 	size_t hdr_size = sizeof(ip_header_t);
-	
-	size_t data_offs = ROUND_UP(hdr_size, 4);
-	
+	if (hdr_size >= mtu)
+		return EINVAL;
+	
+	assert(hdr_size % 4 == 0);
 	assert(offs % FRAG_OFFS_UNIT == 0);
 	assert(offs / FRAG_OFFS_UNIT < fragoff_limit);
@@ -125,7 +123,4 @@
 	/* Value for the fragment offset field */
 	uint16_t foff = offs / FRAG_OFFS_UNIT;
-	
-	if (hdr_size >= mtu)
-		return EINVAL;
 	
 	/* Amount of space in the PDU available for payload */
@@ -152,9 +147,4 @@
 		return ENOMEM;
 	
-	/* Allocate identifier */
-	fibril_mutex_lock(&ip_ident_lock);
-	uint16_t ident = ++ip_ident;
-	fibril_mutex_unlock(&ip_ident_lock);
-	
 	/* Encode header fields */
 	ip_header_t *hdr = (ip_header_t *) data;
@@ -164,5 +154,5 @@
 	hdr->tos = packet->tos;
 	hdr->tot_len = host2uint16_t_be(size);
-	hdr->id = host2uint16_t_be(ident);
+	hdr->id = host2uint16_t_be(packet->ident);
 	hdr->flags_foff = host2uint16_t_be(flags_foff);
 	hdr->ttl = packet->ttl;
@@ -178,5 +168,5 @@
 	
 	/* Copy payload */
-	memcpy((uint8_t *) data + data_offs, packet->data + offs, xfer_size);
+	memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size);
 	
 	*rdata = data;
@@ -202,5 +192,5 @@
  * @param rdata  Place to store pointer to allocated data buffer
  * @param rsize  Place to store size of allocated data buffer
- * @param roffs Place to store offset of remaning data
+ * @param roffs  Place to store offset of remaning data
  *
  */
@@ -208,6 +198,10 @@
     size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs)
 {
+	/* IPv6 mandates a minimal MTU of 1280 bytes */
+	if (mtu < 1280)
+		return ELIMIT;
+	
 	/* Upper bound for fragment offset field */
-	size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+	size_t fragoff_limit = 1 << (OF_FRAGOFF_h - OF_FRAGOFF_l);
 	
 	/* Verify that total size of datagram is within reasonable bounds */
@@ -215,20 +209,27 @@
 		return ELIMIT;
 	
-	size_t hdr_size = sizeof(ip6_header_t);
-	
-	size_t data_offs = ROUND_UP(hdr_size, 4);
-	
+	/* Determine whether we need the Fragment extension header */
+	bool fragment;
+	if (offs == 0)
+		fragment = (packet->size + sizeof(ip6_header_t) > mtu);
+	else
+		fragment = true;
+	
+	size_t hdr_size;
+	if (fragment)
+		hdr_size = sizeof(ip6_header_t) + sizeof(ip6_header_fragment_t);
+	else
+		hdr_size = sizeof(ip6_header_t);
+	
+	if (hdr_size >= mtu)
+		return EINVAL;
+	
+	assert(sizeof(ip6_header_t) % 8 == 0);
+	assert(hdr_size % 8 == 0);
 	assert(offs % FRAG_OFFS_UNIT == 0);
 	assert(offs / FRAG_OFFS_UNIT < fragoff_limit);
 	
-#if 0
-	// FIXME TODO fragmentation
-	
 	/* Value for the fragment offset field */
 	uint16_t foff = offs / FRAG_OFFS_UNIT;
-#endif
-	
-	if (hdr_size >= mtu)
-		return EINVAL;
 	
 	/* Amount of space in the PDU available for payload */
@@ -245,13 +246,8 @@
 	size_t rem_offs = offs + xfer_size;
 	
-#if 0
-	// FIXME TODO fragmentation
-	
 	/* Flags */
-	uint16_t flags_foff =
-	    (packet->df ? BIT_V(uint16_t, FF_FLAG_DF) : 0) +
-	    (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) +
-	    (foff << FF_FRAGOFF_l);
-#endif
+	uint16_t offsmf =
+	    (rem_offs < packet->size ? BIT_V(uint16_t, OF_FLAG_M) : 0) +
+	    (foff << OF_FRAGOFF_l);
 	
 	void *data = calloc(size, 1);
@@ -259,13 +255,4 @@
 		return ENOMEM;
 	
-#if 0
-	// FIXME TODO fragmentation
-	
-	/* Allocate identifier */
-	fibril_mutex_lock(&ip_ident_lock);
-	uint16_t ident = ++ip_ident;
-	fibril_mutex_unlock(&ip_ident_lock);
-#endif
-	
 	/* Encode header fields */
 	ip6_header_t *hdr6 = (ip6_header_t *) data;
@@ -273,6 +260,4 @@
 	hdr6->ver_tc = (6 << (VI_VERSION_l));
 	memset(hdr6->tc_fl, 0, 3);
-	hdr6->payload_len = host2uint16_t_be(packet->size);
-	hdr6->next = packet->proto;
 	hdr6->hop_limit = packet->ttl;
 	
@@ -280,6 +265,28 @@
 	host2addr128_t_be(dest, hdr6->dest_addr);
 	
+	/* Optionally encode Fragment extension header fields */
+	if (fragment) {
+		assert(offsmf != 0);
+		
+		hdr6->payload_len = host2uint16_t_be(packet->size +
+		    sizeof(ip6_header_fragment_t));
+		hdr6->next = IP6_NEXT_FRAGMENT;
+		
+		ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *)
+		    (hdr6 + 1);
+		
+		hdr6f->next = packet->proto;
+		hdr6f->reserved = 0;
+		hdr6f->offsmf = host2uint16_t_be(offsmf);
+		hdr6f->id = host2uint32_t_be(packet->ident);
+	} else {
+		assert(offsmf == 0);
+		
+		hdr6->payload_len = host2uint16_t_be(packet->size);
+		hdr6->next = packet->proto;
+	}
+	
 	/* Copy payload */
-	memcpy((uint8_t *) data + data_offs, packet->data + offs, xfer_size);
+	memcpy((uint8_t *) data + hdr_size, packet->data + offs, xfer_size);
 	
 	*rdata = data;
@@ -290,4 +297,15 @@
 }
 
+/** Decode IPv4 datagram
+ *
+ * @param data   Serialized IPv4 datagram
+ * @param size   Length of serialized IPv4 datagram
+ * @param packet IP datagram structure to be filled
+ *
+ * @return EOK on success
+ * @return EINVAL if the datagram is invalid or damaged
+ * @return ENOMEM if not enough memory
+ *
+ */
 int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
 {
@@ -353,4 +371,15 @@
 }
 
+/** Decode IPv6 datagram
+ *
+ * @param data   Serialized IPv6 datagram
+ * @param size   Length of serialized IPv6 datagram
+ * @param packet IP datagram structure to be filled
+ *
+ * @return EOK on success
+ * @return EINVAL if the datagram is invalid or damaged
+ * @return ENOMEM if not enough memory
+ *
+ */
 int inet_pdu_decode6(void *data, size_t size, inet_packet_t *packet)
 {
@@ -373,19 +402,33 @@
 	size_t payload_len = uint16_t_be2host(hdr6->payload_len);
 	if (payload_len + sizeof(ip6_header_t) > size) {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Payload Length = %zu > PDU size = %zu",
 		    payload_len + sizeof(ip6_header_t), size);
 		return EINVAL;
 	}
 	
-#if 0
-	// FIXME TODO fragmentation
-	
-	uint16_t ident = uint16_t_be2host(hdr->id);
-	uint16_t flags_foff = uint16_t_be2host(hdr->flags_foff);
-	uint16_t foff = BIT_RANGE_EXTRACT(uint16_t, FF_FRAGOFF_h, FF_FRAGOFF_l,
-	    flags_foff);
-#endif
-	
-	/* XXX Checksum */
+	uint32_t ident;
+	uint16_t offsmf;
+	uint16_t foff;
+	uint16_t next;
+	size_t data_offs = sizeof(ip6_header_t);
+	
+	/* Fragment extension header */
+	if (hdr6->next == IP6_NEXT_FRAGMENT) {
+		ip6_header_fragment_t *hdr6f = (ip6_header_fragment_t *)
+		    (hdr6 + 1);
+		
+		ident = uint32_t_be2host(hdr6f->id);
+		offsmf = uint16_t_be2host(hdr6f->offsmf);
+		foff = BIT_RANGE_EXTRACT(uint16_t, OF_FRAGOFF_h, OF_FRAGOFF_l,
+		    offsmf);
+		next = hdr6f->next;
+		data_offs += sizeof(ip6_header_fragment_t);
+		payload_len -= sizeof(ip6_header_fragment_t);
+	} else {
+		ident = 0;
+		offsmf = 0;
+		foff = 0;
+		next = hdr6->next;
+	}
 	
 	addr128_t src;
@@ -399,24 +442,11 @@
 	
 	packet->tos = 0;
-	packet->proto = hdr6->next;
+	packet->proto = next;
 	packet->ttl = hdr6->hop_limit;
-	
-#if 0
-	// FIXME TODO fragmentation
-	
 	packet->ident = ident;
-	packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0;
-	packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0;
+	
+	packet->df = 1;
+	packet->mf = (offsmf & BIT_V(uint16_t, OF_FLAG_M)) != 0;
 	packet->offs = foff * FRAG_OFFS_UNIT;
-	
-	/* XXX IP options */
-	size_t data_offs = sizeof(uint32_t) *
-	    BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h, VI_IHL_l, hdr->ver_ihl);
-#endif
-	
-	packet->ident = 0;
-	packet->df = 0;
-	packet->mf = 0;
-	packet->offs = 0;
 	
 	packet->size = payload_len;
@@ -427,9 +457,17 @@
 	}
 	
-	memcpy(packet->data, (uint8_t *) data + sizeof(ip6_header_t), packet->size);
+	memcpy(packet->data, (uint8_t *) data + data_offs, packet->size);
 	
 	return EOK;
 }
 
+/** Encode NDP packet
+ *
+ * @param ndp   NDP packet structure to be serialized
+ * @param dgram IPv6 datagram structure to be filled
+ *
+ * @return EOK on success
+ *
+ */
 int ndp_pdu_encode(ndp_packet_t *ndp, inet_dgram_t *dgram)
 {
@@ -484,4 +522,13 @@
 }
 
+/** Decode NDP packet
+ *
+ * @param dgram Incoming IPv6 datagram encapsulating NDP packet
+ * @param ndp   NDP packet structure to be filled
+ *
+ * @return EOK on success
+ * @return EINVAL if the Datagram is invalid
+ *
+ */
 int ndp_pdu_decode(inet_dgram_t *dgram, ndp_packet_t *ndp)
 {
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/inetsrv/reass.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -164,5 +164,5 @@
 		return NULL;
 
-	link_initialize(&rdg->map_link);
+	list_append(&rdg->map_link, &reass_dgram_map);
 	list_initialize(&rdg->frags);
 
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/tcp/conn.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -312,4 +312,7 @@
 static bool tcp_socket_match(tcp_sock_t *sock, tcp_sock_t *patt)
 {
+	log_msg(LOG_DEFAULT, LVL_DEBUG2,
+	    "tcp_socket_match(sock=(%u), pat=(%u))", sock->port, patt->port);
+	
 	if ((!inet_addr_is_any(&patt->addr)) &&
 	    (!inet_addr_compare(&patt->addr, &sock->addr)))
@@ -351,4 +354,7 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", sp);
+	
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "compare conn (f:(%u), l:(%u))",
+	    sp->foreign.port, sp->local.port);
 	
 	fibril_mutex_lock(&conn_list_lock);
@@ -357,4 +363,7 @@
 		tcp_conn_t *conn = list_get_instance(link, tcp_conn_t, link);
 		tcp_sockpair_t *csp = &conn->ident;
+		
+		log_msg(LOG_DEFAULT, LVL_DEBUG2, " - with (f:(%u), l:(%u))",
+		    csp->foreign.port, csp->local.port);
 		
 		if (tcp_sockpair_match(sp, csp)) {
Index: uspace/srv/net/tcp/sock.c
===================================================================
--- uspace/srv/net/tcp/sock.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/tcp/sock.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -613,7 +613,12 @@
 	ipc_callid_t wcallid;
 	size_t length;
-	uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
 	tcp_error_t trc;
 	int rc;
+	
+	uint8_t *buffer = calloc(TCP_SOCK_FRAGMENT_SIZE, 1);
+	if (buffer == NULL) {
+		async_answer_0(callid, ENOMEM);
+		return;
+	}
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_send()");
@@ -625,5 +630,5 @@
 	if (sock_core == NULL) {
 		async_answer_0(callid, ENOTSOCK);
-		return;
+		goto out;
 	}
 
@@ -641,5 +646,5 @@
 			fibril_mutex_unlock(&socket->lock);
 			async_answer_0(callid, EINVAL);
-			return;
+			goto out;
 		}
 
@@ -651,5 +656,5 @@
 			fibril_mutex_unlock(&socket->lock);
 			async_answer_0(callid, rc);
-			return;
+			goto out;
 		}
 
@@ -676,5 +681,5 @@
 			fibril_mutex_unlock(&socket->lock);
 			async_answer_0(callid, rc);
-			return;
+			goto out;
 		}
 	}
@@ -685,4 +690,7 @@
 	    IPC_GET_ARG2(answer));
 	fibril_mutex_unlock(&socket->lock);
+	
+out:
+	free(buffer);
 }
 
Index: uspace/srv/net/tcp/tcp.c
===================================================================
--- uspace/srv/net/tcp/tcp.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/tcp/tcp.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -54,6 +54,4 @@
 #define NAME       "tcp"
 
-#define IP_PROTO_TCP 6
-
 static int tcp_inet_ev_recv(inet_dgram_t *dgram);
 static void tcp_received_pdu(tcp_pdu_t *pdu);
Index: uspace/srv/net/tcp/tqueue.c
===================================================================
--- uspace/srv/net/tcp/tqueue.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/tcp/tqueue.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -282,4 +282,8 @@
 void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
 {
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
+	    "tcp_transmit_segment(f:(%u),l:(%u), %p)",
+	    sp->local.port, sp->foreign.port, seg);
+	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
 	    seg->seq, seg->wnd);
Index: uspace/srv/net/tcp/ucall.c
===================================================================
--- uspace/srv/net/tcp/ucall.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/tcp/ucall.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -298,4 +298,8 @@
 	tcp_conn_t *conn;
 
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
+	    "tcp_as_segment_arrived(f:(%u), l:(%u))",
+	    sp->foreign.port, sp->local.port);
+
 	conn = tcp_conn_find_ref(sp);
 	if (conn == NULL) {
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/udp/assoc.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -372,4 +372,7 @@
 static bool udp_socket_match(udp_sock_t *sock, udp_sock_t *patt)
 {
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
+	    "udp_socket_match(sock=(%u), pat=(%u))", sock->port, patt->port);
+	
 	if ((!inet_addr_is_any(&patt->addr)) &&
 	    (!inet_addr_compare(&patt->addr, &sock->addr)))
Index: uspace/srv/net/udp/sock.c
===================================================================
--- uspace/srv/net/udp/sock.c	(revision 34847e2e27574b82c78d62e245fd620e09609132)
+++ uspace/srv/net/udp/sock.c	(revision 2921602409606b0cd4dcd19e8c8197f521e7418e)
@@ -265,4 +265,10 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
 	
+	uint8_t *buffer = calloc(UDP_FRAGMENT_SIZE, 1);
+	if (buffer == NULL) {
+		async_answer_0(callid, ENOMEM);
+		return;
+	}
+	
 	struct sockaddr_in6 *addr6 = NULL;
 	struct sockaddr_in *addr;
@@ -276,5 +282,5 @@
 		if (rc != EOK) {
 			async_answer_0(callid, rc);
-			return;
+			goto out;
 		}
 		
@@ -357,5 +363,5 @@
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to "
 			    "determine local address.");
-			return;
+			goto out;
 		}
 		
@@ -379,5 +385,4 @@
 			length = UDP_FRAGMENT_SIZE;
 		
-		uint8_t buffer[UDP_FRAGMENT_SIZE];
 		int rc = async_data_write_finalize(wcallid, buffer, length);
 		if (rc != EOK) {
@@ -425,4 +430,6 @@
 	if (addr6 != NULL)
 		free(addr6);
+	
+	free(buffer);
 }
 
