#!/bin/bash # # Transparent Network Emulation Proxy for Layer 2 & 3 # # Dependencies: iptables, ebtables and iproute2 # # Author: Steffen Vogel # SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University # SPDX-License-Identifier: Apache-2.0 set -e # Abort on error die() { echo "$1"; exit -1; } # Apply netem qdisc also for reverse path REVERSE=0 # This scripts also supports L3 IP packets. Simply replace the MAC by IP addresses LAYER=2 SRC=00:50:C2:4F:92:D5 DST=00:50:C2:4F:92:D6 #DST=01:0C:CD:01:01:FF MY=$SRC SRC_IF=p5p1.10 DST_IF=p5p1.11 # Network emulation settings (see http://stuff.onse.fi/man?program=tc-netem§ion=8) NETEM="delay 1000000 20000 distribution normal duplicate 4 loss 20" ### # Do not change something below this line! MARK=$RANDOM # Tools TC=/sbin/tc if [ "$LAYER" -eq "2" ]; then NF=/sbin/ebtables elif [ "$LAYER" -eq "3" ]; then NF=/sbin/iptables fi # Test permissions (( $(id -u) == 0 )) || die "This script must be executed as root (run: sudo $0)" # Test if tools are available [ -x $NF ] || die "Please install $NF (run: sudo apt-get install ebtables iptables)" [ -x $TC ] || die "Please install $TC (run: sudo apt-get install iproute2)" # Load kernel modules modprobe sch_netem || die "The netem qdisc is not compiled in this kernel!" # Clear tables and chains to get a clean state $NF -t nat -F $NF -t nat -X exit # Add new chain, mark packets from $SRC and redirect them to $DEST # Insert new chain into flow $NF -t nat -A PREROUTING -i $SRC_IF -s $SRC -j mark --mark-set $MARK --mark-target CONTINUE $NF -t nat -A PREROUTING -i $SRC_IF -s $SRC -j dnat --to-dst $DST --dnat-target ACCEPT $NF -t nat -A PREROUTING -i $DST_IF -s $DST -j mark --mark-set $MARK --mark-target CONTINUE $NF -t nat -A PREROUTING -i $DST_IF -s $DST -j dnat --to-dst $SRC --dnat-target ACCEPT exit # Clean traffic control $TC qdisc delete dev $DST_IF root || true # Add classful qdisc to egress (outgoing) network device $TC qdisc replace dev $DST_IF root handle 4000 prio bands 4 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 $TC qdisc add dev $DST_IF parent 4000:4 handle 4020 netem $NETEM $TC filter add dev $DST_IF protocol ip handle $MARK fw flowid 4000:4 echo -e "Successfully configured network emulation:" echo -e "Netem Settings for $SRC ($SRC_IF) => $DST ($DST_IF):" echo -e " $NETEM" if (( $REVERSE )); then echo -e "Netem Settings for $DST ($DST_IF) => $SRC ($SRC_IF):" echo -e " $NETEM_REV" fi if [ -n $DEBUG ]; then if [ "$SRC_IF" == "$DST_IF" ]; then IFNS="$SRC_IF" else IFNS="$SRC_IF $DST_IF" fi for inf in $IFNS; do for cmd in qdisc filter class; do echo -e "\nTC ==> $if: $cmd" tc -d -p $cmd show dev $inf done done echo -e "\nTABLES ==>" $NF -t nat -L fi