| #!/bin/sh |
| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # |
| # The purpose of this script is to set up all the neccessary magic to |
| # pipe network traffic through a user-space process. That user-space |
| # process can then delay, reorder and drop packets as it pleases to |
| # emulate various network environments. |
| # |
| # The script currently assumes that you communicate with your cast streaming |
| # receiver through eth1. After running "shadow.sh start", your network will |
| # look something like this: |
| # |
| # +--------------------------------------------------+ |
| # | Your linux machine | |
| # | +---------------+ | |
| # cast | |shadowbr bridge| +-------------+ | |
| # streaming <--+-+---> eth1 | |routing table| | |
| # receiver | | tap2 <---+-> tap_proxy <-+-> tap1 | | |
| # | | +->veth | | eth0 <----+--+->internet |
| # | +--+------------+ | lo | | |
| # | | +-------------+ | |
| # | | +------------------+ ^ | |
| # | | |shadow container | | | |
| # | +------+-->veth | chrome | |
| # | | netload.py server| netload.py client| |
| # | +------------------+ | |
| # +--------------------------------------------------+ |
| # |
| # The result should be that all traffic to/from the cast streaming receiver |
| # will go through tap_proxy. All traffic to/from the shadow container |
| # will also go through the tap_proxy. (A container is kind of like a |
| # virtual machine, but more lightweight.) Running "shadow.sh start" does |
| # not start the tap_proxy, so you'll have to start it manually with |
| # the command "tap_proxy tap1 tap2 <network_profile>" where |
| # <network_profile> is one of "perfect", "good", "wifi", "bad" or "evil". |
| # |
| # While testing mirroring, we can now generate TCP traffic through |
| # the tap proxy by talking to the netload server inside the "shadow" |
| # container by using the following command: |
| # |
| # $ netload.py upload IP PORT |
| # |
| # The IP and PORT are printed out by this script when you run |
| # "shadow.sh start", but will generally be the *.*.*.253 address |
| # of the eth1 network, so hopefully that's not already taken... |
| |
| set -x |
| |
| DEV=eth1 |
| TAP1=tap1 |
| TAP2=tap2 |
| |
| IP="$(ifconfig $DEV | sed -n 's@.*inet addr:\([^ ]*\).*@\1@gp')" |
| MASK="$(ifconfig $DEV | sed -n 's@.*Mask:\([^ ]*\).*@\1@gp')" |
| BCAST="$(ifconfig $DEV | sed -n 's@.*Bcast:\([^ ]*\).*@\1@gp')" |
| NET=$(route -n | grep $DEV | head -1 | awk '{print $1}') |
| DIR=$(dirname "$0") |
| |
| case "$MASK" in |
| 255.255.255.0) MASK_BITS=24 ;; |
| 255.255.0.0) MASK_BITS=16 ;; |
| 255.0.0.0) MASK_BITS=8 ;; |
| *) |
| echo "Unknown network mask" |
| exit 1 |
| ;; |
| esac |
| |
| SHADOWIP="$(echo $IP | sed 's@[^.]*$@@g')253" |
| SHADOWCONF="/tmp/shadowconf.$$" |
| cat <<EOF >$SHADOWCONF |
| lxc.utsname = shadow |
| lxc.network.type = veth |
| lxc.network.link = shadowbr |
| lxc.network.flags = up |
| lxc.network.ipv4 = $SHADOWIP/$MASK_BITS |
| lxc.network.ipv4.gateway = $IP |
| lxc.kmsg = 0 |
| EOF |
| |
| trap "rm $SHADOWCONF" SIGINT SIGTERM EXIT |
| LXC_COMMON="-n shadow -f $SHADOWCONF" |
| |
| case "$1" in |
| start) |
| openvpn --mktun --dev $TAP1 |
| openvpn --mktun --dev $TAP2 |
| ifconfig $TAP1 $IP netmask $MASK broadcast $BCAST up |
| ifconfig $TAP2 up |
| route add -net $NET netmask $MASK $TAP1 |
| brctl addbr shadowbr |
| brctl addif shadowbr $TAP2 $DEV |
| ifconfig shadowbr up |
| lxc-create $LXC_COMMON |
| lxc-execute $LXC_COMMON -- \ |
| "$DIRNAME/netload.py listen 9999" >/dev/null </dev/null 2>&1 & |
| echo "Now run: tap_proxy $TAP1 $TAP2 wifi" |
| echo "Data sink/source is available on $SHADOWIP 9999" |
| ;; |
| |
| stop) |
| lxc-kill -n shadow |
| sleep 1 |
| lxc-destroy $LXC_COMMON |
| ifconfig $TAP1 down |
| ifconfig $TAP2 down |
| ifconfig shadowbr down |
| brctl delbr shadowbr |
| openvpn --rmtun --dev $TAP1 |
| openvpn --rmtun --dev $TAP2 |
| ;; |
| |
| *) |
| echo "$0 start/stop" |
| echo "Read $0 for more information." |
| ;; |
| esac |
| |
| |