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.
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.
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:
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 # +--------------------------------------------------+
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".
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:
43 # $ netload.py upload IP PORT
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...
55 IP
="$(ifconfig $DEV | sed -n 's@.*inet addr:\([^ ]*\).*@\1@gp')"
56 MASK
="$(ifconfig $DEV | sed -n 's@.*Mask:\([^ ]*\).*@\1@gp')"
57 BCAST
="$(ifconfig $DEV | sed -n 's@.*Bcast:\([^ ]*\).*@\1@gp')"
58 NET
=$
(route
-n |
grep $DEV |
head -1 |
awk '{print $1}')
62 255.255.255.0) MASK_BITS
=24 ;;
63 255.255.0.0) MASK_BITS
=16 ;;
64 255.0.0.0) MASK_BITS
=8 ;;
66 echo "Unknown network mask"
71 SHADOWIP
="$(echo $IP | sed 's@[^.]*$@@g')253"
72 SHADOWCONF
="/tmp/shadowconf.$$"
73 cat <<EOF >$SHADOWCONF
75 lxc.network.type = veth
76 lxc.network.link = shadowbr
77 lxc.network.flags = up
78 lxc.network.ipv4 = $SHADOWIP/$MASK_BITS
79 lxc.network.ipv4.gateway = $IP
83 trap "rm $SHADOWCONF" SIGINT SIGTERM EXIT
84 LXC_COMMON
="-n shadow -f $SHADOWCONF"
88 openvpn
--mktun --dev $TAP1
89 openvpn
--mktun --dev $TAP2
90 ifconfig
$TAP1 $IP netmask
$MASK broadcast
$BCAST up
92 route add
-net $NET netmask
$MASK $TAP1
94 brctl addif shadowbr
$TAP2 $DEV
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"
106 lxc-destroy
$LXC_COMMON
109 ifconfig shadowbr down
111 openvpn
--rmtun --dev $TAP1
112 openvpn
--rmtun --dev $TAP2
117 echo "Read $0 for more information."