├── sources
├── 8.socket
│ ├── .gitignore
│ ├── httpclient.py
│ ├── echoserver.py
│ ├── addclient.py
│ └── addserver.py
└── README.md
├── commands
├── README.md
├── 2.what-is-tcp-ip
│ ├── how-to-bucket-relay.txt
│ ├── preparation.txt
│ ├── ping.txt
│ ├── bucket-relay.txt
│ └── ipv4-address.txt
├── 8.socket
│ ├── httpclient.txt
│ ├── binproto.txt
│ └── echoserver.txt
├── 3.linux-netns
│ ├── index.txt
│ ├── get-started.txt
│ ├── veth.txt
│ ├── multi-router.txt
│ └── with-router.txt
├── 6.application
│ ├── dns.txt
│ ├── http.txt
│ └── dhcp.txt
├── 5.transport
│ ├── udp.txt
│ └── tcp.txt
├── 4.ethernet
│ ├── how-to-know-hw-addr.txt
│ ├── observe.txt
│ ├── bridge.txt
│ └── multi-domain.txt
└── 7.nat
│ ├── dnat.txt
│ └── snat.txt
├── README.md
└── scripts
├── dhcp.sh
├── single-segment.sh
├── double-segment.sh
├── nat.sh
├── bridge.sh
└── triple-segment.sh
/sources/8.socket/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__/
2 |
--------------------------------------------------------------------------------
/sources/README.md:
--------------------------------------------------------------------------------
1 | ### これはなんですか?
2 |
3 | このディレクトリには本の中で例示したソースコードがあります。
4 |
--------------------------------------------------------------------------------
/commands/README.md:
--------------------------------------------------------------------------------
1 | ### これはなんですか?
2 |
3 | このディレクトリには本の中で例示したコマンドライン操作を記したファイルがあります。
4 |
--------------------------------------------------------------------------------
/commands/2.what-is-tcp-ip/how-to-bucket-relay.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ ip route show
3 | default via 10.0.2.2 dev enp0s3 proto dhcp src 10.0.2.15 metric 100
4 | 10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15
5 | 10.0.2.2 dev enp0s3 proto dhcp scope link src 10.0.2.15 metric 100
6 | ----------
7 |
--------------------------------------------------------------------------------
/commands/2.what-is-tcp-ip/preparation.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo apt-get update
3 | $ sudo apt-get -y install \
4 | bash \
5 | coreutils \
6 | grep \
7 | iproute2 \
8 | iputils-ping \
9 | traceroute \
10 | tcpdump \
11 | bind9-dnsutils \
12 | dnsmasq-base \
13 | netcat-openbsd \
14 | python3 \
15 | curl \
16 | wget \
17 | iptables \
18 | procps \
19 | isc-dhcp-client
20 | ----------
21 |
--------------------------------------------------------------------------------
/commands/2.what-is-tcp-ip/ping.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ ping -c 3 8.8.8.8
3 | PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
4 | 64 bytes from 8.8.8.8: icmp_seq=1 ttl=63 time=9.06 ms
5 | 64 bytes from 8.8.8.8: icmp_seq=2 ttl=63 time=8.88 ms
6 | 64 bytes from 8.8.8.8: icmp_seq=3 ttl=63 time=10.3 ms
7 |
8 | --- 8.8.8.8 ping statistics ---
9 | 3 packets transmitted, 3 received, 0% packet loss, time 2004ms
10 | rtt min/avg/max/mdev = 8.883/9.445/10.386/0.678 ms
11 | ----------
12 |
--------------------------------------------------------------------------------
/commands/8.socket/httpclient.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ wget https://raw.githubusercontent.com/momijiame/linux-tcpip-book/master/sources/8.socket/httpclient.py
3 | ----------
4 |
5 | ----------
6 | $ python3 httpclient.py
7 | HTTP/1.0 200 OK
8 | Server: SimpleHTTP/0.6 Python/3.8.5
9 | Date: Tue, 05 Jan 2021 21:12:21 GMT
10 | Content-type: text/html
11 | Content-Length: 127
12 | Last-Modified: Tue, 05 Jan 2021 21:09:40 GMT
13 |
14 |
15 |
16 |
17 | Hello, World
18 |
19 |
20 | Hello, World
21 |
22 |
23 |
24 | ----------
25 |
--------------------------------------------------------------------------------
/commands/3.linux-netns/index.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip netns add helloworld
3 | ----------
4 |
5 | ----------
6 | $ ip netns list
7 | helloworld
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns exec helloworld ip address show
12 | 1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000
13 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
14 | ----------
15 |
16 | ----------
17 | $ sudo ip netns exec helloworld ip route show
18 | ----------
19 |
20 | ----------
21 | $ sudo ip netns delete helloworld
22 | ----------
23 |
24 | ----------
25 | $ sudo ip netns exec helloworld bash
26 | ----------
27 |
--------------------------------------------------------------------------------
/commands/2.what-is-tcp-ip/bucket-relay.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ traceroute -n 8.8.8.8
3 | traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
4 | 1 10.0.2.2 0.568 ms 0.562 ms 1.044 ms
5 | 2 172.16.0.1 4.495 ms 4.499 ms 4.703 ms
6 | 3 14.0.9.78 11.304 ms 11.319 ms 11.305 ms
7 | 4 14.0.9.77 12.112 ms 11.881 ms 12.097 ms
8 | 5 72.14.222.189 12.916 ms 12.635 ms 12.902 ms
9 | 6 * * *
10 | 7 209.85.242.44 11.620 ms 216.239.62.26 11.019 ms 72.14.233.220 11.260 ms
11 | 8 209.85.143.49 11.138 ms 209.85.255.159 10.154 ms 74.125.37.233 10.105 ms
12 | 9 8.8.8.8 12.775 ms 11.561 ms 12.295 ms
13 | ----------
14 |
--------------------------------------------------------------------------------
/commands/3.linux-netns/get-started.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip netns add helloworld
3 | ----------
4 |
5 | ----------
6 | $ ip netns list
7 | helloworld
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns exec helloworld ip address show
12 | 1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000
13 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
14 | ----------
15 |
16 | ----------
17 | $ sudo ip netns exec helloworld ip route show
18 | Error: ipv4: FIB table does not exist.
19 | Dump terminated
20 | ----------
21 |
22 | ----------
23 | $ sudo ip netns delete helloworld
24 | ----------
25 |
26 | ----------
27 | $ sudo ip netns exec helloworld bash
28 | ----------
29 |
--------------------------------------------------------------------------------
/commands/8.socket/binproto.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ wget https://raw.githubusercontent.com/momijiame/linux-tcpip-book/master/sources/8.socket/addserver.py
3 | $ wget https://raw.githubusercontent.com/momijiame/linux-tcpip-book/master/sources/8.socket/addclient.py
4 | ----------
5 |
6 |
7 | ----------
8 | $ python3 addserver.py
9 | starting server ...
10 | accepted from 127.0.0.1:44754
11 | received: b'\x00\x00\x03\xe8\x00\x00\x07\xd0'
12 | operand1: 1000, operand2: 2000
13 | result: 3000
14 | sent: b'\x00\x00\x00\x00\x00\x00\x0b\xb8'
15 | ----------
16 |
17 | ----------
18 | $ python3 addclient.py
19 | operand1: 1000, operand2: 2000
20 | sent: b'\x00\x00\x03\xe8\x00\x00\x07\xd0'
21 | received: b'\x00\x00\x00\x00\x00\x00\x0b\xb8'
22 | result: 3000
23 | ----------
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Linuxで動かしながら学ぶTCP/IPネットワーク入門
2 |
3 | 書籍「Linuxで動かしながら学ぶTCP/IPネットワーク入門」のサポートページです。
4 |
5 | ## ナビゲーション
6 |
7 | - commands
8 |
9 | - 本の中で例示したコマンドライン操作を記したファイルがあります
10 |
11 | - sources
12 |
13 | - 本の中で例示したソースコードのファイルがあります
14 |
15 | - scripts
16 |
17 | - 本の中に登場したネットワークの作成を自動化するスクリプトがあります
18 |
19 | ## 改訂履歴
20 |
21 | 本の改訂に伴う主要な変更点を以下に示します。
22 | なお、Kindle 版についてはコンテンツをアップデートすることで最新の改訂版が利用できます。
23 |
24 | ### 第2版
25 |
26 | - 対応リリース
27 | - 2021.01.09 ~
28 |
29 | #### 本文の説明とコマンドライン操作の両方に関連する修正
30 |
31 | - ネットワークの作成を自動化するシェルスクリプトを用意しました
32 | - 使用する Linux ディストリビューションを Ubuntu 18.04 LTS から Ubuntu 20.04 LTS に変更しました
33 | - DHCP の実験において、dhclient(8) がシステムの resolv.conf(5) を上書きする問題を修正しました
34 | - ブリッジの実験において、ネットワークブリッジを Network Namespace 内に作成するように変更しました
35 |
36 | #### 本文の説明のみに関連する修正
37 |
38 | - 図にキャプションを追加しました
39 | - VirtualBox が対応している CPU の命令セットアーキテクチャについて注意書きを追加しました
40 |
41 | #### コマンドライン操作のみに関連する修正
42 |
43 | - Network Namespace を一括で削除するコマンドを、ip(8) の ``--all`` オプションを利用するように修正しました
44 | - インストールするパッケージを追加・変更しました
45 |
46 | ### 第1版
47 |
48 | - 対応リリース
49 | - ~ 2020.05.04
50 |
--------------------------------------------------------------------------------
/commands/6.application/dns.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ ping -c 3 localhost
3 | PING localhost (127.0.0.1) 56(84) bytes of data.
4 | 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.040 ms
5 | 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.052 ms
6 | 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.068 ms
7 |
8 | --- localhost ping statistics ---
9 | 3 packets transmitted, 3 received, 0% packet loss, time 2038ms
10 | rtt min/avg/max/mdev = 0.040/0.053/0.068/0.012 ms
11 | ----------
12 |
13 | ----------
14 | $ grep 127.0.0.1 /etc/hosts
15 | 127.0.0.1 localhost
16 | ----------
17 |
18 | ----------
19 | $ sudo tcpdump -tnl -i any "udp and port 53"
20 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
21 | listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
22 | IP 10.0.2.15.51746 > 8.8.8.8.53: 1521+ [1au] A? example.org. (52)
23 | IP 8.8.8.8.53 > 10.0.2.15.51746: 1521$ 1/0/1 A 93.184.216.34 (56)
24 | ----------
25 |
26 | ----------
27 | $ dig +short @8.8.8.8 example.org A
28 | 93.184.216.34
29 | ----------
30 |
--------------------------------------------------------------------------------
/scripts/dhcp.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add server
19 | sudo ip netns add client
20 | }
21 |
22 | : "add-veth" && {
23 | sudo ip link add s-veth0 type veth peer name c-veth0
24 | }
25 |
26 | : "set-veth" && {
27 | sudo ip link set s-veth0 netns server
28 | sudo ip link set c-veth0 netns client
29 | }
30 |
31 | : "set-hw-addr" && {
32 | sudo ip netns exec server ip link set dev s-veth0 address 00:00:5E:00:53:01
33 | sudo ip netns exec client ip link set dev c-veth0 address 00:00:5E:00:53:02
34 | }
35 |
36 | : "link-up" && {
37 | sudo ip netns exec server ip link set s-veth0 up
38 | sudo ip netns exec client ip link set c-veth0 up
39 | }
40 |
41 | : "add-ip" && {
42 | sudo ip netns exec server ip address add 192.0.2.254/24 dev s-veth0
43 | }
44 |
45 | : "done" && {
46 | set +x
47 | echo "successful"
48 | }
--------------------------------------------------------------------------------
/scripts/single-segment.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add ns1
19 | sudo ip netns add ns2
20 | }
21 |
22 | : "add-veth" && {
23 | sudo ip link add ns1-veth0 type veth peer name ns2-veth0
24 | }
25 |
26 | : "set-veth" && {
27 | sudo ip link set ns1-veth0 netns ns1
28 | sudo ip link set ns2-veth0 netns ns2
29 | }
30 |
31 | : "link-up" && {
32 | sudo ip netns exec ns1 ip link set ns1-veth0 up
33 | sudo ip netns exec ns2 ip link set ns2-veth0 up
34 | }
35 |
36 | : "add-ip" && {
37 | sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
38 | sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
39 | }
40 |
41 | : "set-hw-addr" && {
42 | sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01
43 | sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
44 | }
45 |
46 | : "test" && {
47 | sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
48 | }
49 |
50 | : "done" && {
51 | set +x
52 | echo "successful"
53 | }
--------------------------------------------------------------------------------
/commands/6.application/http.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ mkdir -p /var/tmp/http-home
3 | $ cd /var/tmp/http-home/
4 | ----------
5 |
6 | ----------
7 | $ cat << 'EOF' > index.html
8 |
9 |
10 |
11 | Hello, World
12 |
13 |
14 | Hello, World
15 |
16 |
17 | EOF
18 | ----------
19 |
20 | ----------
21 | $ ls
22 | index.html
23 | $ cat index.html
24 |
25 |
26 |
27 | Hello, World
28 |
29 |
30 | Hello, World
31 |
32 |
33 | ----------
34 |
35 | ----------
36 | $ sudo python3 -m http.server -b 127.0.0.1 80
37 | Serving HTTP on 127.0.0.1 port 80 (http://127.0.0.1:80/) ...
38 | ----------
39 |
40 | ----------
41 | $ echo -en "GET / HTTP/1.0\r\n\r\n" | nc 127.0.0.1 80
42 | HTTP/1.0 200 OK
43 | Server: SimpleHTTP/0.6 Python/3.8.5
44 | Date: Tue, 05 Jan 2021 21:10:20 GMT
45 | Content-type: text/html
46 | Content-Length: 127
47 | Last-Modified: Tue, 05 Jan 2021 21:09:40 GMT
48 |
49 |
50 |
51 |
52 | Hello, World
53 |
54 |
55 | Hello, World
56 |
57 |
58 | ----------
59 |
60 | ----------
61 | $ curl -X GET -D - http://127.0.0.1/
62 | HTTP/1.0 200 OK
63 | Server: SimpleHTTP/0.6 Python/3.8.5
64 | Date: Tue, 05 Jan 2021 21:10:46 GMT
65 | Content-type: text/html
66 | Content-Length: 127
67 | Last-Modified: Tue, 05 Jan 2021 21:09:40 GMT
68 |
69 |
70 |
71 |
72 | Hello, World
73 |
74 |
75 | Hello, World
76 |
77 |
78 | ----------
79 |
--------------------------------------------------------------------------------
/commands/5.transport/udp.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo update-alternatives --config nc
3 | ----------
4 |
5 | ----------
6 | $ nc -ulnv 127.0.0.1 54321
7 | Bound on 127.0.0.1 54321
8 | ----------
9 |
10 | ----------
11 | $ nc -u 127.0.0.1 54321
12 | ----------
13 |
14 | ----------
15 | $ sudo tcpdump -i lo -tnlA "udp and port 54321"
16 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
17 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
18 | ----------
19 |
20 | ----------
21 | $ nc -u 127.0.0.1 54321
22 | Hello, World!
23 | ----------
24 |
25 | ----------
26 | $ nc -ulnv 127.0.0.1 54321
27 | Bound on 127.0.0.1 54321
28 | Connection received on 127.0.0.1 32889
29 | Hello, World!
30 | ----------
31 |
32 | ----------
33 | $ sudo tcpdump -i lo -tnlA "udp and port 54321"
34 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
35 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
36 | IP 127.0.0.1.32889 > 127.0.0.1.54321: UDP, length 14
37 | E..*\(@.@............y.1...)Hello, World!
38 | ----------
39 |
40 | ----------
41 | $ nc -ulnv 127.0.0.1 54321
42 | Bound on 127.0.0.1 54321
43 | Connection received on 127.0.0.1 32889
44 | Hello, World!
45 | Reply, World!
46 | ----------
47 |
48 | ----------
49 | $ nc -u 127.0.0.1 54321
50 | Hello, World!
51 | Reply, World!
52 | ----------
53 |
54 | ----------
55 | $ sudo tcpdump -i lo -tnlA "udp and port 54321"
56 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
57 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
58 | IP 127.0.0.1.32889 > 127.0.0.1.54321: UDP, length 14
59 | E..*\(@.@............y.1...)Hello, World!
60 |
61 | IP 127.0.0.1.54321 > 127.0.0.1.32889: UDP, length 14
62 | E..*..@.@............1.y...)Reply, World!
63 | ----------
64 |
--------------------------------------------------------------------------------
/commands/8.socket/echoserver.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ wget https://raw.githubusercontent.com/momijiame/linux-tcpip-book/master/sources/8.socket/echoserver.py
3 | ----------
4 |
5 | ----------
6 | $ python3 echoserver.py
7 | starting server ...
8 | accepted from 127.0.0.1:44692
9 | echo: b'Hello, World!\n'
10 | ----------
11 |
12 | ----------
13 | $ nc 127.0.0.1 54321
14 | Hello, World!
15 | Hello, World!
16 | ----------
17 |
18 | ----------
19 | $ sudo ss -tlnp
20 | State Recv-Q Send-Q Local Address:Port Peer Address:Port
21 | LISTEN 0 128 127.0.0.1:54321 0.0.0.0:* users:(("python3",pid=5038,fd=3))
22 | LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=747,fd=13))
23 | LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=996,fd=3))
24 | LISTEN 0 128 127.0.0.1:6010 0.0.0.0:* users:(("sshd",pid=4815,fd=10))
25 | LISTEN 0 128 127.0.0.1:6011 0.0.0.0:* users:(("sshd",pid=4913,fd=10))
26 | LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=996,fd=4))
27 | LISTEN 0 128 [::1]:6010 [::]:* users:(("sshd",pid=4815,fd=9))
28 | LISTEN 0 128 [::1]:6011 [::]:* users:(("sshd",pid=4913,fd=9))
29 | ----------
30 |
--------------------------------------------------------------------------------
/sources/8.socket/httpclient.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """ソケットを使って HTTP クライアントを実装したスクリプト"""
4 |
5 | import socket
6 |
7 |
8 | def send_msg(sock, msg):
9 | """ソケットに指定したバイト列を書き込む関数"""
10 | # これまでに送信できたバイト数
11 | total_sent_len = 0
12 | # 送信したいバイト数
13 | total_msg_len = len(msg)
14 | # まだ送信したいデータが残っているか判定する
15 | while total_sent_len < total_msg_len:
16 | # ソケットにバイト列を書き込んで、書き込めたバイト数を得る
17 | sent_len = sock.send(msg[total_sent_len:])
18 | # まったく書き込めなかったらソケットの接続が終了している
19 | if sent_len == 0:
20 | raise RuntimeError('socket connection broken')
21 | # 書き込めた分を加算する
22 | total_sent_len += sent_len
23 |
24 |
25 | def recv_msg(sock, chunk_len=1024):
26 | """ソケットから接続が終わるまでバイト列を読み込むジェネレータ関数"""
27 | while True:
28 | # ソケットから指定したバイト数を読み込む
29 | received_chunk = sock.recv(chunk_len)
30 | # まったく読めなかったときは接続が終了している
31 | if len(received_chunk) == 0:
32 | break
33 | # 受信したバイト列を返す
34 | yield received_chunk
35 |
36 |
37 | def main():
38 | """スクリプトとして実行されたときに呼び出されるメイン関数"""
39 | # IPv4 / TCP で通信するソケットを用意する
40 | client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
41 | # ループバックアドレスの TCP/80 ポートに接続する
42 | client_socket.connect(('127.0.0.1', 80))
43 | # HTTP サーバからドキュメントを取得するための GET リクエスト
44 | request_text = 'GET / HTTP/1.0\r\n\r\n'
45 | # 文字列をバイト列にエンコードする
46 | request_bytes = request_text.encode('ASCII')
47 | # ソケットにリクエストのバイト列を書き込む
48 | send_msg(client_socket, request_bytes)
49 | # ソケットからレスポンスのバイト列を読み込む
50 | received_bytes = b''.join(recv_msg(client_socket))
51 | # 読み込んだバイト列を文字列にデコードする
52 | received_text = received_bytes.decode('ASCII')
53 | # 得られた文字列を表示する
54 | print(received_text)
55 | # 使い終わったソケットを閉じる
56 | client_socket.close()
57 |
58 |
59 | if __name__ == '__main__':
60 | """スクリプトのエントリーポイントとしてメイン関数を実行する"""
61 | main()
62 |
--------------------------------------------------------------------------------
/commands/4.ethernet/how-to-know-hw-addr.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip netns exec ns1 ip neigh flush all
3 | ----------
4 |
5 | ----------
6 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
7 | PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
8 | 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.043 ms
9 | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.043 ms
10 | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.053 ms
11 |
12 | --- 192.0.2.2 ping statistics ---
13 | 3 packets transmitted, 3 received, 0% packet loss, time 2053ms
14 | rtt min/avg/max/mdev = 0.043/0.046/0.053/0.007 ms
15 | ----------
16 |
17 | ----------
18 | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp
19 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
20 | listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21 | 00:00:5e:00:53:01 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.2 tell 192.0.2.1, length 28
22 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Reply 192.0.2.2 is-at 00:00:5e:00:53:02, length 28
23 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23597, seq 1, length 64
24 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23597, seq 1, length 64
25 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23597, seq 2, length 64
26 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23597, seq 2, length 64
27 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23597, seq 3, length 64
28 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23597, seq 3, length 64
29 | ----------
30 |
31 | ----------
32 | $ sudo ip netns exec ns1 ip neigh
33 | 192.0.2.2 dev ns1-veth0 lladdr 00:00:5e:00:53:02 REACHABLE
34 | ----------
35 |
--------------------------------------------------------------------------------
/scripts/double-segment.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add ns1
19 | sudo ip netns add router
20 | sudo ip netns add ns2
21 | }
22 |
23 | : "add-veth" && {
24 | sudo ip link add ns1-veth0 type veth peer name gw-veth0
25 | sudo ip link add ns2-veth0 type veth peer name gw-veth1
26 | }
27 |
28 | : "set-veth" && {
29 | sudo ip link set ns1-veth0 netns ns1
30 | sudo ip link set gw-veth0 netns router
31 | sudo ip link set gw-veth1 netns router
32 | sudo ip link set ns2-veth0 netns ns2
33 | }
34 |
35 | : "link-up" && {
36 | sudo ip netns exec ns1 ip link set ns1-veth0 up
37 | sudo ip netns exec router ip link set gw-veth0 up
38 | sudo ip netns exec router ip link set gw-veth1 up
39 | sudo ip netns exec ns2 ip link set ns2-veth0 up
40 | }
41 |
42 | : "add-ip" && {
43 | sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
44 | sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0
45 | sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1
46 | sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
47 | }
48 |
49 | : "add-default-route" && {
50 | sudo ip netns exec ns1 ip route add default via 192.0.2.254
51 | sudo ip netns exec ns2 ip route add default via 198.51.100.254
52 | }
53 |
54 | : "to-be-router" && {
55 | sudo ip netns exec router sysctl net.ipv4.ip_forward=1
56 | }
57 |
58 | : "set-hw-addr" && {
59 | sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:11
60 | sudo ip netns exec router ip link set dev gw-veth0 address 00:00:5E:00:53:12
61 | sudo ip netns exec router ip link set dev gw-veth1 address 00:00:5E:00:53:21
62 | sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:22
63 | }
64 |
65 | : "test" && {
66 | sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
67 | }
68 |
69 | : "done" && {
70 | set +x
71 | echo "successful"
72 | }
--------------------------------------------------------------------------------
/sources/8.socket/echoserver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """ソケットを使ってエコーサーバを実装したスクリプト"""
4 |
5 | import socket
6 |
7 |
8 | def send_msg(sock, msg):
9 | """ソケットに指定したバイト列を書き込む関数"""
10 | # これまでに送信できたバイト数
11 | total_sent_len = 0
12 | # 送信したいバイト数
13 | total_msg_len = len(msg)
14 | # まだ送信したいデータが残っているか判定する
15 | while total_sent_len < total_msg_len:
16 | # ソケットにバイト列を書き込んで、書き込めたバイト数を得る
17 | sent_len = sock.send(msg[total_sent_len:])
18 | # まったく書き込めなかったらソケットの接続が終了している
19 | if sent_len == 0:
20 | raise RuntimeError('socket connection broken')
21 | # 書き込めた分を加算する
22 | total_sent_len += sent_len
23 |
24 |
25 | def recv_msg(sock, chunk_len=1024):
26 | """ソケットから接続が終わるまでバイト列を読み込むジェネレータ関数"""
27 | while True:
28 | # ソケットから指定したバイト数を読み込む
29 | received_chunk = sock.recv(chunk_len)
30 | # まったく読めなかったときは接続が終了している
31 | if len(received_chunk) == 0:
32 | break
33 | # 受信したバイト列を返す
34 | yield received_chunk
35 |
36 |
37 | def main():
38 | """スクリプトとして実行されたときに呼び出されるメイン関数"""
39 | # IPv4 / TCP で通信するソケットを用意する
40 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
41 | # 'Address already in use' の回避策
42 | server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
43 | # クライアントから接続を待ち受ける IP アドレスとポート番号を指定する
44 | server_socket.bind(('127.0.0.1', 54321))
45 | # 接続の待ち受けを開始する
46 | server_socket.listen()
47 | # サーバが動作を開始したことを表示する
48 | print('starting server ...')
49 | # 接続を処理する
50 | client_socket, (client_address, client_port) = server_socket.accept()
51 | # 接続してきたクライアントの情報を表示する
52 | print(f'accepted from {client_address}:{client_port}')
53 | # ソケットからバイト列を読み込む
54 | for received_msg in recv_msg(client_socket):
55 | # 読み込んだ内容をそのままソケットに書き込む (エコーバック)
56 | send_msg(client_socket, received_msg)
57 | # 送受信した内容を出力しておく
58 | print(f'echo: {received_msg}')
59 | # 使い終わったソケットをクローズする
60 | client_socket.close()
61 | server_socket.close()
62 |
63 |
64 | if __name__ == '__main__':
65 | """スクリプトのエントリーポイントとしてメイン関数を実行する"""
66 | main()
67 |
--------------------------------------------------------------------------------
/scripts/nat.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add lan
19 | sudo ip netns add router
20 | sudo ip netns add wan
21 | }
22 |
23 | : "add-veth" && {
24 | sudo ip link add lan-veth0 type veth peer name gw-veth0
25 | sudo ip link add wan-veth0 type veth peer name gw-veth1
26 | }
27 |
28 | : "set-veth" && {
29 | sudo ip link set lan-veth0 netns lan
30 | sudo ip link set gw-veth0 netns router
31 | sudo ip link set gw-veth1 netns router
32 | sudo ip link set wan-veth0 netns wan
33 | }
34 |
35 | : "link-up" && {
36 | sudo ip netns exec lan ip link set lan-veth0 up
37 | sudo ip netns exec router ip link set gw-veth0 up
38 | sudo ip netns exec router ip link set gw-veth1 up
39 | sudo ip netns exec wan ip link set wan-veth0 up
40 | }
41 |
42 | : "setup-lan" && {
43 | sudo ip netns exec lan ip address add 192.0.2.1/24 dev lan-veth0
44 | sudo ip netns exec lan ip route add default via 192.0.2.254
45 | }
46 |
47 | : "setup-router" && {
48 | sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0
49 | sudo ip netns exec router ip address add 203.0.113.254/24 dev gw-veth1
50 | sudo ip netns exec router sysctl net.ipv4.ip_forward=1
51 | }
52 |
53 | : "setup-wan" && {
54 | sudo ip netns exec wan ip address add 203.0.113.1/24 dev wan-veth0
55 | sudo ip netns exec wan ip route add default via 203.0.113.254
56 | }
57 |
58 | : "add-snat-rule" && {
59 | sudo ip netns exec router iptables -t nat \
60 | -A POSTROUTING \
61 | -s 192.0.2.0/24 \
62 | -o gw-veth1 \
63 | -j MASQUERADE
64 | }
65 |
66 | : "add-dnat-rule" && {
67 | sudo ip netns exec router iptables -t nat \
68 | -A PREROUTING \
69 | -p tcp \
70 | --dport 54321 \
71 | -d 203.0.113.254 \
72 | -j DNAT \
73 | --to-destination 192.0.2.1
74 | }
75 |
76 | : "test" && {
77 | sudo ip netns exec lan ping -c 3 203.0.113.1
78 | }
79 |
80 | : "done" && {
81 | set +x
82 | echo "successful"
83 | }
--------------------------------------------------------------------------------
/commands/6.application/dhcp.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/dhcp.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add server
12 | $ sudo ip netns add client
13 | ----------
14 |
15 | ----------
16 | $ sudo ip link add s-veth0 type veth peer name c-veth0
17 | ----------
18 |
19 | ----------
20 | $ sudo ip link set s-veth0 netns server
21 | $ sudo ip link set c-veth0 netns client
22 | ----------
23 |
24 | ----------
25 | $ sudo ip netns exec server ip link set s-veth0 up
26 | $ sudo ip netns exec client ip link set c-veth0 up
27 | ----------
28 |
29 | ----------
30 | $ sudo ip netns exec server ip address add 192.0.2.254/24 dev s-veth0
31 | ----------
32 |
33 | ----------
34 | $ sudo ip netns exec server dnsmasq \
35 | --dhcp-range=192.0.2.100,192.0.2.200,255.255.255.0 \
36 | --interface=s-veth0 \
37 | --port 0 \
38 | --no-resolv \
39 | --no-daemon
40 | ----------
41 |
42 | ----------
43 | $ sudo ip netns exec client dhclient -d c-veth0
44 | Internet Systems Consortium DHCP Client 4.4.1
45 | Copyright 2004-2018 Internet Systems Consortium.
46 | All rights reserved.
47 | For info, please visit https://www.isc.org/software/dhcp/
48 |
49 | Listening on LPF/c-veth0/a2:ef:a4:8e:5b:9b
50 | Sending on LPF/c-veth0/a2:ef:a4:8e:5b:9b
51 | Sending on Socket/fallback
52 | DHCPDISCOVER on c-veth0 to 255.255.255.255 port 67 interval 3 (xid=0x6210f349)
53 | DHCPDISCOVER on c-veth0 to 255.255.255.255 port 67 interval 4 (xid=0x6210f349)
54 | DHCPOFFER of 192.0.2.195 from 192.0.2.254
55 | DHCPREQUEST for 192.0.2.195 on c-veth0 to 255.255.255.255 port 67 (xid=0x49f31062)
56 | DHCPACK of 192.0.2.195 from 192.0.2.254 (xid=0x6210f349)
57 | bound to 192.0.2.195 -- renewal in 1742 seconds.
58 | ----------
59 |
60 | ----------
61 | $ sudo ip netns exec client ip address show | grep "inet "
62 | inet 192.0.2.195/24 brd 192.0.2.255 scope global dynamic c-veth0
63 | ----------
64 |
65 | ----------
66 | $ sudo ip netns exec client ip route show
67 | default via 192.0.2.254 dev c-veth0
68 | 192.0.2.0/24 dev c-veth0 proto kernel scope link src 192.0.2.195
69 | ----------
70 |
--------------------------------------------------------------------------------
/commands/7.nat/dnat.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip netns exec router iptables -t nat \
3 | -A PREROUTING \
4 | -p tcp \
5 | --dport 54321 \
6 | -d 203.0.113.254 \
7 | -j DNAT \
8 | --to-destination 192.0.2.1
9 | ----------
10 |
11 | ----------
12 | $ sudo ip netns exec router iptables -t nat -L
13 | Chain PREROUTING (policy ACCEPT)
14 | target prot opt source destination
15 | DNAT tcp -- anywhere 203.0.113.254 tcp dpt:54321 to:192.0.2.1
16 |
17 | Chain INPUT (policy ACCEPT)
18 | target prot opt source destination
19 |
20 | Chain OUTPUT (policy ACCEPT)
21 | target prot opt source destination
22 |
23 | Chain POSTROUTING (policy ACCEPT)
24 | target prot opt source destination
25 | MASQUERADE all -- 192.0.2.0/24 anywhere
26 | ----------
27 |
28 | ----------
29 | $ sudo ip netns exec lan nc -lnv 54321
30 | Listening on 0.0.0.0 54321
31 | Connection received on 203.0.113.1 48788
32 | Hello, World!
33 | ----------
34 |
35 | ----------
36 | $ sudo ip netns exec wan tcpdump -tnl -i wan-veth0 "tcp and port 54321"
37 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
38 | listening on wan-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
39 | IP 203.0.113.1.48788 > 203.0.113.254.54321: Flags [P.], seq 1647386507:1647386521, ack 1045484319, win 502, options [nop,nop,TS val 2177472125 ecr 352382749], length 14
40 | IP 203.0.113.254.54321 > 203.0.113.1.48788: Flags [.], ack 14, win 509, options [nop,nop,TS val 352403859 ecr 2177472125], length 0
41 | ----------
42 |
43 | ----------
44 | $ sudo ip netns exec wan nc 203.0.113.254 54321
45 | Hello, World!
46 | Hello, World!
47 | ----------
48 |
49 | ----------
50 | $ sudo ip netns exec lan tcpdump -tnl -i lan-veth0 "tcp and port 54321"
51 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
52 | listening on lan-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
53 | IP 203.0.113.1.48788 > 192.0.2.1.54321: Flags [P.], seq 1647386521:1647386535, ack 1045484319, win 502, options [nop,nop,TS val 2177899957 ecr 352403859], length 14
54 | IP 192.0.2.1.54321 > 203.0.113.1.48788: Flags [.], ack 14, win 509, options [nop,nop,TS val 352831691 ecr 2177899957], length 0
55 | ----------
56 |
--------------------------------------------------------------------------------
/commands/5.transport/tcp.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ nc -lnv 127.0.0.1 54321
3 | Listening on 127.0.0.1 54321
4 | ----------
5 |
6 | ----------
7 | $ sudo tcpdump -i lo -tnlA "tcp and port 54321"
8 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
9 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10 | ----------
11 |
12 | ----------
13 | $ nc 127.0.0.1 54321
14 | ----------
15 |
16 | ----------
17 | $ nc -lnv 127.0.0.1 54321
18 | Listening on 127.0.0.1 54321
19 | Connection received on 127.0.0.1 49556
20 | ----------
21 |
22 | ----------
23 | $ sudo tcpdump -i lo -tnlA "tcp and port 54321"
24 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
25 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
26 | IP 127.0.0.1.49556 > 127.0.0.1.54321: Flags [S], seq 1077214334, win 65495, options [mss 65495,sackOK,TS val 682014648 ecr 0,nop,wscale 7], length 0
27 | E..<.D@.@.au...........1@4.~.........0.........
28 | (...........
29 | IP 127.0.0.1.54321 > 127.0.0.1.49556: Flags [S.], seq 474850443, ack 1077214335, win 65483, options [mss 65495,sackOK,TS val 682014648 ecr 682014648,nop,wscale 7], length 0
30 | E..<..@.@.<..........1...M..@4.......0.........
31 | (...(.......
32 | IP 127.0.0.1.49556 > 127.0.0.1.54321: Flags [.], ack 1, win 512, options [nop,nop,TS val 682014648 ecr 682014648], length 0
33 | E..4.E@.@.a|...........1@4...M.......(.....
34 | (...(...
35 | ----------
36 |
37 | ----------
38 | $ nc 127.0.0.1 54321
39 | Hello, World!
40 | ----------
41 |
42 | ----------
43 | $ nc -lnv 127.0.0.1 54321
44 | Listening on 127.0.0.1 54321
45 | Connection received on 127.0.0.1 49556
46 | Hello, World!
47 | ----------
48 |
49 | ----------
50 | $ sudo tcpdump -i lo -tnlA "tcp and port 54321"
51 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
52 | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
53 |
54 | ...(省略)...
55 |
56 | IP 127.0.0.1.49556 > 127.0.0.1.54321: Flags [P.], seq 1:15, ack 1, win 512, options [nop,nop,TS val 682062978 ecr 682014648], length 14
57 | E..B.F@.@.am...........1@4...M.......6.....
58 | (.t.(...Hello, World!
59 |
60 | IP 127.0.0.1.54321 > 127.0.0.1.49556: Flags [.], ack 15, win 512, options [nop,nop,TS val 682062978 ecr 682062978], length 0
61 | E..4L.@.@............1...M..@4.......(.....
62 | (.t.(.t.
63 | ----------
64 |
--------------------------------------------------------------------------------
/sources/8.socket/addclient.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """ソケットを使って ADD プロトコルを実装したクライアントのスクリプト"""
4 |
5 | import socket
6 | import struct
7 |
8 |
9 | def send_msg(sock, msg):
10 | """ソケットに指定したバイト列を書き込む関数"""
11 | # これまでに送信できたバイト数
12 | total_sent_len = 0
13 | # 送信したいバイト数
14 | total_msg_len = len(msg)
15 | # まだ送信したいデータが残っているか判定する
16 | while total_sent_len < total_msg_len:
17 | # ソケットにバイト列を書き込んで、書き込めたバイト数を得る
18 | sent_len = sock.send(msg[total_sent_len:])
19 | # まったく書き込めなかったらソケットの接続が終了している
20 | if sent_len == 0:
21 | raise RuntimeError('socket connection broken')
22 | # 書き込めた分を加算する
23 | total_sent_len += sent_len
24 |
25 |
26 | def recv_msg(sock, total_msg_size):
27 | """ソケットから特定のバイト数を読み込む関数"""
28 | # これまでに受信できたバイト数
29 | total_recv_size = 0
30 | # 指定したバイト数を受信できたか判定する
31 | while total_recv_size < total_msg_size:
32 | # 残りのバイト列を受信する
33 | received_chunk = sock.recv(total_msg_size - total_recv_size)
34 | # 1 バイトも読めなかったときはソケットの接続が終了している
35 | if len(received_chunk) == 0:
36 | raise RuntimeError('socket connection broken')
37 | # 受信したバイト列を返す
38 | yield received_chunk
39 | # 受信できたバイト数を加算する
40 | total_recv_size += len(received_chunk)
41 |
42 |
43 | def main():
44 | """スクリプトとして実行されたときに呼び出されるメイン関数"""
45 | # IPv4 / TCP で通信するソケットを用意する
46 | client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
47 | # ループバックアドレスの TCP/54321 ポートに接続する
48 | client_socket.connect(('127.0.0.1', 54321))
49 | # 足し算したい値を用意する
50 | operand1, operand2 = 1000, 2000
51 | # 送信する値を確認する
52 | print(f'operand1: {operand1}, operand2: {operand2}')
53 | # ネットワークバイトオーダーのバイト列に変換する
54 | request_msg = struct.pack('!ii', operand1, operand2)
55 | # ソケットにバイト列を書き込む
56 | send_msg(client_socket, request_msg)
57 | # 書き込んだバイト列を表示する
58 | print(f'sent: {request_msg}')
59 | # ソケットからバイト列を読み込む
60 | received_msg = b''.join(recv_msg(client_socket, 8))
61 | # 読み込んだバイト列を表示する
62 | print(f'received: {received_msg}')
63 | # 64 ビットの整数として解釈する
64 | (added_value, ) = struct.unpack('!q', received_msg)
65 | # 解釈した値を表示する
66 | print(f'result: {added_value}')
67 | # ソケットを閉じる
68 | client_socket.close()
69 |
70 |
71 | if __name__ == '__main__':
72 | """スクリプトのエントリーポイントとしてメイン関数を実行する"""
73 | main()
--------------------------------------------------------------------------------
/scripts/bridge.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add ns1
19 | sudo ip netns add ns2
20 | sudo ip netns add ns3
21 | sudo ip netns add bridge
22 | }
23 |
24 | : "add-veth" && {
25 | sudo ip link add ns1-veth0 type veth peer name ns1-br0
26 | sudo ip link add ns2-veth0 type veth peer name ns2-br0
27 | sudo ip link add ns3-veth0 type veth peer name ns3-br0
28 | }
29 |
30 | : "set-veth" && {
31 | sudo ip link set ns1-veth0 netns ns1
32 | sudo ip link set ns2-veth0 netns ns2
33 | sudo ip link set ns3-veth0 netns ns3
34 | sudo ip link set ns1-br0 netns bridge
35 | sudo ip link set ns2-br0 netns bridge
36 | sudo ip link set ns3-br0 netns bridge
37 | }
38 |
39 | : "link-up" && {
40 | sudo ip netns exec ns1 ip link set ns1-veth0 up
41 | sudo ip netns exec ns2 ip link set ns2-veth0 up
42 | sudo ip netns exec ns3 ip link set ns3-veth0 up
43 | sudo ip netns exec bridge ip link set ns1-br0 up
44 | sudo ip netns exec bridge ip link set ns2-br0 up
45 | sudo ip netns exec bridge ip link set ns3-br0 up
46 | }
47 |
48 | : "add-ip" && {
49 | sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
50 | sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
51 | sudo ip netns exec ns3 ip address add 192.0.2.3/24 dev ns3-veth0
52 | }
53 |
54 | : "set-hw-addr" && {
55 | sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01
56 | sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
57 | sudo ip netns exec ns3 ip link set dev ns3-veth0 address 00:00:5E:00:53:03
58 | }
59 |
60 | : "add-bridge" && {
61 | sudo ip netns exec bridge ip link add dev br0 type bridge
62 | sudo ip netns exec bridge ip link set br0 up
63 | }
64 |
65 | : "add-bridge-port" && {
66 | sudo ip netns exec bridge ip link set ns1-br0 master br0
67 | sudo ip netns exec bridge ip link set ns2-br0 master br0
68 | sudo ip netns exec bridge ip link set ns3-br0 master br0
69 | }
70 |
71 | : "test" && {
72 | sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
73 | sudo ip netns exec ns1 ping -c 3 192.0.2.3 -I 192.0.2.1
74 | }
75 |
76 | : "done" && {
77 | set +x
78 | echo "successful"
79 | }
--------------------------------------------------------------------------------
/commands/2.what-is-tcp-ip/ipv4-address.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ ip address show
3 | 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
4 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5 | inet 127.0.0.1/8 scope host lo
6 | valid_lft forever preferred_lft forever
7 | inet6 ::1/128 scope host
8 | valid_lft forever preferred_lft forever
9 | 2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
10 | link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff
11 | inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
12 | valid_lft 85939sec preferred_lft 85939sec
13 | inet6 fe80::200:5eff:fe00:5301/64 scope link
14 | valid_lft forever preferred_lft forever
15 | ----------
16 |
17 | ----------
18 | $ ping -c 3 127.0.0.1
19 | PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
20 | 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.016 ms
21 | 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.048 ms
22 | 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.036 ms
23 |
24 | --- 127.0.0.1 ping statistics ---
25 | 3 packets transmitted, 3 received, 0% packet loss, time 2032ms
26 | rtt min/avg/max/mdev = 0.016/0.033/0.048/0.014 ms
27 | ----------
28 |
29 | ----------
30 | $ sudo tcpdump -tn -i any icmp
31 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
32 | listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
33 | IP 10.0.2.15 > 8.8.8.8: ICMP echo request, id 2766, seq 1, length 64
34 | IP 8.8.8.8 > 10.0.2.15: ICMP echo reply, id 2766, seq 1, length 64
35 | IP 10.0.2.15 > 8.8.8.8: ICMP echo request, id 2766, seq 2, length 64
36 | IP 8.8.8.8 > 10.0.2.15: ICMP echo reply, id 2766, seq 2, length 64
37 | IP 10.0.2.15 > 8.8.8.8: ICMP echo request, id 2766, seq 3, length 64
38 | IP 8.8.8.8 > 10.0.2.15: ICMP echo reply, id 2766, seq 3, length 64
39 | ^C
40 | 6 packets captured
41 | 6 packets received by filter
42 | 0 packets dropped by kernel
43 | ----------
44 |
45 | ----------
46 | $ ping -c 3 8.8.8.8
47 | PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
48 | 64 bytes from 8.8.8.8: icmp_seq=1 ttl=63 time=10.6 ms
49 | 64 bytes from 8.8.8.8: icmp_seq=2 ttl=63 time=11.2 ms
50 | 64 bytes from 8.8.8.8: icmp_seq=3 ttl=63 time=12.8 ms
51 |
52 | --- 8.8.8.8 ping statistics ---
53 | 3 packets transmitted, 3 received, 0% packet loss, time 2004ms
54 | rtt min/avg/max/mdev = 10.669/11.585/12.838/0.925 ms
55 | ----------
56 |
--------------------------------------------------------------------------------
/scripts/triple-segment.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Ceuo pipefail
4 |
5 | function error_handler() {
6 | set +x
7 | echo "something went wrong" >&2
8 | exit 1
9 | }
10 |
11 | : "start" && {
12 | echo "start building..."
13 | trap error_handler ERR
14 | set -x
15 | }
16 |
17 | : "add-netns" && {
18 | sudo ip netns add ns1
19 | sudo ip netns add router1
20 | sudo ip netns add router2
21 | sudo ip netns add ns2
22 | }
23 |
24 | : "add-veth" && {
25 | sudo ip link add ns1-veth0 type veth peer name gw1-veth0
26 | sudo ip link add gw1-veth1 type veth peer name gw2-veth0
27 | sudo ip link add gw2-veth1 type veth peer name ns2-veth0
28 | }
29 |
30 | : "set-veth" && {
31 | sudo ip link set ns1-veth0 netns ns1
32 | sudo ip link set gw1-veth0 netns router1
33 | sudo ip link set gw1-veth1 netns router1
34 | sudo ip link set gw2-veth0 netns router2
35 | sudo ip link set gw2-veth1 netns router2
36 | sudo ip link set ns2-veth0 netns ns2
37 | }
38 |
39 | : "link-up" && {
40 | sudo ip netns exec ns1 ip link set ns1-veth0 up
41 | sudo ip netns exec router1 ip link set gw1-veth0 up
42 | sudo ip netns exec router1 ip link set gw1-veth1 up
43 | sudo ip netns exec router2 ip link set gw2-veth0 up
44 | sudo ip netns exec router2 ip link set gw2-veth1 up
45 | sudo ip netns exec ns2 ip link set ns2-veth0 up
46 | }
47 |
48 | : "set-ip" && {
49 | sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
50 | sudo ip netns exec router1 ip address add 192.0.2.254/24 dev gw1-veth0
51 | sudo ip netns exec router1 ip address add 203.0.113.1/24 dev gw1-veth1
52 | sudo ip netns exec router2 ip address add 203.0.113.2/24 dev gw2-veth0
53 | sudo ip netns exec router2 ip address add 198.51.100.254/24 dev gw2-veth1
54 | sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
55 | }
56 |
57 | : "set-default-route" && {
58 | sudo ip netns exec ns1 ip route add default via 192.0.2.254
59 | sudo ip netns exec ns2 ip route add default via 198.51.100.254
60 | }
61 |
62 | : "to-be-router" && {
63 | sudo ip netns exec router1 sysctl net.ipv4.ip_forward=1
64 | sudo ip netns exec router2 sysctl net.ipv4.ip_forward=1
65 | }
66 |
67 | : "add-static-route" && {
68 | sudo ip netns exec router1 ip route add 198.51.100.0/24 via 203.0.113.2
69 | sudo ip netns exec router2 ip route add 192.0.2.0/24 via 203.0.113.1
70 | }
71 |
72 | : "test" && {
73 | sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
74 | }
75 |
76 | : "done" && {
77 | set +x
78 | echo "successful"
79 | }
--------------------------------------------------------------------------------
/sources/8.socket/addserver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """ソケットを使って ADD プロトコルを実装したサーバのスクリプト"""
4 |
5 | import socket
6 | import struct
7 |
8 |
9 | def send_msg(sock, msg):
10 | """ソケットに指定したバイト列を書き込む関数"""
11 | # これまでに送信できたバイト数
12 | total_sent_len = 0
13 | # 送信したいバイト数
14 | total_msg_len = len(msg)
15 | # まだ送信したいデータが残っているか判定する
16 | while total_sent_len < total_msg_len:
17 | # ソケットにバイト列を書き込んで、書き込めたバイト数を得る
18 | sent_len = sock.send(msg[total_sent_len:])
19 | # まったく書き込めなかったらソケットの接続が終了している
20 | if sent_len == 0:
21 | raise RuntimeError('socket connection broken')
22 | # 書き込めた分を加算する
23 | total_sent_len += sent_len
24 |
25 |
26 | def recv_msg(sock, total_msg_size):
27 | """ソケットから特定のバイト数を読み込む関数"""
28 | # これまでに受信できたバイト数
29 | total_recv_size = 0
30 | # 指定したバイト数を受信できたか判定する
31 | while total_recv_size < total_msg_size:
32 | # 残りのバイト列を受信する
33 | received_chunk = sock.recv(total_msg_size - total_recv_size)
34 | # 1 バイトも読めなかったときはソケットの接続が終了している
35 | if len(received_chunk) == 0:
36 | raise RuntimeError('socket connection broken')
37 | # 受信したバイト列を返す
38 | yield received_chunk
39 | # 受信できたバイト数を加算する
40 | total_recv_size += len(received_chunk)
41 |
42 |
43 | def main():
44 | """スクリプトとして実行されたときに呼び出されるメイン関数"""
45 | # IPv4 / TCP で通信するソケットを用意する
46 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
47 | # 'Address already in use' の回避策
48 | server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
49 | # ループバックアドレスの TCP/54321 ポートを使う
50 | server_socket.bind(('127.0.0.1', 54321))
51 | # 接続を待ち受ける
52 | server_socket.listen()
53 | # サーバが動作を開始したことを表示する
54 | print('starting server ...')
55 | # クライアントからの接続を処理する
56 | client_socket, (client_address, client_port) = server_socket.accept()
57 | # 接続してきたクライアントの情報を表示する
58 | print(f'accepted from {client_address}:{client_port}')
59 | # バイト列を受信する
60 | received_msg = b''.join(recv_msg(client_socket, total_msg_size=8))
61 | # 受信したバイト列を表示する
62 | print(f'received: {received_msg}')
63 | # バイト列を 2 つの 32 ビットの整数として解釈する
64 | (operand1, operand2) = struct.unpack('!ii', received_msg)
65 | # 解釈した値を表示する
66 | print(f'operand1: {operand1}, operand2: {operand2}')
67 | # 計算する
68 | result = operand1 + operand2
69 | # 計算した値を表示する
70 | print(f'result: {result}')
71 | # 計算した値を 64 ビットの整数としてネットワークバイトオーダーのバイト列に変換する
72 | result_msg = struct.pack('!q', result)
73 | # ソケットにバイト列を書き込む
74 | send_msg(client_socket, result_msg)
75 | # 書き込んだバイト列を表示する
76 | print(f'sent: {result_msg}')
77 | # ソケットの接続を終了する
78 | client_socket.close()
79 | server_socket.close()
80 |
81 |
82 | if __name__ == '__main__':
83 | """スクリプトのエントリーポイントとしてメイン関数を実行する"""
84 | main()
--------------------------------------------------------------------------------
/commands/3.linux-netns/veth.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/single-segment.sh | bash
3 | ----------
4 |
5 | ----------
6 | $ sudo ip netns add ns1
7 | $ sudo ip netns add ns2
8 | ----------
9 |
10 | ----------
11 | $ sudo ip link add ns1-veth0 type veth peer name ns2-veth0
12 | ----------
13 |
14 | ----------
15 | $ ip link show | grep veth
16 | 3: ns2-veth0@ns1-veth0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
17 | 4: ns1-veth0@ns2-veth0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
18 | ----------
19 |
20 | ----------
21 | $ sudo ip link set ns1-veth0 netns ns1
22 | $ sudo ip link set ns2-veth0 netns ns2
23 | ----------
24 |
25 | ----------
26 | $ ip link show | grep veth
27 | ----------
28 |
29 | ----------
30 | $ sudo ip netns exec ns1 ip link show | grep veth
31 | 4: ns1-veth0@if3: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
32 | $ sudo ip netns exec ns2 ip link show | grep veth
33 | 3: ns2-veth0@if4: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
34 | ----------
35 |
36 | ----------
37 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
38 | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
39 | ----------
40 |
41 | ----------
42 | $ sudo ip netns exec ns1 ip link show ns1-veth0 | grep state
43 | 4: ns1-veth0@if3: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
44 | $ sudo ip netns exec ns2 ip link show ns2-veth0 | grep state
45 | 3: ns2-veth0@if4: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
46 | ----------
47 |
48 | ----------
49 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
50 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
51 | ----------
52 |
53 | ----------
54 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.2
55 | PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
56 | 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.038 ms
57 | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.042 ms
58 | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.042 ms
59 |
60 | --- 192.0.2.2 ping statistics ---
61 | 3 packets transmitted, 3 received, 0% packet loss, time 2045ms
62 | rtt min/avg/max/mdev = 0.038/0.040/0.042/0.007 ms
63 | ----------
64 |
65 | ----------
66 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
67 | PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
68 | 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.026 ms
69 | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.042 ms
70 | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.054 ms
71 |
72 | --- 192.0.2.2 ping statistics ---
73 | 3 packets transmitted, 3 received, 0% packet loss, time 2031ms
74 | rtt min/avg/max/mdev = 0.026/0.040/0.054/0.013 ms
75 | ----------
76 |
--------------------------------------------------------------------------------
/commands/4.ethernet/observe.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/single-segment.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add ns1
12 | $ sudo ip netns add ns2
13 | ----------
14 |
15 | ----------
16 | $ sudo ip link add ns1-veth0 type veth peer name ns2-veth0
17 | ----------
18 |
19 | ----------
20 | $ sudo ip link set ns1-veth0 netns ns1
21 | $ sudo ip link set ns2-veth0 netns ns2
22 | ----------
23 |
24 | ----------
25 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
26 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
27 | ----------
28 |
29 | ----------
30 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
31 | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
32 | ----------
33 |
34 | ----------
35 | $ sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01
36 | $ sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
37 | ----------
38 |
39 | ----------
40 | $ sudo ip netns exec ns1 ip link show | grep link/ether
41 | link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff link-netnsid 1
42 | $ sudo ip netns exec ns2 ip link show | grep link/ether
43 | link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
44 | ----------
45 |
46 | ----------
47 | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp
48 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
49 | listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
50 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23582, seq 1, length 64
51 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23582, seq 1, length 64
52 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23582, seq 2, length 64
53 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23582, seq 2, length 64
54 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 23582, seq 3, length 64
55 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 23582, seq 3, length 64
56 | ----------
57 |
58 | ----------
59 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
60 | PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
61 | 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.039 ms
62 | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.036 ms
63 | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.150 ms
64 |
65 | --- 192.0.2.2 ping statistics ---
66 | 3 packets transmitted, 3 received, 0% packet loss, time 2025ms
67 | rtt min/avg/max/mdev = 0.036/0.075/0.150/0.053 ms
68 | ----------
69 |
--------------------------------------------------------------------------------
/commands/3.linux-netns/multi-router.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/triple-segment.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add ns1
12 | $ sudo ip netns add router1
13 | $ sudo ip netns add router2
14 | $ sudo ip netns add ns2
15 | ----------
16 |
17 | ----------
18 | $ sudo ip link add ns1-veth0 type veth peer name gw1-veth0
19 | $ sudo ip link add gw1-veth1 type veth peer name gw2-veth0
20 | $ sudo ip link add gw2-veth1 type veth peer name ns2-veth0
21 | ----------
22 |
23 | ----------
24 | $ sudo ip link set ns1-veth0 netns ns1
25 | $ sudo ip link set gw1-veth0 netns router1
26 | $ sudo ip link set gw1-veth1 netns router1
27 | $ sudo ip link set gw2-veth0 netns router2
28 | $ sudo ip link set gw2-veth1 netns router2
29 | $ sudo ip link set ns2-veth0 netns ns2
30 | ----------
31 |
32 | ----------
33 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
34 | $ sudo ip netns exec router1 ip link set gw1-veth0 up
35 | $ sudo ip netns exec router1 ip link set gw1-veth1 up
36 | $ sudo ip netns exec router2 ip link set gw2-veth0 up
37 | $ sudo ip netns exec router2 ip link set gw2-veth1 up
38 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
39 | ----------
40 |
41 | ----------
42 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
43 | $ sudo ip netns exec router1 ip address add 192.0.2.254/24 dev gw1-veth0
44 | $ sudo ip netns exec router1 ip address add 203.0.113.1/24 dev gw1-veth1
45 | $ sudo ip netns exec router2 ip address add 203.0.113.2/24 dev gw2-veth0
46 | $ sudo ip netns exec router2 ip address add 198.51.100.254/24 dev gw2-veth1
47 | $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
48 | ----------
49 |
50 | ----------
51 | $ sudo ip netns exec ns1 ip route add default via 192.0.2.254
52 | $ sudo ip netns exec ns2 ip route add default via 198.51.100.254
53 | ----------
54 |
55 | ----------
56 | $ sudo ip netns exec router1 sysctl net.ipv4.ip_forward=1
57 | $ sudo ip netns exec router2 sysctl net.ipv4.ip_forward=1
58 | ----------
59 |
60 | ----------
61 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
62 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
63 | From 192.0.2.254 icmp_seq=1 Destination Net Unreachable
64 | From 192.0.2.254 icmp_seq=2 Destination Net Unreachable
65 | From 192.0.2.254 icmp_seq=3 Destination Net Unreachable
66 |
67 | --- 198.51.100.1 ping statistics ---
68 | 3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2042ms
69 | ----------
70 |
71 | ----------
72 | $ sudo ip netns exec router1 ip route add 198.51.100.0/24 via 203.0.113.2
73 | $ sudo ip netns exec router2 ip route add 192.0.2.0/24 via 203.0.113.1
74 | ----------
75 |
76 | ----------
77 | $ sudo ip netns exec router1 ip route add default via 203.0.113.2
78 | $ sudo ip netns exec router2 ip route add default via 203.0.113.1
79 | ----------
80 |
81 | ----------
82 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
83 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
84 | 64 bytes from 198.51.100.1: icmp_seq=1 ttl=62 time=0.162 ms
85 | 64 bytes from 198.51.100.1: icmp_seq=2 ttl=62 time=0.076 ms
86 | 64 bytes from 198.51.100.1: icmp_seq=3 ttl=62 time=0.060 ms
87 |
88 | --- 198.51.100.1 ping statistics ---
89 | 3 packets transmitted, 3 received, 0% packet loss, time 2054ms
90 | rtt min/avg/max/mdev = 0.060/0.099/0.162/0.045 ms
91 | ----------
92 |
--------------------------------------------------------------------------------
/commands/3.linux-netns/with-router.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/double-segment.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip netns delete ns1
8 | $ sudo ip netns delete ns2
9 | ----------
10 |
11 | ----------
12 | $ sudo ip --all netns delete
13 | ----------
14 |
15 | ----------
16 | $ sudo ip netns add ns1
17 | $ sudo ip netns add router
18 | $ sudo ip netns add ns2
19 | ----------
20 |
21 | ----------
22 | $ sudo ip link add ns1-veth0 type veth peer name gw-veth0
23 | $ sudo ip link add ns2-veth0 type veth peer name gw-veth1
24 | ----------
25 |
26 | ----------
27 | $ sudo ip link set ns1-veth0 netns ns1
28 | $ sudo ip link set gw-veth0 netns router
29 | $ sudo ip link set gw-veth1 netns router
30 | $ sudo ip link set ns2-veth0 netns ns2
31 | ----------
32 |
33 | ----------
34 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
35 | $ sudo ip netns exec router ip link set gw-veth0 up
36 | $ sudo ip netns exec router ip link set gw-veth1 up
37 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
38 | ----------
39 |
40 | ----------
41 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
42 | $ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0
43 | ----------
44 |
45 | ----------
46 | $ sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1
47 | $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
48 | ----------
49 |
50 | ----------
51 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.254 -I 192.0.2.1
52 | PING 192.0.2.254 (192.0.2.254) from 192.0.2.1 : 56(84) bytes of data.
53 | 64 bytes from 192.0.2.254: icmp_seq=1 ttl=64 time=0.059 ms
54 | 64 bytes from 192.0.2.254: icmp_seq=2 ttl=64 time=0.043 ms
55 | 64 bytes from 192.0.2.254: icmp_seq=3 ttl=64 time=0.052 ms
56 |
57 | --- 192.0.2.254 ping statistics ---
58 | 3 packets transmitted, 3 received, 0% packet loss, time 2033ms
59 | rtt min/avg/max/mdev = 0.043/0.051/0.059/0.008 ms
60 | ----------
61 |
62 | ----------
63 | $ sudo ip netns exec ns2 ping -c 3 198.51.100.254 -I 198.51.100.1
64 | PING 198.51.100.254 (198.51.100.254) from 198.51.100.1 : 56(84) bytes of data.
65 | 64 bytes from 198.51.100.254: icmp_seq=1 ttl=64 time=0.099 ms
66 | 64 bytes from 198.51.100.254: icmp_seq=2 ttl=64 time=0.061 ms
67 | 64 bytes from 198.51.100.254: icmp_seq=3 ttl=64 time=0.155 ms
68 |
69 | --- 198.51.100.254 ping statistics ---
70 | 3 packets transmitted, 3 received, 0% packet loss, time 2051ms
71 | rtt min/avg/max/mdev = 0.061/0.105/0.155/0.038 ms
72 | ----------
73 |
74 | ----------
75 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
76 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
77 | ping: sendmsg: Network is unreachable
78 | ping: sendmsg: Network is unreachable
79 | ping: sendmsg: Network is unreachable
80 |
81 | --- 198.51.100.1 ping statistics ---
82 | 3 packets transmitted, 0 received, 100% packet loss, time 2054ms
83 | ----------
84 |
85 | ----------
86 | $ sudo ip netns exec ns1 ip route show
87 | 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1
88 | ----------
89 |
90 | ----------
91 | $ sudo ip netns exec ns1 ip route add default via 192.0.2.254
92 | ----------
93 |
94 | ----------
95 | $ sudo ip netns exec ns1 ip route add 198.51.100.1 via 192.0.2.254
96 | ----------
97 |
98 | ----------
99 | $ sudo ip netns exec ns2 ip route add default via 198.51.100.254
100 | ----------
101 |
102 | ----------
103 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
104 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
105 |
106 | --- 198.51.100.1 ping statistics ---
107 | 3 packets transmitted, 0 received, 100% packet loss, time 2038ms
108 | ----------
109 |
110 | ----------
111 | $ sudo ip netns exec router sysctl net.ipv4.ip_forward=0
112 | ----------
113 |
114 | ----------
115 | $ sudo ip netns exec router sysctl net.ipv4.ip_forward=1
116 | net.ipv4.ip_forward = 1
117 | ----------
118 |
119 | ----------
120 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
121 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
122 | 64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.034 ms
123 | 64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=0.063 ms
124 | 64 bytes from 198.51.100.1: icmp_seq=3 ttl=63 time=0.050 ms
125 |
126 | --- 198.51.100.1 ping statistics ---
127 | 3 packets transmitted, 3 received, 0% packet loss, time 2053ms
128 | rtt min/avg/max/mdev = 0.034/0.049/0.063/0.011 ms
129 | ----------
130 |
--------------------------------------------------------------------------------
/commands/7.nat/snat.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/nat.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add lan
12 | $ sudo ip netns add router
13 | $ sudo ip netns add wan
14 | ----------
15 |
16 | ----------
17 | $ sudo ip link add lan-veth0 type veth peer name gw-veth0
18 | $ sudo ip link add wan-veth0 type veth peer name gw-veth1
19 | ----------
20 |
21 | ----------
22 | $ sudo ip link set lan-veth0 netns lan
23 | $ sudo ip link set gw-veth0 netns router
24 | $ sudo ip link set gw-veth1 netns router
25 | $ sudo ip link set wan-veth0 netns wan
26 | ----------
27 |
28 | ----------
29 | $ sudo ip netns exec lan ip link set lan-veth0 up
30 | $ sudo ip netns exec router ip link set gw-veth0 up
31 | $ sudo ip netns exec router ip link set gw-veth1 up
32 | $ sudo ip netns exec wan ip link set wan-veth0 up
33 | ----------
34 |
35 | ----------
36 | $ sudo ip netns exec lan ip address add 192.0.2.1/24 dev lan-veth0
37 | $ sudo ip netns exec lan ip route add default via 192.0.2.254
38 | ----------
39 |
40 | ----------
41 | $ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0
42 | $ sudo ip netns exec router ip address add 203.0.113.254/24 dev gw-veth1
43 | $ sudo ip netns exec router sysctl net.ipv4.ip_forward=1
44 | ----------
45 |
46 | ----------
47 | $ sudo ip netns exec wan ip address add 203.0.113.1/24 dev wan-veth0
48 | $ sudo ip netns exec wan ip route add default via 203.0.113.254
49 | ----------
50 |
51 | ----------
52 | $ sudo ip netns exec router iptables -t nat -L
53 | Chain PREROUTING (policy ACCEPT)
54 | target prot opt source destination
55 |
56 | Chain INPUT (policy ACCEPT)
57 | target prot opt source destination
58 |
59 | Chain OUTPUT (policy ACCEPT)
60 | target prot opt source destination
61 |
62 | Chain POSTROUTING (policy ACCEPT)
63 | target prot opt source destination
64 | ----------
65 |
66 | ----------
67 | $ sudo ip netns exec router iptables -t nat \
68 | -A POSTROUTING \
69 | -s 192.0.2.0/24 \
70 | -o gw-veth1 \
71 | -j MASQUERADE
72 | ----------
73 |
74 | ----------
75 | $ sudo ip netns exec router iptables -t nat -L
76 | Chain PREROUTING (policy ACCEPT)
77 | target prot opt source destination
78 |
79 | Chain INPUT (policy ACCEPT)
80 | target prot opt source destination
81 |
82 | Chain OUTPUT (policy ACCEPT)
83 | target prot opt source destination
84 |
85 | Chain POSTROUTING (policy ACCEPT)
86 | target prot opt source destination
87 | MASQUERADE all -- 192.0.2.0/24 anywhere
88 | ----------
89 |
90 | ----------
91 | $ sudo ip netns exec lan ping 203.0.113.1
92 | PING 203.0.113.1 (203.0.113.1) 56(84) bytes of data.
93 | 64 bytes from 203.0.113.1: icmp_seq=1 ttl=63 time=0.080 ms
94 | 64 bytes from 203.0.113.1: icmp_seq=2 ttl=63 time=0.091 ms
95 | 64 bytes from 203.0.113.1: icmp_seq=3 ttl=63 time=0.083 ms
96 |
97 | ...(省略)
98 | ----------
99 |
100 | ----------
101 | $ sudo ip netns exec lan tcpdump -tnl -i lan-veth0 icmp
102 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
103 | listening on lan-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
104 | IP 192.0.2.1 > 203.0.113.1: ICMP echo request, id 3059, seq 202, length 64
105 | IP 203.0.113.1 > 192.0.2.1: ICMP echo reply, id 3059, seq 202, length 64
106 | IP 192.0.2.1 > 203.0.113.1: ICMP echo request, id 3059, seq 203, length 64
107 | IP 203.0.113.1 > 192.0.2.1: ICMP echo reply, id 3059, seq 203, length 64
108 | IP 192.0.2.1 > 203.0.113.1: ICMP echo request, id 3059, seq 204, length 64
109 | IP 203.0.113.1 > 192.0.2.1: ICMP echo reply, id 3059, seq 204, length 64
110 | ----------
111 |
112 | ----------
113 | $ sudo ip netns exec wan tcpdump -tnl -i wan-veth0 icmp
114 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
115 | listening on wan-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
116 | IP 203.0.113.254 > 203.0.113.1: ICMP echo request, id 3059, seq 214, length 64
117 | IP 203.0.113.1 > 203.0.113.254: ICMP echo reply, id 3059, seq 214, length 64
118 | IP 203.0.113.254 > 203.0.113.1: ICMP echo request, id 3059, seq 215, length 64
119 | IP 203.0.113.1 > 203.0.113.254: ICMP echo reply, id 3059, seq 215, length 64
120 | IP 203.0.113.254 > 203.0.113.1: ICMP echo request, id 3059, seq 216, length 64
121 | IP 203.0.113.1 > 203.0.113.254: ICMP echo reply, id 3059, seq 216, length 64
122 | ----------
123 |
--------------------------------------------------------------------------------
/commands/4.ethernet/bridge.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/bridge.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add ns1
12 | $ sudo ip netns add ns2
13 | $ sudo ip netns add ns3
14 | $ sudo ip netns add bridge
15 | ----------
16 |
17 | ----------
18 | $ sudo ip link add ns1-veth0 type veth peer name ns1-br0
19 | $ sudo ip link add ns2-veth0 type veth peer name ns2-br0
20 | $ sudo ip link add ns3-veth0 type veth peer name ns3-br0
21 | ----------
22 |
23 | ----------
24 | $ sudo ip link set ns1-veth0 netns ns1
25 | $ sudo ip link set ns2-veth0 netns ns2
26 | $ sudo ip link set ns3-veth0 netns ns3
27 | $ sudo ip link set ns1-br0 netns bridge
28 | $ sudo ip link set ns2-br0 netns bridge
29 | $ sudo ip link set ns3-br0 netns bridge
30 | ----------
31 |
32 | ----------
33 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
34 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
35 | $ sudo ip netns exec ns3 ip link set ns3-veth0 up
36 | $ sudo ip netns exec bridge ip link set ns1-br0 up
37 | $ sudo ip netns exec bridge ip link set ns2-br0 up
38 | $ sudo ip netns exec bridge ip link set ns3-br0 up
39 | ----------
40 |
41 | ----------
42 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
43 | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
44 | $ sudo ip netns exec ns3 ip address add 192.0.2.3/24 dev ns3-veth0
45 | ----------
46 |
47 | ----------
48 | $ sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01
49 | $ sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
50 | $ sudo ip netns exec ns3 ip link set dev ns3-veth0 address 00:00:5E:00:53:03
51 | ----------
52 |
53 | ----------
54 | $ sudo ip netns exec bridge ip link add dev br0 type bridge
55 | $ sudo ip netns exec bridge ip link set br0 up
56 | ----------
57 |
58 | ----------
59 | $ sudo ip netns exec bridge ip link set ns1-br0 master br0
60 | $ sudo ip netns exec bridge ip link set ns2-br0 master br0
61 | $ sudo ip netns exec bridge ip link set ns3-br0 master br0
62 | ----------
63 |
64 | ----------
65 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
66 | PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
67 | 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.061 ms
68 | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.050 ms
69 | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.052 ms
70 |
71 | --- 192.0.2.2 ping statistics ---
72 | 3 packets transmitted, 3 received, 0% packet loss, time 2201ms
73 | rtt min/avg/max/mdev = 0.050/0.054/0.061/0.007 ms
74 | ----------
75 |
76 | ----------
77 | $ sudo ip netns exec ns1 ping -c 3 192.0.2.3 -I 192.0.2.1
78 | PING 192.0.2.3 (192.0.2.3) from 192.0.2.1 : 56(84) bytes of data.
79 | 64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.066 ms
80 | 64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.063 ms
81 | 64 bytes from 192.0.2.3: icmp_seq=3 ttl=64 time=0.062 ms
82 |
83 | --- 192.0.2.3 ping statistics ---
84 | 3 packets transmitted, 3 received, 0% packet loss, time 2038ms
85 | rtt min/avg/max/mdev = 0.062/0.063/0.066/0.009 ms
86 | ----------
87 |
88 | ----------
89 | $ sudo ip netns exec ns1 ping 192.0.2.2 -I 192.0.2.1
90 | ----------
91 |
92 | ----------
93 | $ sudo ip netns exec ns2 tcpdump -tnel -i ns2-veth0 icmp
94 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
95 | listening on ns2-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
96 | ...(省略)...
97 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 2972, seq 101, length 64
98 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 2972, seq 101, length 64
99 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 2972, seq 102, length 64
100 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 2972, seq 102, length 64
101 | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 2972, seq 103, length 64
102 | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 2972, seq 103, length 64
103 | ...(省略)
104 | ----------
105 |
106 | ----------
107 | $ sudo ip netns exec ns3 tcpdump -tnel -i ns3-veth0 icmp
108 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
109 | listening on ns3-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
110 | ----------
111 |
112 | ----------
113 | $ sudo ip netns exec bridge bridge fdb show br br0 | grep -i 00:00:5e
114 | 00:00:5e:00:53:01 dev ns1-br0 master br0
115 | 00:00:5e:00:53:02 dev ns2-br0 master br0
116 | 00:00:5e:00:53:03 dev ns3-br0 master br0
117 | ----------
118 |
--------------------------------------------------------------------------------
/commands/4.ethernet/multi-domain.txt:
--------------------------------------------------------------------------------
1 | ----------
2 | $ sudo ip --all netns delete
3 | $ wget -O - https://raw.githubusercontent.com/momijiame/linux-tcpip-book/2nd-edition/scripts/double-segment.sh | bash
4 | ----------
5 |
6 | ----------
7 | $ sudo ip --all netns delete
8 | ----------
9 |
10 | ----------
11 | $ sudo ip netns add ns1
12 | $ sudo ip netns add router
13 | $ sudo ip netns add ns2
14 | ----------
15 |
16 | ----------
17 | $ sudo ip link add ns1-veth0 type veth peer name gw-veth0
18 | $ sudo ip link add ns2-veth0 type veth peer name gw-veth1
19 | ----------
20 |
21 | ----------
22 | $ sudo ip link set ns1-veth0 netns ns1
23 | $ sudo ip link set gw-veth0 netns router
24 | $ sudo ip link set gw-veth1 netns router
25 | $ sudo ip link set ns2-veth0 netns ns2
26 | ----------
27 |
28 | ----------
29 | $ sudo ip netns exec ns1 ip link set ns1-veth0 up
30 | $ sudo ip netns exec router ip link set gw-veth0 up
31 | $ sudo ip netns exec router ip link set gw-veth1 up
32 | $ sudo ip netns exec ns2 ip link set ns2-veth0 up
33 | ----------
34 |
35 | ----------
36 | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
37 | $ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0
38 | $ sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1
39 | $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
40 | ----------
41 |
42 | ----------
43 | $ sudo ip netns exec ns1 ip route add default via 192.0.2.254
44 | $ sudo ip netns exec ns2 ip route add default via 198.51.100.254
45 | ----------
46 |
47 | ----------
48 | $ sudo ip netns exec router sysctl net.ipv4.ip_forward=1
49 | net.ipv4.ip_forward = 1
50 | ----------
51 |
52 | ----------
53 | $ sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:11
54 | $ sudo ip netns exec router ip link set dev gw-veth0 address 00:00:5E:00:53:12
55 | $ sudo ip netns exec router ip link set dev gw-veth1 address 00:00:5E:00:53:21
56 | $ sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:22
57 | ----------
58 |
59 | ----------
60 | $ sudo ip netns exec router tcpdump -tnel -i gw-veth0 icmp or arp
61 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
62 | listening on gw-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
63 | 00:00:5e:00:53:11 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.254 tell 192.0.2.1, length 28
64 | 00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype ARP (0x0806), length 42: Reply 192.0.2.254 is-at 00:00:5e:00:53:12, length 28
65 | 00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 1, length 64
66 | 00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 1, length 64
67 | 00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 2, length 64
68 | 00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 2, length 64
69 | 00:00:5e:00:53:11 > 00:00:5e:00:53:12, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 3, length 64
70 | 00:00:5e:00:53:12 > 00:00:5e:00:53:11, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 3, length 64
71 | ----------
72 |
73 | ----------
74 | $ sudo ip netns exec ns1 ip route show
75 | default via 192.0.2.254 dev ns1-veth0
76 | 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1
77 | ----------
78 |
79 | ----------
80 | $ sudo ip netns exec router tcpdump -tnel -i gw-veth1 icmp or arp
81 | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
82 | listening on gw-veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
83 | 00:00:5e:00:53:21 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 198.51.100.1 tell 198.51.100.254, length 28
84 | 00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype ARP (0x0806), length 42: Reply 198.51.100.1 is-at 00:00:5e:00:53:22, length 28
85 | 00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 1, length 64
86 | 00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 1, length 64
87 | 00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 2, length 64
88 | 00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 2, length 64
89 | 00:00:5e:00:53:21 > 00:00:5e:00:53:22, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 198.51.100.1: ICMP echo request, id 24652, seq 3, length 64
90 | 00:00:5e:00:53:22 > 00:00:5e:00:53:21, ethertype IPv4 (0x0800), length 98: 198.51.100.1 > 192.0.2.1: ICMP echo reply, id 24652, seq 3, length 64
91 | ----------
92 |
93 | ----------
94 | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
95 | PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
96 | 64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.046 ms
97 | 64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=0.053 ms
98 | 64 bytes from 198.51.100.1: icmp_seq=3 ttl=63 time=0.052 ms
99 |
100 | --- 198.51.100.1 ping statistics ---
101 | 3 packets transmitted, 3 received, 0% packet loss, time 2003ms
102 | rtt min/avg/max/mdev = 0.046/0.050/0.053/0.006 ms
103 | ----------
104 |
105 | ----------
106 | $ sudo ip netns exec router ip route show
107 | 192.0.2.0/24 dev gw-veth0 proto kernel scope link src 192.0.2.254
108 | 198.51.100.0/24 dev gw-veth1 proto kernel scope link src 198.51.100.254
109 | ----------
110 |
111 |
--------------------------------------------------------------------------------