2008-12-23

MagicPacketを送るJAVAプログラム

外から Wake on Lan で PC を起動する試み…失敗でした の続き

匿名さんからルータのDHCPリース情報があればNATで直接クライアントPCのIPアドレスにWOLパケットを送れるのではないかとコメントがついていまして、試していなかったとコメント返したのですが…

よくよく考えたら最初に潰してました

いや、やったこと全てメモに残さないからこういう事になるんですけどね…

そもそもクライアントPCのIPアドレスは固定でないとアドレス変換の変換先が決まらないので、DHCPを使うなら固定IPの予約を入れておく必要があります。
なので、リース期間も何もないんですよ~

で、予想どおりと言いますか、クライアントPCのIPアドレスに変換する設定ではNATでの破棄はおこらないものの、クライアントPCまでパケットは届きません。
DHCPの情報とARPテーブルは連動していないようです。
なんとなくですが、これは連動しない実装が正解なんじゃないでしょうか?

ちなみにPCの電源を落とした直後であればちゃんと起動します。
これはARPのキャッシュが残っているからでしょう。

色々試してみるのにブロードキャストアドレス以外にMagicPacketを送る適当なツールが見あたらなかったのでJAVAで作って見ました。
ちなみに私はJAVAのお作法などに詳しくないため(というか全く知らない)おかしなところがあるかもしれません。

ファイルにしないでコードをここに直接乗せるのはファイルのアップロード先を確保するのが面倒だからです。
てなわけで、確認のために使ったJAVAプログラムは以下の通り。

ファイル名:JAVACUIWOL.java
//
// JAVACUIWOL.java
// JAVACUIWOL
//
// Created by nova on 08/12/20.
// Copyright (c) 2008 nova. All rights reserved.
//
import java.util.*;
import java.io.*;
import java.net.*;

public class JAVACUIWOL {
public static final int DEFAULT_PORT = 9; //デフォルトポートは9とする
public static void main (String args[]) {
try {
// 引数の数をチェック
if (args.length != 2) {
throw new IllegalArgumentException("引数の数が不正です");
}
String argHostStr = args[0];
String argMacStr = args[1];

// 引数からMACアドレスを取得する
byte[] macBytes = getMacBytes(argMacStr);

// 引数からIPアドレスを取得する
SocketAddress socketAddress = getHostSocketAddress(argHostStr);

// Magic Packet を作成する
byte[] magicPacketBytes = new byte[6 + 16 * macBytes.length];
for (int i = 0; i < 6; i++) {
magicPacketBytes[i] = (byte) 0xff;
}
for (int i = 6; i < magicPacketBytes.length; i += macBytes.length) {
System.arraycopy(macBytes, 0, magicPacketBytes, i, macBytes.length);
}

// Magic Packet を送信する
DatagramPacket packet = new DatagramPacket(magicPacketBytes, magicPacketBytes.length, socketAddress);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();

// 終了メッセージ
System.out.println(socketAddress + " へ Magic Packet を送信しました");
}
catch (Exception e) {
System.out.println("エラーが発生しました:" + e);
System.out.println("");
System.out.println("使い方");
System.out.println(" : java -cp JAVACUIWOL.jar JAVACUIWOL <host name>[:<port no>] <mac address<");
System.out.println("LAN上のPCを起動する場合にはブロードキャストアドレスで送ります");
System.out.println(" : java -cp JAVACUIWOL.jar JAVACUIWOL 192.168.0.255 01-23-45-67-89-AB");
System.out.println("DynDNSなどを使ってルータに送信する場合はホスト名でも送る事が出来ます");
System.out.println(" : java -cp JAVACUIWOL.jar JAVACUIWOL example.com 01-23-45-67-89-AB");
System.out.println("ポートの指定も可能です(デフォルトはUDP9)");
System.out.println(" : java -cp JAVACUIWOL.jar JAVACUIWOL example.com:9 01-23-45-67-89-AB");
System.exit(1);
}
}

private static byte[] getMacBytes(String argMacStr) throws IllegalArgumentException {
// MACアドレスの文字列を6個に区切る
String[] macHexStrs;
if (argMacStr.length() == 12) {
macHexStrs = new String[6];
for (int i = 0; i < 6; i++) {
macHexStrs[i] = argMacStr.substring(i*2, i*2+1);
}
}
else if (argMacStr.length() == 17) {
macHexStrs = argMacStr.split("(\\:|\\-)");
if (macHexStrs.length != 6) {
throw new IllegalArgumentException("MACアドレスの形式が不正です");
}
}
else {
throw new IllegalArgumentException("MACアドレスの形式が不正です");
}

// MACアドレスをバイト配列に変換する
byte[] macBytes = new byte[6];
try {
for (int i = 0; i < 6; i++) {
macBytes[i] = (byte) Integer.parseInt(macHexStrs[i], 16);
}
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("MACアドレスの形式が不正です");
}
return macBytes;
}

private static SocketAddress getHostSocketAddress(String argHostStr) throws IllegalArgumentException {
String[] hostStrs = argHostStr.split(":");
String hostName;
int portNo;
SocketAddress sa;

if (hostStrs.length == 1 ) {
hostName = hostStrs[0];
portNo = DEFAULT_PORT;
}
else if (hostStrs.length == 2) {
hostName = hostStrs[0];
try {
portNo = Integer.parseInt(hostStrs[1]);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("ホストのポート指定が不正です");
}
}
else {
throw new IllegalArgumentException("ホスト名の指定が不正です");
}

try {
sa = new InetSocketAddress(hostName, portNo);
return sa;
}
catch (Exception e) {
throw new IllegalArgumentException("ホスト名の指定が不正です");
}
}
}

使い方はテキストエディタで JAVACUIWOL.java を作成し、
javac JAVACUIWOL.java

で、コンパイル
java JAVACUIWOL <ホスト名> <MACアドレス>

で実行です。

恥ずかしい間違いを犯していなければよいのですが…自信ないなぁorz

2008-12-09

Mac OS X Leopard でネイティブ動作する GIMP2.6.3

実はGIMPをインストールしたもののほとんど使っていなかったりします(^^;)
今回は記録を取っていないので結果だけMacPortsでgimp-appをアップグレードできました
投げたコマンドすら記憶が…多分こんな感じだったと思います
sudo port -fR upgrade gimp-app
色々エラーも出たけどもう面倒になって全部スルーしてしまいました。

一応2.6.3がネイティブで動いていますが、ファイルをDrag&Dropで固まったり、Mac版固有の問題は多分そのままだと思います

ちなみにアップグレードすると日本語表示は出来ない状態に戻ってしまうので再度設定が必要です。
Mac OS X Leopard でネイティブ動作するGIMP2.6.2をインストールするでは
sudo vi /opt/local/share/gimp/2.0/themes/Default/gtkrc
としましたが、今回は
vi ~/.gimp-2.6/gtkrc
として、適当なところに
style "gimp-default-style"
{
font_name = "Osaka"
}
を追加しました
こっちの方が正解…かな?

2008-12-08

そういえばGearsって何の役に立ってるんだ?

Firefox の拡張機能 Google Gears を入れてますが

「DocsもReaderもオフラインで使えるようになってないよな?」
と、今頃気づきました(^^;)

今まで気づかなかったと言う事は別に必要ない機能だったっぽいですが、せっかく入れているのに使えないのは気分がよくない。
ヘルプを見てみると表示言語をEnglish(US)に設定すれば使える模様。
言われた通り設定したら状態を表すアイコンがSettingsの左に表示され、オフラインで使用できるようになりました。

ReaderもDocsもオフラインで使えるよってアナウンスを見てからかなり経ってる気がするんですが…
日本語版は対応する気がないのかな?

他の機能も日本語設定で使えるようになるまである程度期間がかかるし、他のサービスもまとめて英語表示で使う事にしました

2008-12-02

Google Chrome の Windows2000用インストーラ

Trac Lightning の表示が乱れると言う理由で Windows2000 に Safari をインストールしてみましたが微妙に遅い気がするので再び Google Chrome をインストールしてみる事にしました。

毎回お世話になっている黒翼猫さんの所にインストールようスクリプトがあったはず…

インストーラが配布されてる!! ∑( ̄□ ̄;)

Googleからダウンロードするところからインストールまで上から順にボタンを押していくだけってどこまで素敵なんですか!!

ボタン順番に押して再起動してみると…とっても快適に動きます



で、結局 Safari と Chrome どっちを使う事にするかかなり迷ってます
描画エンジンは同じ WebKit ですが、Safariの方はフォントが美しくスムージングされていて読みやすいんですよね
迷うなぁ…