2 Copyright
2016-
2017 Dan Luedtke
<mail@danrl.com
>
3 Licensed to the public under the Apache License
2.0.
7 local uci = uci.cursor()
12 local wg_dump = io.popen(
"wg show all dump")
15 for line in wg_dump:lines() do
16 local line = string.split(line,
"\t")
17 if not (last_device == line[
1]) then
22 listen_port = line[
4],
26 local s = uci:get_list(
"network", line[
1],
"addresses")
29 for key, value in pairs(s) do
31 address = address..
", " ..value
36 enc[line[
1]] =
"[Interface]\nPrivateKey = " ..line[
2]..
"\nAddress = " ..address
42 latest_handshake = line[
6],
43 transfer_rx = line[
7],
44 transfer_tx = line[
8],
45 persistent_keepalive = line[
9]
47 if not (line[
4] == '(none)') then
49 for ipkey, ipvalue in pairs(string.split(line[
5],
",")) do
51 table.insert(peer['allowed_ips'], ipvalue)
55 table.insert(data[line[
1]].peers, peer)
56 enc[line[
1]] = enc[line[
1]]..
"\n\n[Peer]\nEndpoint = " ..line[
4]..
"\nPublicKey = " ..line[
2]..
"\nAllowedIPs = " ..line[
5]
61 if luci.http.formvalue(
"status") ==
"1" then
62 luci.http.prepare_content(
"application/json")
63 luci.http.write_json(data)
70 <script type=
"text/javascript">//<![CDATA[
72 function bytes_to_str(bytes) {
73 bytes = parseFloat(bytes);
74 if (bytes <
1) { return
"0 B"; }
75 var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
76 var i = parseInt(Math.floor(Math.log(bytes) / Math.log(
1024)));
77 return Math.round(bytes / Math.pow(
1024, i),
2) + ' ' + sizes[i];
80 function timestamp_to_str(timestamp) {
85 var seconds = (now.getTime() /
1000) - timestamp;
88 ago = parseInt(seconds) + '<%:s ago%
>';
89 } else if (seconds <
3600) {
90 ago = parseInt(seconds /
60) + '<%:m ago%
>';
91 } else if (seconds <
86401) {
92 ago = parseInt(seconds /
3600) + '<%:h ago%
>';
94 ago = '<%:over a day ago%
>';
96 var t = new Date(timestamp *
1000);
97 return t.toUTCString() + ' (' + ago + ')';
100 function toggle_qrcode(iface) {
101 var view = document.getElementById(iface.name);
102 if (view.style.display ===
"none") {
103 view.style.display =
"block";
105 view.style.display =
"none";
109 XHR.poll(
5, '<%=REQUEST_URI%
>', { status:
1 },
111 for (var key in data) {
112 if (!data.hasOwnProperty(key)) { continue; }
114 var iface = data[key];
116 if (iface.public_key == '(none)') {
117 s += '
<em><%:Interface does not have a public key!%
></em>';
120 '
<strong><%:Public Key%
>:
</strong>%s',
124 if (iface.listen_port
> 0) {
126 '
<br /><strong><%:Listen Port%
>:
</strong>%s',
130 if (iface.fwmark != 'off') {
132 '
<br /><strong><%:Firewall Mark%
>:
</strong>%s',
136 document.getElementById(ifname +
"_info").innerHTML = s;
137 for (var i =
0, ilen = iface.peers.length; i < ilen; i++) {
138 var peer = iface.peers[i];
139 var s = String.format(
140 '
<strong><%:Public Key%
>:
</strong>%s',
143 if (peer.endpoint != '(none)') {
145 '
<br /><strong><%:Endpoint%
>:
</strong>%s',
149 if (peer.allowed_ips.length
> 0) {
150 s += '
<br /><strong><%:Allowed IPs%
>:
</strong>';
151 for (var k =
0, klen = peer.allowed_ips.length; k < klen; k++) {
152 s += '
<br />  • ' + peer.allowed_ips[k];
155 if (peer.persistent_keepalive != 'off') {
157 '
<br /><strong><%:Persistent Keepalive%
>:
</strong>%ss',
158 peer.persistent_keepalive
161 var icon = '
<img src=
"<%=resource%>/icons/tunnel_disabled.png" />';
162 var now = new Date();
163 if (((now.getTime() /
1000) - peer.latest_handshake) <
140) {
164 icon = '
<img src=
"<%=resource%>/icons/tunnel.png" />';
167 '
<br /><strong><%:Latest Handshake%
>:
</strong>%s',
168 timestamp_to_str(peer.latest_handshake)
171 '
<br /><strong><%:Data Received%
>:
</strong>%s' +
172 '
<br /><strong><%:Data Transmitted%
>:
</strong>%s',
173 bytes_to_str(peer.transfer_rx),
174 bytes_to_str(peer.transfer_tx),
176 document.getElementById(ifname +
"_" + peer.public_key +
"_icon").innerHTML = icon;
177 document.getElementById(ifname +
"_" + peer.public_key +
"_info").innerHTML = s;
183 <h2>WireGuard Status
</h2>
185 <div class=
"cbi-section">
188 for ikey, iface in pairs(data) do
190 <h3><%:Interface%
> <%=ikey%
></h3>
191 <div class=
"cbi-value" id=
"button" style=
"padding: 5px">
192 <input class=
"cbi-button cbi-button-apply" type=
"button" name=
"qrcode_<%=ikey%>" value=
"<%:Show/Hide QR-Code%>" onclick=
"toggle_qrcode(this)" />
196 if fs.access(
"/usr/bin/qrencode") then
197 if enc[ikey]:sub(
26,
31) ~=
"(none)" then
198 qrcode = luci.sys.exec(
"/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" ..enc[ikey]..
"'")
201 qrcode =
"<em>For QR-Code support please install package 'qrencode'!</em>"
204 <div class=
"cbi-value-title">
205 <span class=
"cbi-value" style=
"display: none" id=
"qrcode_<%=ikey%>"><%=qrcode%
></span>
207 <div class=
"cbi-section-node">
208 <div class=
"table cbi-section-table">
209 <div class=
"tr cbi-section-table-row" style=
"text-align: left;">
210 <div class=
"td" style=
"text-align: left; vertical-align:top"><%:Configuration%
></div>
211 <div class=
"td" style=
"flex: 0 1 90%; text-align: left;">
212 <div class=
"table cbi-section-table" style=
"border: 0px;">
213 <div class=
"tr cbi-section-table-row" style=
"text-align: left; border: 0px;">
214 <div class=
"td" id=
"<%=ikey%>_icon" style=
"width: 22px; text-align: left; border-top: 0px; padding: 3px;"> </div>
215 <div class=
"td" id=
"<%=ikey%>_info" style=
"flex: 0 1 90%; text-align: left; vertical-align:middle; padding: 3px; border-top: 0px;"><em><%:Collecting data...%
></em></div>
221 local cur = uci.cursor()
223 for pkey, peer in pairs(iface.peers) do
225 cur:foreach(
"network",
"wireguard_" .. ikey, function(s)
226 local key, value, tmp_desc, pub_key
227 for key, value in pairs(s) do
228 if key ==
"description" then
231 if value == peer.public_key then
234 if pub_key and tmp_desc then
235 desc = ': ' ..tmp_desc
240 <div class=
"tr cbi-section-table-row" style=
"text-align: left;">
241 <div class=
"td" style=
"text-align: left; vertical-align:top"><%:Peer%
><%=desc%
></div>
242 <div class=
"td" style=
"flex: 0 1 90%; text-align: left;">
243 <div class=
"table cbi-section-table" style=
"border: 0px">
244 <div class=
"tr cbi-section-table-row" style=
"border: 0px;">
245 <div class=
"td" id=
"<%=ikey%>_<%=peer.public_key%>_icon" style=
"width:16px; text-align: left; padding: 3px;border-top: 0px;">
246 <img src=
"<%=resource%>/icons/tunnel_disabled.png" />
249 <div class=
"td" id=
"<%=ikey%>_<%=peer.public_key%>_info" style=
"flex: 0 1 90%; text-align: left; vertical-align:middle; padding: 3px;border-top: 0px;"><em><%:Collecting data...%
></em></div>