Create a gist now

Instantly share code, notes, and snippets.

@hongjiang /vpn.sh
Last active Oct 27, 2015

What would you like to do?
mac vpn connection script
#!/bin/bash
PROG_NAME=$0
ACTION=$1
usage() {
echo "Usage: $PROG_NAME {list|ping|optimal|conn|close|status}"
exit 1
}
get_services() {
local protocol=${1:-"L2TP|PPTP"}
scutil --nc list | grep -iE "$protocol" | awk -F'"' '{print $2}'
}
get_service_addr() {
local service=$1
scutil --nc show "$service" | awk '$1~/CommRemoteAddress/{print $3}'
}
vpn_list() {
local protocol=$1
IFS=$'\n' && declare -a services=( `get_services $protocol` )
for service in "${services[@]}";do
addr=$(get_service_addr $service)
echo "$service: $addr"
done
}
vpn_test() {
local protocol=$1
declare -a hosts=()
IFS=$'\n' && declare -a services=( `get_services $protocol` )
for service in "${services[@]}";do
host=$(scutil --nc show "$service" | awk '$1~/CommRemoteAddress/{print $3}')
[[ "${hosts[*]}" =~ "$host" ]] || hosts+=("$host")
done
for h in "${hosts[@]}";do
ping -c3 $h 2>/dev/null | tail -1 | cut -d'=' -f2 | cut -d'/' -f2 | xargs -I {} echo "$h " {} 2>/dev/null &
done
children=$(jobs -p | xargs)
trap 'kill $children >/dev/null 2>&1' SIGINT SIGTERM
wait
}
get_protocol() {
local service=$1
scutil --nc show "$service" | awk -F':|]' 'NR==1{print $(NF-1)}'
}
get_fastest_service() {
local protocol=$1
local host=$(vpn_test $protocol 2>/dev/null | sort -nk2 | head -1 | awk '{print $1}')
if [ -z "$protocol" ];then
vpn_list | grep "$host" | cut -d':' -f1 | head -1
else
vpn_list $protocol | grep "$host" | cut -d':' -f1
fi
}
to_upper() {
echo ${@^^}
}
vpn_status() {
which ack >/dev/null 2>&1
if [ $? -eq 0 ];then
scutil --nc list | grep -E "L2TP|PPTP" | ack --passthru Connected
else
scutil --nc list | grep -E "L2TP|PPTP"
fi
}
vpn_connect() {
local service=$1
/usr/bin/env osascript <<-EOF
tell application "System Events"
tell current location of network preferences
set VPN to service "$service" -- your VPN name here
if exists VPN then connect VPN
repeat while (current configuration of VPN is not connected)
delay 1
end repeat
end tell
end tell
EOF
}
get_connected_service() {
vpn_status | awk '$2~/Connected/' | awk -F'"' '{print $2}'
}
vpn_disconnect() {
local service=$1
/usr/bin/env osascript <<-EOF
tell application "System Events"
tell current location of network preferences
set VPN to service "$service" -- your VPN name here
if exists VPN then disconnect VPN
end tell
end tell
return
EOF
}
case "$ACTION" in
ping|test)
vpn_test
;;
optimal)
shift
get_fastest_service $@
;;
list)
vpn_list
;;
conn)
shift && service="$(get_fastest_service $@)"
vpn_connect "$service"
[ $? -eq 0 ] && echo "ok, $service connected."
;;
close)
service=$(get_connected_service)
[ -z "$service" ] && echo "not connected to any service." && exit 0
vpn_disconnect "$service"
[ $? -eq 0 ] && echo "ok, $service disconnected."
;;
status)
vpn_status
;;
*)
usage
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment