1#!/bin/sh 2# Copyright 2014 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# 6# The purpose of this script is to set up all the neccessary magic to 7# pipe network traffic through a user-space process. That user-space 8# process can then delay, reorder and drop packets as it pleases to 9# emulate various network environments. 10# 11# The script currently assumes that you communicate with your cast streaming 12# receiver through eth1. After running "shadow.sh start", your network will 13# look something like this: 14# 15# +--------------------------------------------------+ 16# | Your linux machine | 17# | +---------------+ | 18# cast | |shadowbr bridge| +-------------+ | 19# streaming <--+-+---> eth1 | |routing table| | 20# receiver | | tap2 <---+-> tap_proxy <-+-> tap1 | | 21# | | +->veth | | eth0 <----+--+->internet 22# | +--+------------+ | lo | | 23# | | +-------------+ | 24# | | +------------------+ ^ | 25# | | |shadow container | | | 26# | +------+-->veth | chrome | 27# | | netload.py server| netload.py client| 28# | +------------------+ | 29# +--------------------------------------------------+ 30# 31# The result should be that all traffic to/from the cast streaming receiver 32# will go through tap_proxy. All traffic to/from the shadow container 33# will also go through the tap_proxy. (A container is kind of like a 34# virtual machine, but more lightweight.) Running "shadow.sh start" does 35# not start the tap_proxy, so you'll have to start it manually with 36# the command "tap_proxy tap1 tap2 <network_profile>" where 37# <network_profile> is one of "perfect", "good", "wifi", "bad" or "evil". 38# 39# While testing mirroring, we can now generate TCP traffic through 40# the tap proxy by talking to the netload server inside the "shadow" 41# container by using the following command: 42# 43# $ netload.py upload IP PORT 44# 45# The IP and PORT are printed out by this script when you run 46# "shadow.sh start", but will generally be the *.*.*.253 address 47# of the eth1 network, so hopefully that's not already taken... 48 49set -x 50 51DEV=eth1 52TAP1=tap1 53TAP2=tap2 54 55IP="$(ifconfig $DEV | sed -n 's@.*inet addr:\([^ ]*\).*@\1@gp')" 56MASK="$(ifconfig $DEV | sed -n 's@.*Mask:\([^ ]*\).*@\1@gp')" 57BCAST="$(ifconfig $DEV | sed -n 's@.*Bcast:\([^ ]*\).*@\1@gp')" 58NET=$(route -n | grep $DEV | head -1 | awk '{print $1}') 59DIR=$(dirname "$0") 60 61case "$MASK" in 62 255.255.255.0) MASK_BITS=24 ;; 63 255.255.0.0) MASK_BITS=16 ;; 64 255.0.0.0) MASK_BITS=8 ;; 65 *) 66 echo "Unknown network mask" 67 exit 1 68 ;; 69esac 70 71SHADOWIP="$(echo $IP | sed 's@[^.]*$@@g')253" 72SHADOWCONF="/tmp/shadowconf.$$" 73cat <<EOF >$SHADOWCONF 74lxc.utsname = shadow 75lxc.network.type = veth 76lxc.network.link = shadowbr 77lxc.network.flags = up 78lxc.network.ipv4 = $SHADOWIP/$MASK_BITS 79lxc.network.ipv4.gateway = $IP 80lxc.kmsg = 0 81EOF 82 83trap "rm $SHADOWCONF" SIGINT SIGTERM EXIT 84LXC_COMMON="-n shadow -f $SHADOWCONF" 85 86case "$1" in 87 start) 88 openvpn --mktun --dev $TAP1 89 openvpn --mktun --dev $TAP2 90 ifconfig $TAP1 $IP netmask $MASK broadcast $BCAST up 91 ifconfig $TAP2 up 92 route add -net $NET netmask $MASK $TAP1 93 brctl addbr shadowbr 94 brctl addif shadowbr $TAP2 $DEV 95 ifconfig shadowbr up 96 lxc-create $LXC_COMMON 97 lxc-execute $LXC_COMMON -- \ 98 "$DIRNAME/netload.py listen 9999" >/dev/null </dev/null 2>&1 & 99 echo "Now run: tap_proxy $TAP1 $TAP2 wifi" 100 echo "Data sink/source is available on $SHADOWIP 9999" 101 ;; 102 103 stop) 104 lxc-kill -n shadow 105 sleep 1 106 lxc-destroy $LXC_COMMON 107 ifconfig $TAP1 down 108 ifconfig $TAP2 down 109 ifconfig shadowbr down 110 brctl delbr shadowbr 111 openvpn --rmtun --dev $TAP1 112 openvpn --rmtun --dev $TAP2 113 ;; 114 115 *) 116 echo "$0 start/stop" 117 echo "Read $0 for more information." 118 ;; 119esac 120 121 122