目次
ーーーーーーー2ページーーーーーーー
ファイル保存・アクセス制限
ファイルは全てWord Pressのフォルダーに保存。
以下は「\wordpress\wp-content\wol」に保存した例
wp-contentフォルダー及びwolフォルダーにはアクセス制限をしておく。
wp-contentフォルダーに配置の「.htaccess」
指定のファイル拡張子のファイルは指定の経由アクセス元(自サイト)「リファラー(Referrer)」のみアクセス許可する。
アクセス制限はwp-contentフォルダー以下に適用
Apache 2.2以前 (Apache 2.4以降でも可)
<Files ~ "\.(gif|png|jpg|jpeg|php|html)$">
SetEnvIf Referer "https://domaim\.com/" allow_ref
order deny,allow
deny from all
allow from env=allow_ref
</Files>
Apache 2.4以降
2.4は基本アクセス禁止なので許可のみ定義
<Files ~ "\.(gif|png|jpg|jpeg|php|html)$">
SetEnvIf Referer "https://domaim\.com/" allow_ref
Require env allow_ref
</Files>
設置フォルダー以下の全ファイルに適用の場合
SetEnvIf Referer "https://domaim\.com/" allow_ref
Require env allow_ref
wolフォルダーに配置の「.htaccess」
ベーシック認証用
# BASIC認証
AuthType Basic
AuthName "Please enter your ID and password"
AuthUserFile d:/www/private_html/wol/.htpasswd
AuthGroupFile /dev/null
require valid-user
ソース説明
wol_monitor.js
メインの処理コードを記載しており,ヤマハのオリジナルからの変更点は下記のとおり
1.ルーター起動からサーバーへ変更したことにより,データ保存場所もサーバーに変更
2.ルーターコマンドをサーバーのコマンド処理に変更のためPHPでのコマンド処理追加
3.PoE監視からWOL(起動)監視に変更により,WOLコマンド処理追加
4.PHPでのソート機能追加(IPアドレス昇順)
// wol_monitor.js
var tlist; // 監視対象一覧のテーブルのオブジェクト
var clist; // Ping失敗数カウント用テーブルのオブジェクト
var logfd; // ログ表示用フィールドのオブジェクト
var intobj; // Ping定期実行用インターバルのオブジェクト
// 以下パラメーター定義
var authuser = "user"; // ベーシック認証 ユーザーid
var authpass = "pass"; // ベーシック認証 パスワード
var authstr = 'Basic ' + window.btoa(authuser + ':' + authpass); // Authorizationヘッダー埋込認証用
var maxEntryNum = 16; // 登録可能最大数
var pingWaitInterval = 1; // Pingの待ち時間(s)
var pingExecInterval = 3000; // Pingの一斉実行間隔(ms)
var pingErrorCount = 3; // 何回Pingに失敗したらダウンと判断するか
function getResource(url, callback) {
$.ajax({
type: "get",
url: url,
contentType: "charset=shift_jis",
cache: false,
headers: {
"Authorization": "Basic " + btoa(authuser + ":" + authpass)
},
success: function(data) {
callback(data);
}
});
}
function cmdExecute(cmd, callback, arg1, arg2, arg3) {
$.ajax({
type: "post",
url: "execute.php",
cache: false,
dataType : 'json',
data: {post_cmd:cmd},
headers: {
"Authorization": "Basic " + btoa(authuser + ":" + authpass)
},
success: function(result){
var data = result;
if (callback != undefined)
callback(data, arg1, arg2, arg3);
}
});
}
//
// 引数がIPアドレスとして正しいものか調べる
//
function isValidIPaddress(target, on) {
var i;
var confirm = document.getElementById('confirm');
var factor;
if (target.indexOf(".0") != -1) {
if (on)
confirm.innerHTML = "<font color=\"red\">入力値に誤りがあります</font>";
return 1;
}
factor = target.split('.');
if (factor.length != 4) {
if (on)
confirm.innerHTML = "<font color=\"red\">入力値に誤りがあります</font>";
return 1;
}
for (i = 0; i < 4; i++) {
if (factor[i].match(/[^0-9]+/)) {
if (on)
confirm.innerHTML = "<font color=\"red\">入力値に誤りがあります</font>";
return 1;
}
}
for (i = 0; i < target.length; i++) {
if (encodeURI(target.charAt(i)).length >= 4) {
if (on)
confirm.innerHTML = "<font color=\"red\">入力値に誤りがあります</font>";
return 1;
}
}
for (i = 0; i < 4; i++) {
var num = Number(factor[i]);
if (num == NaN || factor[i] < 0 || factor[i] > 255) {
if (on)
confirm.innerHTML = "<font color=\"red\">入力値に誤りがあります</font>";
return 1;
}
}
confirm.innerHTML = " ";
return 0;
}
//
// 入力されたIPアドレスからMACアドレスを調べる
//
function getMacAddress() {
var cmd = "arp -a";
cmdExecute(cmd, showMacAddress);
}
$(document).ready(function() {
tlist = document.getElementById('target_list');
clist = document.getElementById('target_list_cnt');
logfd = document.getElementById('log');
// コマンドの実行で管理者へ
updateStatusMain();
// データベースを開く
getResource("database.txt", function(data) {
var i, j, str, rows, line, num, cnt, rec;
if (data != undefined) {
str = data.split("\n");
// 端末の登録
for (i = 0; i < str.length; i++) {
line = str[i].split(",");
if (line.length != 4)
continue;
rows = tlist.insertRow(-1);
rows.style.height = "40";
num = tlist.rows.length;
for (j = 0; j < 8; j++) {
rows.insertCell(-1);
}
rows.cells[0].innerHTML = String(i + 1);
rows.cells[1].innerHTML = line[0];
rows.cells[2].innerHTML = line[1];
rows.cells[3].innerHTML = "";
rows.cells[4].innerHTML = line[2];
rows.cells[5].innerHTML = "確認中";
if (line[3].indexOf("auto") != -1) {
rows.cells[6].innerHTML = "自動起動";
} else {
rows.cells[6].innerHTML = "手動起動 <input type=\"button\" value=\"実行\" onclick=\"offPortUse(\'" + line[0] + "\', 1);\">";
}
rows.cells[7].innerHTML = "<input type=\"button\" value=\"削除\" onclick=\"deleteTarget(\'" + line[0] + "\');\">";
rows.style.textAlign = "center";
// 端末毎のPing欠落回数の設定
rows = clist.insertRow(-1);
num = clist.rows.length;
cnt = "cnt_" + line[0];
rec = "rec_" + line[0];
rows.insertCell(-1);
rows.insertCell(-1);
rows.cells[0].innerHTML = "<input type=\"hidden\" id=\"" + cnt + "\">";
rows.cells[1].innerHTML = "<input type=\"hidden\" id=\"" + rec + "\">";
document.getElementById(cnt).value = 0;
document.getElementById(rec).value = 0;
}
// MACアドレスと経路情報の取得と表示
setTimeout(getMacAddress, 1000);
}
updateStatus();
})
// ログファイルを開く
getResource("logfile.txt", function(data) {
if (data != undefined) {
var log = document.getElementById('log');
str = data.split("\r\n");
for (i = 0; i < str.length; i++) {
if (i == 0) {
log.innerHTML = str[i];
} else {
log.innerHTML = log.innerHTML + "<br>" + str[i];
}
}
}
})
});
function updateStatusMain() {
updateStatus();
setInterval(updateStatus, pingExecInterval);
}
//
// Pingによる疎通確認を行う
//
function updateStatus() {
// 対象が無ければ何もしない
if (tlist.rows.length > 1) {
var i;
for (i = 1; i < tlist.rows.length; i++){
updateStatusEach(i)
}
intobj = setTimeout(function() {checkPing();}, 2000);
}
}
//
// テーブルのNoを指定してPingによる疎通確認を行う
//
function updateStatusEach(id) {
var target;
var cmd = "nwolc -p ";
if (tlist.rows.length == id)
return;
target = tlist.rows[id].cells[1].innerHTML;
if (isValidIPaddress(target, 0))
return;
cmd = cmd + target + " -t " + pingWaitInterval;
cmdExecute(cmd, checkLuaStatus);
}
//
// Pingの結果を確認するため、show status luaを実行する DUMMY
//
function checkPing() {
//
}
//
// Pingの結果を表示に反映させる
// ダウン時の自動起動を実行する
//
function checkLuaStatus(data) {
var i, j, id;
var str = String(data[0]).split(' ');
var str1 = data;
var str2;
var target;
var cel2,cel3, cel5, cel6;
var cnt, rect, cnt_ele, rec_ele, cnt_num, rec_num;
for (i = 1; i < tlist.rows.length; i++) {
target = tlist.rows[i].cells[1].innerHTML;
cel2 = tlist.rows[i].cells[2];
cel3 = tlist.rows[i].cells[3];
cel5 = tlist.rows[i].cells[5];
cel6 = tlist.rows[i].cells[6];
cnt = "cnt_" + target;
rec = "rec_" + target;
cnt_ele = document.getElementById(cnt);
rec_ele = document.getElementById(rec);
cnt_num = Number(cnt_ele.value);
rec_num = Number(rec_ele.value);
if (str[0] == target) {
if (str1[1] == 0) {
if (cel5.innerHTML == "OFF" || cel5.innerHTML.indexOf("確認中") != -1 || cel5.innerHTML.indexOf("WOL起動中") != -1 ) {
makeStateLog(target, 1);
}
cel3.innerHTML = cnt_num;
cel5.innerHTML = "ON";
cel5.style.backgroundColor = "#7bdf2e";
cnt_ele.value = 0;
rec_ele.value = 0;
// MACアドレスの更新
if (cel2.innerHTML == "") {
getMacAddress();
}
} else {
if (cnt_num < pingErrorCount) {
cnt_num += 1;
}
cnt_ele.value = cnt_num;
if (rec_num > 0) {
break;
}
if (cnt_num >= pingErrorCount) {
if (cel5.innerHTML.indexOf("WOL起動中") == -1) {
if (cel5.innerHTML == "ON" || cel5.innerHTML.indexOf("確認中") != -1) {
makeStateLog(target, 0);
}
cel3.innerHTML = cnt_num;
cel5.innerHTML = "OFF";
cel5.style.backgroundColor = "#F83131";
if (cel6.innerHTML == "自動起動") {
// 自動起動
offPortUse(target, 0);
}
}
}
}
break;
}
}
}
//
// マジックバケットを送信する
//
function offPortUse(target, manual) {
var i;
var rec = "rec_" + target;
var rec_ele = document.getElementById(rec);
var macaddr;
for (i = 1; i < tlist.rows.length; i++) {
if (tlist.rows[i].cells[1].innerHTML == target) {
macaddr = tlist.rows[i].cells[2].innerHTML;
break;
}
}
if (macaddr == "") {
return;
}
var mac = macaddr.replace(/:/g, '' );
cmd0 = "nwolc -m " + mac;
cmdExecute(cmd0);
rec_ele.value = 1;
tlist.rows[i].cells[5].innerHTML = "WOL起動中";
tlist.rows[i].cells[5].style.backgroundColor = "#FF9900";
makePoeLog(manual, target, 0);
// Pingの監視をリスタート
clearTimeout(intobj);
setTimeout(updateStatus, 3000);
}
//
// 給電設定変更のログを作る
//
function makePoeLog(manual, target, on) {
var dateinfo = new Date();
var year = dateinfo.getFullYear();
var month = dateinfo.getMonth() + 1;
var day = dateinfo.getDate();
var hour = dateinfo.getHours();
var minute = dateinfo.getMinutes();
var second = dateinfo.getSeconds();
var time;
var method = (manual == 1) ? "[手動起動]" : "[自動起動]";
var proc = (on == 1) ? "の給電を再開しました" : "へマジックパケットを送信しました";
var str;
month = doubleNumber(month);
day = doubleNumber(day);
hour = doubleNumber(hour);
minute = doubleNumber(minute);
second = doubleNumber(second);
time = year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second;
str = time + " " + method + target + proc;
logfd.innerHTML = str + "<br>" + logfd.innerHTML;
LogSave(str);
}
//
// 監視状態変更のログを作る
//
function makeStateLog(target, on) {
var dateinfo = new Date();
var year = dateinfo.getFullYear();
var month = dateinfo.getMonth() + 1;
var day = dateinfo.getDate();
var hour = dateinfo.getHours();
var minute = dateinfo.getMinutes();
var second = dateinfo.getSeconds();
var time;
var proc = (on == 1) ? "の状態が [<b><font color=\"green\">ON</font></b>] になりました" : "の状態が [<b><font color=\"red\">OFF</font></b>] になりました";
var str;
month = doubleNumber(month);
day = doubleNumber(day);
hour = doubleNumber(hour);
minute = doubleNumber(minute);
second = doubleNumber(second);
time = year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second;
str = time + " " + target + proc;
logfd.innerHTML = str + "<br>" + logfd.innerHTML;
LogSave(str);
}
//
// 1桁の数字を2桁にする(1->01)
//
function doubleNumber(num) {
num += "";
if (num.length === 1) {
num = "0" + num;
}
return num;
}
//
// 端末の登録を行う
//
function registDevice1() {
var i, num, ret;
var target = document.forms.id_target_form.elements.target.value;
var comment = document.forms.id_target_form.elements.comment.value;
var confirm = document.getElementById('confirm');
var cmd;
// IPアドレス入力チェック
if (isValidIPaddress(target, 1))
return;
// コメント入力チェック
if (comment.indexOf(',') != -1) {
confirm.innerHTML = "<font color=\"red\">コメントに , は使用できません</font>";
return;
}
// 設定数上限の確認
if (tlist.rows.length == maxEntryNum + 1) {
confirm.innerHTML = "<font color=\"red\">これ以上登録できません</font>";
return;
}
// 管理者への昇格およびARPテーブルの更新
cmd = "nwolc -p " + target;
cmdExecute(cmd);
setTimeout(registDevice2, 1000);
}
function registDevice2() {
var i, num;
var ret = 0;
var target = document.forms.id_target_form.elements.target.value;
var comment = document.forms.id_target_form.elements.comment.value;
var recover = document.forms.id_target_form.id_recover1.checked;
var rows, cnt, rec, cmd;
// 登録情報の上書き
for (i = 1; i < tlist.rows.length; i++) {
rows = tlist.rows[i];
if (rows.cells[1].innerHTML == target) {
rows.cells[4].innerHTML = comment;
rows.cells[5].innerHTML = "確認中";
if (recover == true)
rows.cells[6].innerHTML = "自動起動";
else
rows.cells[6].innerHTML = "手動起動 <input type=\"button\" value=\"実行\" onclick=\"offPortUse(\'" + target + "\', 1);\">";
return;
}
}
// 端末の登録
rows = tlist.insertRow(-1);
rows.style.height = "40";
num = tlist.rows.length;
for (i = 0; i < 8; i++) {
rows.insertCell(-1);
}
rows.cells[0].innerHTML = String(num - 1);
rows.cells[1].innerHTML = target;
rows.cells[2].innerHTML = "";
rows.cells[3].innerHTML = "";
rows.cells[4].innerHTML = comment;
rows.cells[5].innerHTML = "確認中";
if (recover == true)
rows.cells[6].innerHTML = "自動起動";
else
rows.cells[6].innerHTML = "手動起動 <input type=\"button\" value=\"実行\" onclick=\"offPortUse(\'" + target + "\', 1);\">";
rows.cells[7].innerHTML = "<input type=\"button\" value=\"削除\" onclick=\"deleteTarget(\'" + target + "\');\">";
rows.style.textAlign = "center";
// 端末毎のPing欠落回数の設定
rows = clist.insertRow(-1);
num = clist.rows.length;
cnt = "cnt_" + target;
rec = "rec_" + target;
rows.insertCell(-1);
rows.insertCell(-1);
rows.cells[0].innerHTML = "<input type=\"hidden\" id=\"" + cnt + "\">";
rows.cells[1].innerHTML = "<input type=\"hidden\" id=\"" + rec + "\">";
document.getElementById(cnt).value = 0;
document.getElementById(rec).value = 0;
// MACアドレスと経路情報の取得と表示
setTimeout(getMacAddress, 1000);
return;
}
//
// 導出したMACアドレスを表示する
//
function showMacAddress(data) {
var i, j;
var str1 = JSON.stringify(data).split(',');
var str2;
var target_ip;
var macaddr;
for (i = 1; i < tlist.rows.length; i++) {
target_ip = tlist.rows[i].cells[1].innerHTML;
for (j = 0; j < str1.length; j++) {
str1[j] = str1[j].replace(/{"|"}/g, '');
str1[j] = str1[j].replace(/":"/g, ' ');
str2 = str1[j].replace(/"/g, '');
str2 = str2.split(' ');
if (str2[0] == target_ip) { // ip
macaddr = str2[1].replace( /-/g , ':' );
tlist.rows[i].cells[2].innerHTML = macaddr;
}
}
}
}
//
// 現状の監視対象のリストを保存する
//
async function saveTargetList() {
var i, str;
var rows, line = "";
await DataClear();
for (i = 1; i < tlist.rows.length; i++) {
// async内のawaitから呼び出した関数(_sleep)からPromiseが返されるまで待機
await _sleep(300);
rows = tlist.rows[i];
if (isValidIPaddress(rows.cells[1].innerHTML, 0))
continue;
rows.cells[0].style.backgroundColor = "#F83131";
line = rows.cells[1].innerHTML + "," + rows.cells[2].innerHTML + "," + rows.cells[4].innerHTML + ",";
str = rows.cells[6].innerHTML.split(" ");
if (str[0] == "自動起動")
line = line + "auto ";
else
line = line + "manual ";
await DataSave(line);
await _sleep(300);
rows.cells[0].style.backgroundColor = "#7bdf2e";
}
}
//
// sleep処理
//
function _sleep(ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, ms);
});
}
//
// データベースを保存する
//
function DataSave(data) {
dataurl = "database.php"
$(function(){
//ajax送信
$.ajax({
url : dataurl,
type : "POST",
dataType : 'json',
data : {post_data:data},
headers: {
"Authorization": "Basic " + btoa(authuser + ":" + authpass)
},
xhrFields: {
withCredentials: true
}
});
});
}
//
// 現状の監視対象のリストをIPアドレスで並び替えする
//
function datasort() {
dataurl = "datasort.php"
$(function(){
//ajax送信
$.ajax({
url : dataurl,
type : "POST",
dataType : 'json',
headers: {
"Authorization": "Basic " + btoa(authuser + ":" + authpass)
}
}).always(
function() {
location.reload(true);
}
);
});
}
//
// データベースを消去する
//
function DataClear() {
datacurl = "dataclear.php"
var xhr = new XMLHttpRequest();
xhr.open('POST', datacurl);
xhr.setRequestHeader("Authorization" , authstr);
xhr.withCredentials = true;
xhr.send();
}
//
// 監視対象一覧から1行削除する
//
function deleteTarget(target) {
var i, rows;
// tlistから削除
for (i = 1; i < tlist.rows.length; i++) {
if (tlist.rows[i].cells[1].innerHTML == target) {
tlist.deleteRow(i);
break;
}
}
for (i = 1; i < tlist.rows.length; i++) {
tlist.rows[i].cells[0].innerHTML = i;
}
// clistから削除
for (i = 0; i < clist.rows.length; i++) {
if (clist.rows[i].cells[0].innerHTML.indexOf("id=\"cnt_" + target + "\"") != -1) {
clist.deleteRow(i);
break;
}
}
}
//
// ログファイルを保存する
//
function LogSave(log) {
logurl = "logfile.php"
$(function(){
//ajax送信
$.ajax({
url : logurl,
type : 'POST',
dataType : 'json',
data : {post_log:log},
headers: {
'Authorization': 'Basic ' + btoa(authuser + ':' + authpass)
},
xhrFields: {
withCredentials: true
}
});
});
}
//
//
// ログファイルを消去する
//
function LogClear() {
logcurl = "logclear.php"
var xhr = new XMLHttpRequest();
xhr.open('POST', logcurl);
xhr.setRequestHeader("Authorization" , authstr);
xhr.withCredentials = true;
xhr.send();
}
//
// ログファイルの削除とログフィールドのクリア
//
function clearLog() {
logfd.innerHTML = "";
LogClear();
}
wol.html
1.並び替えボタン追加
ボタン押下でサーバー保存のデータを並び替えして再読み込みする。表示データは上書きされるので,並び替え前にデータ保存する。
連続ボタン操作でサーバーIO処理能力によってはデータ抜けの可能性あり。
2.接続ポート欄をPINGエラー回数に変更
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- wol.html -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script type="text/javascript" src="wol_monitor.js"></script>
<link href="custom.css" rel="stylesheet" type="text/css"/>
<title>ネットワーク機器監視システム</title>
</head>
<body>
<!--監視対象の登録-->
<div id="register_field">
<img class="register_title_icon" src="register_icon.png" alt=""><h1 class="register_title">監視対象の登録</h1>
<form name="target_form" id="id_target_form" action="">
<table border="1">
<tbody>
<tr>
<td class="td">監視対象IPアドレス</td>
<td><input type="text" name="target" id="id_target" maxlength="15"></td>
</tr>
<tr>
<td class="td">機器名・コメント</td>
<td><input type="text" name="comment" id="id_comment" maxlength="30"></td>
</tr>
<tr>
<td class="td">WOL起動方法</td>
<td><input type="radio" name="recover" id="id_recover1" value="auto">自動起動<br>
<input type="radio" name="recover" id="id_recover2" value="manual" checked="">手動起動</td>
</tr>
</tbody>
</table>
<div id="confirm"> </div>
<div align="right"><input type="button" class="normal_button" value="登 録" onclick="registDevice1();"></div>
</form>
</div>
<hr>
<!--起動状況ログ-->
<div id="log_field">
<img class="log_title_icon" src="log.png" alt=""><h1 class="log_title">起動状況ログ</h1>
<div id="log" class="log"></div>
<div> </div>
<div align="right"><input type="button" class="normal_button" value="ログのクリア" onclick="clearLog();"></div>
</div>
<hr>
<!--監視対象一覧-->
<div id="list_field">
<div id="list_field_title">
<img class="list_title_icon" src="camera.png" alt=""><h1 class="list_title">監視対象一覧</h1>
</div>
<div class="target_poe" id="target_poe"></div>
<table align="right">
<tr align="right" style="padding-bottom: 10px; margin-top: -20px;">
<td> <input type="button" class="blink_button" value="監視対象情報を保存" onclick="saveTargetList();"/>
<td> <input type="button" class="blink_button" value="並び替え" onclick="datasort();"/>
</tr>
</table>
<table border="1" id="target_list" width="100%"><tbody>
<tr class="tr">
<th width="6">№</th>
<th width="130">IPアドレス</th>
<th width="130">MACアドレス</th>
<th width="8">ERR</th>
<th>機器名・<br>コメント</th>
<th width="100">状態</th>
<th width="200">起動方法</th>
<th width="100">削除</th>
</tr>
</tbody></table>
<table border="0" id="target_list_cnt"><tbody>
</tbody></table>
</div>
</body>
</html>
custom.css
1.並び替えボタン追加に伴う若干の変更
2.ログ表示欄を移動
@charset "utf-8";
/* CSS Document custom.css */
body{
font-family:"Hiragino Kaku Gothic Pro",Meiryo, "MS PGothic", sans-serif
}
td{
padding:5 15 5 15;
border-color:#9e9e9e;
}
.td{
background-color: #90caf9;
min-width: 150px;
}
.td2{
width: 50px;
}
.tr{
background-color: #90caf9;
height: 40px;
}
th{
border-color: #9e9e9e;
}
table{
max-width:100%;
font-size:12px;
margin-bottom:0px;
border-collapse:collapse;
border:#9e9e9e;
}
.normal_button{
display:inline-block;
padding: 9px 10px;
font-size: 16px;
//border: 1px solid #90caf9;
border: solid 2px;
border-color: #2196f3;
color: #000;
background-color: #ffffff;
box-shadow: 4px 4px #9e9d9d;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
margin: 0 5px;
min-width: 130px;
text-align: center;
}
.normal_button:hover {
background: #c4e5f7;
}
.normal_button:active {
background: #2196f3;
}
.blink_button {
display:inline-block;
padding: 9px 10px;
font-size: 16px;
//border: 1px solid #90caf9;
border: solid 2px;
border-color: #2196f3;
color: #000;
background-color: #ffffff;
box-shadow: 4px 4px #9e9d9d;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
margin: 0 5px;
min-width: 130px;
text-align: center;
}
.blink_button:hover {
background: #c4e5f7;
}
.blink_button:active {
background: #2196f3;
}
div.body{
margin-top:0px;
margin-left:0px;
}
div.log{
overflow: scroll;
width: auto;
height: 150px;
}
div.target_poe{
display:inline;
margin-left: 0px;
}
div.h3{
border: solid 2px #ffe082;
width: auto;
height: 130px;
margin: 20px 30px;
padding: 0px;
}
h1{
margin-bottom: 0px;
display:inline;
}
h3{
padding:10 20 10 20;
margin: 10px;
background-color: #ffe082;
position: relative;
}
.register_title{
position: relative;
left: 30px;
}
.register_title_icon{
position: relative;
left: 15px;
}
.log_title{
position: relative;
left: 30px;
}
.log_title_icon{
position: relative;
left: 15px;
}
.list_title{
position: relative;
left: 30px;
}
.list_title_icon{
position: relative;
left: 15px;
}
#register_field {
margin-left: 50px;
padding-right: 100px;
}
#log_field {
width: auto;
margin-left: 0px;
margin-bottom: 15px;
}
#list_field {
width: auto;
margin-left: 0px;
margin-bottom: 15px;
}
database.php
1.監視対象データを受け取って保存処理する。
2.1レコード毎に受け取って連続追加保存するので,サーバー負荷等の状況によりレコード抜けが発生するのでスリープを入れて保存遅延させている。
3.以下の4ファイルは,(ヤマハルーターのPoE監視デモ改造時)のものをそのまま使用
<?php
/* database.php */
usleep(1000);
$fileName='database.txt';
$data=$_POST['post_data'] . "\r\n";
file_put_contents($fileName, $data, LOCK_EX | FILE_APPEND);
?>
dataclear.php
<?php
/* dataclear.php */
$fileName='database.txt';
file_put_contents($fileName,"");
?>
logfile.php
<?php
/* logfile.php */
usleep(2000);
$fileName='logfile.txt';
$logdata=$_POST['post_log'] . "\r\n" . file_get_contents($fileName);
file_put_contents($fileName, $logdata, LOCK_EX);
?>
logclear.php
<?php
/* logclear.php */
$fileName='logfile.txt';
file_put_contents($fileName,"");
?>
execute.php
1.サーバーコマンド実行用
2.’arp -a’コマンドは結果取得後,データ処理して戻り値として返す。
3.その他コマンドはnWOLc.exe(nwolc-p,nwolc -m)を処理する。
4.Windowsコマンドの’arp -a’を入力するので,パスを通す(Path:C:\Windows\System32)5.「nWOLc.exe」はこのファイルと同じフォルダーに保存する。
5.「nWOLc.exe」はphpのルートフォルダーに保存する。( 例:D:\Program Files\php)
<?php
/* execute.php */
$cmd = $_POST['post_cmd'];
$table = array();
$result;
exec($cmd, $opt , $return_ver);
if ($cmd == 'arp -a'){
foreach ($opt as $line) {
if (preg_match('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*([0-9a-f]{2}[\-:][0-9a-f]{2}[\-:][0-9a-f]{2}[\-:][0-9a-f]{2}[\-:][0-9a-f]{2}[\-:][0-9a-f]{2})/i', $line, $matches)) {
$ip = $matches[1];
$mac = strtoupper(str_replace(array('-', '.'), ':', $matches[2]));
$table[$ip] = $mac;
}
}
/* arp -aの実行結果を配列で返す */
$result = $table;
}else {
/* 実行結果と戻り値を配列で返す */
$result=array(
0 => $opt,
1 => $return_ver
);
};
echo json_encode( $result ) ;
return;
?>
datasort.php
1.ソート機能をwindowsのsortコマンドで処理している。
2.IPアドレスのセパレーターを削除したものをキーとして追加し,ソート用ファイルに保存・ソート後,追加したキーを削除してデータベースに保存し直している。
3.Windowsのsortコマンド前後にタイミング遅延のためスリープを入れている。
<?php
/* datasort.php */
// $sleeptime = '20000'; // マイクロ秒 1,000,000=1秒
$fileName='database.txt';
$sortfile='sortfile.txt';
$spos = array();
$epos = array();
$ipadr = array();
/* ソートファイルクリア */
file_put_contents($sortfile, "");
/* データファイルから呼び出してソートキー(先頭12桁)を追加してソートファイルに保存 */
/* ファイルポインタをオープンしファイルを1行ずつ出力 */
$file = fopen($fileName, "r");
if($file){
while ($data = fgets($file)) {
$data = mb_convert_encoding($data,"SJIS-win","utf-8"); // UTF-8からシフトJISに変換
/* ipアドレス取り出し */
$wdata = $data;
$posip = strpos($wdata, ',');
$ipaddr = substr($wdata, 0, $posip);
$ipadr[1] = $ipaddr;
$spos[1] = 0;
/* セパレーター単位で個別取り出し */
for ($i = 1; $i <= 4; $i++) {
$wdata = $data;
$bi = $i - 1;
$ai = $i + 1;
if ($i < 4){
$epos[$i] = strpos($ipadr[$i], '.');
}else{
$epos[$i] = strpos($ipadr[$i], ',');
};
if ($epos[$i] == false){
$epos[$i] = 3;
};
if ($i > 1){
$spos[$i] = $epos[$bi] + 1;
};
$ipadr[$i] = substr($wdata, $spos[$i], $epos[$i]);
$wdata = $data;
$epos[$i] = $spos[$i] + $epos[$i];
$ipadr[$ai] = substr($wdata, $epos[$i] + 1, 3);
}
/* 3桁で0埋め ゼロパディング*/
$ipaddr01 = str_pad($ipadr[1], 3, 0, STR_PAD_LEFT);
$ipaddr02 = str_pad($ipadr[2], 3, 0, STR_PAD_LEFT);
$ipaddr03 = str_pad($ipadr[3], 3, 0, STR_PAD_LEFT);
$ipaddr04 = str_pad($ipadr[4], 3, 0, STR_PAD_LEFT);
/* データ結合 ソートキーを先頭12桁に追加 123.456.7.8 >>> 123456007008 */
$ipaddr0 = $ipaddr01 . $ipaddr02 . $ipaddr03 . $ipaddr04;
$sortdata = $ipaddr0 . $data;
/* ソートファイルに保存 */
file_put_contents($sortfile, $sortdata, LOCK_EX | FILE_APPEND);
}
}
usleep(2000);
/* ソート */
$cmd = "SORT " . $sortfile . " /O " . $sortfile;
exec($cmd);
usleep(10000);
/* データーファイルクリア */
file_put_contents($fileName,"");
/* ソートファイルから1行ずつ呼び出してソートキー(先頭12桁)削除して保存 */
$file = fopen($sortfile, "r");
if($file){
while ($sortline = fgets($file)) {
$sortline = mb_convert_encoding($sortline,"utf-8","SJIS-win"); // シフトJISからUTF-8に変換
file_put_contents($fileName,substr($sortline, 12), LOCK_EX | FILE_APPEND);
}
}
?>
ダウンロードファイル一覧
ヤマハのホームページからダウンロードしたpoe_demo.zipを解凍
1 camera.png
2 custom.css 変更あり
3 database.txt 4 deletelog.lua 不要
5 index.html wol.htmlに名称変更6 jquery-1.11.1.min.js 不要
7 kconv.lua 不要
8 kconv_utable.lua 不要
9 log.lua 不要
10 log.png
11 logo.png12 logout.html 不要
13 logout.js 不要
14 monitor.js wol_monitor.jsに名称変更15 ping.lua 不要
16 register_icon.png17 save.lua 不要
18 skeleton.png
流用(ヤマハルーターのPoE監視デモ改造時のものをそのまま使用)
database.php
dataclear.php
logfile.php
logclear.php
新規作成
execute.php コマンド実行用
datasort.php ソート処理用
考察
元々完成されたコードがあったので,比較的簡単に作成できた。_(._.)_
外部からLAN内機器へPINGを送信できないので,WOL機能よりLAN内機器の稼働状況の確認用としての用途のほうが多いと思う。
ルーターへログオンが必要な従来システムでは外部からVPNを通してからでないと使用できないので,Word Pressに埋め込んでのほうが使い勝手がよい。ただしセキュリティ対策は必要。
javascriptのコードにベーシック認証用のユーザーidとパスワードを記載しており,ソースコードの閲覧で見られてしまうため,Word Pressに埋め込む際はページにパスワード設定するか,ベーシック認証が必要なページに埋め込む必要がある。wolフォルダーにベーシック認証を設定すれば,ページ表示時に認証要求されるので,認証が通らないと画面表示されない。