29-Sep-2022
[なかなかまとまりません]

SLIPのコードをいじって、AX.25/KISSのヘッダの挿入/削除をできるようにしています。後から見直すと大した改造ではないのですが、なるべく元のコードをいじらず、機能が不要な時に無理なく外せるように追加するのはなかなか難しいものです。

この改造では単純にヘッダの挿入/削除しか対応していないため、CSLIP(RFC1144)のようにIPヘッダを圧縮/伸長するケースには対応できません。また、RFC1144ではIPv6に対応できないため、RFC2507もしくはその後継にも目を通さないといけないのですが…今はAX.25の方を優先させたいのでCSLIPは考慮しません。

気付いたらスマホがなんとなく膨れていて、案の定LiPo電池の問題でした。電池だけ入手して交換できれば良いのですが、難しそうなので端末の買い換えが必要になりそうです(この状況での出費はかなり痛い)。買ってから3年近くが経過していれば、部材の入手が難しいのも仕方がないのでしょうか。56.4kg(07:45)

02-Oct-2022補足:結局こんな感じになりました。ヘッダ用の小さな作業バッファを用意したので、そこに収まるならそちらに書き出せば良いし、そうでなければ別途作業バッファを(staticに)確保してそちらのポインタを返せば良い…そんな作りです。

19-Sep-2022
[うーん]

SLIPによるデータ転送を行うコードに、少し味を付ければKISS TNC越しにTCP/IPを流せるんじゃないかなーと考えていたのですが、なかなか進みません。

おそらくこんな感じの処理を追加すれば良いはずなのですが…

送信
TUNデバイスから得たIPパケットから送り先のIPアドレスを取り出し、これをキーにしてコールサインを検索する。自局/相手局コールサインおよびその他必要な項目をAX.25ヘッダとして作成し、IPパケットの前に追加する。送り先のIPアドレスに対応する相手局コールサインが見つからなかった場合、送信せずにdropするか、設定次第ではCQ等適当なコールサイン宛に送信する。
受信
受信したSLIPフレームからAX.25ヘッダ(可変長)およびIPパケットを切り出す。パケットを送信したIPアドレスと、相手局コールサインが一致していた場合はIPパケットをTUNデバイスへ送信する。不一致の場合にdropするか、受信するかは設定次第。

IPアドレスとこれに対応するコールサイン(+その他必要な情報)を記述した設定ファイルを、どういう体裁で作るかも考えないといけません。そもそもこのアイデアで動くかどうかも分かりません…どこから取りかかれば良いものか。56.3kg(22:15)

09-Sep-2022
[Debian-11.4でのNFSおぼえがき(2)]

10-Aug-2022の続き。実際に運用してみると意外にpermission deniedに遭遇する場面が多く、マシン間でUID/GIDを統一する必要があるという結論になりました。nfsdでall_squashオプションを指定しているので、anonuid, anongidに対応するものを用意すれば十分。

とはいえ…/etc/{passwd,group}を見るに、どの辺りが空いているかを調べるのもなかなか面倒です。nobodyやnogroup辺りのUID/GIDが値としては最大なのかなーと思っていたのですが、

nobodyのUID
99
Void Linux, Slackware
32767
NetBSD, OpenBSD
65534
Arch Linux, Debian, FreeBSD, DragonflyBSD
nobodyのGID
39
NetBSD
98
Slackware
32767
OpenBSD
65534
Arch Linux, FreeBSD, DragonflyBSD
なし
Debian, Void Linux
nogroupのGID
99
Void Linux, Slackware
32766
NetBSD, OpenBSD
65533
FreeBSD, DragonflyBSD
65534
Debian
なし
Arch Linux

65000を使うのが妥当かどうかは何とも言えないので、32000にします。shellもnobody準拠…といきたいところですが、

nobodyのshell
/bin/false
Void Linux, Slackware
/sbin/nologin
DragonflyBSD, NetBSD, OpenBSD
/usr/bin/nologin
Arch Linux
/usr/sbin/nologin
Debian, FreeBSD

こんな感じにしっちゃかめっちゃかです。nologin, falseをwhichで確認するに、

nologinの所在
/sbin/nologin
Void Linux, Slackware, FreeBSD, DragonflyBSD, NetBSD, OpenBSD
/usr/bin/nologin
Arch Linux
/usr/sbin/nologin
Debian
falseの所在
/sbin/false
Void Linux
/usr/bin/false
Arch Linux, Debian, Slackware, FreeBSD, DragonflyBSD, NetBSD, OpenBSD

これもバラバラ。とはいえ、ここに挙げているLinux distroは/bin/falseと/usr/bin/falseと/sbin/nologinが通ります。ArchとVoidは/sbin/false, /usr/sbin/false, /bin/nologin, /usr/bin/nologinにも対応し、Slackware, NetBSD, OpenBSDは/usr/sbin/nologinに非対応です。/sbin/nologinもしくは/usr/bin/falseのどちらかを使えば良さそうです。

さて、これからやるべきことは単純に…

これを各OS毎に設定していくことなのですが、useraddが使えないケースもあったりオプションの指定も微妙に違っていたりとなかなかに厄介です。

まずは仮想マシンのホスト機兼NFSサーバのDebianから。rootでログインしている場合は/sbinへのパスが通っていますが、su等で他のユーザからrootに化けた場合は/sbin/addgroupとフルパスで呼び出す必要があります(haltですら/sbin/haltとしないと呼べないので面倒くさい…)。

Debian
/sbin/addgroup --gid 32000 export; /sbin/adduser --system --home /export ---no-create-home --uid 32000 --gid 32000 --disabled-password --disabled-login export; /sbin/adduser <自分のアカウント> export

あとは/etc/exportsのanonuidとanongidをそれぞれ32000に修正。/sbin/useradd, /sbin/groupaddも持っているようですが、これは他のLinux distroで試します。うっかり間違っちゃった場合は/sbin/groupdelなり/sbin/userdelなり使えば良いでしょう。

あとは他の仮想マシンを設定していきます。

NetBSD, OpenBSD, Slackware, Arch Linux, Void Linux
groupadd -g export 32000; useradd -d /export -g 32000 -s /sbin/nologin -u 32000 export

SlackwareやOpenBSDにはadduserがあるものの、Debianのようにグループへユーザを追加する機能を持ちません。そのために、/etc/group(とLinux系OSは/etc/gshadow)を編集してexportグループにユーザを追加します。NetBSDとOpenBSDは/etc/groupをvi等で直接編集し、Slackwareではvigr, vigr -s、Arch LinuxおよびVoid Linuxはvigr(/etc/group編集後に/etc/gshadowの編集に移ります)を使用してください。

FreeBSD, DragonflyBSD
pw groupadd export -g 32000; pw useradd export -d /export -g 32000 -s /sbin/nologin -u 32000; pw groupmod export -M <自分のアカウント>

FreeBSDとその派生であるDragonFlyBSDに関しては、ユーザとグループの管理はpwコマンドに集約されているのでこれを使います。グループへのユーザの追加もコマンドラインから行えますが、groupmodである点に注意して下さい。

これでもまだ時折permission deniedを起こすことがあるのですが、発生する頻度が減ったことで使い勝手は上がっているので、のんびり原因を調べていこうと思います。57.5kg(08:05)

07-Sep-2022
[Linux AX.25おぼえがき]

Debianだと、apt-get install direwolf ax25-tools ax25-appsでビルド済みのdirewolfやら他必要な物一式が入ります。本当はdirewolf.confを作成する必要があるのだけど、ひとまず無視します。

ipコマンドでaddress maskを指定しないとテスト用のパケットすら出ていかないような感じです。tcpdumpのログdirewolfのログを見るに、「自分>自分」なUIフレームを投げているのがすごく気になります。

LinuxならAX.25のスタックが入っている以上デジピーター等を使用した転送制御もちゃんとできる筈なので、相手が分かっていれば「自分>相手」になるのではないかと期待しているのですが…なにしろこれが動いている現場を見たことが無いもので。57.5kg(19:45)

04-Sep-2022
[車輪の再発明してました(2)(ソケット周りおぼえがき)]

TUNデバイス越しにSLIPを喋る例のアレ、KISS over TCP/IPへの布石としてSLIP over TCP/IPなる謎機能を追加していました(とはいえHP AdvanceStack 100Base-T Hubs and Switch Modulesの説明書(PDF)にはSLIP over TCP/IPなる言葉が散見されるのでとんちんかんなものではないと思う)。ソケット使ったコードを真面目に書くのは結構大変だったので、その愚痴メモを。

コードの書き方を分かっている人なら「そんなところで引っかかったのか」という話なので笑って読み飛ばして頂ければと(むしろつまづきのレベルが低すぎて笑えないかも)。

socket()の戻り値とaccept()の戻り値
これちゃんと理解している人なら迷いませんよね、同じモノじゃないです。OpenBSDのmanにあるsocket(2)の戻り値の説明は"If successful, socket() returns a non-negative integer, the socket file descriptor."、accept(2)は"If successful, accept() and accept4() return a non-negative integer, the accepted socket file descriptor."とあり、acceptedの有無の違いで違うものを示しています
ノンブロッキングにしたsocket()に対するaccept()後の挙動
LinuxのMan page of ACCEPTの準拠の項を参照。O_NONBLOCKしたソケットに対するaccept()を行うと、その新しいソケットに対してLinuxではO_NONBLOCKが解除されているのに対し、OpenBSDではO_NONBLOCKが設定されたまま。なので、accept()で得られた新しいソケットに対しては、必要に応じO_NONBLOCKを設定/解除しましょう。
poll()あるいはselect()によるaccept()待ち
待ちを抜けたからといってaccept()をしてくれている訳じゃなく、抜けた後にaccept()しなければ物事は進みません。getpeername()で接続先が得られずおかしいなと何度首を傾げたことか。

とりあえず基本的な骨子はこれでできたと思うので、あとはKISS(AX.25)向けの味付けを考えていくことになります。その前に、LinuxはAX.25上でどうTCP/IPを喋っているのかを見ないといけないのですが…設定方法がよく分からないんですよね…それ以前に現在でも動くのかなコレ…56.3kg(10:05)