NetStress
Overview
NetStress is a command line utility that simulates bad network conditions for multiple kinds of streaming. It is meant for testing multimedia server and client robustness by stressing the transmission channel. To do so NetStress provides two different packet modeling:
- Loss: Percentage in which the packets are randomly dropped. For a 1% loss: 1 of 100 packets is dropped randomly.
- Delay: Amount of milliseconds to delay samples.
Both parameters apply in a bidirectional way, this is, for packets coming from the server and entering the client, and packets entering the server coming from the client.
Dependencies
NetStress is based on GNU/Linux traffic control (tc). This tool is distributed as part of the iproute package.
Basic Usage
~# netstress -h ~# netstress -a ip [-i interface] [-d delay] [-l loss] [-r rate] [-n | -o]
Arguments
Argument | Purpose | Nature |
---|---|---|
-h | Help | Optional |
-a | IP address | Mandatory |
-d | Delay (ms) | Optional |
-l | Loss (%) | Optional |
-r | Rate (bps) | Optional |
-i | interface (defaults to eth0) | Optional |
-n | Apply to input packtets* | Optional |
-o | Apply to output packets* | Optional |
- If neither input (-n) or output (-o) are specified packets are filtered bidirectionally.
Adding packet delay
To add a 10ms delay to every packet sent and received from a RTSP stream produced by a device with IP address: 192.168.1.58
~# netstress -d 10 -a 192.168.1.58
Adding packet loss
To add a 5% loss to every packet sent and received from an UPD stream produced by a device with IP address: 10.251.101.66
~# netstress -l 5 -a 10.251.101.66
Adding packet delay and loss
To add a 1% loss and 20ms delay to every packet sent and received from a RTP stream produced by a device with IP address: 10.251.101.146
~# netstress -l 1 -d 20 -a 10.251.101.146
Clearing up simulation
To clear up any current configured simulation
~# netstress
Download
Copy this script into a file named netstress.sh and give it read and execution permissions
#!/bin/sh LOSS=0% DELAY=0ms INTERFACE=eth0 ADDRESS=0 RATE=100Mbps DIR="bi" usage() { cat <<EOF This script simulates bad streaming conditions by dropping or delaying network packets streamed to a given port. Root is the only user allowed to run this script Options: -h : Prints this help -i <interface> : Specifies the interface to be used on the simulation. Defaults to 'eth0'. -l <loss> : Defines the percentage of packets to drop. Defaults to 0. -d <delay> : Defines the amount of miliseconds to delay packets. Defaults to 0. -r <rate> : Limits the bandwidth of the filter. Defaults to 100Mbps. -a <ipaddress> : Mandatory argument to specifies the ip address to apply the simulation to. The loss and delay will be applied to the packets coming from and going to this address. -o : Apply simulation to outgoing packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly. -n : Apply simulation to incoming packets only. If neither -o or -i option is specified then simulation will be applied bidirectionaly. Examples: Drop 1% of the packets received through a UDP stream at address 192.168.1.168 on both incoming and outgoing packets ~# netstress -l 1 -a 192.168.1.168 Drop 10% of the outgoing packets and apply a delay of 5ms of a RTSP stream from device 10.251.101.135 received using the eth1 interface. ~# netstress -l 10 -d 5 -i eth1 -a 10.251.101.135 -o Erase all the simulations applied to the interface 'eth1' ~# netstress -i eth1 Erase all the simulations applied to the default interface 'eth0' ~# netstress Copyright (c) RidgeRun 2013 Michael Gruner <michael.gruner@ridgerun.com> EOF } logerror() { echo "NetStress: error: $1" 1>&2 exit 1 } parseop() { while getopts "honi:l:d:a:r:" OP do case $OP in h) usage exit 0 ;; i) INTERFACE=$OPTARG ;; l) LOSS="$OPTARG"% ;; r) RATE="$OPTARG" ;; d) DELAY="$OPTARG"ms ;; a) ADDRESS=$OPTARG ;; o) DIR="out" ;; n) DIR="in" ;; *) usage exit 1 ;; esac done } redirecttraffic() { # Insert the module if not already modprobe ifb ip link set dev ifb0 up # Grab the incomming packets and redirect them to ifb0 tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo "" tc qdisc add dev $INTERFACE ingress # Redirect to ifb0 tc filter add dev $INTERFACE parent ffff: \ protocol ip u32 match u32 0 0 \ action mirred egress redirect dev ifb0 } createtree() { # Tree layout # # Ingress 1:0 (ifb0) Egress 2:0 (eth0) # | | # Class 1:1 Class 2:1 # | | # (Attach netem leaf) (Attach netem leaf) # # Root of the tree for all the non-filtered input packets tc qdisc add dev ifb0 root handle 1: htb # Create a class to attach the filter. Netem leafs can attach to this class tc class add dev ifb0 parent 1: classid 1:1 htb rate 100Mbps # Root of the tree for all the non-filtered ouput packets tc qdisc add dev $INTERFACE root handle 2: htb # Create a class to attach the filter. Netem leafs can attach to this class tc class add dev $INTERFACE parent 2: classid 2:1 htb rate 100Mbps } applyrules() { echo -n "Applying rules..." # Input packets tc qdisc add dev ifb0 parent 1:1 handle 10: netem delay $DELAY rate $RATE || \ logerror "Failed to apply rules" # Output packets tc qdisc add dev $INTERFACE parent 2:1 handle 20: netem delay $DELAY rate $RATE || \ logerror "Failed to apply rules" echo " done!" } applyfilter() { echo -n "Applying filters..." #Incoming packets if [ $DIR != "out" ]; then tc filter add dev ifb0 protocol ip parent 1: prio 3 u32 match ip src $ADDRESS flowid 1:1 fi #Outgoing packets if [ $DIR != "in" ]; then tc filter add dev $INTERFACE protocol ip parent 2: prio 3 u32 match ip dst $ADDRESS flowid 2:1 fi echo " done!" } checkroot() { if [ "root" != `whoami` ]; then logerror "Only root is allowed to run this script!" fi } stopsimulation() { echo -n "Stopping simulation at interface $INTERFACE..." # Avoid any problems if there was no simulation running tc qdisc del dev $INTERFACE ingress 2>/dev/null || echo -n "" tc qdisc del dev $INTERFACE root 2>/dev/null || echo -n "" tc qdisc del dev ifb0 root 2>/dev/null || echo -n "" echo " done!" } main() { #Parse the options passed through the cmdline parseop $@ #Check that the user is root checkroot stopsimulation #Check if user wants to erase all rules if [ x$LOSS = "x0%" ] && [ x$DELAY = "x0ms" ] && [ x$RATE = "x100Mbps" ]; then exit 0 fi #Ip is a mandatory argument if [ x$ADDRESS = "x0" ]; then logerror "Ip address is a mandatory parameter" fi echo "Simulation configured to" echo -e "\tInterface: $INTERFACE" echo -e "\tLoss: $LOSS" echo -e "\tDelay: $DELAY" echo -e "\tAddress: $ADDRESS" redirecttraffic createtree applyrules applyfilter } #Calling starting point main $@
Known Limitations
- Only one IP address can be filtered at a time.
- Port filtering is not supported yet
Support
If you have any questions please contact us or email to support@ridgerun.com.