diff --git a/modules/responses-tcp.sh b/modules/responses-tcp.sh
new file mode 100755
index 0000000000000000000000000000000000000000..109a9a673e35db2d43384931bd6d353973e9c07e
--- /dev/null
+++ b/modules/responses-tcp.sh
@@ -0,0 +1,260 @@
+#!/usr/bin/env bash
+
+#set -x
+
+PKT_OVERHEAD=42
+IPTABLES="iptables"
+
+# Discover network setup
+function net_discover()
+{
+	UNIQ="guniq"
+	if [ `uname` = "Linux" ]; then
+		 UNIQ="uniq"
+	fi
+
+	ip4=""; ip6=""; mac=""
+	addr=""; link=""
+	if [ "`ssh $1 uname`" = "Linux" ]; then
+		addr="$(ssh $1 ip -d -o addr|grep ": ${2}"|grep -o -E "(inet|inet6) ([^ ]+)"|grep -v Link|$UNIQ -w 5)"
+		link="$(ssh $1 ip -d -o link|grep ": ${2}"|grep -o -E "(ether) ([^ ]+)"|$UNIQ -w 5)"
+	else
+		addr="$(ssh $1 ifconfig ${2}|grep -o -E "inet(6)? ([^ ]+)"|$UNIQ|grep -v -E "(fe80)|%")"
+		link="$(ssh $1 ifconfig ${2}|grep -o -E "ether ([^ ]+)"|$UNIQ -w 5)"
+	fi
+
+	while read -r l; do
+		l=( $(echo $l) )
+		case ${l[0]} in
+		inet)  ip4=( ${net_v4[@]} $(echo ${l[1]}|cut -d\/ -f1) ) ;;
+		inet6) ip6=( ${net_v6[@]} $(echo ${l[1]}|cut -d\/ -f1) ) ;;
+		esac
+	done <<< "$addr"
+	while read -r l; do
+		l=( $(echo $l) )
+		case ${l[0]} in
+		ether) mac=( ${net_mac[@]} ${l[1]} ) ;;
+		esac
+	done <<< "$link"
+
+	# Decide used address
+	output=()
+
+	if [[ ${IP_VERSION} -eq 4 ]]; then
+		output=("${mac}" "${ip4}")
+	else
+		output=("${mac}" "${ip6}")
+	fi
+
+	echo ${output[@]}
+}
+
+# Rewrite pcap file according to current network settings
+function trace_rewrite()
+{
+	player=( $(echo ${players[$2]}|tr ':' ' ') )
+	net_dst=( $(net_discover ${target} ${iface}) )
+	net_src=( $(net_discover ${player[0]} ${player[1]}) )
+	
+	tcprewrite --dlt=enet -i ${1} -o ${1}.live.${2} &>>${LOG}
+	tcpprep --auto=client --cachefile=tmp.cache --pcap=${1}.live.${2} &>>${LOG}
+
+	if [ -z "${net_dst[1]}" ]; then
+		echo "FATAL ERROR: net_dst[1] is empty. Is the dst interface UP?"
+		return
+	fi
+
+	if [ -z "${net_src[1]}" ]; then
+		echo "FATAL ERROR: net_src[1] is empty. Is the src interface UP?"
+		return
+	fi
+
+	#Store TCPGen configuration at player
+	cat <<- CONFIGURATION | ssh -T ${player[0]} "cat > /tmp/tcpgen.conf"
+		source-mac ${net_src[0]}
+		destination-mac ${net_dst[0]}
+
+		ipv${IP_VERSION}-source-network 10.10.0.0
+		ipv${IP_VERSION}-source-netmask 255.255.0.0
+		ipv${IP_VERSION}-destination-ip ${net_dst[1]}
+
+		tcp-destination-port ${PORT}
+		#ip-ipv6-probability 0.5
+	CONFIGURATION
+
+	# Copy rewrited file
+	scp ${BASEDIR}/${1}.live.${2} ${player[0]}:/tmp/ &>> ${LOG}
+
+	#TODO Test on BSD systems
+	if [ `uname` = "Linux" ]; then
+		sudo ip -${IP_VERSION} neigh replace "${net_src[1]}" lladdr "${net_src[0]}" dev "${iface}"
+	fi
+
+	RP="arp"
+	if [ $IP_VERSION -eq "6" ]; then
+		RP="ndp"
+	fi
+	sudo $RP -s ${net_src[1]} ${net_src[0]}
+}
+
+function stats() {
+	RX_bytes=`grep -E "RX bytes" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
+	RX_responses=`grep -E "RX responses" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
+	TX_bytes=`grep -E "TX bytes" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
+	TX_queries=`grep -E "TX queries" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
+
+	echo ${TX_bytes} ${TX_queries} ${RX_bytes} ${RX_responses}
+}
+
+function load_dpdk_driver()
+{
+	[ $# -lt 2 ] && echo "Not enough arguments!"
+	info=`ssh $1 "dpdk-devbind --status-dev net | grep if=$2"`
+
+	original_driver=`echo $info | sed -e "s/^.*drv=//" -e "s/ .*$//"`
+	bus=`echo $info | awk '{print $1}' | cut -c 6-`
+	ssh $1 "sudo ip link set $2 down"
+	ssh $1 "sudo dpdk-devbind -b igb_uio $bus"
+	echo $bus $original_driver
+}
+
+function unload_dpdk_driver()
+{
+	ssh $1 "sudo dpdk-devbind -b $3 $2"
+}
+
+# Replay pcap file to nameserver and evaluate number of answered responses
+function trace_replay()
+{
+	# Prepare tcpreplay flags
+	speed="-g 0"
+	[ "${1}" -gt 0 ] && speed="-g $(( 1000000 * ${#players[@]} / ${1} ))"
+	duration="-r $(( ${replay_duration:-30} * 1000000 ))"
+	rflags="-p 1 ${speed} ${duration}"
+	# Replay the trace files
+	jobs=()
+	i=0; while [ ${i} -lt ${#players[@]} ]; do
+		player=( $(echo ${players[$i]}|tr ':' ' ') )
+		ret=( $(load_dpdk_driver ${player[0]} ${player[1]}) )
+		
+		cmd="sudo ~/dpdk-tcp-generator/build/tcpgen -c 1 -- ${rflags} -c /tmp/tcpgen.conf --pcap /tmp/${2}.live.${i}"
+		(ssh "${player[0]}" "${cmd}" 2>&1 | grep -ve 'EAL'  >> tcpgen.out) &
+
+		jobs=( ${jobs[@]} $! )
+		bus=( ${bus[@]} ${ret[0]} )
+		drivers=( ${drivers[@]} ${ret[1]} )
+		(( i += 1 ))
+	done
+	i=0; while [ ${i} -lt ${#players[@]} ]; do
+		wait ${jobs[$i]}
+		player=( $(echo ${players[$i]}|tr ':' ' ') )
+		unload_dpdk_driver $player ${bus[$i]} ${drivers[$i]}
+		(( i += 1 ))
+	done
+
+	# Wait for delayed packets
+	sleep ${replay_duration:-30}
+
+	statistics=( $(stats) )
+
+	query_size="${statistics[0]}"
+	query_pkts="${statistics[1]}"
+	reply_size="${statistics[2]}"
+	reply_pkts="${statistics[3]}"
+
+	# Calculate results
+	answered=$(bc <<< "scale=2; ${reply_pkts}*100.0/${query_pkts}")
+	query_rate=$(bc <<< "scale=0; ${query_pkts}/${replay_duration:-30}")
+	reply_rate=$(bc <<< "scale=0; ${reply_pkts}/${replay_duration:-30}")
+	query_avglen=$(bc <<< "scale=0; ${query_size}/${query_pkts}")
+	reply_avglen=$(bc <<< "scale=0; ${reply_size}/${reply_pkts}")
+
+	echo ${answered} ${query_rate} ${query_avglen} ${reply_rate} ${reply_avglen}
+}
+
+function module_init()
+{
+	line=`tar --gzip --list --verbose --file=${DATADIR}/${2}.tgz | grep .pcap`
+	if [[ `uname` == "Linux" ]]; then
+		TRACE=`echo $line | awk '{print $6}'`
+	else
+		TRACE=`echo $line | awk '{print $9}'`
+	fi
+	#Get number of IPv from pcap file
+	ip=${TRACE:11:1}
+	IP_VERSION=$ip
+
+	# Check for IPv6 measurement
+	if [ ${ip} ] && [ ${ip} = "6" ]; then
+		PKT_OVERHEAD=62
+		IPTABLES="ip6tables"
+	fi
+
+	if [ ! -f ${TRACE} ]; then
+		echo "'${TRACE}' not found, skipping"
+		return 1
+	fi
+
+	# Populate address list
+	addr=( $(net_discover ${target} ${iface}) )
+	ADDRLIST=( 127.0.0.1 ${addr[1]} )
+}
+
+function module_exec()
+{
+	output="${BASEDIR}/results/${1}.data"
+
+	# Drop filesystem and page caches
+	sudo sync
+	echo 3|sudo tee /proc/sys/vm/drop_caches &>/dev/null
+
+	# Start nameserver
+	ns_prep ${NAMECONF}
+	ns_start ${NAMECONF}
+	if [ $? -gt 0 ]; then
+		echo "error: failed to start '${1}'"
+		return 1
+	fi
+
+	if [[ `uname` != "Linux" ]]; then
+		SEQ="gseq"
+	else
+		SEQ="seq"
+	fi
+
+	# Perform measurement of answered queries
+	do_rates=(0)
+	if [ "${replay_rates}" ]; then
+		if [ "${replay_step}" ] && [ ${#replay_rates[@]} -ge 2 ]; then
+			do_rates=( $(${SEQ} ${replay_rates[0]} ${replay_step} ${replay_rates[1]}) )
+		else
+			do_rates=${replay_rates[@]}
+		fi
+	fi
+
+	# Prepare pcap files for replaying
+	i=0; while [ ${i} -lt ${#players[@]} ]; do
+		trace_rewrite ${TRACE} ${i}
+		if [ $? -ne 0 ]; then
+			echo "error: failed to prepare tracefile for ${players[$i]}"
+			return 1
+		fi
+		(( i += 1 ))
+	done
+
+	# Replay the pcap files
+	for pps in ${do_rates[@]}; do
+		result=( $(trace_replay ${pps} ${TRACE}) )
+		[ ${pps} -eq 0 ] && pps="maximum"
+		echo "${1} ${result[0]} % answered for ${result[1]} q/s, ${result[2]} B avg (${result[3]} a/s, ${result[4]} B avg)"
+		echo -e "${result[1]}\t${result[0]}\t${result[2]}" >> ${output}.tmp
+	done
+
+	# Stop nameserver
+	ns_stop ${NAMECONF}
+
+	# Save results
+	echo -e "# $(ns_info)" > ${output}
+	cat ${output}.tmp|sort -n >> ${output}
+	rm ${output}.tmp
+}