読者です 読者をやめる 読者になる 読者になる

non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

WindowsだけでAmazon DashボタンのMACアドレスを取得できるjsを書いた

こんばんは。先日、保育園から習い事の教室に向かう際、以前、習い事の教室のトイレが故障しており、難儀したことがあり、かなり強く長男に、保育園で事前にトイレに行っておけと言ったのをすっかり忘れてましたが、長男はちゃんとそれを実践しており、感心したkjunichiです。

背景

LinuxMacだと、npmモジュールのnode-dash-buttonに付属のfindbuttonで Amazon DashボタンのMACアドレスが簡単に取得できる。

しかし、Windowsだと、このモジュールがWindowsに対応していないようで、 ビルドエラーとなり使えません。

代わりに当ブログでも何度か紹介しているwin-node-dash-button がつけるのですが、MACアドレスの検出のプログラムは付属していない。

MacLinuxが使えない環境だとこのMACアドレスを取得するところでつまずいて残念なことになる。

http://tanbonomannaka.hatenablog.com/entry/2016/12/18/204217tanbonomannaka.hatenablog.com

なんて記事をたまたま見つけたから、ちょっと記事にしてみた。

つくった

パケットキャプチャー関連の知識がなかったので、勉強になった。 Cだとこの手のプログラムは面倒な印象を持っているが、Node.jsだと思った通り、わかりやすかった。 結局、win-node-dash-buttonのコードを少し手を入れるだけでよかった。

"use strict";

const Cap = require('cap').Cap,
    decoders = require('cap').decoders,
    _ = require("lodash"),

    Server =  function() {
        const self = this,
            savedMacAddr={},
            lastUpdate ="",
            cap = new Cap(),
            buffer = new Buffer(65536);

        this.packetReceived = (nbytes, trunc) => {
            const ret = decoders.Ethernet(buffer);
            if (ret.info.type === 2054) { // arp
                if(! savedMacAddr[ret.info.srcmac]) {
                    console.log(ret.info.srcmac);
                    savedMacAddr[ret.info.srcmac] = true;
                }
            }
        };

        this.start = (ip) => {
            const device = Cap.findDevice(ip),
                linkType = cap.open(device, "", 10 * 1024 * 1024, buffer);

            try {
                cap.setMinBytes(0);
            } 
            catch (e) {
                console.log(e);
            }

            cap.on("packet", self.packetReceived);

            process.on("SIGINT", self.stop);
        };

        this.stop = () => {
            console.log("Shutting down");
            cap.removeListener("packet", self.packetReceived);
            cap.close();
        };
    };

const srv = new Server();
srv.start('192.168.0.2'); // 192.168.0.2は動かすホストのIPアドレス

CapというnpmモジュールがUnix系だとlibpcapを使い、Windowsだとwinpcapを同梱しており、これを組み込むことで、 マルチプラットフォームでパケットキャプチャーを実現している。

自分のPCのIPアドレスもわからない場合

以下のような感じで、できたが、どんな環境でも動かくは不明。 osというNode.js標準モジュールで実装している。

const os = require('os');
nifs = os.networkInterfaces();
for(let nif in nifs) {
    if(nif.startsWith("Virtual")|| nif.startsWith("Loopback")) {
        continue;
    }
    //console.log(nif);
    for(let ad in nifs[nif]) {
        if(nifs[nif][ad].family == 'IPv4') {
            //console.log(nifs[nif][ad]);
            console.log(nifs[nif][ad].address);
        }        
    }
}

まとめ

Windows環境だとnode-dash-buttonではなく、win-node-dash-buttonを使う。 MACアドレスの取得は、win-node-dash-button付属のコードをちょっと変更するか、 この記事の検出用のコードを利用する。