Initial commit
This commit is contained in:
commit
0a65725361
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.log
|
||||
status
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "bashserv"]
|
||||
path = bashserv
|
||||
url = https://github.com/fumyuun/bashserv.git
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Wakeboard
|
||||
A simple status page to remotely wake up hosts, to use on a DHCP server using `dnsmasq`. It will read the leases as given out, and display all hosts that are statically configured, uses ping to figure out if they are awake or not, and can send a wake-on-lan packet to awake them.
|
||||
|
||||
It is likely full of security holes, so please ensure it is not accessable from an untrusted network :)
|
||||
|
1
bashserv
Submodule
1
bashserv
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 797abde65eeecc327bdb577c75b05942716ef8ea
|
11
handle_404.sh
Executable file
11
handle_404.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
body="<html>\n"
|
||||
body+="<head><title>Not found</title></head>\n"
|
||||
body+="<body>The requested resource $2 was not found</body>\n"
|
||||
body+="</html>\n"
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "text/html" -l $(echo -ne "$body" | wc -c) 404)
|
||||
$(echo -ne $body)
|
||||
EOF
|
49
handle_get.sh
Executable file
49
handle_get.sh
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "[$(date +%T)] GET $1 ($2)" >> get.log
|
||||
|
||||
./handle_requests.sh $@
|
||||
if [ $? -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$1" -o "$1" == "index.html" ]; then
|
||||
body="<html>\n<head>\n<title>$WAKEBOARD_TITLE</title>\n<script type='text/javascript' src='main.js'></script>\n<link rel='stylesheet' href='main.css'></link>\n</head>\n"
|
||||
body+="<body>\n<table>\n<tr><td></td><td>Hostname</td><td>IP Address</td><td>MAC Address</td><td>Wakeup</td></tr>\n"
|
||||
|
||||
IFS=$'\n'
|
||||
leases=$(cat /var/lib/misc/dnsmasq.leases | cut -d ' ' -f2-4)
|
||||
for lease in $leases; do
|
||||
mac=$(echo $lease | cut -d ' ' -f1)
|
||||
ip=$(echo $lease | cut -d ' ' -f2)
|
||||
hostname=$(echo $lease | cut -d ' ' -f3)
|
||||
|
||||
if [ -n "$(grep -i "$mac" /etc/dnsmasq.conf)" ]; then
|
||||
body+="<tr class='host' data-ip='$ip' data-mac='$mac'>\n"
|
||||
|
||||
body+="<td class='status'>"
|
||||
body+="<div 'class='fail'>X</div>"
|
||||
body+="<div class='success' style='display: none;'>✓</div>"
|
||||
body+="<div class='undef' style='display: none;'>?</div>"
|
||||
body+="</td>\n"
|
||||
|
||||
body+="<td>$hostname</td>"
|
||||
body+="<td>$ip</td>"
|
||||
body+="<td>$mac</td>"
|
||||
body+="<td><button class='wol'>Wake up!</button><td>\n"
|
||||
body+="</tr>"
|
||||
fi
|
||||
done
|
||||
|
||||
body+="</table>\n</body>\n</html>\n"
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "text/html" -l $(echo -ne "$body" | wc -c))
|
||||
$(echo -ne $body)
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
./handle_404.sh $@
|
||||
exit $?
|
95
handle_requests.sh
Executable file
95
handle_requests.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$1" =~ ^refresh ]]; then
|
||||
ip=$(echo "$1" | cut -d '/' -f2)
|
||||
|
||||
body="{\n\"time\": \"$(date +%T)\",\n"
|
||||
body+="\"status\": \"unknown\"\n}\n"
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "application/json" -l $(echo -ne "$body" | wc -c))
|
||||
$(echo -ne $body)
|
||||
EOF
|
||||
|
||||
echo -ne "$body" > status/$ip
|
||||
|
||||
ret=1
|
||||
for i in {0..30}; do
|
||||
ping -c 1 -w 5 -t 1 -q "$ip"
|
||||
ret=$?
|
||||
[ $ret -eq 0 ] && break
|
||||
done
|
||||
|
||||
echo -e "{\n\"time\": \"$(date +%T)\"," > status/$ip
|
||||
|
||||
if [ $ret -eq 0 ]; then
|
||||
echo -e "\"status\": \"up\"\n}\n" >> status/$ip
|
||||
else
|
||||
echo -e "\"status\": \"down\"\n}\n" >> status/$ip
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$1" =~ ^status ]]; then
|
||||
ip=$(echo "$1" | cut -d '/' -f2)
|
||||
|
||||
if [ ! -r "status/$ip" ]; then
|
||||
body="{\n\"status\": \"unknown\"\n}\n"
|
||||
else
|
||||
body=$(cat status/$ip)
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "application/json" -l $(echo -e "$body" | wc -c))
|
||||
$body
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$1" =~ ^quickping || "$1" =~ ^ping ]]; then
|
||||
ip=$(echo "$1" | cut -d '/' -f2)
|
||||
|
||||
attempts=1
|
||||
timeout=1
|
||||
|
||||
if [[ "$1" =~ ^ping ]]; then
|
||||
attempts=30
|
||||
timeout=5
|
||||
fi
|
||||
|
||||
ret=1
|
||||
for i in $(seq 1 $attempts); do
|
||||
ping -c 1 -w $timeout -t 1 -q "$ip" > ping.log
|
||||
ret=$?
|
||||
[ $ret -eq 0 ] && break
|
||||
done
|
||||
|
||||
if [ $ret -eq 0 ]; then
|
||||
body="{\"response\": \"ok\"}\n"
|
||||
else
|
||||
body="{\"response: \"fail\"}\n"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "application/json" -l $(echo -ne "$body" | wc -c))
|
||||
$(echo -ne $body)
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$1" =~ ^wol ]]; then
|
||||
mac=$(echo "$1" | cut -d '/' -f2)
|
||||
|
||||
wol "$mac" > /dev/null
|
||||
body="{\"response\": \"ok\"}\n"
|
||||
|
||||
cat <<EOF
|
||||
$($BASHSERV_DIR/header.sh -t "application/json" -l $(echo -ne "$body" | wc -c))
|
||||
$(echo -ne $body)
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exit 1
|
7
static/main.css
Normal file
7
static/main.css
Normal file
@ -0,0 +1,7 @@
|
||||
body {
|
||||
background: #aaaaaa;
|
||||
}
|
||||
|
||||
table {
|
||||
background: #bbbbbb;
|
||||
}
|
112
static/main.js
Normal file
112
static/main.js
Normal file
@ -0,0 +1,112 @@
|
||||
var request_status = function (host) {
|
||||
console.log("Update " + host.ip);
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.addEventListener("load", function () {
|
||||
var response;
|
||||
console.log(this.status, this.responseText);
|
||||
if (this.status !== 200) {
|
||||
return;
|
||||
}
|
||||
response = JSON.parse(this.responseText);
|
||||
if (response.status === "up") {
|
||||
host.status_node.innerHTML = "✓";
|
||||
} else if (response.status === "unknown") {
|
||||
setTimeout(function () {
|
||||
request_status(host);
|
||||
}, 1000);
|
||||
} else {
|
||||
host.status_node.innerHTML = "X";
|
||||
}
|
||||
});
|
||||
|
||||
request.open("GET", "status/" + host.ip);
|
||||
request.send();
|
||||
}
|
||||
var request_refresh = function (host) {
|
||||
console.log("Refresh " + host.ip);
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.addEventListener("load", function () {
|
||||
var response;
|
||||
console.log(this.status, this.responseText);
|
||||
if (this.status !== 200) {
|
||||
return;
|
||||
}
|
||||
response = JSON.parse(this.responseText);
|
||||
if (response.status === "ok") {
|
||||
host.status_node.innerHTML = "✓";
|
||||
} else {
|
||||
host.status_node.innerHTML = "X";
|
||||
}
|
||||
});
|
||||
|
||||
request.open("GET", "refresh/" + host.ip);
|
||||
request.send();
|
||||
|
||||
setTimeout(function () {
|
||||
request_status(host);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
var request_wol = function (host) {
|
||||
console.log("Wakeup " + host.mac);
|
||||
|
||||
host.status_node.innerText = "?";
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.addEventListener("load", function () {
|
||||
var response;
|
||||
console.log(this.status, this.responseText);
|
||||
if (this.status !== 200) {
|
||||
return;
|
||||
}
|
||||
response = JSON.parse(this.responseText);
|
||||
if (response.response === "ok") {
|
||||
host.status_node.innerHTML = "?";
|
||||
} else {
|
||||
host.status_node.innerHTML = "X";
|
||||
}
|
||||
});
|
||||
|
||||
request.open("GET", "wol/" + host.mac);
|
||||
request.send();
|
||||
|
||||
setTimeout(function () {
|
||||
request_refresh(host);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
var host_nodes = document.getElementsByClassName('host');
|
||||
var hosts = [];
|
||||
var i;
|
||||
|
||||
if (host_nodes == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < host_nodes.length; i++) {
|
||||
var host = {
|
||||
ip : host_nodes[i].dataset.ip,
|
||||
mac : host_nodes[i].dataset.mac
|
||||
};
|
||||
var status_node = host_nodes[i].getElementsByClassName('status');
|
||||
var wol_button = host_nodes[i].getElementsByClassName('wol');
|
||||
if (status_node == undefined || wol_button == undefined ||
|
||||
status_node.length < 1 || wol_button.length < 1) {
|
||||
return;
|
||||
}
|
||||
host.status_node = status_node[0];
|
||||
host.wol_button = wol_button[0];
|
||||
hosts.push(host);
|
||||
|
||||
(function (host_bound) {
|
||||
host_bound.wol_button.onclick = function (e) {
|
||||
request_wol(host_bound);
|
||||
}
|
||||
}) (host);
|
||||
|
||||
request_refresh(host);
|
||||
}
|
||||
}
|
42
wakeboard
Executable file
42
wakeboard
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
WAKEBOARD_TITLE="Wakeboard"
|
||||
PORT=8000
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
key="$1"
|
||||
case $key in
|
||||
-h|--help)
|
||||
HELP=1
|
||||
shift
|
||||
;;
|
||||
-p|--port)
|
||||
PORT="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-t|--title)
|
||||
WAKEBOARD_TITLE="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$HELP" ]; then
|
||||
echo "Usage: $0 [-h|--help] [-t|--title <title>] [-p|--port <port>]"
|
||||
echo " -h | --help: Show this help"
|
||||
echo " -t | --title: Title to give to the served page (defaults to Wakeboard)"
|
||||
echo " -p | --port <port>: Port number to use (default 8000)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d "status" ]; then
|
||||
mkdir "status"
|
||||
fi
|
||||
|
||||
# Ensure variable can be read by the get handler
|
||||
export WAKEBOARD_TITLE
|
||||
|
||||
./bashserv/bashserv.sh -s "./static" -g "./handle_get.sh" -p "$PORT"
|
||||
|
Loading…
Reference in New Issue
Block a user