-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpupubridge
executable file
·104 lines (85 loc) · 2.74 KB
/
pupubridge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/bin/sh -eu
kill_parent () {
# When setting this trap we have made sure this is run by SSH, so
# we won't kill a random parent, e.g. your mom.
kill $PPID
}
while getopts i:n:c:h name; do
case $name in
i) ip="$OPTARG" ;;
n) link_new="$OPTARG" ;;
c) cost="$OPTARG" ;;
?) fail= ;;
esac
done
shift $(($OPTIND - 1))
# Fail if no bridge name given, fail set or interface name unset
if test "${fail+1}" -o -z "${link_new+1}"; then
cat 2>&1 <<EOF
Renames this ethernet tunnel to LINK_NAME and adds it to given BRIDGE
with given COST for spanning-tree link cost. If multiple bridges are
given, user may select it by passing it as an parameter to ssh. If no
bridges are given, not adding to any bridges.
Server usage: Add the following line to ~root/.ssh/authorized_keys:
command="$0 -n LINK_NAME [-c COST] [BRIDGE..]",restrict SSH_PUBLIC_KEY
Client usage: Add the following line to ssh command line:
-o PermitLocalCommand=true -o "LocalCommand=exec $0 -n LINK_NAME [-i IP/CIDR] [-c COST] [BRIDGE]"
EOF
exit 1
fi
if test "$(cat /proc/$PPID/comm)" != ssh; then
echo "This command must be run by SSH and not from shell" >&2
exit 1
fi
# Now, since we are sure we are running through ssh, we are ready to
# kill our parent process if we fail
trap kill_parent EXIT
link_orig=`sed -nr 's/^iff:\s*(.*)/\1/p' /proc/$PPID/fdinfo/*`
if test -z "$link_orig"; then
echo "This session has no ethernet tunnel. Are you running: ssh -o 'Tunnel=ethernet'" >&2
exit 2
fi
# Removing old if any
ip link delete "$link_new" 2>/dev/null || true
# Renaming current link and bring it up
ip link set "$link_orig" name "$link_new" up
# Add IP address if given
if test ${ip+1}; then
ip address add "$ip" dev "$link_new"
ipmsg=" IP address is $ip."
fi
test ${SSH_CONNECTION+1} && site="Remote:" || site="Local: "
# If bridges are given, try to bridge
if test $# -gt 0; then
if test ${SSH_CONNECTION+1}; then
if echo "${SSH_ORIGINAL_COMMAND-}" | grep -qx '[0-9]'; then
# Bridge selector is a number, trying to get that index
shift "$SSH_ORIGINAL_COMMAND"
bridge="$1"
else
# Bridge selector is a string, trying to find it
error=" The following bridges are allowed: $@."
bridge="$1"
for x in "$@"; do
if test "$x" = "${SSH_ORIGINAL_COMMAND-}"; then
bridge="$x"
error=
fi
done
fi
else
if test $# -gt 1; then
echo "Local: Only one bridge may be given" >&2
exit 1
fi
bridge="$1"
error=
fi
# Add to bridge
ip link set "$link_new" master "$bridge"
test -z ${cost+1} || bridge link set dev "$link_new" cost "$cost"
bridgemsg=" and connected to $bridge.${error-}"
fi
# Now we're ready to exit cleanly
trap - EXIT
echo "$site Interface $link_new is ready${bridgemsg-.}${ipmsg-}"