memo.log

技術情報の雑なメモ

Amazon VPCでパケットのヘッダ内のチェックサム値が誤っていると宛先ホストに届く前にドロップされる

RAWソケットのプログラミングをしていた時に表記の仕様に気がついた。 チェックサムのフィールドをとりあえず適当に埋めていたらVPC内(同一サブネット)の宛先ホストに届かなかった。 どうやらVPC内でドロップしているもよう。

rb_tuntap(x86用Native Extensionのgem)をARM版にして手元でインストールする

github.com

を使いたいのだが、手元の環境がARMで、Native Extensionで普通に公開されているのがx86_Linux用だった。↓

rb_tuntap | RubyGems.org | your community gem host

Native Extension はプラットフォーム別に公開されるようで、x86_Mac用のは別の人がアップしてくれていた。

search | RubyGems.org | your community gem host

そこでARM用のをコンパイルして使うまでのメモ。 作者がよければ公開してもいいのだけど、とりあえずローカルインストールすることにする。

手順メモ

リポジトリのソースをDLして、Rakefileのあるディレクトリで、

% gem install rake-compiler # なければ。
% rake build
% gem install pkg/rb_tuntap-0.2.0-aarch64-linux.gem # バージョンが違ったら適宜読み替えること

あとは普通に require できる。

 % irb                                                                              (git)-[master] 
irb(main):001:0> require "rb_tuntap"
=> true
irb(main):002:0> tun = RbTunTap::TunDevice.new("tun0")
=> #<RbTunTap::TunDevice:0x0000000030f1a128 @name="tun0", @type=1, @dev="/dev/net/tun", @fd=-1>

※ sudo で実行するときは sudo gem install する必要がある

参考

qiita.com

qiita.com

IP over DNS を実現する iodine を試してみたメモ

メモ

  • サーバ
  • クライアント
    • WSL
    • 実IP: 192.168.201.105

サーバ手順

$ sudo apt-get install iodine
$ sudo iodined -f 192.168.1.100/24 example.com
Enter password:
Opened dns0
Setting IP of dns0 to 192.168.1.100
Setting MTU of dns0 to 1130
Opened IPv4 UDP socket
Listening to dns for domain example.com

別ウィンドウで ifconfig するとVPN用のインターフェースが上がるのが確認できる

dns0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1130
        inet 192.168.1.100  netmask 255.255.255.224  destination 192.168.1.100
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ルートにもエントリが追加される

 $ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.150.1   0.0.0.0         UG    304    0        0 wlan0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 dns0
192.168.150.0   0.0.0.0         255.255.255.0   U     304    0        0 wlan0

クライアント手順

$ sudo apt-get install iodine
$ sudo iodine -f -r kure10 example.com

クライアント側も仮想IFが立ち上がる。

dns0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1130
        inet 192.168.1.97  netmask 255.255.255.224  destination 192.168.1.97
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1  bytes 48 (48.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ちなみにルートテーブルにもエントリが追加されてる。

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         KURE-EXPERTBOOK 0.0.0.0         UG    0      0        0 eth0
192.168.1.96    0.0.0.0         255.255.255.224 U     0      0        0 dns0
192.168.192.0   0.0.0.0         255.255.240.0   U     0      0        0 eth0

クライアントは立ち上げるときに指定した仮想IFのアドレスに疎通ができるようになる。

$ ping 192.168.1.100

動作確認

クライアント(WSLのIF)でのキャプチャ。 DNSで見えてるけど、データ部のところでICMPぽいデータが送られているのがわかる。

f:id:kuredev:20210516014207p:plain

参考

github.com

code.kryo.se

『オブジェクト指向設計実践ガイド』第4章メモ

第4章のメモ。 第4章はクラス間のメッセージに焦点を当てた設計方法。とてもおもしろく、勉強になったのだが、サンプルコードがほしいところだった。読みながら図4-5 ~ 4-7 をコードにおこしてみたのだが、こんなイメージかしら?

# 図 4-5
class Trip
  @bycycles
  mechanic

  # 旅行が開始されるために、使われる自転車がすべて整備されていることを確実にする
  def prepare_trip
    @bycycles.each do |bike|
      mechanic.clean_bycle(bike) # 自転車を洗浄する
      mechanic.pump_tires(bike) # 空気を入れる
      mechanic.lube_chain(bike) # チェーンに油を差す
      mechanic.check_brakes(byte) # ブレーキをチェックする
    end
  end
end

# 図4-6
class Trip
  @bycycles
  mechanic

  # 旅行が開始されるために、使われる自転車がすべて整備されていることを確実にする
  def prepare_trip
    @bycycles.each do |bike|
      mechanic.prepare_bicycle(bike)
    end
  end
end

# 図4-7
class Trip
  @bycycles
  mechanic

  # 旅行の準備が必要なことに自転車が必要なことすら知らなくて良い
  def prepare_trip
    mechanic.prepare_trip(self)
  end
end

クラスに基づく設計から、メッセージに基づく設計への移行が、設計者としてのキャリアの転機となります。

.

メニューを使えば、厨房が「どのように」料理をつくるかは一切感知させずに、「何を」望むかをお客さんに頼ませることができます。[...]自身の書くクラスはそれぞれが厨房のようなものです。

.

旅行が準備されなければいけないという知識は、間違いなく、そして正当に、Tripの責任の領域です。しかし、「自転車」が必要だという事実は、おそらくMechanicの領域に属します。

.

Tripは単にprepare_trip を送るためのオブジェクトを保持しているだけです。このメッセージの受け手を信頼し、適切に振る舞ってくれることを期待しています。この考えをさらに広げてみましょう。Tripはそのようなオブジェクトを配列内にいくつもおいて、それぞれにprepare_trip メッセージを送ることもできそうです。このとき、Tripは準備してくれるオブジェクトが何をしようとも、そのオブジェクトを信頼しています。準備をしてくれるオブジェクトがやることだからです。

TUN/TAPについて調べるメモ

コードはここ。

drivers/net/tap.c

drivers/net/tun.c

詳細はこれから。 TUNには net_device_ops とかネットワークドライバっぽいリソースが見えるけどTAPにはそれらが見当たらない。 cdev_init とかキャラクデバイスドライバっぽい?

Raspberry Pi 4でネットワークドライバにデバッグ用の一行だけ追加するメモ

Raspberry Pi 4の有線LANのインターフェースのドライバに一行加えてパケットを送信するためにログ出力するように改造してみたメモ。

NICはどうやら Broadcom 2711 というSoCに付いているもの?のようで参考リンクに記載がある。

手順

一行追加

以下に一行追加

drivers/net/ethernet/broadcom/genet/bcmgenet.c

linux/bcmgenet.c at 96110e96f1a82e236afb9a248258f1ef917766e9 · raspberrypi/linux · GitHub

int i;

pr_info("====bcmgenet_xmit\n"); // ★追加
index = skb_get_queue_mapping(skb);

カーネルビルド

以下でビルド

Raspberry Pi 4 のカーネルビルドの最低限の手順メモ - memo.log

確認

LANケーブルを接続して少し通信させてみると、↓の通り、パケットが送信されるたびに一行出力される。

$ sudo tail -f /var/log/kern.log
May  3 15:28:23 kure10 kernel: [  341.514906] bcmgenet fd580000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
May  3 15:28:23 kure10 kernel: [  341.514959] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
May  3 15:28:23 kure10 kernel: [  341.554601] bcmgenet: ====bcmgenet_xmit
May  3 15:28:23 kure10 kernel: [  341.594867] bcmgenet: ====bcmgenet_xmit
May  3 15:28:24 kure10 kernel: [  341.824589] bcmgenet: ====bcmgenet_xmit
May  3 15:28:24 kure10 kernel: [  342.154625] bcmgenet: ====bcmgenet_xmit
May  3 15:28:25 kure10 kernel: [  343.079368] bcmgenet: ====bcmgenet_xmit

メモ

もう少し送信時の処理を深堀りしてみたい。イーサネットコントローラの仕様とにらめっこしてドライバの仕事を確認してみたい。

参考

qiita.com →Raspberry Pi4搭載のSoCについてのまとめ記事