#!/bin/sh packet=/tmp/udp if [ -z "$2" ]; then echo "Usage: flood payload seconds [iface]">&2 exit 1 fi payload="$1" ip="10.0.0.2" sec="$2" target="$3" len=$(($payload + 14 + 20 + 8)) l2len=$(($len+8+4+12)) set -f set `arp -n $ip` case "$4" in no|*incomplete*) echo "$ip: looking for MAC (not cached)" ping -W 1000 -c1 -q $ip >/dev/null 2>&1 set `arp -n $ip` ;; esac if [ "$4" = no ]; then echo "$ip: MAC not found, assume it's reachable through gateway" eval `route -n get $ip | awk '/interface:/ {printf "iface=%s\n", $2;}'` else iface="$6" fi echo "$ip: reachable through interface: $iface" fakeip=no if [ "$4" = '(incomplete)' ]; then echo "$ip: MAC not found at $iface, using faked MAC" arp -S $ip 01:01:01:01:01:01 && fakeip=yes fi sysctl_rx() { # sysctl dev.$1 | awk '/\.rx_frames_/ { s+=$2 } END {print s}' # sysctl dev.$1 | awk '/\.mac_stats.good_pkts_recvd/ { s+=$2 } END {print s}' # sysctl dev.$1 | awk '/\.mac_stats.total_pkts_recvd/ { s+=$2 } END {print s}' sysctl dev.$1.mac_stats.total_pkts_recvd | awk '{ print $2 }' } sysctl_tx() { sysctl dev.$1.mac_stats.total_pkts_txd | awk '{ print $2 }' } mk_packet() { echo "$ip: preparing a packet for flood..." rm -f $packet.pcap [ -n "$target" ] && iface="$target" tcpdump -w $packet.pcap -i $iface -s0 -c1 -np dst host $ip and udp port 5001 >/dev/null 2>&1 & tpid=$! iperf -l $payload -u -t 1 -c $ip -b 10K >/dev/null 2>&1 sleep 1 kill $tpid >/dev/null 2>&1 set -- `ls -l $packet.pcap` if [ -z "$5" -o "$5" -le 24 ]; then echo $ip: cannot prepare a packet, stop. >&2 exit 1 fi tail -c $len $packet.pcap > $packet.raw } mk_packet [ $fakeip = yes ] && arp -d $ip echo "$ip: flooding through $iface: payload=$payload iplen="$(($payload+20+8))" framelen=$len l2len=$l2len" stop_and_show() { ngctl msg $iface:orphans stop eval `ngctl msg $iface:orphans getstats |\ awk '/^Args:/ { print $3, $4, $16, $17 }'` sleep 2 s_tx=$((`sysctl_tx igb.0`-$s_tx)) s_rx=$((`sysctl_rx igb.1`-$s_rx)) echo $ip: flood time was `printf "scale=3\n$tv_sec+${tv_usec}/1000000\n" | bc -l` sec, $s_tx frames sent echo $ip: flood L2 speed was `printf "scale=3\n$s_tx/($tv_sec+${tv_usec}/1000000)\n" | bc -l` frames/sec echo $ip: flood L2 speed was `printf "scale=3\n$l2len*$s_tx*8/($tv_sec+${tv_usec}/1000000)/1000000\n" | bc -l` Mbit/sec ngctl shutdown $iface:orphans lost=`printf "scale=3\n($s_tx-$s_rx)/($tv_sec+${tv_usec}/1000000)\n" | bc -l` echo $ip: "lost " $(($s_tx-$s_rx)) frames, $lost frames/sec, `printf "scale=3\n($s_tx-$s_rx)*100/$s_tx\n" | bc -l`\% echo $ip: transmitted $s_tx, received $s_rx } trap 'stop_and_show; exit 0' SIGHUP SIGINT SIGTERM count=1000000000 if ngctl mkpeer $iface: source orphans output >/dev/null 2>&1; then sleep 2 s_tx=`sysctl_tx igb.0` s_rx=`sysctl_rx igb.1` nghook $iface:orphans input < $packet.raw >/dev/null 2>&1 ngctl msg $iface:orphans start $count sleep $sec stop_and_show exit 0 fi echo $ip: cannot flood through interface $iface