├── 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 | --------------------------------------------------------------------------------