IPv6

友人から電話が有って、いきなり聞かれた。光回線代幾ら払ってますと? プロバイダー込みで、XXX円と言うと、大体そんなもんですよねと応答有。彼の所は、オイラーの所より若干高かったけど、相場だと思う。

彼が言う事には、光回線を乗り換えませんかと、知らない所から勧誘電話が有ったそうな。 普通は光回線は1Gぐらいなはずなんだけど、そこの会社では2Gと言ってたそうな。 しかも、プロバイダー代込みで、現有の価格よりは、1200円もお得とアッピール。

それに対し興味を示した彼は、プロバイダーは何処を使ってるの? 返ってきた答えは、 彼も昔使ってた、某有名処。で、今契約してる所は、3年縛りが有るんで、途中契約解除すると 2万円近くの違約金を取られるよと、抵抗。

先方はそれに対して、支度金として違約金を現金支払いしてくれると言ったとか。 ここまで餌をまかれると、ぐらっとなったとか。とりあえずの保留。

で、彼は、わざわざ某有名処のプロバイダーに確認したそうな。これこれしかじかの話を 振られたけど、相手はちゃんとした所? それによると、正式代理店ではないけど、それに 準拠する扱いをしてるとか。まあ、詐欺ではなさそうって判断をしたそうな。

で、今使ってる回線屋へ行って、こんな勧誘を受けたんで、解約しよーーーかなと言ったらしい。 2Gに惹かれたんなら、そんな速度が活躍する場面なんてありませんよと、諭されたとか。 言ってみれば、混雑してる都内の道の極々一部を、某知事の一存で、オリンピック記念道路として、100m幅の道路を作ったとする。そこだけは、すいすい流れるけど、後は、昔と同じの大渋滞。でも、嘘は無いんだなあ。

某回線屋は、新手の通信屋に対抗すべく、1万5千円のキャッシュバックで引き留め策を 提示してきたとか。これって、1年分新手の通信屋に乗り換え効果じゃないですか。 こうして、相談があれば引き留めの防止を図れるけど、いきなり解除されると、脅威と 認めた事ですな。

最近はスマホの値引きも、しっかり総務のおばちゃんが目を光らせているんで、こういう所で ぬけがけしてるのね。

いい事を聞いたんで、オイラーもごねてみるかな。

IPv6を試す

前回のetcで、ちょいとIPv6の記事をピックックアップした。IoTを広く拡散するには、 どうしても避けて通れないという事情があるようだ。某スマホ屋は、IPv6をスマホに 取りつけるとか。なんせ、IPv4は貴重な資源で高騰してるから、そんなのやめて、安価な もので代用しようって作戦だな。そのうち、何処でもやりだす錬金術だな。

気になったので、IPアドレスの料金とやらを調べてみた。 IPアドレス維持料で、 料金表が出てきたけど、これだけの料金なの? それに、IPv6は、v4に比べて安いと思って いたけど、一緒じゃん。

IPアドレスに「値段」が付く?相当が頭の片隅に残っていたからかしらん。

ちなみに、プロバイダーから固定IPを買うと幾らになる? 固定IPアドレスをサービス提供している主要各社(OCN等のプロバイダ)を比較してみた何時の時点での価格かは 分からないけど、中には暴利を貪っている所も有るようで。ひょっとしたら、シスコにでも 貢ぐ金を多めに設定してるのかな?

オイラーも、その錬金術に乗ってみるか。IPv6って言ったら、カメとうさぎだな。 始点・終点をカメで固めてみる。まずは、 OpenBSD側でIPv6を使えるようにする

[ob: ~]$ cat /etc/hostname.em0
rtsol
dhcp

同じく、FreeBSD側でもIPv6のアドレスを使えるようにする

[sakae@fb11 ~]$ cat /etc/rc.conf
hostname="fb11"
ifconfig_em0="DHCP"
ipv6_enable="YES"

どうも上の設定方法は古いらしい。dmesg -a して、じっくり眺めたら、下記のような指導がなされていた。そんな長ったらしい名前は嫌いだぞーー。

/etc/rc: WARNING: $ipv6_enable is obsolete.  Use $ipv6_activate_all_interfaces i
nstead.

FreeBSD側のem0を確認(OpenBSD側は省略)

[sakae@fb11 ~]$ ifconfig em0
em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=98<VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 00:0c:29:aa:bb:cc
        inet6 fe80::20c:29ff:feaa:bbcc%em0 prefixlen 64 scopeid 0x1
        inet xxx.xxx.xxx.xxx netmask 0xffffff00 broadcast xxx.xxx.xxx.255
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active

IPv6でピンしたら、ピンと拒否された。何で?

[ob: ~]$ ping6 fe80::20c:29ff:feaa:bbcc
PING6 fe80::20c:29ff:feaa:bbcc (fe80::20c:29ff:feaa:bbcc): 24 data bytes
ping6: sendmsg: Network is unreachable
ping6: wrote fe80::20c:29ff:feaa:bbcc 32 chars, ret=-1
ping6: sendmsg: Network is unreachable
ping6: wrote fe80::20c:29ff:feaa:bbcc 32 chars, ret=-1
ping6: sendmsg: Network is unreachable
ping6: wrote fe80::20c:29ff:feaa:bbcc 32 chars, ret=-1
^C--- fe80::20c:29ff:feaa:bbcc ping6 statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss

思い当たってアドレスにNICの名前を混ぜてみたら、成功した。

[ob: ~]$ ping6 fe80::20c:29ff:feaa:bbcc%em0
PING6 fe80::20c:29ff:feaa:bbcc%em0 (fe80::20c:29ff:feaa:bbcc%em0): 24 data bytes
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=0 hlim=64 time=0.327 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=1 hlim=64 time=0.628 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=2 hlim=64 time=0.669 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=3 hlim=64 time=0.686 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=4 hlim=64 time=0.651 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=5 hlim=64 time=0.628 ms
32 bytes from fe80::20c:29ff:feaa:bbcc%em0, icmp_seq=6 hlim=64 time=0.601 ms
^C--- fe80::20c:29ff:feaa:bbcc%em0 ping6 statistics ---
7 packets transmitted, 7 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.327/0.599/0.686/0.114 ms

余力で、IPv6でsshしてみたら、ちゃんと繋がった。

[ob: ~]$ ssh -6 fe80::20c:29ff:feaa:bbcc%em0
Password for sakae@fb11:
Last login: Tue Dec  6 15:02:11 2016 from fe80::20c:29ff:fedd:eeff%em0
FreeBSD 11.0-RELEASE-p2 (GENERIC) #0: Mon Oct 24 06:55:27 UTC 2016

このIPv6は、KAMEプロジェクトによって未来を見据えて開発されていたはず。 その痕跡がきっと有るだろうと思って、netinet6の下を探してみた。 オリジナルは、今は亡き itojunさん。彼の功績には、OpenBSDの親分も敬意を 払っていて、どこかのバージョンは、彼に捧げられていたはず。

/*      $OpenBSD: raw_ip6.c,v 1.93 2016/07/22 11:14:41 mpi Exp $        */
/*      $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $        */

どれぐらい功績が有ったか、ファイルの個数で調べてみた。70%以上が、彼によって 書かれたとな。ご冥福をお祈りします。

[ob: netinet6]$ ls | wc
      37      37     376
[ob: netinet6]$ grep itojun *|wc
      27     264    1975
[ob: ~]$ dig www.goole.com
  :
;; QUESTION SECTION:
;www.google.com.                        IN      A

;; ANSWER SECTION:
www.google.com.         5       IN      A       172.217.25.228

Aレコードしか返ってこないじゃん。itojunの功績を踏みにじっている悪い人はだれだ。

AAAAレコードを返すと、IPv6の袋小路に入ってしまい、レスポンスが遅くなるってんで、 どっかの馬鹿が握り潰して知らん顔してんだな。

上記の問い合わせ、ひょっとしたらIPv6のパケットを送りつけないとAAAAレコードを 返してくれないようになってるかもね。問い合わせ先を 8.8.8.8 のgoogle管理サーバーを 指定しても、Aレコードしか返ってこなかったぞ。

幾らなんでもと思って、manを真面目に眺めたら、有ったぞ。

[ob: ~]$ dig www.google.com any
  :
;; QUESTION SECTION:
;www.google.com.                        IN      ANY

;; ANSWER SECTION:
www.google.com.         5       IN      A       216.58.197.228
www.google.com.         5       IN      AAAA    2404:6800:4004:80f::2004

ググルと言えども、IPv6はこれからね。黒船来襲で、AAAAレコードしか返さないという 横暴な事をやってくれ。ああ、さりげなくDNSラウンドロビンが動いているな。 AAAAレコードは、何度問い合わせしても不変だから、v6パケットが押し寄せて来て 困った事態にはなっていないのか。

こうして、世界で有名な、ガラパゴスIPv6網になってて、パケット鎖国時代。これを どう活用するか? そんなの、NHKとの共同戦略が有るにきまってるじゃん。 国内専用IPv6網を利用して、どんどんオンデマンドのNHK放送を楽しんで、いっぱいNHKに お金を落としてください。

TVに否定的な若者もスマホで自由な番組を見られる。こうして、通信屋もインフラの 利用代ががっぼり入ってくる仕組み。鎖国してるから、ウィルスの検閲も楽だしね。

IPv6のアプリ

思いつくのは、上で使った ping6とかtraceroute6ぐらい。後は、sshみたいに、6オプションで 切り替えるやつぐらい。他に無いかとmanの下の いち か はち を探してみる。

まずは、いち から。

[ob: ~]$ cd /usr/share/man/man1
[ob: man1]$ fgrep 'Fl 6' *
compress.1:.Fl 6 .
cpio.1:.Op Fl 6BbcdfjmrSstuvZz
cpio.1:.It Fl 6
ftp.1:.It Fl 6
gzip.1:.Fl 6 .
nc.1:.It Fl 6
openssl.1:.It Fl 6
scp.1:.It Fl 6
sftp.1:.It Fl 6
ssh-keyscan.1:.It Fl 6
ssh.1:.It Fl 6
tcpbench.1:.It Fl 6
telnet.1:.It Fl 6

こんどは、はち の方

[ob: man1]$ cd ../man8
[ob: man8]$ fgrep 'Fl 6' *
bgpctl.8:.It Fl 6
ftp-proxy.8:.Op Fl 6Adrv
ftp-proxy.8:.It Fl 6
ftpd.8:.It Fl 6
identd.8:.It Fl 6
iked.8:.Op Fl 6dnSTtv
iked.8:.It Fl 6
rdate.8:.It Fl 6
sshd.8:.It Fl 6
syslogd.8:.It Fl 6
tftp-proxy.8:.It Fl 6
tftpd.8:.It Fl 6

関係無いものも混じっているけど、まあ、ピン ときてください。

     -4      Forces ssh to use IPv4 addresses only.

     -6      Forces ssh to use IPv6 addresses only.

上記は、sshの例だけど、古いの新しいのと、限定で使えるようになってる。指定しない時は、 どちらが優先するの? そんなの、ソース嫁。

nc

上で出てきたディアルスタックのアプリをどれか一つやってみる。ncあたりが、オイラーも 余り使った事が無く、簡単そうなんでチョイスしてみた。使い方はmanで。

OpenBSDのそれでは、冒頭部分が、

NAME
     nc – arbitrary TCP and UDP connections and listens

となってたけど、リナでは、スイス アーミーナイフですって記述されてた。こういう比喩、 ある程度状況が分かっていると、頭にガツンと来るね。

NAME
       nc - TCP/IP swiss army knife

サーバー/クライアントプログラムなんで、端末を2つ用意して、それぞれを担当させる。 まずは、サーバーの方。

[ob: ~]$ nc -l ::1 1234
hello
world

こちらは、クライアント側。

[ob: ~]$ nc -N ::1 1234
hello
world
^D

クライアント側から入力すると、それがサーバー側に反映されます。-Nは、EOTを送ると サーバー側が閉じる仕組み。

見慣れない、コロコロ1は、IPv6対応のlocalhostの表記。1234はポート番号ね。

そんじゃ実験。サーバー側は上記の設定にプラスして、-4って言う矛盾した設定を してみる。

[ob: ~]$ nc -4 -l ::1 1234
nc: getaddrinfo: no address associated with name

起動直後は、何のエラーも出さずに、あたかも矛盾を受け入れたように見えたけど、 暫くして、エラーが出てきた。これって、コロコロ1を、IPv4のアドレスと思って、 世界中に問い合わせしてたんだな。そして、最後にギブアップしたという事か。

[ob: ~]$ nc -6 -l 127.0.0.1 1234
nc: getaddrinfo: no address associated with name

こちらも矛盾した設定。すぐにエラーが返ってきた。アドレス表記が間違ってるのを 直ぐに報告したんだな。

これだけの実験で、大体性格が掴めたように思う。ソースを少し覗いてみるか。 その前に、パケットを眺めてみれ。localhost相当なんで、NICをlo0に設定、protoに ip6を設定してから盗聴。後は、結果をwireshark送り。

# tcpdump -s 512 -w 6log -i lo0 ip6
tcpdump: listening on lo0, link-type LOOP
^C
11 packets received by filter
0 packets dropped by kernel
# wireshark 6log

クライアント側でCTRL-Dした時、FINパケットが送出されるのね。これが契機となって、 サーバーからもFINが送られて、回線が閉じるとな。 パケットの構造を見て、フムフムと頷くのが、正しい鑑賞方法。

ああ、もう一つ思い出した、調べておく事を。そう、arpはIPv6に対応しているか? ncを使って、NICのem0側にパケットを流してみる。そして、arpを実行。あれ? 記録されてるのは、IPv4とMACアドレスの関係だけだなあ。

今回の場合、MACを元にIPv6のアドレスを自動生成してるんで、記録する必要は無い? いつでも、MACを逆生成出来るからね。でも、念のためにmanすると、ndp なんてのを 紹介された。

[ob: ~]$ ndp -a
Neighbor                             Linklayer Address  Netif Expire    S Flags
fe80::20c:29ff:fe11:2233%em0         00:0c:29:11:22:33    em0 permanent R l
[ob: ~]$ arp -a
Host                                 Ethernet Address   Netif Expire     Flags
xxx.xxx.xxx.xxx                      00:50:56:44.55.66    em0 6m5s

こうして、IPv4用のarpと対比してみると、言葉の言い換えが起きている事が分かる。 たかが32Bitから128Bitになって、ヘッダーを整理したぐらいで、用語まで変えてしまうって、 心機一転、再出発しますって言う、決意の表れだろうね。

nc source

mainの中のオプション解析を見ていくのが、常套手段かな。

        while ((ch = getopt(argc, argv,
            "46C:cDde:FH:hI:i:K:klM:m:NnO:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) {
                switch (ch) {
                case '4':
                        family = AF_INET;
                        break;
                case '6':
                        family = AF_INET6;
                        break;
                case 'U':
                        family = AF_UNIX;
                        break;

4でも6でもUNIXドメインでも、どんど来いって事だな。なお、このfamilyの初期値は、 AF_UNSPECだから、まあ定義無しって所だな。

例えば、local_listen なんていう関数

/*
 * local_listen()
 * Returns a socket listening on a local port, binds to specified source
 * address. Returns -1 on failure.
 */
int
local_listen(char *host, char *port, struct addrinfo hints)

を見ると、

        /*
         * In the case of binding to a wildcard address
         * default to binding to an ipv4 address.
         */
        if (host == NULL && hints.ai_family == AF_UNSPEC)
                hints.ai_family = AF_INET;

        if ((error = getaddrinfo(host, port, &hints, &res)))
                errx(1, "getaddrinfo: %s", gai_strerror(error));

        res0 = res;
        do {
                if ((s = socket(res0->ai_family, res0->ai_socktype,
                    res0->ai_protocol)) < 0)
                        continue;

ipv4が優先されるようだ。じゃ、上記のコードでホストがNULLじゃ無かったら、AF_INETは 設定されず、UNSPECのまま。その時はどうなるの?

それを解決してくれるのが、getaddrinfo関数。manしてみる。

EXAMPLES
     The following code tries to connect to “www.kame.net” service “www” via a
     stream socket.  It loops through all the addresses available, regardless
     of address family.  If the destination resolves to an IPv4 address, it
     will use an AF_INET socket.  Similarly, if it resolves to IPv6, an
     AF_INET6 socket is used.  Observe that there is no hardcoded reference to
     a particular address family.  The code works even if getaddrinfo()
     returns addresses that are not IPv4/v6.

           struct addrinfo hints, *res, *res0;
           int error;
           int save_errno;
           int s;
           const char *cause = NULL;

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = AF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
           error = getaddrinfo("www.kame.net", "www", &hints, &res0);
           if (error)
                   errx(1, "%s", gai_strerror(error));
           s = -1;
           for (res = res0; res; res = res->ai_next) {
                   s = socket(res->ai_family, res->ai_socktype,
                       res->ai_protocol);

manにしっかりkameを使った説明が載ってた。

Fedora 24 のそれ

それって何だ? リンクローカルなアドレスには、fffeが挟まっていると教わったんだけど、そうなっていない。 ルール破りのとんでもない奴? 7機に入ってるFedora23は、ルールを順守してるよ。

[sakae@fedora ~]$ ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask 255.255.255.0  broadcast yyy.yyy.yyy.yyy
        inet6 fe80::19a9:5c91:6d6b:ccd0  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:1f:94:1a  txqueuelen 1000  (Ethernet)
        RX packets 119  bytes 12863 (12.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 116  bytes 14645 (14.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ついでに、リナ版のnetstat。何もつけないと4側が表示され、-6を付けるとやっと6側が 出て来る。カメとうさぎの競争では、絶対にうさぎが勝てないパラドックスがありますから、 うさぎは控えめなのかな。

[sakae@fedora ~]$ netstat -6 -nr
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
fe80::/64                      ::                         U    256 0     0 ens33
::/0                           ::                         !n   -1  1   241 lo
::1/128                        ::                         Un   0   3     5 lo
fe80::19a9:5c91:6d6b:ccd0/128  ::                         Un   0   1     5 lo
ff00::/8                       ::                         U    256 1     8 ens33
::/0                           ::                         !n   -1  1   241 lo