Skip to content

Commit

Permalink
Some lab to test IPv6 route cache.
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentbernat committed Dec 27, 2011
1 parent 499b0ad commit 5aef838
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lab-route-cache-ipv6/inject-100.py
@@ -0,0 +1,7 @@
#!/usr/bin/python

from scapy.all import *

# Inject 1000 packets
send([IPv6(src=RandIP6("2001:db8:beef:**"),
dst=RandIP6("2001:db8:beef:**"))/ICMPv6EchoRequest()/"12345678"]*1000, inter=0.01)
228 changes: 228 additions & 0 deletions lab-route-cache-ipv6/setup
@@ -0,0 +1,228 @@
#!/bin/sh

LABNAME="route-cache-ipv6"
# Change ROOT to the directory containing a chrooted system if you
# don't want to use your own system as a reference
ROOT=$(readlink -f ${ROOT:-/})
LINUX=$(which linux)
DEPS="screen vde_switch $LINUX start-stop-daemon"
CHROOTDEPS="ip"
PROGNAME=$(readlink -f $0)
PROGARGS="$@"

# Check for dependencies needed by this tool
check_dependencies() {
WHICH=$(which which)
for dep in $DEPS; do
$WHICH $dep 2> /dev/null > /dev/null || {
echo "[!] Missing dependency: $dep"
exit 1
}
done
[ -d $ROOT ] || {
echo "[!] Chroot $ROOT does not exists"
}
for dep in $CHROOTDEPS; do
PATH=$ROOT/usr/local/bin:$ROOT/usr/bin:$ROOT/bin:$ROOT/sbin:$ROOT/usr/local/sbin:$ROOT/usr/sbin $WHICH $dep 2> /dev/null > /dev/null || {
echo "[!] Missing dependency: $dep (in $ROOT)"
exit 1
}
done
[ x"$ROOT" = x"/" ] || {
[ -d $(dirname $ROOT/$PROGNAME) ] || mkdir -p $(dirname $ROOT/$PROGNAME)
cp "$PROGNAME" "$ROOT/$PROGNAME"
}
}

# Run our lab in screen
setup_screen() {
[ x"$TERM" = x"screen" ] || \
exec screen -ln -S $LABNAME -c /dev/null -t main "$PROGNAME" "$PROGARGS"
sleep 1
screen -X caption always "%{= wk}%-w%{= BW}%n %t%{-}%+w %-="
screen -X zombie cr
}

# Setup a VDE switch
setup_switch() {
echo "[+] Setup switch $1"
screen -t "switch-$1" \
start-stop-daemon --make-pidfile --pidfile "$TMP/switch-$1.pid" \
--start --startas $(which vde_switch) -- \
--sock "$TMP/switch-$1.sock" -f $2
screen -X select 0
}

# Start a VM
start_vm() {
echo "[+] Start VM $1"
name="$1"
shift
screen -t $name \
start-stop-daemon --make-pidfile --pidfile "$TMP/vm-$name.pid" \
--start --startas $LINUX -- \
uts=$name mem=64M \
root=/dev/root rootfstype=hostfs rootflags=$ROOT myroot=$ROOT init="$PROGNAME" \
"$@"
screen -X select 0
sleep 0.3
}

display_help() {
cat <<EOF
Some screen commands :
C-a d - Detach the screen (resume with screen -r $LABNAME)
C-a " - Select a window
C-a space - Next window
C-a C-a - Previous window
EOF
echo "Press enter to exit the lab"
read a
}

cleanup() {
for pid in $TMP/*.pid; do
kill $(cat $pid)
done
rm -rf $TMP # sh does not seem to handle "trap EXIT"
screen -X quit
}

# Exec function associated to first argument if provided
case $1 in
""|--)
;;
*)
"$@"
exit 0
;;
esac

# No argument is given, setup the lab or act as init.
case $$ in
1)
# Inside UML. Three states:
# 1. Setup the getty
# 2. Setup AUFS
# 3. Remaining setup
STATE=${STATE:-1}

case $STATE in
1)
echo "[+] Set hostname"
hostname -b ${uts}
echo "[+] Set path"
export TERM=xterm
export PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/local/sbin:/usr/sbin

# Setup getty
export STATE=2
exec setsid python -c '
import os, sys
os.close(0)
os.open("/dev/tty0", os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK, 0)
os.dup2(0, 1)
os.dup2(0, 2)
# os.tcsetpgrp(0, 1)
os.execv(sys.argv[1], [sys.argv[1]])' "$PROGNAME"
;;
2)
echo "[+] Setup AUFS"
mount -n -t proc proc /proc
mount -n -t sysfs sysfs /sys
mount -n -t hostfs hostfs /lib/modules -o /usr/lib/uml/modules,ro
mount -n -t tmpfs tmpfs /tmp -o rw,nosuid,nodev
mkdir /tmp/ro
mkdir /tmp/rw
mkdir /tmp/aufs
mount -n -t hostfs hostfs /tmp/ro -o $myroot,ro
mount -n -t aufs aufs /tmp/aufs -o noxino,noatime,dirs=/tmp/rw:/tmp/ro=ro

# Chroot inside our new root
export STATE=3
exec chroot /tmp/aufs "$PROGNAME"
;;
esac

echo "[+] Set filesystems"
rm /etc/mtab
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /dev -o rw && {
cd /dev
if [ -f $(dirname "$PROGNAME")/dev.tar ]; then
tar xf $(dirname "$PROGNAME")/dev.tar
else
MAKEDEV null consoleonly
fi
}
mount -t hostfs hostfs /lib/modules -o /usr/lib/uml/modules,ro
for fs in /var/run /var/tmp /var/log /tmp; do
mount -t tmpfs tmpfs $fs -o rw,nosuid,nodev
done
mount -t hostfs hostfs $(dirname "$PROGNAME") -o $(dirname "$PROGNAME")

# Interfaces
echo "[+] Set interfaces"
for intf in /sys/class/net/*; do
intf=$(basename $intf)
ip a l dev $intf 2> /dev/null >/dev/null && ip link set up dev $intf
done

echo "[+] Start syslog"
rsyslogd

cd $(dirname "$PROGNAME")
[ -f dev.tar ] || {
tar -C /dev -cf dev.tar.$uts . && mv dev.tar.$uts dev.tar
}

# Configure each UML
echo "[+] Setup UML"
modprobe ipv6
case ${uts} in
injector)
ip addr add 2001:db8:cafe:1::1/64 dev eth0
ip route add default via 2001:db8:cafe:1::2
;;
blackhole)
ip addr add 2001:db8:cafe:2::1/64 dev eth0
ip -6 route add default blackhole
;;
router)
sysctl -w net.ipv6.conf.all.forwarding=1
ip addr add 2001:db8:cafe:1::2/64 dev eth0
ip addr add 2001:db8:cafe:2::2/64 dev eth1
ip route add default via 2001:db8:cafe:2::1
;;
esac

echo "[+] Drop to a shell"
exec /bin/bash

;;
*)
TMP=$(mktemp -d)
trap "rm -rf $TMP" EXIT
check_dependencies
setup_screen

# Setup switches
setup_switch global

# Start VM
start_vm injector eth0=vde,$TMP/switch-global.sock
start_vm blackhole eth0=vde,$TMP/switch-global.sock
start_vm router eth0=vde,$TMP/switch-global.sock eth1=vde,$TMP/switch-global.sock

display_help
cleanup
;;
esac

# Local Variables:
# mode: sh
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

0 comments on commit 5aef838

Please sign in to comment.