ping localhost
mouseが老衰した
15年近く飼っているマウスが老衰した。女房がマウス欲しいと言って、猫のイラストが入ったパッドと一緒に買った物。スケルトンの小ぶりな奴。
こいつの動きが数日前から、すこぶる悪くなった。ただパソコンの周りを走り回っているだけで、無理はさせなかったんだけどな。老衰で光の発信が弱くなったのかな? で、乱反射の状況を網膜で上手く補足出来なくなったのだろう。
ならば、白黒はっきりするような現場に置いてみるか。藤色のパッドより、より黒いパッドが良いだろう。家の中見回しても黒色の表面が平板な物って、余り無いな。まさか、玉子焼き用のフライパンの裏を使う訳にもいかないしね。
借りてきている本の表紙が夜空の写真と言うのがあった。これを厚いマウスパッドと思って使ってみたら、キビキビと動き出した。応急処置だな。はて、今後はどうする?
ThinkPadなんで、マウスの代わりは、タッチパッドとかトラックポインター(赤ポッチ)で代用可能。だけど、近頃のWindows10は、おさわり画面を推してるみたいで、スクロールバーが極狭。これじゃ、赤ポッチで操作するのは嫌になる。やっぱり、2匹目のうなぎ(7/28)じゃなくて、マウスを用意するかな。まずは100均方面に狩りに出かけてみるか。
ctags -R -e
前回はgdbを使って、kernel側でICMPパケットの処理具合をトレースした。目ぼしい場所にBPを置いて、ヒットしたら、そこに至る経路を表示するってやつ。
この経路情報ってかバックトレースって、schemeで言う継続を見せてくれているのではなかろうか。どこにも有る継続なんて言えば、括弧いいじゃん。いや、scheme知らない人には、糸と言っておこう。それじゃ余りに日本語的と言うなら、スレッドって言えばいい。これなら、あらかたなプログラマーにも理解出来るだろう。
カーネルは割り込み主導型なんで、あちこちにこの継続って言うかスレッドが存在してて、しかもそれらが独立してる。だから、ソースを読む時は、何の目的なスレッドかってのをしっかり把握しとく必要が有る(と思うよ)。前回の例だと、ICMPのパケットが到着した時、カーネルはどんな経路で処理するか、だね。
if_put()
に処理が委ねられる、なんて書いたけど、それじゃ、その関数は何処に定義されてたの? 生憎記録を残していなかったので、ソースツリーから再度検索する事になる。
そんな事もあらーなって事で、emacs用のTAGSファイルを作っておいたんだけど、そこには登録が無かった。んな馬鹿な。今回初めて使うのかな。昔の事でうろ覚えなんだけど、
find . -name '*.[ch]' | xargs etags
とかやって作ったと思う。これじゃ、対応出来ないのかな? ググれ。
cd /usr/src/sys ctags -R -e
こういうのが多数ヒットした。注意書きとして、emacsをインストールすると、ctags,etagsも一緒にインストールされるけど、このctagsを使ってはいけないとの事。ちゃんと sudo apt install ctags して、お勧めの拡張されたctagsをインストールしなさいって事みたい。
確かに、emacsから来たctagsには、-eオプション(emacs用のtag生成)はサポートされていなかった。拡張版はちゃんとサポートされてた。識者によると、debianの場合は、色々なアプリが取替可能になってるそうである。
sakae@pen:~$ ls -l /etc/alternatives/ctags lrwxrwxrwx 1 root root 24 Jul 11 15:24 /etc/alternatives/ctags -> /usr/bin/ctags-exuberant
ctags xxってやると、/etc/alternativesの下を見て、リンクをたどるって機構になってる。恐ろしいと言うか便利と言うか。。。300個近い代替アプリが登録されてたぞ。
こんな機構はOpenBSDでは許し難い。じゃ、etagsで何とかするしかないだろう(デフォのctagsはBSD由来の奴だからね)。穴の開くほどetagsのマニュアルを参照。
-a, --append Append to existing tag file. (For vi-format tag files, see also --update.)
これを使えばいいのかな。
カーネルソースを読む ( 3 ) タグファイルを作る ( Emacs )
やっぱりね。どうやら当たりのようです。こちらの方は、アセンブラまで視野に入れてらっしゃるみたいで、頭が下がりますよ。オイラーはインテル石のアセンブラなんて読めないのさ。
TAGSファイルが有ると、defineの場所とかへも簡単に飛んで行けるので、便利です。例
netinet/ip_icmp.c
case ICMP_ECHO: if (!icmpbmcastecho && (m->m_flags & (M_MCAST | M_BCAST)) != 0) { icmpstat_inc(icps_bmcastecho); break;
ICMP_ECHO
って、何よ? カーソル合わせてタグジャンプ
ip_icmp.h
#define ICMP_ECHO 8 /* echo service */
ヘッダーファイル・ファーストって、都民ファーストに通じるものがあるな。よく忘れるけどね(小池のボスさん)。 この便利なデータベースは巨大です。140Mも有りました。使う時、巨大だけど本当に使っていいかってemacsが確認を求めてきますよ。
Linux src
上の方もリナのソースを見ているし、食わず嫌いはいかんぜよ、とばかりオイラーも参照してみる(本当は、前回の最後にチラ出ししたeBPFを見たいと言う野次馬根性)。 kernel.orgへ行って次期でびあんに採用されるであろうやつを落としてきた。展開すると、 1.1Gって、どんだけオバケだ。ハリボテ具合を確認。
sakae@debian:/usr/src/linux-5.10.46$ du -s * | sort -nr 686216 drivers 136912 arch 53632 Documentation 47436 include 43416 fs 43116 tools 41584 sound 33880 net 11156 kernel 6280 lib 4228 mm 3816 scripts 3644 crypto 3176 security 1868 block 1712 samples 564 MAINTAINERS 264 ipc 256 LICENSES 228 virt 200 init 100 CREDITS 64 usr 64 Makefile 56 certs 4 README 4 Kconfig 4 Kbuild 4 COPYING
半分以上は、ドライバーか。世の中にあるデバイスを貪欲に取り込んでいるのが魅力なのかな。
今ちょうどやってるICMPな部分がどうなっているか、ちょいと調べてみる。全く土地勘がないので、特徴的な語句を探す。
sakae@debian:/usr/src/linux-5.10.46$ find . -name '*.c' | xargs grep -l ICMP_ECHO ./tools/testing/selftests/bpf/progs/xdping_kern.c ./tools/testing/selftests/bpf/progs/test_cls_redirect.c ./net/ipv4/proc.c ./net/ipv4/ping.c ./net/ipv4/route.c ./net/ipv4/icmp.c ./net/ipv4/netfilter/nf_log_ipv4.c ./net/ipv4/netfilter/ipt_REJECT.c ./net/ipv4/netfilter/ipt_CLUSTERIP.c ./net/core/flow_dissector.c ./net/netfilter/nf_nat_proto.c ./net/netfilter/nf_conntrack_proto_icmp.c
ぴったりそうな、net/ipv4/icmp.cを開いてみた。
static bool icmp_echo(struct sk_buff *skb) { struct net *net; net = dev_net(skb_dst(skb)->dev); if (!net->ipv4.sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; icmp_param.data.icmph = *icmp_hdr(skb); icmp_param.data.icmph.type = ICMP_ECHOREPLY; icmp_param.skb = skb; icmp_param.offset = 0; icmp_param.data_len = skb->len; icmp_param.head_len = sizeof(struct icmphdr); icmp_reply(&icmp_param, skb); } /* should there be an ICMP stat for ignored echos? */ return true; }
要求を受けたら、即返信モードに設定して、返事をだしてるね。後は、どんな継続が組み立てられているかは、gdbを使った方が圧倒的に楽。簡単にgdb出来る環境って組み立てられるの?
やっぱり、qemuにdebug用のカーネルを入れてやるんだね。ユーザーアプリが、initだけってのは、寂しいぞ。OSを丸ごと入れた物って、用意が大変だからね。その点、オイラーのOpenBSD観光は、どんなユーザーランドにも対応してる。小粒だけど、非常に便利で楽しいぞ。
OpenBSD src
対抗上、OpenBSDのカーネルエリアの容量も確認。全体では283Mと小粒です。
vbox$ du -s * | sort -nr 501004 dev 47876 arch 6152 net 4260 kern 3776 lib 2436 sys 2288 netinet 1728 ufs 1672 uvm 1440 net80211 1176 netinet6 1028 scsi 964 crypto 912 nfs 472 isofs 444 stand 444 msdosfs 404 ddb 284 tmpfs 260 ntfs 224 miscfs 116 conf 76 netmpls 4 Makefile
やっぱりデバドラの容量がダントツだね。archも大きいので、一応確認
vbox$ ls arch alpha/ arm64/ i386/ luna88k/ mips64/ powerpc64/ sparc64/ amd64/ armv7/ landisk/ m88k/ octeon/ sgi/ arm/ hppa/ loongson/ macppc/ powerpc/ sh/
これってOpenBSDの元になったNetBSDのDNAを継承してるのかな。ちょっと歴史的だな。何でも新しい方が良いと、IDEのツリーを最近削除しちまったリナとは、大違い。
リナではnet-dirの下にipv4とかipv6ってdirが配置されてるけど、OpenBSDは、独立してるね。考え方の違いが有るんだな。多分、こうだったんじゃなかろうか劇場(あれをパクってます)。
昔々、その昔、4.X BSDを継承した時、netが現れた。混沌とした世界、ゼロックスは独自プロトコルを流行らせようとするし、それを牽制しようとISOと言う標準機構も口出し。そんな事になって見通しがつかないため、それらは袂を別れたじゃなくて、dirを別にして独立性を保った。
が、主流はTCP/IPに傾き、今後の大いなる発展が期待された。で、netの下に関係者を全部入れてしまえって案も出たが、ファイル個数のバランスを考慮してnetinetが並列的に作成された(ここはIPv4関係者)。
そのうちに、日本発のIPv6プロジェクトとして、 kameプロジェクトが発動した。名前の由来は、同プロジェクトの主要開発者 萩野純一郎氏の行動による。開発合宿で、どうしても取れないバグに遭遇。その時、近くに有った亀さんぬいぐるみにすがった所、霊感新たに、バグが取れたらしい。で、縁起物の亀がプロジェクト名になった。
このIPv6スタックは、勿論OpenBSDに移植されてる。netinet6 としてね。このIPv6が取り込まれたOpenBSD 4.2は、直前に急逝した彼に捧げられている。
リナは対抗してIPv6プロジェクトとして、うさぎ を利用したが、絶対に亀には追いつけないぞ。ウサギとカメとアキレスとゼノン
ping localhost
前回苦労して作った、tapを使った環境。遊んでいる時、HostOSのネットがハングアップしちゃう事が有った。これじゃ、安心して遊べない。そこで頭を振る回転、目眩がして出た結論は?
強い味方がいるじゃないですか。loopbackデバイスという奴ね。これなら、送り出したパケットがOS内部で折り返される。だから、普通にpingしたら、送受の継続が実行されるんではなかろうか。
ホストOSで、予備実験してみる。
sakae@pen:~$ ping -c 2 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.184 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.082 ms
普通にlocalhostを指定すると、IPv6のそれが使われちゃったので、生IPを指定したよ。
sakae@pen:/tmp$ sudo tcpdump -i lo icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes 08:21:08.164755 IP localhost > localhost: ICMP echo request, id 2724, seq 1, length 64 08:21:08.164818 IP localhost > localhost: ICMP echo reply, id 2724, seq 1, length 64 08:21:09.186158 IP localhost > localhost: ICMP echo request, id 2724, seq 2, length 64 08:21:09.186182 IP localhost > localhost: ICMP echo reply, id 2724, seq 2, length 64
tcpdumpと言う、公正な観測者からもお墨付きを得たぞ。これで思う存分、楽しめそう。
lo
localhostは文字通り、ローカルで完結する。使うデバイスはloだ。manを引いてみると
NAME lo – software loopback network interface SYNOPSIS pseudo-device loop DESCRIPTION The loop interface is a software loopback mechanism which may be used for performance analysis, software testing, and/or local communication.
仮想デバイスってなってる。何処に定義されてるの? loopbackなんて言うコメント文字を全文検索。辿りついた所は、 net/if_loop.c
/* * Loopback interface driver for protocol testing and timing. */ #define LOMTU 32768 int loioctl(struct ifnet *, u_long, caddr_t); void loopattach(int); void lortrequest(struct ifnet *, int, struct rtentry *); void loinput(struct ifnet *, struct mbuf *); int looutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int loop_clone_create(struct if_clone *, int); int loop_clone_destroy(struct ifnet *);
パケットが外に出ていかないので、1パケットの梱包サイズを大きくしても大丈夫。皆様に迷惑をかける事が無い。ってんで、通常1500サイズの所を、大判振る舞いで32768にしてる。IPv6とかで、無理するとジャイアント・パケットを設定出来たかな。ジャイアントと言っても、16kだったような。。
デバドラの体裁になってますなあ。デバイスを作ったり、接続したり破棄したり。
ob$ doas ifconfig lo1 create ob$ ifconfig -a lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768 index 3 priority 0 llprio 3 groups: lo inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 inet 127.0.0.1 netmask 0xff000000 : lo1: flags=8008<LOOPBACK,MULTICAST> mtu 32768 index 4 priority 0 llprio 3 groups: lo
lo1って言う2番目のデバイスを作ってみた。登録はされたけど、まだ活動出来ない。
ob$ doas ifconfig lo1 127.0.0.2 ob$ ifconfig lo1 lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768 index 4 priority 0 llprio 3 groups: lo inet 127.0.0.2 netmask 0xff000000 ob$ ping 127.0.0.2 PING 127.0.0.2 (127.0.0.2): 56 data bytes 64 bytes from 127.0.0.2: icmp_seq=0 ttl=255 time=0.156 ms 64 bytes from 127.0.0.2: icmp_seq=1 ttl=255 time=0.202 ms :
IPを振ると同時に、活性化した。一応動作確認。
using lo driver
loinput,looutputに網を張ってから、ping localhostしてみた。
(gdb) bt 8 #0 looutput (ifp=0xd180bc00, m=0xd1893300, dst=0xd17b0758, rt=0xd178ad5c) at /usr/src/sys/net/if_loop.c:246 #1 0xd06332ca in ip_output (m0=0xd1893300, opt=0x0, ro=0xd17b0750, flags=32, imo=0x0, inp=0xd17b0708, ipsecflowinfo=0) at /usr/src/sys/netinet/ip_output.c:470 #2 0xd0da551e in rip_output (m=0xd1893300, so=0xd17b1d20, dstaddr=0xf1d09368, control=0x0) at /usr/src/sys/netinet/raw_ip.c:286 #3 0xd0da5fa4 in rip_usrreq (so=0xd17b1d20, req=9, m=0xd1893900, nam=0xd1893700, control=0x0, p=0xd1681d8c) at /usr/src/sys/netinet/raw_ip.c:538 #4 0xd021ccef in sosend (so=0xd17b1d20, addr=0xd1893700, uio=0xf1d094b0, top=0xd1893900, control=0x0, flags=0) at /usr/src/sys/kern/uipc_socket.c:524 #5 0xd051e618 in sendit (p=0xd1681d8c, s=3, mp=0xf1d09530, flags=0, retsize=0xf1d0967c) at /usr/src/sys/kern/uipc_syscalls.c:662 #6 0xd051e9f4 in sys_sendmsg (p=0xd1681d8c, v=0xf1d09684, retval=0xf1d0967c) at /usr/src/sys/kern/uipc_syscalls.c:567 #7 0xd06bae59 in mi_syscall (p=0xd1681d8c, code=28, callp=0xd10f8ff8 <sysent+336>, argp=0xf1d09684, retval=0xf1d0967c) at /usr/src/sys/sys/syscall_mi.h:92 (More stack frames follow...)
frame 6で、システムコールが見て取れる。
(gdb) bt #0 loinput (ifp=0xd180bc00, m=0xd1893300, cookie=0x0) at /usr/src/sys/net/if_loop.c:232 #1 0xd0398db4 in if_ih_input (ifp=0xd180bc00, m=0xd1893300) at /usr/src/sys/net/if.c:912 #2 0xd0398d36 in if_input_process (ifp=0xd180bc00, ml=0xf1cc6c48) at /usr/src/sys/net/if.c:946 #3 0xd0a54e13 in ifiq_process (arg=0xd180be70) at /usr/src/sys/net/ifq.c:607 #4 0xd06be752 in taskq_thread (xtq=0xd17fd040) at /usr/src/sys/kern/kern_task.c:367 #5 0xd09af481 in proc_trampoline ()
こちらは、受信の方だから、システムコールは見えていない。丹念に追っていけば、見えるかな?
見えない、見えない! デカとしては筋読み失敗の新人刑事ですよ。このスレッドが、何処に繋がるか、裏読みしてミロ。
長くなりそうなので、今日の所はこれぐらいにしといたる。
Blue LED
な、マウスをget。結局100均には無くて、ホームセンターへ。 主流は無線マウスになってて、有線マウスは2種しか無かった。赤と青バージョンのLED式。どっちかから選べ。中村先生に敬意を表して、青色式のやつにした。金648円也。赤式はこれよりちょっと安かったけど、時代の進歩に追従って事で。
この青色式は、白い紙の上でも反応した。ガラス面上では動かない場合があるそうだけど、そこまでは、求めまい。
昔のマウスは、玉がゴロゴロする機械式。ずっと使っているとゴミを巻き込んで、動きが悪くなる。そんな時は、綿棒で掃除をしたものだ。それに、USBなんて無い時代だから、PS2なんて言う規格の丸いコネクタが主流だったな。ああ、懐かしい。
更に余談になるけど、 どうやら都会の100均ではマウスも手に入るみたい。 Bluetoothマウスも100円ショップで手に入る!? 楽しい事、やってますなあ。
password gen
パスワード管理ってみんなどうしてるの??こうするといいと思うよ!
オイラーも真似してみよう。Windows10に入っているWSL上のDebian用
sakae@pen:~$ echo -n hallo | shasum -a 256 | base64 -w0 | cut -b -20 ZDM3NTFkMzNmOWNkNTA0 sakae@pen:~$ echo -n hall | shasum -a 256 | base64 -w0 | cut -b -20 M2NiYWViNTdjNjQwMjBl
記号を混ぜろとか言われると、プチ面倒。cutの所をawkにでもして、ちょっとプログラミングぽい事をせにゃならん。でも、記号は3文字以上、数字は4文字以上とか面倒言うのには、対応が難しいな。
あ、ここで使ったshasumは、母語がperlさんか。彼がPerl module Digest::SHAを呼び出しているとな。ならば、記号の事は、彼に任せればいいのか。って、今更記号言語perlなんて、オイラーには、難し過ぎて使えませんよ。ちょいと覗いてみたら、正規表現のオンパレード、桑原桑原、ブルブルブル。
ついでに、リナでしか動かない事にも、ブルブルブルブルしとく。OpenBSDでも動くように汎用化しとけ。道具は、どんな環境でも動いてこそ、です。
vbox$ echo ha | openssl sha224 (stdin)= b936af95a546a471264bfea2662a2029fdc7cd333df0308fd06fcd0c vbox$ echo 9fdc7cd333df0308fd06f | openssl base64 OWZkYzdjZDMzM2RmMDMwOGZkMDZmCg==
主要エンジン部分の置き換えが可能か、確認しました。ここまでやったら、スクリプトにしておくってのが親切ってものだろう。
#!/bin/sh # Usage: pg.sh mypassword [n] n=$2 if [ "x$2" = "x" ]; then n=20 fi start=66 stop=`expr $start + $n` stop=`expr $stop - 1` echo -n "$1" | openssl sha512 | openssl base64 | tr -d '\n' | cut -b $start-$stop
nはデフォルトのパスワード長。startの66は、ソルトの積り。この値を変更する時は、よく考えてね。小さすぎてもいけないし、長すぎてもまずいです。
[sakae@fb /tmp]$ ./pg.sh sakae mU2NWQ1NTJkYjUzZTI1M [sakae@fb /tmp]$ ./pg.sh sakae 10 mU2NWQ1NTJ [sakae@fb /tmp]$ ./pg.sh 'sakae desu' WQ1MzA4NTQ4MDA1MDI5M
FreeBSDでの実行例です。
password checker にかけたら、10000世紀のうちにに解読されるかも、ですってさ。