Enjoy source reading

NetBSD on FreeBSD

OpenBSD in OpenBSD

前回と前々回のオイラーの駄文のタイトルを上げてみた。これの何が違う? onとinが 違います。正解!

onの方は、流行りの Ubuntu on Windows をもじったもの。でも、よく考えたら、on より in の方がオイラーには相応しいと思ったから、前置詞だかを変えてみたんだ。(本当に 前置詞かどうかは、英語を良く知らないオイラーは自信がないけど)

昔々、サラリーマンをしてた頃、大型コンピュータに Logon して、作業する事が有った。 DBからデータを抽出して、それをグラフにしてプレゼン資料を作っていたんだけど、 遅くて遅くて、いらいらのし通しだった記憶がある。

それから数年後、世に言うUnixに login する仕事も降ってきた。こちらは慣れれば 快適そのもの。

ここに、LogonとLoginの違いが隠されているように思う。

Baby on bed. と、Baby in car. の違いと言ったらいいかな。前者は、赤ちゃんがベッドで すやすや眠っています、ってイメージ。後者は、赤ちゃんが狭い車の中でむずがって泣き叫んで います。おやおや、そのうち、糞を垂れたぞ。臭い臭いって、オイラーが勝手に想像した。

何となく、on は、お上品な感じがする。決められた事しかやりません。いやなら、さっさと 逃げ出しましょって感じ。in の方は、深く潜って、とことん使い倒してやるぞ。その代わり 運命共同体だからな。逃れられないぞって風に思う。自分の腕が確かなら、何でも出来るぞ、 とも思う。

gauche作者のshiroさんが、coljure本を翻訳した時、ベースにJavaを採用したのは、 思い切った決断だと言ってた。その理由は、Javaの掌に居るうちはいいけど、ガラスの 天井にぶつからないのかしらって、危惧しちゃうって心配してた。まさにその通りだと 思うぞ。

OpenBSD in OpenBSDには、今の所泣かされているけど、得る所は大きいので、 もう少し遊ばれてみる。

マカフィーの火壁

いよいよワクチンソフトをどうするか、決断する時期が来た。無料で使えれば嬉しいな。 商用でお試しってのも色々な所がやってるから、順番に使ってみるって手もあるな。 物によっては、過去に試したって記憶を植え付けておき、2度と無料版を使えないように 防御してるやつもあるだろう。

そういう過去の記憶はレジストリに(多分)置かれていると思うので、知恵比べをする のも楽しいかも知れない。

無料/有料を含めてワクチンを 列挙しておく。皆さん、この分野には積極的なようで、頭が下がりますよ。

じゃ、オイラーも、その一助になるべく協力しておきましょう。今入っているマカフィーの 火壁の防御力を調査してみました。

[sakae@fb11 ~]$ nmap xxx.xxx.xxx.xxx

Starting Nmap 7.30 ( https://nmap.org ) at 2016-10-29 06:14 JST
Nmap scan report for xxx.xxx.xxx.xxx
Host is up (1.0s latency).
Not shown: 991 closed ports
PORT     STATE    SERVICE         VERSION
135/tcp  open     msrpc
139/tcp  open     netbios-ssn
445/tcp  open     microsoft-ds
514/tcp  filtered shell
902/tcp  open     iss-realsecure VMware Authentication Daemon 1.10 (Uses VNC, SOAP)
912/tcp  open     apex-mesh      VMware Authentication Daemon 1.0 (Uses VNC, SOAP)
2869/tcp open     icslap         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
5357/tcp open     wsdapi         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
6646/tcp open     unknown

Nmap done: 1 IP address (1 host up) scanned in 210.25 seconds

nmap -A -Pn xxx.xxx.xxx.xxx すると、もう少し詳細が出て来る。(上の一部は、それを 引っ張ってきてある)

Nmap リファレンスガイド (Man Page)

ポートスキャンツール「Nmap」を使ったセキュリティチェック

くれぐれも、悪用しないでね。場合によっては、電磁的なんとか罪で、全国に ブロードキャストされますから。その時に備えて、幼少の頃の写真を用意して、 近所付き合いは積極的に行っておきましょう。例えば、月に一回ぐらい行われる、 近所の掃除に積極的に参加すろとかね。

折角nmap入れたんで、Fedoraの火壁も味わっておこう。

[sakae@fb11 ~]$ nmap z.zz.zzz.zzz

Starting Nmap 7.30 ( https://nmap.org ) at 2016-10-29 13:33 JST
Warning: z.zz.zzz.zzz giving up on port because retransmission cap hit (10).
Stats: 0:08:41 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 51.35% done; ETC: 13:50 (0:08:14 remaining)
Nmap scan report for z.zz.zzz.zzz
Host is up (0.00089s latency).
Not shown: 996 closed ports
PORT     STATE    SERVICE
22/tcp   open     ssh
23/tcp   filtered telnet
587/tcp  filtered submission
1720/tcp filtered h323q931

Nmap done: 1 IP address (1 host up) scanned in 1047.76 seconds

同一ホストからの連続アクセスには、抵抗するような機構が組み込まれているみたいだな。 今時、フィルターされているとは言え、telnetポートが開いているって、Fortranを 使う人向け、、、、だったりして。

baud

仮想マシンを起動した時、コンソールに接続されましたってなって、その後メッセージが 流れてこない。何度か実行すると、ちゃんとメッセージが流れてくる。

ネットで検索しても、そんな症状を訴える人は居ない。まあ、非常にレアなあれだから 知が集積してない可能性大だな。

で、原因を推測してみた。ひょっとして、PuTTYで開いている端末の設定が合っていない から? えと、端末属性を調べるコマンドが有ったな。端末だからttyと連想記憶が 働いたけど違った。man ttyしたら、sttyも見て桶ってヒントが出てきた。

増井さんの第9回 ExpandHelp じゃないけど、Helpって適切じゃないと使う気が失せるんだよな。>某Windows屋さん

[ob: ~]$ stty -a
speed 38400 baud; 42 rows; 80 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
        -extproc -xcase
iflags: -istrip icrnl -inlcr -igncr -iuclc ixon -ixoff ixany imaxbel
        -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -ocrnl -onocr -onlret -olcuc oxtabs -onoeot
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
        eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
        min = 1; quit = ^\; reprint = ^R; start = ^Q; status = <undef>;
        stop = ^S; susp = ^Z; time = 0; werase = ^W;

VMのコンソールは9600baudを期待するのに対して、38400で使われている。これを その場で変更するのは簡単だけど、永続化するにはどうやればいいの?

方針をsttyで変更するんじゃなくて、端末プログラムのcu側で設定すべく考えてみる。 man cu したら、デフォが9600だけど、設定ファイルの/etc/remoreを用意しとくて いかようにもなるよって示唆された。続けてremoteを見ると

br=br#38400

とか、書いておくと良いらしい。でも、デフォで9600ってのは、リーズナブルな 設定値だな。38400ってのが異端な気がしてきた。

そんな38400を設定してるのは、PuTTYに違いない。設定をくまなく漁ったら(こういう場合、 GUIって不便、いちいち開いていかないと、分からないから) 接続の所のデータの部に、端末の速さって項目があって、それが38400,38400ってなってた。

同様な設定は、MobaXtermでは、何処に有るんだろう。GUI恐怖症にかかっていますよ。 ちら見したけど、見つからず。38400が決め打ちだろうか?

VMWAREのコンソールは9600、vboxのコンソールは38400になってた。Linuxに的を絞った やつは、より快適に38400を選択。どこでも繋がる安定感を求めると、9600って事かな。 実際、9600にして使ってみたけど、特に遅いと感じる事も無かったぞ。大体、動体視力が 衰えていますから、そんなに速い必要は全く無いのよね。

気になってたイメージ

前から気になってたOpenBSDの所にある、xxx.fsってやつ。yyy.isoとかと同じ所に 置いてあるんで、同種なものと思うんだけど、調べてみる。

[ob: vm]# ls
disk.img*       install60.fs
[ob: vm]# vnconfig vnd0 install60.fs
[ob: vm]# mount /dev/vnd0a /mnt
[ob: vm]# df
Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a     31997276  12102308  18295108    40%    /
/dev/vnd0a      571996    469728    102268    82%    /mnt
[ob: vm]# umount /mnt
[ob: vm]# vnconfig -u vnd0

例の方法で仮想ハードに見せかけておいて、マウント。そして確認。

[ob: mnt]$ cd /mnt
[ob: mnt]$ tree
.
|-- 6.0
|   `-- amd64
|       |-- INSTALL.amd64
|       |-- SHA256
|       |-- base60.tgz
|       |-- bsd
|       |-- bsd.mp
|       |-- bsd.rd
|       |-- comp60.tgz
|       |-- game60.tgz
|       |-- man60.tgz
|       |-- xbase60.tgz
|       |-- xfont60.tgz
|       |-- xserv60.tgz
|       `-- xshare60.tgz
|-- boot
|-- bsd
`-- etc
    `-- boot.conf

なる程、同じものね。ついでに前回の失敗作も確認。

[ob: vm]# disklabel vnd0
# /dev/rvnd0c:
type: SCSI
disk: SCSI disk
label: Block Device
duid: 61bde4531abf33ea
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 255
sectors/cylinder: 16065
cylinders: 261
total sectors: 4194304
boundstart: 64
boundend: 4192965
drivedata: 0

16 partitions:
#                size           offset  fstype [fsize bsize  cpg]
  a:          4192896               64  4.2BSD   2048 16384    1
  c:          4194304                0  unused

残骸調査

前回仮想PCにインストールしようとして、見事失敗。最後っ屁で、どんなコマンドが 使えるか調べておいた。で、dmesgを発見。ならば、見てみるか。

# dmesg
OpenBSD 6.0 (RAMDISK_CD) #2100: Tue Jul 26 13:05:59 MDT 2016
    deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/RAMDISK_CD
RTC BIOS diagnostic error 20<config_unit>
real mem = 520093696 (496MB)
avail mem = 502673408 (479MB)
mainbus0 at root
bios0 at mainbus0
acpi at bios0 not configured
cpu0 at mainbus0: (uniprocessor)
cpu0: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz, 9056.85 MHz
cpu0: FPU,VME,DE,PSE,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,MMX,FXSR,SSE,SSE2,SS,SSE3,PCLMUL,SSSE3,FMA3,CX16,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,AVX,F16C,RDRAND,HV,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,ARAT
pvbus0 at mainbus0: OpenBSD
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "OpenBSD VMM PCI Host Bridge" rev 0x00
virtio0 at pci0 dev 1 function 0 "Qumranet Virtio RNG" rev 0x00
viornd0 at virtio0
virtio0: irq 3
virtio1 at pci0 dev 2 function 0 "Qumranet Virtio Storage" rev 0x00
vioblk0 at virtio1
scsibus0 at vioblk0: 2 targets
sd0 at scsibus0 targ 0 lun 0: <VirtIO, Block Device, > SCSI3 0/direct fixed
sd0: 2048MB, 512 bytes/sector, 4194304 sectors
virtio1: irq 5
virtio2 at pci0 dev 3 function 0 "Qumranet Virtio Network" rev 0x00
vio0 at virtio2: address fe:e1:ba:d0:a4:5e
virtio2: irq 9
isa0 at mainbus0
com0 at isa0 port 0x3f8/8 irq 4: ns8250, no fifo
com0: console
softraid0 at root
scsibus1 at softraid0: 256 targets
root on rd0a swap on rd0b dump on rd0b
WARNING: invalid time in clock chip
WARNING: CHECK AND RESET THE DATE!

何だか、RTCのエラーが出てるのが気になる。dmsgの最後に出てる警告。昔使ってた Sunの宝石箱でも出てたのと同じ気がした。

RTCの電池がヘタっていて、時刻を正しく提供出来ないものだから、shutdownした時の 時刻と比べておかしいぞって事だったような。で、電池を交換しようとすると、その モジュールにNVRAMが付いていて、そいつにMACアドレスが書き込んであるんで、 それを何とかしなくちゃいけなくて、えらい苦労した覚えがある。

今の場合仮想PCにBIOSなんて載っていないから、エラーなんだろうな。幸いソースが 有るんで、味わってみる。

[ob: ~]$ cd /sys
[ob: sys]$ find . -name '*[ch]' | xargs fgrep 'RTC BIOS diagnostic error'
./arch/amd64/isa/clock.c:               printf("RTC BIOS diagnostic error %b\n", s, NVRAM_DIAG_BITS);
./arch/i386/isa/clock.c:                printf("RTC BIOS diagnostic error %b\n", (unsigned int) s,
void
startclocks(void)
{
        int s;

        mtx_enter(&timer_mutex);
        rtclock_tval = TIMER_DIV(hz);
        i8254_startclock();
        mtx_leave(&timer_mutex);

        /* Check diagnostic status */
        if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */
                printf("RTC BIOS diagnostic error %b\n", s, NVRAM_DIAG_BITS);
}

mc146818ってモトローラ社が作ってたCMOSの時計な石なのね。データシートをチラ見すると ユーザーが使える領域も有るな。そこに秘密のデータを隠しておけるとな。

#define MC_NVRAM_START  0xe     /* start of NVRAM: offset 14 */
#define MC_NVRAM_SIZE   50      /* 50 bytes of NVRAM */

ソフト屋は、データシートより先に、mc146818reg.hを当たるべき。

/*
 * Initialize the time of day register, based on the time base which is, e.g.
 * from a filesystem.
 */
void
inittodr(time_t base)
  :
        /*
         * We mostly ignore the suggested time (which comes from the
         * file system) and go for the RTC clock time stored in the
         * CMOS RAM.  If the time can't be obtained from the CMOS, or
         * if the time obtained from the CMOS is 5 or more years less
         * than the suggested time, we used the suggested time.  (In
         * the latter case, it's likely that the CMOS battery has
         * died.)
         */

	 /*
         * If time_t is 32 bits, then the "End of Time" is
         * Mon Jan 18 22:14:07 2038 (US/Eastern)
         * This code copes with RTC's past the end of time if time_t
         * is an int32 or less. Needed because sometimes RTCs screw
         * up or are badly set, and that would cause the time to go
         * negative in the calculation below, which causes Very Bad
         * Mojo. This at least lets the user boot and fix the problem.
         * Note the code is self eliminating once time_t goes to 64 bits.
         */

CMOSバッテリィー劣化の検出法とな。5年って妥当な線だと思うぞ。そして、いわゆる 2038年問題に対する苦肉の対策も、盛り込まれている。

2038年を検出したら、1年戻して2037年にしちゃうって言う、壮大なループが 組み込まれていました。面白いな、こういうの。 Mojoって単語も面白い。やつらは、こう言うのね。勉強になったぞ。

vmctl and vmd

もう少しコードを見ておく。vmctlでイメージを作る部分

create_imagefile(const char *imgfile_path, long imgsize)
{
        int fd, ret;

        /* Refuse to overwrite an existing image */
        fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
            S_IRUSR | S_IWUSR);
        if (fd == -1)
                return (errno);

        /* Extend to desired size */
        if (ftruncate(fd, (off_t)imgsize * 1024 * 1024) == -1) {
                ret = errno;
                close(fd);
                unlink(imgfile_path);
                return (ret);
        }

        ret = close(fd);
        return (ret);
}

核となる部分は、ftruncateだな。与えるサイズは、MByte単位ね。で、この関数は何処? 探し回ったけど見つからず。しょうがないので、manすると

TRUNCATE(2)                   System Calls Manual                  TRUNCATE(2)

NAME
     truncate, ftruncate – truncate or extend a file to a specified length

なんだ、システムコールでした。つらつら見ていくと、全領域をzeroにしてくれるのね。

__dead void
ctl_openconsole(const char *name)
{
        closefrom(STDERR_FILENO + 1);
        execl(VMCTL_CU, VMCTL_CU, "-l", name, "-s", "9600", (char *)NULL);
        err(1, "failed to open the console");
}

コンソールのボーレートは、ハードコーディングされてた。何処でも接続出来るだろうって言う スタンダード設定ですよ。こうでなくちゃね。

使う端末は、特に指定しなければ、今使ってるものが流用される。それは当然の事だな。