Haskell でリンクレイヤーにおける ICMP パケットの構築, 送受信および解析による ping の実装

Haskell で低レイヤーのネットワークプログラミングをそういえばしたことがなかったので, 何か実装してみたかったのだが特別ネタも思いつかないので, とりあえずイーサヘッダ, IP ヘッダ等を含む, 生の ICMP Echo/Reply パケットを扱ってみることとした.

ICMP パケットは IP パケットであるので, 通常は ICMP パケット部分のみを構築してPF_INET等で開いたソケットに送りつけたり, recv 等すれば送受信においては必要十分であるが, これではあまり面白みがないので, リンクレイヤーから扱うこととした.

生の ICMP パケットを扱うということは, ICMP データの自作はもちろん, イーサヘッダ, IP ヘッダの自作が必要となる. またイーサヘッダを自作するということは, MAC アドレスを解決しなければならないので, 最低限 ARP パケットの送受信および解析機能の自作が必要となることを意味する. ARP パケットの自作を要するということは, デフォルトゲートウェイやサブネット環境などを取得する機能も必要である. これらを自作してみた.

Read More...

Haskell で D-Bus から systemd unit を制御する

D-Bus とはメッセージバスシステムであり, アプリケーション間で互いにやりとりを行うためのプロセス間通信実装の 1 つである. システムデーモン(新しいハードウェアデバイスの追加やプリンタキューの変更などのイベント等)と, ユーザー単位のログインセッションデーモン(ユーザーアプリケーション間の一般的なIPC)を提供する1.

現代的な Linux カーネルの init プロセスにて起動される systemd デーモンおよびその補助デーモンは, D-Bus にいくつかの API を公開している. 私の観測範囲内において, C や Python, Go 等でこれらを利用する例はそこそこ見たことがあるのだが, Haskell での取り組みは一切見たことがなかったので, 少々これらで遊んで見た日記として本エントリに記す.

Read More...

エルガマル暗号

エルガマル暗号が離散対数問題の応用であることは認知していたものの, きっちりと自分でまとめたことが無かったと思うので, それに関連する諸々の前提についてもふまえて, 一度書くことにした. また, その処理系を実装した. 本エントリでは, 同暗号プロトコルの話の前にまず前提を示し, その後, 実装の観点から見た要点を示す.

Read More...

amazonka で EC2 インスタンスの操作

以前のエントリ1では, AWS の API を golang から叩くために golang の言語機能を一通り触った. 自分は元々よく C++ を書いていたので golang で叩く前にまず C++ から適当に叩いてみていたのだが, ふと Haskell 用の AWS のライブラリの存在を知り, ひとまず触ってみたので, 記録と紹介を兼ねて書き残してみる. 執筆時現時点では, 公式が提供する AWS SDK は awscli を除き C++, Go, Java, javascript, .NET, PHP, Python, Ruby 2となっており, amazonka3 は非公式の Haskell 用 AWS SDK である. 基本的には, まず amazonka を導入した後, 必要となる AWS サービスに該当する amazonka-** を導入する. 今回は, ec2 インスタンスの立ち上げ, 停止を行なったので, amazonka-ec24 を利用した. amazonka は全体のデータのやり取りに Lens を多様しており, 利用者はこの恩恵を傍受できる.

早速であるが, くだらないサンプルを次に示す. とくにいま ec2 インスタンス上で何かしたいことはないので, 東京リージョンでインスタンスを立ち上げて, その直後に落とすこととする5.

module Main where
import qualified Network.AWS as AWS
import qualified Network.AWS.Data as AWSD
import qualified Network.AWS.EC2 as EC2
import System.IO (stdout)
import Control.Lens

instanceIds :: String
instanceIds = "i-********"

main :: IO ()
main = do
    let t0 = EC2.startInstances & EC2.sInstanceIds .~ [AWSD.toText instanceIds]
    let t1 = EC2.stopInstances & EC2.siInstanceIds .~ [AWSD.toText instanceIds]
    env <- AWS.newEnv (AWS.FromFile (AWSD.toText "default") "/path/to/credentials")
    lgr <- AWS.newLogger AWS.Debug stdout
    res0 <- AWS.runResourceT $ AWS.runAWS (env & AWS.envLogger .~ lgr) $ AWS.within AWS.Tokyo $ AWS.send t0
    res1 <- AWS.runResourceT $ AWS.runAWS (env & AWS.envLogger .~ lgr) $ AWS.within AWS.Tokyo $ AWS.send t1
    print res0
    print res1

本家の各 SDK と同じように, 必要なサービスごとにライブラリがそれぞれ独立しているので, 基本的にまずは AWS CLI Command Reference をみてから, その操作を行うのに必要とするライブラリを amazonka から選んで導入することで, 実際に動くまでを円滑に進めることができるだろう.

参照


  1. roki (2018)「golang 始めたてメモ」/roki.log/2018/06/17/golangtrial/\url{/roki.log/2018/06/17/golangtrial/}↩︎

  2. 「AWS SDK とツール」https://aws.amazon.com/en/getting-started/tools-sdks/ 2018 年 6 月 24 日アクセス.↩︎

  3. 参照.↩︎

  4. 参照.↩︎

  5. 前提として, AWS IAM の設定およびアクセスキーの設定が済んでいること.↩︎


De Bruijn Sequence

大学のレポート内で De Bruijn Sequence について書く機会があった. これまた以前と同じく, 折角なのでこちらのブログにも, 若干内容を変えつつ載せておくことにした.

De Bruijn Sequence は, オランダ人の数学者 Nicolaas de Bruijn に因んで命名された系列で, 特定の長さのすべての組み合わせを含む系列である. 次数 nnkk 種類に関する De Bruijn Sequence B(k,n)B(k, n) は, 長さ nn で表現可能なすべての部分列によって構成される. 次元数 22 (すなわちバイナリ) の De Bruijn Sequence は B(2,n)B(2, n) であり, nn ビットの固有な部分系列から成る 2n2^n ビット長の系列である. 例えば, B(2,3)B(2, 3)00011101(2)00011101_{(2)} であり nn に対する有向グラフが下図1のように示される.

De Burijn Sequence B(2,n)B(2,n) の有向グラフ
Read More...