2018/03/15

Recent entries from same category

  1. Go 言語プログラミングエッセンスという本を書きました。
  2. errors.Join が入った。
  3. unsafe.StringData、unsafe.String、unsafe.SliceData が入った。
  4. Re: Go言語で画像ファイルか確認してみる
  5. net/url に JoinPath が入った。

pingを打つと「にゃーん」を返すサービス、ネットワークエンジニアが開発 - ITmedia NEWS

関連記事 メイドさんと一緒に学ぶ「週末プログラミングスクール」開校 そこに隠された2つの社会的意義 一見、華やかな場の創造に見えるこの取り組みだが……。 太田智美がなんかやる:WWDC冒頭で、クックC...

http://www.itmedia.co.jp/news/articles/1709/07/news106.html

ping を打ったら「にゃーん」と文字が表示されるサービス。ICMP でメッセージを送信したら応答を返す、普通のプロトコルなのだけど、文字のドットが存在する部分だけタイムアウトエラーが発生するという物。どうしてもこれを Windows でしかも golang で実行したかったので作ってみた。golang にも ICMP プロトコルを扱うパッケージが用意されている。

icmp - GoDoc

Package icmp provides basic functions for the manipulation of messages used in the Internet Control Message Protocols, ICMPv4 and ICMPv6.

http://godoc.org/golang.org/x/net/icmp

送信は icmp.Message という struct に icmp.Echo を設定し、メッセージとして(なんでもいいのだけど) HELLO(R-U-THERE) を送信します。

wm := icmp.Message{
    Type: ipv4.ICMPTypeEcho,
    Code: 0,
    Body: &icmp.Echo{
        ID: os.Getpid() & 0xffff, Seq: i,
        Data: []byte("HELLO-R-U-THERE"),
    },
}
wb, err := wm.Marshal(nil)
if err != nil {
    log.Fatalf("Marshal: %v", err)
}
if _, err := c.WriteTo(wb, &net.IPAddr{IP: ip.IP}); err != nil {
    log.Fatalf("WriteTo: %v", err)
}

受信は 0.1 秒のタイムアウトを付け、時間切れもしくはレスポンス異常であれば U を、正常であれば ! を表示します。

c.SetReadDeadline(time.Now().Add(timeout))
rb := make([]byte1500)
n, _, err := c.ReadFrom(rb)
if err != nil {
    fmt.Print("U")
else {
    rm, err := icmp.ParseMessage(ipv4.ICMPTypeEcho.Protocol(), rb[:n])
    if err == nil && rm.Type == ipv4.ICMPTypeEchoReply {
        fmt.Print("!")
    } else {
        fmt.Print("U")
    }
}

文字幅が 70 桁を超えれば改行します。

にゃーん

うまく表示する事が出来ました。コードは以下に置いておきます。適当に改造するなりして遊んで下さい。尚、IP プロトコルを使うので実行には管理者権限が必要です。

GitHub - mattn/nyan-ping

にゃーん

https://github.com/mattn/nyan-ping
Posted at by | Edit