├── lab6 ├── README-II.md ├── README-I.md ├── README.md ├── ss-data-analysis.R ├── el5373-lab6-611.md ├── ss-output.sh ├── el5373-lab6-69.md ├── el5373-lab6-68.md └── el5373-lab6-610.md ├── lab-dynamic-internet ├── reserve-fabric.md ├── reserve-cloudlab.md └── README.md ├── lab-multicast-pim ├── reserve-fabric.md ├── fabric-intro-multicast-pim.md ├── reserve-cloudlab.md └── fabric-define-multicast-pim.md ├── README.md ├── lab0 ├── 1-jacks-edit.png ├── 1-jacks-rspec.png ├── 1-jacks-network.png ├── 1-jacks-status.png ├── 1-jacks-topology.png ├── 1-network-diagram.png ├── 1-split-terminator.png ├── 1-jacks-login-details.png ├── 1-jacks-some-resources-ready.png ├── README.md ├── 1-5-delete-resources.md └── 1-0-prepare-workstation.md ├── lab8 ├── http-hostname.png ├── http-pageload.png ├── README.md ├── lab8-http-rspec.xml └── el5373-lab8-87.md ├── lab3 ├── subnet-worksheet.png ├── subnet-design-table.png ├── subnet-design-topology.png ├── subnet-table-submitted.png ├── subnet-design-table-empty.png ├── 3-arp-route-diagram.md ├── 3-static-routing-reserve.md ├── 3-5-simple-bridge.md └── README.md ├── lab1 ├── 1-wireshark-display.png ├── 1-wireshark-highlight.png ├── README.md ├── 1-x-loopback.md └── 1-2-linux-navigating.md ├── lab-stp ├── spanning-tree-order.png ├── README.md ├── reserve-fabric.md ├── stp-loopfree.md ├── reserve-cloudlab.md ├── stp-reserve.md ├── stp-setup.md ├── stp-change.md └── stp-id.md ├── lab-tcp-congestion ├── sender-ss.png └── reserve-cloudlab.md ├── lab-tcp ├── StateTransitionDiagram.png ├── file-receiver.py ├── file-sender.py ├── file-receiver-slow.py └── reserve.md ├── lab-static-design ├── subnet-worksheet.png ├── subnet-design-table.png ├── subnet-design-topology.png ├── subnet-design-table-empty.png ├── README.md ├── fabric-intro-static-design.md ├── reserve-fabric.md ├── reserve-cloudlab.md └── fabric-define-static-design.md ├── .gitmodules ├── lab-tcp-socket ├── StateTransitionDiagram.png └── reserve-cloudlab.md ├── _config.yml ├── lab4 ├── README-II.md ├── README-I.md └── README.md ├── lab-l2-arp ├── README.md ├── fabric-intro-l2-arp.md ├── reserve-fabric.md ├── reserve-cloudlab.md ├── fabric-define-l2-arp.md └── fabric-transfer-l2-arp.md ├── lab-dynamic ├── README.md └── reserve.md ├── lab-multicast-basic ├── README.md ├── fabric-intro-multicast-basic.md ├── reserve-fabric.md ├── reserve-cloudlab.md ├── fabric-define-multicast-basic.md └── fabric-transfer-multicast-basic.md ├── lab-dynamic-basic ├── README.md ├── fabric-intro-dynamic-basic.md ├── fabric-extra-config-dynamic-basic.md ├── reserve-fabric.md ├── reserve-cloudlab.md └── fabric-define-dynamic-basic.md ├── scripts ├── no-offload.sh ├── no-auto-routes.sh ├── delete-default-route.sh ├── echo ├── ss-data-analysis.R └── ss-output.sh ├── lab2 ├── README.md ├── 2-reserve-resources.md ├── 2-8-icmp-ping.md └── 2-loopback.md ├── lab5 ├── echo ├── README.md ├── lab5-udp-rspec.xml ├── 2-8-icmp-ping.md └── el5373-lab5-55.md ├── lab-l2-bridge ├── README.md ├── fabric-intro-l2-bridge.md ├── reserve-fabric.md ├── reserve-cloudlab.md ├── fabric-define-l2-bridge.md ├── fabric-transfer-l2-bridge.md └── simple-bridge.md ├── lab-static-basic ├── README.md ├── fabric-intro-static-basic.md ├── reserve-fabric.md ├── reserve-cloudlab.md ├── fabric-define-static-basic.md └── fabric-transfer-static-basic.md ├── lab-line-direct ├── fabric-intro-ntp.md ├── fabric-intro-linux.md ├── fabric-intro-udp.md ├── README.md ├── fabric-define-line-direct.md ├── reserve-fabric-ntp.md ├── reserve-fabric-udp.md ├── reserve-fabric-linux.md ├── reserve-cloudlab.md ├── fabric-transfer-ntp.md ├── fabric-transfer-linux.md ├── iperf3.md └── fabric-transfer-udp.md ├── lab-line-router ├── fabric-intro-tcp-1.md ├── fabric-intro-tcp-2.md ├── fabric-intro-udp.md ├── README.md ├── reserve-fabric-udp.md ├── reserve-fabric-tcp-1.md ├── reserve-fabric-tcp-2.md ├── reserve-cloudlab.md ├── fabric-define-line-router.md ├── fabric-transfer-udp.md ├── fabric-transfer-tcp-2.md ├── fabric-transfer-tcp-1.md └── fabric-analysis-tcp-2.md ├── lab-tcp-error ├── file-receiver.py └── file-sender.py ├── lab7 └── README.md ├── lab-snmp-security ├── fabric-intro-snmp-security.md ├── README.md ├── reserve-fabric.md ├── reserve-cloudlab.md ├── firewalls.md └── fabric-define-snmp-security.md ├── lab9 ├── README.md └── el5373-lab9-912.md ├── lab-fragment ├── reserve-cloudlab.md └── iperf3.md ├── lab-tcp-bulk └── reserve-cloudlab.md ├── lab-udp └── reserve-cloudlab.md ├── _layouts └── default.html ├── rspecs ├── two-hosts-one-public.xml ├── two-hosts-one-segment.xml ├── two-hosts-one-segment-16.xml ├── line.xml └── line-tso-off.xml ├── lab-loopback └── loopback.md └── key-concepts.md /lab6/README-II.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lab-dynamic-internet/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lab-multicast-pim/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lab-dynamic-internet/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials 2 | 3 | See https://ffund.github.io/tcp-ip-essentials/ 4 | 5 | -------------------------------------------------------------------------------- /lab0/1-jacks-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-edit.png -------------------------------------------------------------------------------- /lab0/1-jacks-rspec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-rspec.png -------------------------------------------------------------------------------- /lab8/http-hostname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab8/http-hostname.png -------------------------------------------------------------------------------- /lab8/http-pageload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab8/http-pageload.png -------------------------------------------------------------------------------- /lab0/1-jacks-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-network.png -------------------------------------------------------------------------------- /lab0/1-jacks-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-status.png -------------------------------------------------------------------------------- /lab0/1-jacks-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-topology.png -------------------------------------------------------------------------------- /lab0/1-network-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-network-diagram.png -------------------------------------------------------------------------------- /lab0/1-split-terminator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-split-terminator.png -------------------------------------------------------------------------------- /lab3/subnet-worksheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab3/subnet-worksheet.png -------------------------------------------------------------------------------- /lab1/1-wireshark-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab1/1-wireshark-display.png -------------------------------------------------------------------------------- /lab3/subnet-design-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab3/subnet-design-table.png -------------------------------------------------------------------------------- /lab-stp/spanning-tree-order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-stp/spanning-tree-order.png -------------------------------------------------------------------------------- /lab-tcp-congestion/sender-ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-tcp-congestion/sender-ss.png -------------------------------------------------------------------------------- /lab0/1-jacks-login-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-login-details.png -------------------------------------------------------------------------------- /lab1/1-wireshark-highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab1/1-wireshark-highlight.png -------------------------------------------------------------------------------- /lab3/subnet-design-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab3/subnet-design-topology.png -------------------------------------------------------------------------------- /lab3/subnet-table-submitted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab3/subnet-table-submitted.png -------------------------------------------------------------------------------- /lab-tcp/StateTransitionDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-tcp/StateTransitionDiagram.png -------------------------------------------------------------------------------- /lab3/subnet-design-table-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab3/subnet-design-table-empty.png -------------------------------------------------------------------------------- /lab0/1-jacks-some-resources-ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab0/1-jacks-some-resources-ready.png -------------------------------------------------------------------------------- /lab-static-design/subnet-worksheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-static-design/subnet-worksheet.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fabric-snippets"] 2 | path = fabric-snippets 3 | url = https://github.com/teaching-on-testbeds/fabric-snippets 4 | -------------------------------------------------------------------------------- /lab-static-design/subnet-design-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-static-design/subnet-design-table.png -------------------------------------------------------------------------------- /lab-tcp-socket/StateTransitionDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-tcp-socket/StateTransitionDiagram.png -------------------------------------------------------------------------------- /lab-static-design/subnet-design-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-static-design/subnet-design-topology.png -------------------------------------------------------------------------------- /lab-static-design/subnet-design-table-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffund/tcp-ip-essentials/HEAD/lab-static-design/subnet-design-table-empty.png -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | title : Internet Architecture and Protocols 2 | author : 3 | name : Fraida Fund 4 | email : ffund@nyu.edu 5 | github : ffund 6 | feedburner : nil 7 | 8 | theme: jekyll-theme-cayman 9 | -------------------------------------------------------------------------------- /lab-dynamic-internet/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Dynamic routing 4 | 5 | * [Routing across the Internet](https://witestlab.poly.edu/blog/a-peek-into-internet-routing/) 6 | -------------------------------------------------------------------------------- /lab4/README-II.md: -------------------------------------------------------------------------------- 1 | ### Routing: Part II 2 | 3 | * [RIP exercises](el5373-lab4-46.md) 4 | * [Routing experiments with ICMP](el5373-lab4-47.md) 5 | * [A peek into Internet routing](https://witestlab.poly.edu/blog/a-peek-into-internet-routing/) 6 | -------------------------------------------------------------------------------- /lab-l2-arp/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Bridges and LANs, ARP 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * ARP exercises: [on CloudLab](arp-cloudlab.md), [on FABRIC](arp-fabric.md) -------------------------------------------------------------------------------- /lab-dynamic/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Dynamic routing 4 | 5 | * [Reserve resources](reserve) 6 | * [RIP](rip) 7 | * [Routing and ICMP](icmp) 8 | * [Routing across the Internet](https://witestlab.poly.edu/blog/a-peek-into-internet-routing/) 9 | -------------------------------------------------------------------------------- /lab-multicast-basic/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Multicast 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * Simple multicast exercise: [on CloudLab](simple-cloudlab.md), [on FABRIC](simple-fabric.md) 7 | -------------------------------------------------------------------------------- /lab-static-design/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Static routing 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * Designing subnets: [on CloudLab](designing-subnets-cloudlab.md), [on FABRIC](designing-subnets-fabric.md) 7 | -------------------------------------------------------------------------------- /lab-dynamic-basic/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Dynamic routing 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * RIP: [on CloudLab](rip-cloudlab.md), [on FABRIC](rip-fabric.md) 7 | * Routing and ICMP: [on CloudLab](icmp-cloudlab.md), [on FABRIC](icmp-fabric.md) 8 | -------------------------------------------------------------------------------- /scripts/no-offload.sh: -------------------------------------------------------------------------------- 1 | # Get a list of all experiment interfaces, excluding loopback 2 | ifs=$(netstat -i | tail -n+3 | grep -Ev "lo" | cut -d' ' -f1 | tr '\n' ' ') 3 | 4 | # Turn off offloading of all kinds, if possible! 5 | for i in $ifs; do 6 | sudo ethtool -K $i gro off 7 | sudo ethtool -K $i gso off 8 | sudo ethtool -K $i tso off 9 | done 10 | -------------------------------------------------------------------------------- /lab2/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### ARP, Bridges 4 | 5 | * [Reserve resources for ARP experiment](2-reserve-resources) 6 | * [ARP exercises](2-arp) 7 | * [Operation of a basic Ethernet switch or bridge](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation) 8 | * [A simple bridge experiment](../lab3/3-5-simple-bridge.md) 9 | 10 | -------------------------------------------------------------------------------- /lab5/echo: -------------------------------------------------------------------------------- 1 | service echo 2 | { 3 | disable = no 4 | type = INTERNAL 5 | id = echo-stream 6 | socket_type = stream 7 | protocol = tcp 8 | user = root 9 | wait = no 10 | } 11 | 12 | # This is the udp version. 13 | service echo 14 | { 15 | disable = no 16 | type = INTERNAL 17 | id = echo-dgram 18 | socket_type = dgram 19 | protocol = udp 20 | user = root 21 | wait = yes 22 | } 23 | -------------------------------------------------------------------------------- /lab-l2-bridge/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Bridges and LANs, ARP 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * Operation of a basic Ethernet switch or bridge: [on CloudLab](learning-switch-cloudlab.md), [on FABRIC](learning-switch-fabric.md) 7 | * A simple bridge experiment: [on CloudLab](simple-bridge-cloudlab.md), [on FABRIC](simple-bridge-fabric.md) 8 | -------------------------------------------------------------------------------- /scripts/no-auto-routes.sh: -------------------------------------------------------------------------------- 1 | # Get a list of all experiment interfaces 2 | ifs=$(netstat -i | tail -n+3 | grep -Ev "lo|eth0" | cut -d' ' -f1 | tr '\n' ' ') 3 | 4 | # remove InstaGENI-generated automatic routes 5 | for i in $ifs; do 6 | sudo ifconfig $i down 7 | sudo ifconfig $i up 8 | # Turn on IPv4 and IPv6 forwarding 9 | sudo sysctl -w net.ipv4.conf.$i.forwarding=1 10 | sudo sysctl -w net.ipv6.conf.$i.forwarding=1 11 | done 12 | -------------------------------------------------------------------------------- /lab-static-basic/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Static routing 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * Exercises with IP address and subnet masks: [on CloudLab](routing-subnet-cloudlab.md), [on FABRIC](routing-subnet-fabric.md) 7 | * Exercises with static routing between networks: [on CloudLab](routing-between-cloudlab.md), [on FABRIC](routing-between-fabric.md) 8 | -------------------------------------------------------------------------------- /lab6/README-I.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | ### TCP study - Part I 6 | 7 | * [TCP sockets and the TCP state diagram](el5373-lab6-6x.md) 8 | * [TCP bulk file transfer](el5373-lab6-6y.md) 9 | -------------------------------------------------------------------------------- /lab1/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Linux 4 | 5 | * [Learning the basics of the Bash shell](1-1-linux-shell.md) 6 | * [Navigating the filesystem](1-2-linux-navigating.md) 7 | * [Working with files and directories](1-3-linux-files-directories.md) 8 | * [Manipulating output of a command](1-4-linux-manipulate.md) 9 | * [Using `tcpdump` and Wireshark](1-5-tcpdump-wireshark.md) 10 | * [Loopback interface](1-x-loopback.md) 11 | 12 | -------------------------------------------------------------------------------- /lab-line-direct/fabric-intro-ntp.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # NTP 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two directly connected hosts 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab4/README-I.md: -------------------------------------------------------------------------------- 1 | ### Routing: Part I 2 | 3 | *Note*: there is a different experiment topology for each of the three parts of this experiment. To reserve additional resources in an existing slice, use a *different* InstaGENI site for each new set of resources. 4 | 5 | * [Exercises with IP address and subnet masks](2-9-ip-subnet.md) 6 | * [A simple router experiment](el5373-lab4-45.md) 7 | * [Designing subnets](https://witestlab.poly.edu/blog/designing-subnets/) 8 | 9 | -------------------------------------------------------------------------------- /lab-l2-arp/fabric-intro-l2-arp.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # ARP 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the ARP experiment: four hosts on a single Ethernet segment 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-line-router/fabric-intro-tcp-1.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # TCP Part I 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two hosts connected by a router 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-line-router/fabric-intro-tcp-2.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # TCP Part II 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two hosts connected by a router 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-tcp/file-receiver.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 | sock.bind(('10.10.2.100', 4000)) 5 | sock.listen() 6 | 7 | conn_sock, conn_addr = sock.accept() 8 | 9 | f = open('file.txt', "wb") 10 | 11 | bytes_read = 0 12 | while bytes_read < 5767184: 13 | b = conn_sock.recv(4096) 14 | f.write(b) 15 | bytes_read += len(b) 16 | 17 | conn_sock.shutdown(socket.SHUT_RDWR) 18 | sock.shutdown(socket.SHUT_RDWR) 19 | f.close() 20 | -------------------------------------------------------------------------------- /lab-tcp/file-sender.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 | 5 | sock.connect(('10.10.2.100', 4000)) 6 | 7 | f = open('file.txt', "rb") 8 | 9 | b = f.read(4096) 10 | 11 | bytes_sent = 0 12 | 13 | while (b): 14 | sock.sendall(b) 15 | bytes_sent += 4096 16 | print("Sent %d out of 5767184 bytes" % min(bytes_sent, 5767184)) 17 | b = f.read(4096) 18 | 19 | sock.shutdown(socket.SHUT_RDWR) 20 | 21 | f.close() 22 | -------------------------------------------------------------------------------- /lab-tcp-error/file-receiver.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 | sock.bind(('10.10.2.100', 4000)) 5 | sock.listen() 6 | 7 | conn_sock, conn_addr = sock.accept() 8 | 9 | f = open('file.txt', "wb") 10 | 11 | bytes_read = 0 12 | while bytes_read < 5767184: 13 | b = conn_sock.recv(4096) 14 | f.write(b) 15 | bytes_read += len(b) 16 | 17 | conn_sock.shutdown(socket.SHUT_RDWR) 18 | sock.shutdown(socket.SHUT_RDWR) 19 | f.close() 20 | -------------------------------------------------------------------------------- /lab-tcp-error/file-sender.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 | 5 | sock.connect(('10.10.2.100', 4000)) 6 | 7 | f = open('file.txt', "rb") 8 | 9 | b = f.read(4096) 10 | 11 | bytes_sent = 0 12 | 13 | while (b): 14 | sock.sendall(b) 15 | bytes_sent += 4096 16 | print("Sent %d out of 5767184 bytes" % min(bytes_sent, 5767184)) 17 | b = f.read(4096) 18 | 19 | sock.shutdown(socket.SHUT_RDWR) 20 | 21 | f.close() 22 | -------------------------------------------------------------------------------- /lab0/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Set up your lab account 4 | 5 | * [Prepare your workstation](1-0-prepare-workstation.md) 6 | * [Set up an account on GENI](1-1-setup-account.md) 7 | * [Reserve a simple network on GENI](1-2-reserve-and-login.md) 8 | * [Inspect network interfaces](1-3-network-interfaces.md) 9 | * [Working on remote hosts](1-4-working-on-remote-hosts.md) 10 | * [Save data and delete resources on GENI](1-5-delete-resources.md) 11 | -------------------------------------------------------------------------------- /lab-line-direct/fabric-intro-linux.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Linux, networking utilities 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two directly connected hosts 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-l2-bridge/fabric-intro-l2-bridge.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Bridge 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Bridge experiments: four hosts connected by a layer 2 switch/bridge 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-static-design/fabric-intro-static-design.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Static Routing - Subnet Design 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Static Routing - Subnet Design experiment: four subnets connected by three routers 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Delete your FABRIC resources to free them for other experimenters 16 | 17 | ::: 18 | -------------------------------------------------------------------------------- /lab-multicast-basic/fabric-intro-multicast-basic.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Multicast 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Multicast experiment: two subnets connected by a router 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-line-direct/fabric-intro-udp.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # UDP - `iperf3`, Datagram Sizes, FTP and TFTP 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two directly connected hosts 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-line-router/fabric-intro-udp.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # UDP as a connectionless transport protocol 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the experiment: two hosts connected by a router 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-tcp/file-receiver-slow.py: -------------------------------------------------------------------------------- 1 | import socket, time 2 | 3 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 | sock.bind(('10.10.2.100', 4000)) 5 | sock.listen() 6 | 7 | conn_sock, conn_addr = sock.accept() 8 | 9 | f = open('file.txt', "wb") 10 | 11 | bytes_read = 0 12 | while bytes_read < 5767184: 13 | b = conn_sock.recv(4096) 14 | time.sleep(0.1) 15 | f.write(b) 16 | bytes_read += len(b) 17 | 18 | conn_sock.shutdown(socket.SHUT_RDWR) 19 | sock.shutdown(socket.SHUT_RDWR) 20 | f.close() 21 | -------------------------------------------------------------------------------- /lab7/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | 6 | ### Multicast and realtime service 7 | 8 | * [7.4 Simple multicast exercise](el5373-lab7-74.md) 9 | * [Multicast routing with PIM](https://witestlab.poly.edu/blog/multicast-routing-with-pim/) 10 | -------------------------------------------------------------------------------- /lab-static-basic/fabric-intro-static-basic.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Static Routing 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Static Routing experiment: four subnets connected by three routers 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-dynamic-basic/fabric-intro-dynamic-basic.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Dynamic Routing 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Dynamic Routing experiment: four subnets connected by four routers 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab-stp/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Spanning tree procotol 4 | 5 | * [Background](stp-background.md) 6 | * [Reserve resources](reserve-cloudlab.md) 7 | * [Set up bridge interfaces](stp-setup.md) 8 | * [Create a broadcast storm](stp-broadcast.md) 9 | * [Before beginning the spanning tree protocol](stp-id.md) 10 | * [Observe the spanning tree protocol](stp-configure.md) 11 | * [Test the loop-free topology](stp-loopfree.md) 12 | * [Adapt to changes in the topology](stp-change.md) 13 | -------------------------------------------------------------------------------- /lab-snmp-security/fabric-intro-snmp-security.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # SNMP and Network Security 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the SNMP and Network Security experiment: four hosts connected by two routers 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /scripts/delete-default-route.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | read _ _ gateway _ < <(ip route list match 0/0) 4 | 5 | sudo route add -net 0.0.0.0/5 gw $gateway 6 | sudo route add -net 8.0.0.0/7 gw $gateway 7 | sudo route add -net 11.0.0.0/8 gw $gateway 8 | sudo route add -net 12.0.0.0/6 gw $gateway 9 | sudo route add -net 16.0.0.0/4 gw $gateway 10 | sudo route add -net 32.0.0.0/3 gw $gateway 11 | sudo route add -net 64.0.0.0/2 gw $gateway 12 | sudo route add -net 128.0.0.0/1 gw $gateway 13 | 14 | sudo route del default gw $gateway -------------------------------------------------------------------------------- /lab-snmp-security/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### SNMP, network security 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric.md) 6 | * SNMP exercises: [on CloudLab](snmp-cloudlab.md), [on FABRIC](snmp-fabric.md) 7 | * Exercises on secure applications: [on CloudLab](applications-cloudlab.md), [on FABRIC](applications-fabric.md) 8 | * [Exercises on network layer security](vpn.md) 9 | * Exercises on firewalls: [on CloudLab](firewalls-cloudlab.md), [on FABRIC](firewalls-fabric.md) 10 | -------------------------------------------------------------------------------- /lab5/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | 6 | ### UDP and its applications 7 | 8 | * [UDP as a connectionless transport protocol](el5373-lab5-5z.md) 9 | * [Using `iperf3`](el5373-lab5-55.md) 10 | * [UDP Exercises with Datagram Sizes](el5373-lab5-56.md) 11 | * [FTP and TFTP](el5373-lab5-58.md) 12 | -------------------------------------------------------------------------------- /lab9/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | 6 | ### Network management and security 7 | 8 | * [9.9 SNMP exercises](el5373-lab9-909.md) 9 | * [9.10 Exercises on secure applications](el5373-lab9-910.md) 10 | * [9.1x Exercises on network layer security](el5373-lab9-91x.md) 11 | * [9.12 Exercises on firewalls](el5373-lab9-912.md) 12 | -------------------------------------------------------------------------------- /lab-multicast-pim/fabric-intro-multicast-pim.md: -------------------------------------------------------------------------------- 1 | 2 | ::: {.cell .markdown} 3 | 4 | # Multicast Routing with PIM 5 | 6 | ::: 7 | 8 | ::: {.cell .markdown} 9 | 10 | In this notebook you will: 11 | 12 | * Reserve resources for the Multicast Routing with PIM experiment: one rendezvous point router, two core routers, two first hop routers, two last hop routers, two multicast sources, and four multicast receivers 13 | * Configure your reserved resources 14 | * Access your reserved resources over SSH 15 | * Retrieve files saved on a FABRIC resources 16 | * Delete your FABRIC resources to free them for other experimenters 17 | 18 | ::: 19 | -------------------------------------------------------------------------------- /lab6/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | ### TCP study 6 | 7 | * [TCP sockets and the TCP state diagram](el5373-lab6-6x.md) 8 | * [TCP bulk file transfer](el5373-lab6-6y.md) 9 | * [TCP congestion control](https://witestlab.poly.edu/blog/tcp-congestion-control-basics/) (note: the topology in this experiment is the same as in the previous experiments, so you don't need to reserve new resources.) 10 | 11 | 12 | -------------------------------------------------------------------------------- /lab-line-direct/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### Linux, networking utilities 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-linux.md) 6 | 7 | ### UDP 8 | 9 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-udp.md) 10 | * [Using `iperf3`](iperf3.md) 11 | * Exercises with Datagram Sizes: [on CloudLab](datagram-cloudlab.md), [on FABRIC](datagram-fabric.md) 12 | * Exercises with FTP and TFTP: [on CloudLab](ftp-tftp-cloudlab.md), [on FABRIC](ftp-tftp-fabric.md) 13 | 14 | ### NTP 15 | 16 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-ntp.md) -------------------------------------------------------------------------------- /lab-l2-bridge/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology that includes a bridge with four ports, and one host connected to each port. 4 | 5 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 6 | 7 | ``` 8 | git clone https://github.com/ffund/tcp-ip-essentials.git 9 | git checkout wip 10 | ``` 11 | 12 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-l2-bridge". 13 | 14 | Then open the notebook titled "setup.ipynb". 15 | 16 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab4/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | 6 | ### Part I 7 | 8 | * [Exercises with IP address and subnet masks](2-9-ip-subnet.md) 9 | * [A simple router experiment](el5373-lab4-45.md) 10 | * [Designing subnets](https://witestlab.poly.edu/blog/designing-subnets/) 11 | 12 | ### Part II 13 | 14 | * [RIP exercises](el5373-lab4-46.md) 15 | * [Routing experiments with ICMP](el5373-lab4-47.md) 16 | * [A peek into Internet routing](https://witestlab.poly.edu/blog/a-peek-into-internet-routing/) 17 | 18 | -------------------------------------------------------------------------------- /scripts/echo: -------------------------------------------------------------------------------- 1 | # default: off 2 | # description: An xinetd internal service which echo's characters back to 3 | # clients. 4 | # This is the tcp version. 5 | service echo 6 | { 7 | disable = yes 8 | type = INTERNAL 9 | id = echo-stream 10 | socket_type = stream 11 | protocol = tcp 12 | user = root 13 | wait = no 14 | } 15 | 16 | # This is the udp version. 17 | service echo 18 | { 19 | disable = yes 20 | type = INTERNAL 21 | id = echo-dgram 22 | socket_type = dgram 23 | protocol = udp 24 | user = root 25 | wait = yes 26 | } 27 | -------------------------------------------------------------------------------- /lab-stp/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology that includes four bridges connected in a loop. There is also one host on each network segment: 4 | 5 | ![](spanning-tree-topo.svg) 6 | 7 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 8 | 9 | ``` 10 | git clone https://github.com/ffund/tcp-ip-essentials.git 11 | git checkout wip 12 | ``` 13 | 14 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-stp". 15 | 16 | Then open the notebook titled "setup.ipynb". 17 | 18 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-direct/fabric-define-line-direct.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for the experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="line-direct-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 12 | ] 13 | net_conf = [ 14 | {"name": "net0", "subnet": "10.10.0.0/24", "nodes": [{"name": "romeo", "addr": "10.10.0.100"}, {"name": "juliet", "addr": "10.10.0.101"}]} 15 | ] 16 | route_conf = [] 17 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 18 | ``` 19 | ::: -------------------------------------------------------------------------------- /lab-snmp-security/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use the topology illustrated here, with IP addresses as noted on the diagram and a subnet mask of 255.255.255.0 on each interface: 4 | 5 | ![Network topology](security-topology.svg) 6 | 7 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 8 | 9 | ``` 10 | git clone https://github.com/ffund/tcp-ip-essentials.git 11 | git checkout wip 12 | ``` 13 | 14 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-snmp-security". 15 | 16 | Then open the notebook titled "setup.ipynb". 17 | 18 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-l2-bridge/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology that includes a bridge with four ports, and one host connected to each port. 4 | 5 | To reserve resources on Cloudlab, open this profile page: 6 | 7 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/learning_switch_22 8 | 9 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 10 | 11 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab-line-direct/reserve-fabric-ntp.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | 8 | each with a netmask of 255.255.255.0. 9 | 10 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 11 | 12 | ``` 13 | git clone https://github.com/ffund/tcp-ip-essentials.git 14 | git checkout wip 15 | ``` 16 | 17 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-direct". 18 | 19 | Then open the notebook titled "setup-ntp.ipynb". 20 | 21 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-direct/reserve-fabric-udp.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | 8 | each with a netmask of 255.255.255.0. 9 | 10 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 11 | 12 | ``` 13 | git clone https://github.com/ffund/tcp-ip-essentials.git 14 | git checkout wip 15 | ``` 16 | 17 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-direct". 18 | 19 | Then open the notebook titled "setup-udp.ipynb". 20 | 21 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-direct/reserve-fabric-linux.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | 8 | each with a netmask of 255.255.255.0. 9 | 10 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 11 | 12 | ``` 13 | git clone https://github.com/ffund/tcp-ip-essentials.git 14 | git checkout wip 15 | ``` 16 | 17 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-direct". 18 | 19 | Then open the notebook titled "setup-linux.ipynb". 20 | 21 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-router/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | ### UDP 4 | 5 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-udp.md) 6 | * UDP as a connectionless transport protocol: [on CloudLab](connectionless-cloudlab.md), [on FABRIC](connectionless-fabric.md) 7 | 8 | ### TCP I 9 | 10 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-tcp-1.md) 11 | * TCP sockets and the TCP state diagram: [on CloudLab](sockets-cloudlab.md), [on FABRIC](sockets-fabric.md) 12 | * TCP error control: [on CloudLab](error-cloudlab.md), [on FABRIC](error-fabric.md) 13 | 14 | ### TCP II 15 | 16 | * Reserve resources: [on CloudLab](reserve-cloudlab.md), [on FABRIC](reserve-fabric-tcp-1.md) 17 | * TCP bulk file transfer: [on CloudLab](rwnd-cwnd-cloudlab.md), [on FABRIC](rwnd-cwnd-fabric.md) 18 | * [TCP congestion control](congestion.md) -------------------------------------------------------------------------------- /lab-l2-arp/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with four connected workstations on a single network segment, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | * hamlet: 10.10.0.102 8 | * ophelia: 10.10.0.103 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 13 | 14 | ``` 15 | git clone https://github.com/ffund/tcp-ip-essentials.git 16 | git checkout wip 17 | ``` 18 | 19 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-l2-arp". 20 | 21 | Then open the notebook titled "setup.ipynb". 22 | 23 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-multicast-basic/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology with four hosts and one router, and IP addresses as follows: 4 | 5 | * romeo - 10.10.1.100 6 | * juliet - 10.10.1.101 7 | * hamlet - 10.10.1.102 8 | * ophelia - 10.10.2.103 9 | * router - 10.10.1.1 and 10.10.2.1 10 | 11 | with netmask 255.255.255.0. 12 | 13 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 14 | 15 | ``` 16 | git clone https://github.com/ffund/tcp-ip-essentials.git 17 | git checkout wip 18 | ``` 19 | 20 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-multicast-basic". 21 | 22 | Then open the notebook titled "setup.ipynb". 23 | 24 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab0/1-5-delete-resources.md: -------------------------------------------------------------------------------- 1 | ## Delete resources 2 | 3 | ### Exercise - Delete your resources 4 | 5 | Part of being a good GENI citizen is releasing resources when you're not using them anymore. When you have finished all parts of your lab assignment (successfully), finished your network diagram, and retrieved all data from your remote hosts, use the "Delete" button at the bottom of the canvas in the GENI portal to delete your resources. 6 | 7 | Once you delete your resources, you will no longer have access to them, and all the data on them will be deleted. Make sure that you have saved *everything* before you delete your resources. 8 | 9 | You don't have to delete your slice; it will be deleted automatically when it expires. 10 | 11 | In general, your resources will not persist forever if you don't delete them. Resources are reserved with an expiration date, at which time you will lose access to them. 12 | -------------------------------------------------------------------------------- /lab-stp/stp-loopfree.md: -------------------------------------------------------------------------------- 1 | ## Test the loop-free topology 2 | 3 | Let us verify that with the spanning tree algorithm in place to ensure a loop-free topology, a broadcast storm cannot occur. We should see that with the spanning tree protocol creating a logical loop-free topology, we can send a broadcast packet without creating a broadcast storm. 4 | 5 | For this section, you will need one SSH session on each bridge, and one SSH session on the "romeo" host. 6 | 7 | 8 | On each of the four bridges, run 9 | 10 | ``` 11 | sudo tcpdump -env -i br0 12 | ``` 13 | 14 | and then, in the terminal on "romeo", run 15 | 16 | ``` 17 | ping -b -c 1 10.10.0.255 18 | ``` 19 | 20 | to generate a single broadcast packet. 21 | 22 | **Lab report**: Compare this result to the previous experiment with a broadcast frame. How many times does the ICMP packet appear on each network segment? Does it reach every network segment? Does a broadcast storm occur? 23 | -------------------------------------------------------------------------------- /lab-snmp-security/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use the topology illustrated here, with IP addresses as noted on the diagram and a subnet mask of 255.255.255.0 on each interface: 4 | 5 | ![Network topology](security-topology.svg) 6 | 7 | To reserve resources on Cloudlab, open this profile page: 8 | 9 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/network_security 10 | 11 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 12 | 13 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab6/ss-data-analysis.R: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | dat <- read.csv("sender-ss.csv", header=FALSE) 3 | names(dat) <- c("ts", "sender", "retr", "retr.total", "cwnd", "ssthresh") 4 | 5 | senders <- data.frame(table(dat$sender)) 6 | sndlist <- senders[senders$Freq > 100,]$Var1 7 | 8 | dat <- dat[dat$sender %in% sndlist,] 9 | dat$sender <- factor(dat$sender) 10 | 11 | lost <- na.omit(dat[dat$retr>0,]) 12 | 13 | tsmin <- min(dat$ts) 14 | 15 | q <- ggplot(dat) + geom_line(aes(x=ts-tsmin, y=cwnd, colour=as.factor(sender))) + geom_line(aes(x=ts-tsmin, y=ssthresh, colour=as.factor(sender)), linetype='twodash') 16 | q <- q + theme_bw() + facet_wrap(~sender, ncol=1, drop=T) + geom_vline(data=lost, aes(xintercept=ts-tsmin, colour=as.factor(sender)), alpha=0.1) 17 | q <- q + scale_y_continuous("CWND") + scale_colour_discrete("Sender") + scale_x_continuous("Time (s)") + theme(legend.position="bottom") 18 | 19 | 20 | svg("sender-ss.svg") 21 | print(q) 22 | dev.off() 23 | -------------------------------------------------------------------------------- /scripts/ss-data-analysis.R: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | dat <- read.csv("sender-ss.csv", header=FALSE) 3 | names(dat) <- c("ts", "sender", "retr", "retr.total", "cwnd", "ssthresh") 4 | 5 | senders <- data.frame(table(dat$sender)) 6 | sndlist <- senders[senders$Freq > 100,]$Var1 7 | 8 | dat <- dat[dat$sender %in% sndlist,] 9 | dat$sender <- factor(dat$sender) 10 | 11 | lost <- na.omit(dat[dat$retr>0,]) 12 | 13 | tsmin <- min(dat$ts) 14 | 15 | q <- ggplot(dat) + geom_line(aes(x=ts-tsmin, y=cwnd, colour=as.factor(sender))) + geom_line(aes(x=ts-tsmin, y=ssthresh, colour=as.factor(sender)), linetype='twodash') 16 | q <- q + theme_bw() + facet_wrap(~sender, ncol=1, drop=T) + geom_vline(data=lost, aes(xintercept=ts-tsmin, colour=as.factor(sender)), alpha=0.1) 17 | q <- q + scale_y_continuous("CWND") + scale_colour_discrete("Sender") + scale_x_continuous("Time (s)") + theme(legend.position="bottom") 18 | 19 | 20 | svg("sender-ss.svg") 21 | print(q) 22 | dev.off() 23 | -------------------------------------------------------------------------------- /lab-line-direct/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | 8 | each with a netmask of 255.255.255.0. 9 | 10 | To reserve these resources on Cloudlab, open this profile page: 11 | 12 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_direct_22 13 | 14 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 15 | 16 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab-static-basic/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with five hosts, three routers, and four network segments, with addresses on each network interface configured as follows: 4 | 5 | ![](static-routing-topo.svg) 6 | 7 | each with a netmask of 255.255.255.0. 8 | 9 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 10 | 11 | ``` 12 | git clone https://github.com/ffund/tcp-ip-essentials.git 13 | git checkout wip 14 | ``` 15 | 16 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-static-basic". 17 | 18 | Then open the notebook titled "setup.ipynb". 19 | 20 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. 21 | 22 | Use `ip addr` to view the network interface configuration on each host, and save the output for your own reference. -------------------------------------------------------------------------------- /lab-multicast-pim/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology that includes a bridge with four ports, and one host connected to each port. 4 | 5 | To reserve resources on Cloudlab, open this profile page: 6 | 7 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/multicast_pim_20](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/multicast_pim_20 8 | ) 9 | 10 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 11 | 12 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the client, router, and server hosts, and SSH into each. 13 | -------------------------------------------------------------------------------- /lab-line-router/reserve-fabric-udp.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 13 | 14 | ``` 15 | git clone https://github.com/ffund/tcp-ip-essentials.git 16 | git checkout wip 17 | ``` 18 | 19 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-router". 20 | 21 | Then open the notebook titled "setup-udp.ipynb". 22 | 23 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-router/reserve-fabric-tcp-1.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 13 | 14 | ``` 15 | git clone https://github.com/ffund/tcp-ip-essentials.git 16 | git checkout wip 17 | ``` 18 | 19 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-router". 20 | 21 | Then open the notebook titled "setup-tcp-1.ipynb". 22 | 23 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-line-router/reserve-fabric-tcp-2.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 13 | 14 | ``` 15 | git clone https://github.com/ffund/tcp-ip-essentials.git 16 | git checkout wip 17 | ``` 18 | 19 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-line-router". 20 | 21 | Then open the notebook titled "setup-tcp-2.ipynb". 22 | 23 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. -------------------------------------------------------------------------------- /lab-l2-arp/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with four connected workstations on a single network segment, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | * hamlet: 10.10.0.102 8 | * ophelia: 10.10.0.103 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/lan_one_segment 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab-stp/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology that includes four bridges connected in a loop. There is also one host on each network segment: 4 | 5 | ![](spanning-tree-topo.svg) 6 | 7 | To reserve resources on Cloudlab, open this profile page: 8 | 9 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/spanning_tree_protocol_22](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/spanning_tree_protocol_22) 10 | 11 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. 12 | 13 | Then click "next", and "finish". 14 | 15 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 16 | -------------------------------------------------------------------------------- /lab3/3-arp-route-diagram.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ```mermaid 4 | graph TD 5 | classDef hi fill:#f9f; 6 | A["Look up destination IP in routing table"] 7 | A -->|"Matching route is
directly connected (G=0)"| B["Check if destination IP
is in ARP table"] 8 | A -->|"No matching route"| D["Return error:
Network is unreachable"] 9 | A -->|"Matching route is
via gateway (G=1)"| C["Check if gateway IP
is in ARP table"] 10 | B -->|"In ARP table"| F["Send IP packet to
destination IP with
destination host's
MAC address"] 11 | B -->|"Not in table"| E["Try to resolve
destination IP by
sending ARP request(s)"] 12 | E -->|"ARP reply"|F 13 | E -->|"ARP timeout"|I["Send ICMP to self:
Destination Unreachable:
Host Unreachable"] 14 | C -->|"Not in table"| G["Try to resolve
gateway IP by
sending ARP request(s)"] 15 | G -->|"ARP timeout"|I 16 | G -->|"ARP reply"|H["Send IP packet to
destination IP
with gateway's
MAC address"] 17 | C -->|"In ARP table"| H 18 | ``` -------------------------------------------------------------------------------- /lab6/el5373-lab6-611.md: -------------------------------------------------------------------------------- 1 | ## 6.11 Other TCP exercises 2 | 3 | For this experiment, we will reuse the same network as in the [previous experiment](el5373-lab6-67.md). 4 | 5 | ### Exercise 7 6 | 7 | Run an `iperf3` server on "juliet", if one is not already running: 8 | 9 | ``` 10 | iperf3 -s 11 | ``` 12 | 13 | On "romeo", start a `tcpdump` with 14 | 15 | ``` 16 | sudo tcpdump -S -s 68 -i eth1 -w tcp-fragmentation-$(hostname -s).pcap 17 | ``` 18 | 19 | While `tcpdump` is running to capture traffic between "romeo" and "juliet", execute the following command, which is similar to the command we used to find out the maximum size of a UDP datagram in Chapter 5, on "romeo": 20 | 21 | ``` 22 | iperf3 -c 10.10.2.100 -l 70000 -n 70000 23 | ``` 24 | 25 | Note that we use a size that is larger than the maximum UDP datagram size we found in Exercise 5 of Chapter 5. 26 | 27 | **Lab report**: Did you observe any IP fragmentation? If IP fragmentation did not occur this time, how do you explain this compared to what you observed in [Section 5.6](/lab5/el5373-lab5-56.md)? 28 | -------------------------------------------------------------------------------- /lab-l2-arp/fabric-define-l2-arp.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for ARP experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="l2-arp-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 13 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 14 | ] 15 | net_conf = [ 16 | {"name": "net0", "subnet": "10.10.0.0/24", "nodes": [{"name": "romeo", "addr": "10.10.0.100"}, {"name": "juliet", "addr": "10.10.0.101"}, {"name": "hamlet", "addr": "10.10.0.102"}, {"name": "ophelia", "addr": "10.10.0.103"}]}, 17 | ] 18 | route_conf = [] 19 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 20 | ``` 21 | ::: -------------------------------------------------------------------------------- /lab-fragment/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 4 | 5 | * romeo: 10.0.0.100 6 | * juliet: 10.0.0.101 7 | 8 | each with a netmask of 255.255.255.0. 9 | 10 | To reserve these resources on Cloudlab, open this profile page: 11 | 12 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_direct_compat](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_direct_compat) 13 | 14 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 15 | 16 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 17 | -------------------------------------------------------------------------------- /lab-tcp/reserve.md: -------------------------------------------------------------------------------- 1 | ## Reserve resources 2 | 3 | In this exercise and the ones that follow, we'll examine these features of TCP. 4 | 5 | For these experiments, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 6 | 7 | * romeo: 10.10.1.100 8 | * router, interface connected to romeo: 10.10.1.1 9 | * router, interface connected to juliet: 10.10.2.1 10 | * juliet: 10.10.2.100 11 | 12 | each with a netmask of 255.255.255.0. 13 | 14 | To set up this topology in the GENI Portal, create a slice, click on "Add Resources", and load the RSpec from the following URL: https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/line-tso-off.xml 15 | 16 | Refer to the [monitor website](https://fedmon.fed4fire.eu/overview/instageni) to identify an InstaGENI site that has many "free VMs" available. Then bind to an InstaGENI site and reserve your resources. Wait for them to become available for login ("turn green" on your canvas) and then SSH into each, using the details given in the GENI Portal. 17 | -------------------------------------------------------------------------------- /lab-dynamic-basic/fabric-extra-config-dynamic-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .code} 2 | ```python 3 | # Install and configure FRR on routers 4 | for i in range(4): 5 | router_node = slice.get_node("router-%i" % (i + 1)) 6 | router_node.execute("curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -") 7 | router_node.execute("echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable | sudo tee -a /etc/apt/sources.list.d/frr.list") 8 | router_node.execute("sudo apt update; sudo apt -y install frr frr-pythontools nload", quiet=True) 9 | router_node.execute("sudo sed -i 's/zebrad=no/zebrad=yes/g' /etc/frr/daemons") 10 | router_node.execute("sudo sed -i 's/ripd=no/ripd=yes/g' /etc/frr/daemons") 11 | router_node.execute("sudo systemctl restart frr.service") 12 | # Add hosts to the multicast group RIPv2 uses 13 | for i, node_name in enumerate(["romeo", "hamlet", "othello", "petruchio"]): 14 | host_node = slice.get_node(node_name) 15 | host_node.execute("sudo ip maddr add 01:00:5e:00:00:09 dev $(ip route get 10.10.6%i.0 | grep -oP \"(?<=dev )[^ ]+\")" % (i + 1)) 16 | ``` 17 | ::: -------------------------------------------------------------------------------- /lab-line-router/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab-tcp-bulk/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. -------------------------------------------------------------------------------- /lab-multicast-basic/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | First, you will reserve a topology with four hosts and one router, and IP addresses as follows: 4 | 5 | * romeo - 10.10.1.100 6 | * juliet - 10.10.1.101 7 | * hamlet - 10.10.1.102 8 | * ophelia - 10.10.2.103 9 | * router - 10.10.1.1 and 10.10.2.1 10 | 11 | with netmask 255.255.255.0. 12 | 13 | To reserve resources on Cloudlab, open this profile page: 14 | 15 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/multicast_basic_20](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/multicast_basic_20) 16 | 17 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 18 | 19 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 20 | -------------------------------------------------------------------------------- /lab3/3-static-routing-reserve.md: -------------------------------------------------------------------------------- 1 | ## Reserve resources 2 | 3 | For this experiment, we will use a topology with five hosts, three routers, and four network segments, with addresses on each network interface configured as follows: 4 | 5 | ![](static-routing-topo.svg) 6 | 7 | each with a netmask of 255.255.255.0. 8 | 9 | To set up this topology in the GENI Portal, create a slice, click on "Add Resources", and load the RSpec from the following URL: [https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/static-routing.xml](https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/static-routing.xml) 10 | 11 | Refer to the [monitor website](https://fedmon.fed4fire.eu/overview/instageni) to identify an InstaGENI site that has many "free VMs" available. Then bind to an InstaGENI site and reserve your resources. Wait for them to become available for login ("turn green" on your canvas) and then SSH into each, using the details given in the GENI Portal. 12 | 13 | Use `ifconfig -a` to view the network interface configuration on each host, and save the output for your own reference. 14 | 15 | 16 | -------------------------------------------------------------------------------- /lab8/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | 6 | ### The Web, DHCP, NTP and NAT 7 | 8 | Unlike some other lab exercises, for this lab, the instructions do not include interspersed notes about what you will need to include/answer in your lab report. Instead, those instructions are listed at the end of the page in an "Exercise" section. Before you start each section, you should carefully read the associated part of the exercise at the end, so that you know what output to save and what questions you will need to answer. 9 | 10 | You will use the same topology for all three parts of this exercise, so don't delete your resources until you have finished all of it! 11 | 12 | * [Basic home gateway services: DHCP, DNS, NAT](https://witestlab.poly.edu/blog/basic-home-gateway-services-dhcp-dns-nat/) 13 | * [8.7 HTTP exercises](el5373-lab8-87.md) 14 | * [8.9 NTP exercises](el5373-lab8-89.md) 15 | -------------------------------------------------------------------------------- /lab2/2-reserve-resources.md: -------------------------------------------------------------------------------- 1 | ## Reserve resources 2 | 3 | For this experiment, we will use a topology with four connected workstations on a single network segment, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.0.100 6 | * juliet: 10.10.0.101 7 | * hamlet: 10.10.0.102 8 | * ophelia: 10.10.0.103 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To set up this topology in the GENI Portal, create a slice, click on "Add Resources", and load the RSpec from the following URL: [https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/single-segment.xml](https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/single-segment.xml) 13 | 14 | Refer to the [monitor website](https://fedmon.fed4fire.eu/overview/instageni) to identify an InstaGENI site that has many "free VMs" available. Then bind to an InstaGENI site and reserve your resources. Wait for them to become available for login ("turn green" on your canvas) and then SSH into each, using the details given in the GENI Portal. 15 | 16 | Use `ifconfig -a` to view the network interface configuration on each host, and save the output for your own reference. 17 | -------------------------------------------------------------------------------- /lab-line-router/fabric-define-line-router.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for the experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="line-router-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "router", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 13 | ] 14 | net_conf = [ 15 | {"name": "net0", "subnet": "10.10.1.0/24", "nodes": [{"name": "romeo", "addr": "10.10.1.100"}, {"name": "router", "addr": "10.10.1.1"}]}, 16 | {"name": "net1", "subnet": "10.10.2.0/24", "nodes": [{"name": "juliet", "addr": "10.10.2.100"}, {"name": "router", "addr": "10.10.2.1"}]} 17 | ] 18 | route_conf = [ 19 | {"addr": "10.10.2.0/24", "gw": "10.10.1.1", "nodes": ["romeo"]}, 20 | {"addr": "10.10.1.0/24", "gw": "10.10.2.1", "nodes": ["juliet"]} 21 | ] 22 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 23 | ``` 24 | ::: -------------------------------------------------------------------------------- /lab-static-basic/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with five hosts, three routers, and four network segments, with addresses on each network interface configured as follows: 4 | 5 | ![](static-routing-topo.svg) 6 | 7 | each with a netmask of 255.255.255.0. 8 | 9 | To reserve resources on Cloudlab, open this profile page: 10 | 11 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/static_routing](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/static_routing) 12 | 13 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment will run on any CloudLab cluster.) Then click "next", and "finish". 14 | 15 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 16 | 17 | Use `ip addr` to view the network interface configuration on each host, and save the output for your own reference. 18 | -------------------------------------------------------------------------------- /lab-udp/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.0.1.100 6 | * router, interface connected to romeo: 10.0.1.1 7 | * router, interface connected to juliet: 10.0.2.1 8 | * juliet: 10.0.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_udp](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_udp) 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the resources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 19 | -------------------------------------------------------------------------------- /lab-tcp-socket/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off) 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 19 | -------------------------------------------------------------------------------- /lab-line-router/fabric-transfer-udp.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | ``` 21 | ::: 22 | 23 | 24 | ::: {.cell .markdown} 25 | #### Packet Captures for Exercise: UDP as a connectionless protocol 26 | 27 | ::: 28 | 29 | 30 | ::: {.cell .code} 31 | ```python 32 | romeo_pcap = "/home/ubuntu/%s-echoping.pcap" % romeo_name 33 | romeo_exec.download_file(os.path.abspath('romeo-echoping.pcap'), romeo_pcap) 34 | ``` 35 | ::: 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab-tcp-congestion/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), and a router in between them, with IP addresses configured as follows: 4 | 5 | * romeo: 10.10.1.100 6 | * router, interface connected to romeo: 10.10.1.1 7 | * router, interface connected to juliet: 10.10.2.1 8 | * juliet: 10.10.2.100 9 | 10 | each with a netmask of 255.255.255.0. 11 | 12 | To reserve these resources on Cloudlab, open this profile page: 13 | 14 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/line_tso_off) 15 | 16 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 17 | 18 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 19 | -------------------------------------------------------------------------------- /lab6/ss-output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DST=$1 4 | 5 | touch sender-ss.txt 6 | 7 | rm -f sender-ss.txt 8 | 9 | cleanup () 10 | { 11 | # get timestamp 12 | ts=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | awk '{print $1}') 13 | 14 | # get sender 15 | sender=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | awk '{print $6}') 16 | 17 | 18 | # retransmissions - current, total 19 | retr=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep -oP '\bunacked:.*\brcv_space' | awk -F '[:/ ]' '{print $4","$5}' | tr -d ' ') 20 | 21 | 22 | # get cwnd, ssthresh 23 | cwn=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | grep -oP '\bcwnd:.*(\s|$)\bbytes_acked' | awk -F '[: ]' '{print $2","$4}') 24 | 25 | # concatenate into one CSV 26 | paste -d ',' <(printf %s "$ts") <(printf %s "$sender") <(printf %s "$retr") <(printf %s "$cwn") > sender-ss.csv 27 | 28 | exit 0 29 | } 30 | 31 | trap cleanup SIGINT SIGTERM 32 | 33 | while [ 1 ]; do 34 | ss --no-header -ein dst $DST | ts '%.s' | tee -a sender-ss.txt 35 | done 36 | -------------------------------------------------------------------------------- /lab-stp/stp-reserve.md: -------------------------------------------------------------------------------- 1 | ## Reserve resources 2 | 3 | First, you will reserve a topology on GENI that includes four bridges connected in a loop. There is also one host on each network segment: 4 | 5 | ![](spanning-tree-topo.svg) 6 | 7 | 8 | 9 | In the GENI Portal, create a new slice, then click "Add Resources". Scroll down to where it says "Choose RSpec" and select the "URL" option, the load the RSpec from the URL: [https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/lab-stp/stp.xml](https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/lab-stp/stp.xml) 10 | 11 | In the Portal, there will be warning indicators on the canvas alerting you that a duplicate IP address is assigned. You can ignore this warning - we are deliberately assigning an IP address of 0.0.0.0 (i.e., no IP address) to each bridge interface. Since a bridge does not originate any Layer 3 packets, it does not need an IP address. 12 | 13 | Click on "Site 1" and choose an InstaGENI site to bind to. (There have been some reports that this experiment does not work at the Illinois InstaGENI site; I recommend avoiding that one.) Then reserve your resources. Wait for your nodes to boot up (they will turn green in the canvas display on your slice page in the GENI portal when they are ready). 14 | 15 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% if site.google_analytics %} 6 | 7 | 13 | {% endif %} 14 | 15 | 16 | {% seo %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | {{ content }} 28 | 29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /lab-line-direct/fabric-transfer-ntp.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .markdown} 16 | #### Packet Captures for Exercise - IP layer limit and fragmentation 17 | 18 | ::: 19 | 20 | 21 | ::: {.cell .code} 22 | ```python 23 | import os 24 | client_node = # TODO: fill in whichever node on which you run 'ntpdate' ("romeo" or "juliet") 25 | client_exec = slice.get_node(client_node) 26 | client_name = client_exec.execute("hostname", quiet=True)[0].strip() 27 | ``` 28 | ::: 29 | 30 | ::: {.cell .code} 31 | ```python 32 | client_pcap = "/home/ubuntu/ntp-%s.pcap" % client_name 33 | client_exec.download_file(os.path.abspath('ntp-%s.pcap' % client_node), client_pcap) 34 | ``` 35 | ::: -------------------------------------------------------------------------------- /lab-static-design/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, you will reserve a topology that includes three routers (router-a, router-b, and router-c) and two hosts connected to each router. The routers will already be configured with IP addresses (in the 10.1.10.0/24 subnet) on the link that connects the routers to one another. However, it will be up to you to design subnets for the small LAN connected to each router. 4 | 5 | The topology will look like the following: 6 | 7 | ![](subnet-design-topology.png) 8 | 9 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 10 | 11 | ``` 12 | git clone https://github.com/ffund/tcp-ip-essentials.git 13 | git checkout wip 14 | ``` 15 | 16 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-static-design". 17 | 18 | Then open the notebook titled "setup.ipynb". 19 | 20 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. 21 | 22 | Use `ip addr` to view the network interface configuration on each host, and save the output for your own reference. 23 | 24 | In particular, make sure to note **the name of the interface on each router that is on the 10.1.10.0/24 subnet** (Routing LAN), and the name of the interface that has no assigned address yet (LAN). -------------------------------------------------------------------------------- /scripts/ss-output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DST=$1 4 | 5 | touch sender-ss.txt 6 | 7 | rm -f sender-ss.txt 8 | 9 | cleanup () 10 | { 11 | # get timestamp 12 | ts=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | awk '{print $1}') 13 | 14 | # get sender 15 | sender=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | awk '{print $6}') 16 | 17 | 18 | # retransmissions - current, total 19 | retr=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep -oP '\bunacked:.*\brcv_space' | awk -F '[:/ ]' '{print $4","$5}' | tr -d ' ') 20 | 21 | 22 | # get cwnd, ssthresh 23 | cwn=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | grep -oP '\bcwnd:.*(\s|$)\bbytes_acked' | awk -F '[: ]' '{print $2","$4}') 24 | 25 | # get smoothed RTT (in ms) 26 | srtt=$(cat sender-ss.txt | sed -e ':a; /<->$/ { N; s/<->\n//; ba; }' | grep "ESTAB" | grep "unacked" | grep -oP '\brtt:[0-9]+\.[0-9]+' | awk -F '[: ]' '{print $2}') 27 | 28 | # concatenate into one CSV 29 | paste -d ',' <(printf %s "$ts") <(printf %s "$sender") <(printf %s "$retr") <(printf %s "$cwn") <(printf %s "$srtt") > sender-ss.csv 30 | 31 | 32 | exit 0 33 | } 34 | 35 | trap cleanup SIGINT SIGTERM 36 | 37 | while [ 1 ]; do 38 | ss --no-header -ein dst $DST | ts '%.s' | tee -a sender-ss.txt 39 | done 40 | -------------------------------------------------------------------------------- /lab-l2-bridge/fabric-define-l2-bridge.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Bridge experiments 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="l2-bridge-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 13 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 14 | {'name': "bridge", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 15 | ] 16 | net_conf = [ 17 | {"name": "net0", "subnet": "10.0.0.0/24", "nodes": [{"name": "romeo", "addr": "10.0.0.1"}, {"name": "bridge", "addr": None}]}, 18 | {"name": "net1", "subnet": "10.0.0.0/24", "nodes": [{"name": "juliet", "addr": "10.0.0.2"}, {"name": "bridge", "addr": None}]}, 19 | {"name": "net2", "subnet": "10.0.0.0/24", "nodes": [{"name": "hamlet", "addr": "10.0.0.3"}, {"name": "bridge", "addr": None}]}, 20 | {"name": "net3", "subnet": "10.0.0.0/24", "nodes": [{"name": "ophelia", "addr": "10.0.0.4"}, {"name": "bridge", "addr": None}]} 21 | ] 22 | route_conf = [] 23 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 24 | ``` 25 | ::: -------------------------------------------------------------------------------- /lab-l2-bridge/fabric-transfer-l2-bridge.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from Bridge experiments 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | juliet_exec = slice.get_node("juliet") 21 | juliet_name = juliet_exec.execute("hostname", quiet=True)[0].strip() 22 | ``` 23 | ::: 24 | 25 | 26 | ::: {.cell .markdown} 27 | #### Packet Captures for Exercise - a simple bridge experiment 28 | 29 | ::: 30 | 31 | 32 | ::: {.cell .code} 33 | ```python 34 | romeo_pcap = "/home/ubuntu/%s-bridge.pcap" % romeo_name 35 | romeo_exec.download_file(os.path.abspath('romeo-bridge.pcap'), romeo_pcap) 36 | ``` 37 | ::: 38 | 39 | 40 | ::: {.cell .code} 41 | ```python 42 | juliet_pcap = "/home/ubuntu/%s-bridge.pcap" % romeo_name 43 | juliet_exec.download_file(os.path.abspath('juliet-bridge.pcap'), juliet_pcap) 44 | ``` 45 | ::: -------------------------------------------------------------------------------- /lab-multicast-basic/fabric-define-multicast-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Multicast experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="multicast-basic-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['iperf']}, 12 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['iperf']}, 13 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['iperf']}, 14 | {'name': "router", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 15 | ] 16 | net_conf = [ 17 | {"name": "net1", "subnet": "10.10.1.0/24", "nodes": [{"name": "romeo", "addr": "10.10.1.100"}, {"name": "juliet", "addr": "10.10.1.101"}, {"name": "hamlet", "addr": "10.10.1.102"}, {"name": "router", "addr": "10.10.1.1"}]}, 18 | {"name": "net2", "subnet": "10.10.2.0/24", "nodes": [{"name": "ophelia", "addr": "10.10.2.103"}, {"name": "router", "addr": "10.10.2.1"}]} 19 | ] 20 | route_conf = [ 21 | {"addr": "10.10.2.0/24", "gw": "10.10.1.1", "nodes": ["romeo", "juliet", "hamlet"]}, 22 | {"addr": "10.10.1.0/24", "gw": "10.10.2.1", "nodes": ["ophelia"]} 23 | ] 24 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 25 | ``` 26 | ::: -------------------------------------------------------------------------------- /lab-line-direct/fabric-transfer-linux.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | ``` 20 | ::: 21 | 22 | 23 | ::: {.cell .markdown} 24 | #### Packet Captures for Exercise - Save a packet capture to a file and analyze it in Wireshark 25 | 26 | ::: 27 | 28 | 29 | ::: {.cell .code} 30 | ```python 31 | romeo_file_pcap = "/home/ubuntu/romeo-tcpdump-file.pcap" 32 | romeo_exec.download_file(os.path.abspath('romeo-tcpdump-file.pcap'), romeo_file_pcap) 33 | ``` 34 | ::: 35 | 36 | 37 | ::: {.cell .markdown} 38 | #### Packet Captures for Exercise - Useful display options and capture options in tcpdump 39 | 40 | ::: 41 | 42 | 43 | ::: {.cell .code} 44 | ```python 45 | romeo_snaplen_pcap = "/home/ubuntu/romeo-tcpdump-snaplen.pcap" 46 | romeo_exec.download_file(os.path.abspath('romeo-tcpdump-snaplen.pcap'), romeo_snaplen_pcap) 47 | ``` 48 | ::: -------------------------------------------------------------------------------- /lab-static-design/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, you will reserve a topology that includes three routers (router-a, router-b, and router-c) and two hosts connected to each router. The routers will already be configured with IP addresses (in the 10.1.10.0/24 subnet) on the link that connects the routers to one another. However, it will be up to you to design subnets for the small LAN connected to each router. 4 | 5 | The topology will look like the following: 6 | 7 | ![](subnet-design-topology.png) 8 | 9 | To reserve resources on Cloudlab, open this profile page: 10 | 11 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/design_subnets_22](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/design_subnets_22) 12 | 13 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. Then click "next", and "finish". 14 | 15 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 16 | 17 | Use `ip addr` to view the network interface configuration on each host and router, and save the output for your own reference. 18 | 19 | In particular, make sure to note **the name of the interface on each router that is on the 10.1.10.0/24 subnet** (Routing LAN), and the name of the interface that has no assigned address yet (LAN). 20 | -------------------------------------------------------------------------------- /lab-dynamic-basic/reserve-fabric.md: -------------------------------------------------------------------------------- 1 | ## FABRIC-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with four routers in a ring, and a host connected to each LAN. 4 | 5 | The topology for this experiment, with the IP address of each interface, is illustrated in the following diagram: 6 | 7 | 8 | 9 | The topology has four LANs: 10 | 11 | * 10.10.61.0/24 (LAN 61) 12 | * 10.10.62.0/24 (LAN 62) 13 | * 10.10.63.0/24 (LAN 63) 14 | * 10.10.64.0/24 (LAN 64) 15 | 16 | For convenience, the last octet of each IP address is the router index (for routers) or 100 (for workstations), so that it is easy to identify. 17 | 18 | To run this experiment on FABRIC, open the JupyterHub environment on FABRIC, open a shell, and run 19 | 20 | ``` 21 | git clone https://github.com/ffund/tcp-ip-essentials.git 22 | git checkout wip 23 | ``` 24 | 25 | In the File Browser on the left, first go to the directory "tcp-ip-essentials", and then go to the directory "lab-dynamic-basic". 26 | 27 | Then open the notebook titled "setup.ipynb". 28 | 29 | Follow along inside the notebook to reserve resources and get the login details for each node in the experiment. 30 | 31 | Before you start, use `ip addr` to capture the network interface configuration of each host and router in this topology. Save this for your reference. 32 | 33 | On boot, each workstation and router will only have routing rules for subnets that it directly connects to (and for the control interface). It will not have routing rules for other subnets in the experiment topology. Confirm this with 34 | 35 | ``` 36 | ip route 37 | ``` 38 | -------------------------------------------------------------------------------- /lab6/el5373-lab6-69.md: -------------------------------------------------------------------------------- 1 | ## 6.9 Exercise on TCP bulk data flow 2 | 3 | For this experiment, we will reuse the same network as in the [previous experiment](el5373-lab6-67.md). 4 | 5 | ### Exercise 4 6 | 7 | On "juliet", download a small file (e.g. an image file) from the Internet to your home directory. Rename it to `out.file` (use the `mv` command to rename). 8 | 9 | Then, start a `tcpdump` on "juliet": 10 | 11 | ``` 12 | sudo tcpdump -S -i eth1 -w tcp-bulk-1-$(hostname -s).pcap 13 | ``` 14 | 15 | While `tcpdump` is running and capturing the packets between "romeo" and "juliet", on "romeo" run 16 | 17 | ``` 18 | nc -l -p 1234 > out.file 19 | ``` 20 | 21 | Then, on another SSH session on "juliet", run 22 | 23 | ``` 24 | nc -w 3 10.10.1.100 1234 < out.file 25 | ``` 26 | 27 | to transfer the file from "juliet" to "romeo". 28 | 29 | Do the same experiment three times, but change the `tcpdump` output file name so that a new file is created each time. Save the `tcpdump` outputs for your lab report. 30 | 31 | **Lab report**: Using one of the three `tcpdump` outputs, explain the operation of TCP in terms of data segments and their acknowledgements. Does the number of data segments different from that of their acknowledgements? 32 | 33 | Compare all the `tcpdump` outputs you saved. Discuss any differences among them, in terms of data segments and their acknowledgements. 34 | 35 | **Lab report**: From the `tcpdump` output, how many different TCP flags can you see? Enumerate the flags and explain their meanings. 36 | 37 | How many different TCP options can you see? Explain their meanings. 38 | 39 | Once you are done with this part of the lab , proceed to the [next part](el5373-lab6-610.md) 40 | -------------------------------------------------------------------------------- /lab-stp/stp-setup.md: -------------------------------------------------------------------------------- 1 | ## Set up bridge interfaces 2 | 3 | Next, we will set up the bridge nodes. Open a terminal for every bridge node, and SSH into each one. 4 | 5 | Follow the setup procedure in this section on _each_ bridge node (but not on the other hosts!). 6 | 7 | (It may be quickest to bring up four terminals, each logged in to another bridge node, then copy each command and paste it into all four terminals at once. That way, you will set up all the bridge nodes together.) 8 | 9 | Flush the IP address on each experiment interface - since a bridge operates at Layer 2, bridge interfaces do not need an IP address: 10 | 11 | ``` 12 | sudo ip addr flush dev eth1 13 | sudo ip addr flush dev eth2 14 | ``` 15 | 16 | Then, create a new bridge interface named `br0` with the command 17 | 18 | ``` 19 | sudo ip link add br0 type bridge 20 | ``` 21 | 22 | and add the two experiment interfaces to the bridge: 23 | 24 | ``` 25 | sudo ip link set eth1 master br0 26 | sudo ip link set eth2 master br0 27 | ``` 28 | 29 | In the next part of this experiment, we will deliberately trigger a broadcast storm by sending a broadcast frame through this network of bridges. However, there is some background network protocol traffic in the network that may trigger a broadcast storm automatically, even before we send our own broadcast frame! To make it less likely that a broadcast storm will be triggered by automatic network protocol traffic, we will turn off multicast frame flooding on our bridges. 30 | 31 | ``` 32 | sudo bridge link set dev eth1 mcast_flood off 33 | sudo bridge link set dev eth2 mcast_flood off 34 | echo '0' | sudo tee -a /sys/class/net/br0/bridge/multicast_snooping 35 | ``` 36 | 37 | At this point, the bridges are configured but they are not yet "up" - we'll do that in the next section! 38 | -------------------------------------------------------------------------------- /rspecs/two-hosts-one-public.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /lab-dynamic-basic/reserve-cloudlab.md: -------------------------------------------------------------------------------- 1 | ## Cloudlab-specific instructions: Reserve resources 2 | 3 | For this experiment, we will use a topology with four routers in a ring, and a host connected to each LAN. 4 | 5 | The topology for this experiment, with the IP address of each interface, is illustrated in the following diagram: 6 | 7 | 8 | 9 | The topology has four LANs: 10 | 11 | * 10.10.61.0/24 (LAN 61) 12 | * 10.10.62.0/24 (LAN 62) 13 | * 10.10.63.0/24 (LAN 63) 14 | * 10.10.64.0/24 (LAN 64) 15 | 16 | For convenience, the last octet of each IP address is the router index (for routers) or 100 (for workstations), so that it is easy to identify. 17 | 18 | To reserve these resources on Cloudlab, open this profile page: 19 | 20 | [https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/dynamic_basic_22](https://www.cloudlab.us/p/nyunetworks/education?refspec=refs/heads/dynamic_basic_22) 21 | 22 | Click "next", then select the Cloudlab project that you are part of and a Cloudlab cluster with available resources. (This experiment is compatible with any of the Cloudlab clusters.) Then click "next", and "finish". 23 | 24 | Wait until all of the sources have turned green and have a small check mark in the top right corner of the "topology view" tab, indicating that they are fully configured and ready to log in. Then, click on "list view" to get SSH login details for the nodes. 25 | 26 | Before you start, use `ip addr` to capture the network interface configuration of each host and router in this topology. Save this for your reference. 27 | 28 | On boot, each workstation and router will only have routing rules for subnets that it directly connects to (and for the control interface). It will not have routing rules for other subnets in the experiment topology. Confirm this with 29 | 30 | ``` 31 | ip route 32 | ``` 33 | -------------------------------------------------------------------------------- /lab6/el5373-lab6-68.md: -------------------------------------------------------------------------------- 1 | ## 6.8 Exercise on TCP interactive data flow 2 | 3 | For this experiment, we will reuse the same network as in the [previous experiment](el5373-lab6-67.md). 4 | 5 | ### Exercise 3 6 | 7 | On "juliet", start a `tcpdump`: 8 | 9 | ``` 10 | sudo tcpdump -S -i eth1 -w tcp-interactive-$(hostname -s).pcap 11 | ``` 12 | 13 | While `tcpdump` capturing the traffic between "romeo" and "juliet", issue the following command on "romeo": 14 | 15 | ``` 16 | telnet 10.10.2.100 17 | ``` 18 | 19 | Enter your username and password at the prompt. Then type 20 | 21 | ``` 22 | date 23 | ``` 24 | 25 | and press Enter. 26 | 27 | Now, in order to generate data faster than the round-trip time of a single byte to be sent and echoed, type any sequence of keys in the `telnet` window very rapidly. 28 | 29 | Save the `tcpdump` output for your lab report. Type 30 | 31 | ``` 32 | exit 33 | ``` 34 | 35 | in the `telnet` session to end it. 36 | 37 | **Lab report**: Answer the following questions, based on the `tcpdump` output saved in the above exercise: 38 | 39 | 1. What is a delayed acknowledgement? What is it used for? 40 | 2. Can you see any delayed acknowledgements in your `tcpdump` output? If yes, explain the reason. Mark some of the lines with delayed acknowledgements, and submit this with your report. Explain how the delayed ACK timer operates, using your `tcpdump` output.

If you don't see any delayed acknowledgements, explain the reason why none was observed. 41 | 3. What is the Nagle algorithm used for? From your `tcpdump` output, can you tell whether the Nagle algorithm is enabled or not? Give the reason for your answer.

From your `tcpdump` output for when you typed very rapidly can you see any segment that contains more than one character going from your workstation to the remote machine? 42 | 43 | Once you are done with this part of the lab , proceed to the [next part](el5373-lab6-69.md) 44 | -------------------------------------------------------------------------------- /lab-dynamic/reserve.md: -------------------------------------------------------------------------------- 1 | ## Reserve resources for RIP experiment 2 | 3 | For this experiment, we will use a topology with four routers in a ring, and a host connected to each LAN. 4 | 5 | To set up this topology in the GENI Portal, create a slice, click on "Add Resources", and load the RSpec from the following URL: https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/dynamic-routing.xml 6 | 7 | The topology for this experiment, with the IP address of each interface, is illustrated in the following diagram: 8 | 9 | 10 | 11 | The topology has four LANs: 12 | 13 | * 10.10.61.0/24 (LAN 61) 14 | * 10.10.62.0/24 (LAN 62) 15 | * 10.10.63.0/24 (LAN 63) 16 | * 10.10.64.0/24 (LAN 64) 17 | 18 | For convenience, the last octet of each IP address is the router index (for routers) or 100 (for workstations), so that it is easy to identify 19 | 20 | Once you have loaded the topology in the GENI Portal, bind to an InstaGENI site and reserve your resources. (You can refer to the [monitor website](https://fedmon.fed4fire.eu/overview/instageni) to identify an InstaGENI site that has many "free VMs" available.) Wait for your resources to become available for login ("turn green" on your canvas). 21 | 22 | This RSpec also defines a configuration script that runs when each host boots, so after the resources "turn green", wait a few more minutes beyond that for the configuration script to finish running. Then SSH into each, using the details given in the GENI Portal. 23 | 24 | Before you start, use `ifconfig -a` to capture the network interface configuration of each host and router in this topology. Save this for your reference. 25 | 26 | On boot, each workstation and router will only have routing rules for subnets that it directly connects to (and for the control interface). It will not have routing rules for other subnets in the experiment topology. Confirm this with 27 | 28 | ``` 29 | route -n 30 | ``` 31 | -------------------------------------------------------------------------------- /lab-l2-arp/fabric-transfer-l2-arp.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from ARP experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | ``` 21 | ::: 22 | 23 | 24 | ::: {.cell .markdown} 25 | #### Packet Captures for Exercise - ARP 26 | 27 | ::: 28 | 29 | 30 | ::: {.cell .code} 31 | ```python 32 | romeo_arp_pcap = "/home/ubuntu/%s-arp.pcap" % romeo_name 33 | romeo_exec.download_file(os.path.abspath('romeo-arp.pcap'), romeo_arp_pcap) 34 | ``` 35 | ::: 36 | 37 | 38 | ::: {.cell .code} 39 | ```python 40 | romeo_no_arp_pcap = "/home/ubuntu/%s-no-arp.pcap" % romeo_name 41 | romeo_exec.download_file(os.path.abspath('romeo-no-arp.pcap'), romeo_no_arp_pcap) 42 | ``` 43 | ::: 44 | 45 | 46 | ::: {.cell .markdown} 47 | #### Packet Captures for Exercise - ARP for a non-existent host 48 | 49 | ::: 50 | 51 | ::: {.cell .code} 52 | ```python 53 | romeo_eth_pcap = "/home/ubuntu/%s-eth-nonexistent.pcap" % romeo_name 54 | romeo_exec.download_file(os.path.abspath('romeo-eth-nonexistent.pcap'), romeo_eth_pcap) 55 | ``` 56 | ::: 57 | 58 | ::: {.cell .code} 59 | ```python 60 | romeo_lo_pcap = "/home/ubuntu/%s-lo-nonexistent.pcap" % romeo_name 61 | romeo_exec.download_file(os.path.abspath('romeo-lo-nonexistent.pcap'), romeo_lo_pcap) 62 | ``` 63 | ::: 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /lab-multicast-basic/fabric-transfer-multicast-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from Multicast experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | router_exec = slice.get_node("router") 21 | router_name = router_exec.execute("hostname", quiet=True)[0].strip() 22 | ``` 23 | ::: 24 | 25 | 26 | ::: {.cell .markdown} 27 | #### Packet Captures for Exercise - MAC addresses for multicast, broadcast, and unicast addresses 28 | 29 | ::: 30 | 31 | 32 | ::: {.cell .code} 33 | ```python 34 | romeo_mac_pcap = "/home/ubuntu/simple-multicast-mac-%s.pcap" % romeo_name 35 | romeo_exec.download_file(os.path.abspath('simple-multicast-mac-romeo.pcap'), romeo_mac_pcap) 36 | ``` 37 | ::: 38 | 39 | 40 | ::: {.cell .markdown} 41 | #### Packet Captures for Exercise - Receiving traffic for a multicast group 42 | 43 | ::: 44 | 45 | 46 | ::: {.cell .code} 47 | ```python 48 | router_net1_pcap = "/home/ubuntu/simple-multicast-net1-group-%s.pcap" % router_name 49 | router_exec.download_file(os.path.abspath('simple-multicast-net1-group-router.pcap'), router_net1_pcap) 50 | router_net2_pcap = "/home/ubuntu/simple-multicast-net2-group-%s.pcap" % router_name 51 | router_exec.download_file(os.path.abspath('simple-multicast-net2-group-router.pcap'), router_net2_pcap) 52 | ``` 53 | ::: -------------------------------------------------------------------------------- /lab-static-basic/fabric-define-static-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Static Routing experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="static-basic-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 13 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 14 | {'name': "router-1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 15 | {'name': "router-2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 16 | {'name': "router-3", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 17 | {'name': "othello", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 18 | ] 19 | net_conf = [ 20 | {"name": "net0", "subnet": "10.10.0.0/24", "nodes": [{"name": "romeo", "addr": "10.10.0.100"}, {"name": "juliet", "addr": "10.10.0.101"}, {"name": "hamlet", "addr": "10.10.0.102"}, {"name": "ophelia", "addr": "10.10.0.103"}, {"name": "router-1", "addr": "10.10.0.1"}]}, 21 | {"name": "net1", "subnet": "10.10.100.0/24", "nodes": [{"name": "router-1", "addr": "10.10.100.1"}, {"name": "router-2", "addr": "10.10.100.2"}, {"name": "router-3", "addr": "10.10.100.3"}]}, 22 | {"name": "net2", "subnet": "10.10.1.0/24", "nodes": [{"name": "othello", "addr": "10.10.1.104"}, {"name": "router-2", "addr": "10.10.1.1"}]}, 23 | {"name": "net3", "subnet": "10.10.2.0/24", "nodes": [{"name": "othello", "addr": "10.10.2.104"}, {"name": "router-3", "addr": "10.10.2.1"}]} 24 | ] 25 | route_conf = [] 26 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 27 | ``` 28 | ::: -------------------------------------------------------------------------------- /lab-dynamic-basic/fabric-define-dynamic-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Dynamic Routing experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="dynamic-basic-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['traceroute']}, 11 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "othello", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 13 | {'name': "petruchio", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 14 | {'name': "router-1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 15 | {'name': "router-2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 16 | {'name': "router-3", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 17 | {'name': "router-4", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 18 | ] 19 | net_conf = [ 20 | {"name": "net61", "subnet": "10.10.61.0/24", "nodes": [{"name": "romeo", "addr": "10.10.61.100"}, {"name": "router-1", "addr": "10.10.61.1"}, {"name": "router-4", "addr": "10.10.61.4"}]}, 21 | {"name": "net62", "subnet": "10.10.62.0/24", "nodes": [{"name": "hamlet", "addr": "10.10.62.100"}, {"name": "router-1", "addr": "10.10.62.1"}, {"name": "router-2", "addr": "10.10.62.2"}]}, 22 | {"name": "net63", "subnet": "10.10.63.0/24", "nodes": [{"name": "othello", "addr": "10.10.63.100"}, {"name": "router-2", "addr": "10.10.63.2"}, {"name": "router-3", "addr": "10.10.63.3"}]}, 23 | {"name": "net64", "subnet": "10.10.64.0/24", "nodes": [{"name": "petruchio", "addr": "10.10.64.100"}, {"name": "router-3", "addr": "10.10.64.3"}, {"name": "router-4", "addr": "10.10.64.4"}]} 24 | ] 25 | route_conf = [] 26 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 27 | ``` 28 | ::: -------------------------------------------------------------------------------- /lab-static-design/fabric-define-static-design.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Static Routing - Subnet Design experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="static-design-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "router-a", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 11 | {'name': "router-b", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 12 | {'name': "router-c", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 13 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 14 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 15 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 16 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 17 | {'name': "othello", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']}, 18 | {'name': "desdemona", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['mtr']} 19 | ] 20 | net_conf = [ 21 | {"name": "net0", "subnet": "10.10.100.0/24", "nodes": [{"name": "router-a", "addr": "10.1.10.1"}, {"name": "router-b", "addr": "10.1.10.2"}, {"name": "router-c", "addr": "10.1.10.3"}]}, 22 | {"name": "net1", "subnet": None, "nodes": [{"name": "router-a", "addr": None}, {"name": "romeo", "addr": None}, {"name": "juliet", "addr": None}]}, 23 | {"name": "net2", "subnet": None, "nodes": [{"name": "router-b", "addr": None}, {"name": "hamlet", "addr": None}, {"name": "ophelia", "addr": None}]}, 24 | {"name": "net3", "subnet": None, "nodes": [{"name": "router-c", "addr": None}, {"name": "othello", "addr": None}, {"name": "desdemona", "addr": None}]} 25 | ] 26 | route_conf = [] 27 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 28 | ``` 29 | ::: -------------------------------------------------------------------------------- /lab-stp/stp-change.md: -------------------------------------------------------------------------------- 1 | ## Adapt to changes in the topology 2 | 3 | Finally, we will observe how the spanning tree protocol adapts to changes in the topology. After bringing down the root bridge, we will see a temporary loss in connectivity between two end hosts, then a change in bridge port state on some bridges and re-establishment of a link (following a different Layer 2 path). 4 | 5 | 6 | We are going to choose two hosts that are on opposite sides of the root bridge: "othello" and "hamlet". 7 | 8 | On "othello", run 9 | 10 | ``` 11 | ping 10.10.0.102 12 | ``` 13 | 14 | to send ICMP echo requests to "hamlet". A new ICMP echo request (with increasing sequence number) will be sent after each second. 15 | 16 | 17 | On all four hosts, run 18 | 19 | ``` 20 | sudo tcpdump -i eth1 -w stp-change-$(hostname -s).pcap 21 | ``` 22 | 23 | Then, on "bridge-2" - the _root_ bridge in the spanning tree - bring the bridge interface down with 24 | 25 | ``` 26 | sudo ip link set br0 down 27 | ``` 28 | 29 | On the other bridges, run 30 | 31 | ``` 32 | brctl showstp br0 33 | ``` 34 | 35 | and see how they reconfigure themselves to work around the change in the topology. How long does it take before the ICMP echo requests you are sending start to get a response again? 36 | 37 | Once the ICMP echo requests are getting through again, stop the `tcpdump` instances. Use `scp` to transfer these to your laptop. Also run `brctl showstp br0` to get the bridge port state on all four bridges, and save these for your lab report. 38 | 39 | 40 | 41 | **Lab report**: Describe the path that the ICMP echo requests took through the network *before* you brought down the root bridge, and describe the path that the ICMP echo requests took through the network *after* you brought down the root bridge. 42 | 43 | 44 | **Lab report**: When you changed the topology, how much time elapsed between the last ping request arriving at the target _before_ you brought the root bridge down, and the first ping request arriving at the target _after_ you brought the root bridge down? (Use the packet capture from the network segment on which the target node was located.) 45 | Show evidence from your packet captures to support your answer. 46 | 47 | -------------------------------------------------------------------------------- /lab-line-router/fabric-transfer-tcp-2.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | juliet_exec = slice.get_node("juliet") 21 | juliet_name = juliet_exec.execute("hostname", quiet=True)[0].strip() 22 | ``` 23 | ::: 24 | 25 | 26 | ::: {.cell .markdown} 27 | #### Packet Captures for Exercise: CWND-limited bulk file transfer 28 | 29 | ::: 30 | 31 | 32 | ::: {.cell .code} 33 | ```python 34 | romeo_bulk_cwnd_pcap = "/home/ubuntu/%s-tcp-bulk-cwnd.pcap" % romeo_name 35 | romeo_exec.download_file(os.path.abspath('romeo-tcp-bulk-cwnd.pcap'), romeo_bulk_cwnd_pcap) 36 | ``` 37 | ::: 38 | 39 | 40 | ::: {.cell .markdown} 41 | #### Packet Captures for Exercise: RWND-limited bulk file transfer 42 | 43 | ::: 44 | 45 | 46 | ::: {.cell .code} 47 | ```python 48 | romeo_bulk_rwnd_pcap = "/home/ubuntu/%s-tcp-bulk-rwnd.pcap" % romeo_name 49 | romeo_exec.download_file(os.path.abspath('romeo-tcp-bulk-rwnd.pcap'), romeo_bulk_rwnd_pcap) 50 | ``` 51 | ::: 52 | 53 | 54 | ::: {.cell .markdown} 55 | #### Packet Captures for Exercise: Explicit congestion notification (ECN) 56 | 57 | ::: 58 | 59 | 60 | ::: {.cell .code} 61 | ```python 62 | romeo_ecn_pcap = "/home/ubuntu/%s-tcp-ecn.pcap" % romeo_name 63 | romeo_exec.download_file(os.path.abspath('romeo-tcp-ecn.pcap'), romeo_ecn_pcap) 64 | ``` 65 | ::: 66 | 67 | ::: {.cell .code} 68 | ```python 69 | juliet_ecn_pcap = "/home/ubuntu/%s-tcp-ecn.pcap" % juliet_name 70 | juliet_exec.download_file(os.path.abspath('juliet-tcp-ecn.pcap'), juliet_ecn_pcap) 71 | ``` 72 | ::: -------------------------------------------------------------------------------- /lab9/el5373-lab9-912.md: -------------------------------------------------------------------------------- 1 | ## Exercises on firewalls 2 | 3 | For this experiment, we will reuse the same network as in the previous experiment. 4 | 5 | ### Exercise: Firewall with drop rule 6 | 7 | On "server", execute 8 | 9 | ``` 10 | sudo iptables -L -v 11 | ``` 12 | 13 | to list the existing rules in the filter table. Save the output for your lab report. 14 | 15 | Append a rule to the end of the INPUT chain by executing 16 | 17 | ``` 18 | sudo iptables -A INPUT -v -p TCP --dport 23 -j DROP 19 | ``` 20 | 21 | Run 22 | 23 | ``` 24 | sudo iptables -L -v 25 | ``` 26 | 27 | 28 | again to display the filter table. Save the output. 29 | 30 | On "romeo", run 31 | 32 | ``` 33 | sudo tcpdump -i eth1 -w iptables-drop-$(hostname -s).pcap 34 | ``` 35 | 36 | to capture traffic between "romeo" and "server". While this is running, initiate a `telnet` connection from "romeo" to "server" - on "romeo", run 37 | 38 | ``` 39 | telnet server 40 | ``` 41 | 42 | Wait until your `telnet` process terminates (this may take some time), then stop the `tcpdump` and transfer the packet capture to your laptop with `scp`. 43 | 44 | 45 | **Lab report**: Can you `telnet` to the host from the remote machine? Explain. 46 | 47 | 48 | ### Exercise: Firewall with TCP RST reject 49 | 50 | Delete the rule created in the last exercise - on "server", execute 51 | 52 | ``` 53 | sudo iptables -D INPUT -v -p TCP --dport 23 -j DROP 54 | ``` 55 | 56 | Then, append a new rule to the INPUT chain: 57 | 58 | ``` 59 | sudo iptables -A INPUT -v -p TCP --dport 23 -j REJECT --reject-with tcp-reset 60 | ``` 61 | 62 | Run 63 | 64 | ``` 65 | sudo iptables -L -v 66 | ``` 67 | 68 | 69 | to display the filter table. Save the output. 70 | 71 | On "romeo", run 72 | 73 | ``` 74 | sudo tcpdump -i eth1 -w iptables-reset-$(hostname -s).pcap 75 | ``` 76 | 77 | to capture traffic between "server" and "romeo". While this is running, initiate a `telnet` connection from "romeo" to "server" - on "romeo", run 78 | 79 | ``` 80 | telnet server 81 | ``` 82 | 83 | Wait until your `telnet` process terminates, then stop the `tcpdump` and transfer the packet capture to your laptop with `scp`. 84 | 85 | 86 | **Lab report**: Explain the different between the `tcpdump` output in this exercise and the previous exercise. 87 | -------------------------------------------------------------------------------- /lab-l2-bridge/simple-bridge.md: -------------------------------------------------------------------------------- 1 | ## Exercise - a simple bridge experiment 2 | 3 | For this experiment, we will use the same network from "Operation of a basic Ethernet switch or bridge". After you have completed that experiment through the section titled "Exercise", you will also run the following: 4 | 5 | 6 | On *both* romeo and juliet, run 7 | 8 | ``` 9 | sudo tcpdump -i EXPIFACE1 -w $(hostname -s)-bridge.pcap 10 | ``` 11 | 12 | Then, in another terminal tab or window, send echo requests from romeo to juliet: 13 | 14 | ``` 15 | ping -c 3 10.0.0.2 16 | ``` 17 | 18 | After receiving the third echo reply, stop both `tcpdump` processes. You can play back a summary of your packet capture with 19 | 20 | ``` 21 | tcpdump -en -r $(hostname -s)-bridge.pcap 22 | ``` 23 | 24 | on each host, and you can use `scp` to transfer them to your laptop for further analysis. 25 | 26 | 27 | Pick a single ICMP request, and find the packet carrying that ICMP request in both packet captures; the one on romeo and the one on juliet. (To make sure it is the same packet, check the ICMP sequence number. It should be the same in both.) 28 | 29 | In the packet capture on romeo, you will see what this packet looks like as it traverses the link from romeo to the bridge. In the packet capture on juliet, you will see what this packet looks like as it traverses the link from the bridge to juliet. 30 | 31 | **Lab report**: What are the source and destination IP and MAC addresses of a packet that went from romeo to the bridge? Show the annotated screenshot from your `tcpdump` replay on romeo, with the source and destination IP address and source and destination MAC address clearly labeled. Does romeo put the bridge's MAC address or juliet's MAC address in the destination address field of the Ethernet header? 32 | 33 | **Lab report**: What are the source and destination IP and MAC addresses of the same packet when it goes from the bridge to juliet? Show the annotated screenshot *of the same packet* from your `tcpdump` replay on juliet, with the source and destination IP address and source and destination MAC address clearly labeled. Does the bridge modify the source or destination MAC address in the Ethernet header? 34 | 35 | After completing all this and saving all the output you will need for your lab report, you can delete your resources from this experiment. 36 | -------------------------------------------------------------------------------- /lab-line-router/fabric-transfer-tcp-1.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | ``` 21 | ::: 22 | 23 | 24 | ::: {.cell .markdown} 25 | #### Packet Captures for Exercise: TCP connection refused 26 | 27 | ::: 28 | 29 | 30 | ::: {.cell .code} 31 | ```python 32 | romeo_refused_pcap = "/home/ubuntu/%s-tcp-connection-refused.pcap" % romeo_name 33 | romeo_exec.download_file(os.path.abspath('romeo-tcp-connection-refused.pcap'), romeo_refused_pcap) 34 | ``` 35 | ::: 36 | 37 | 38 | ::: {.cell .markdown} 39 | #### Packet Captures for Exercise: TCP connection establishment 40 | 41 | ::: 42 | 43 | 44 | ::: {.cell .code} 45 | ```python 46 | romeo_established_pcap = "/home/ubuntu/%s-tcp-connection-establishment.pcap" % romeo_name 47 | romeo_exec.download_file(os.path.abspath('romeo-tcp-connection-establishment.pcap'), romeo_established_pcap) 48 | ``` 49 | ::: 50 | 51 | 52 | ::: {.cell .markdown} 53 | #### Packet Captures for Exercise: TCP bulk transfer 54 | 55 | ::: 56 | 57 | 58 | ::: {.cell .code} 59 | ```python 60 | romeo_bulk_error_pcap = "/home/ubuntu/%s-tcp-bulk-error.pcap" % romeo_name 61 | romeo_exec.download_file(os.path.abspath('romeo-tcp-bulk-error.pcap'), romeo_bulk_error_pcap) 62 | ``` 63 | ::: 64 | 65 | 66 | ::: {.cell .markdown} 67 | #### Packet Captures for Exercise: interrupted bulk file transfer 68 | 69 | ::: 70 | 71 | 72 | ::: {.cell .code} 73 | ```python 74 | romeo_bulk_interrupted_pcap = "/home/ubuntu/%s-tcp-bulk-interrupted.pcap" % romeo_name 75 | romeo_exec.download_file(os.path.abspath('romeo-tcp-bulk-interrupted.pcap'), romeo_bulk_interrupted_pcap) 76 | ``` 77 | ::: -------------------------------------------------------------------------------- /lab3/3-5-simple-bridge.md: -------------------------------------------------------------------------------- 1 | ## Exercise - a simple bridge experiment 2 | 3 | For this experiment, we will use the same network from [Operation of a basic Ethernet switch or bridge](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/). After you have completed that experiment through the section titled "Exercise", you will also run the following: 4 | 5 | 6 | On *both* node-1 and node-2, run 7 | 8 | ``` 9 | sudo tcpdump -i eth1 -w $(hostname -s)-bridge.pcap 10 | ``` 11 | 12 | Then, in another terminal tab or window, send echo requests from node-1 to node-2: 13 | 14 | ``` 15 | ping -c 3 10.0.0.2 16 | ``` 17 | 18 | After receiving the third echo reply, stop both `tcpdump` processes. You can play back a summary of your packet capture with 19 | 20 | ``` 21 | tcpdump -en -r $(hostname -s)-bridge.pcap 22 | ``` 23 | 24 | on each host, and you can use `scp` to transfer them to your laptop for further analysis. 25 | 26 | 27 | Pick a single ICMP request, and find the packet carrying that ICMP request in both packet captures; the one on node-1 and the one on node-2. (To make sure it is the same packet, check the ICMP sequence number. It should be the same in both.) 28 | 29 | In the packet capture on node-1, you will see what this packet looks like as it traverses the link from node-1 to the bridge. In the packet capture on node-2, you will see what this packet looks like as it traverses the link from the bridge to node-2. 30 | 31 | **Lab report**: What are the source and destination IP and MAC addresses of a packet that went from node-1 to the bridge? Show the annotated screenshot from your `tcpdump` replay on node-1, with the source and destination IP address and source and destination MAC address clearly labeled. Does node-1 put the bridge's MAC address or node-2's MAC address in the destination address field of the Ethernet header? 32 | 33 | **Lab report**: What are the source and destination IP and MAC addresses of the same packet when it goes from the bridge to node-2? Show the annotated screenshot *of the same packet* from your `tcpdump` replay on node-2, with the source and destination IP address and source and destination MAC address clearly labeled. Does the bridge modify the source or destination MAC address in the Ethernet header? 34 | 35 | After completing all this and saving all the output you will need for your lab report, you can delete your resources from this experiment. 36 | -------------------------------------------------------------------------------- /lab5/lab5-udp-rspec.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /lab8/lab8-http-rspec.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-line-router/fabric-analysis-tcp-2.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Data visualization 3 | ::: 4 | 5 | ::: {.cell .markdown} 6 | 7 | To visualize the results of your experiment, you should first retrieve the data file `sender-ss.csv` from host romeo. To do that, execute the following command: 8 | 9 | ::: 10 | 11 | ::: {.cell .code} 12 | ```python 13 | import os 14 | slice.get_node("romeo").download_file(os.path.abspath("sender-ss.csv"), "/home/ubuntu/sender-ss.csv") 15 | ``` 16 | ::: 17 | 18 | ::: {.cell .markdown} 19 | 20 | In the Jupyter environment, click on the folder icon in the file browser on the left to make sure that you are located in your “Jupyter home” directory. 21 | 22 | Then, you should see the `sender-ss.csv` file appear in the Jupyter file browser on the left. 23 | 24 | Before running the following Python script to plot the `sender-ss.csv` file, in the Jupyter environment make sure that your `setup.ipynb` and `sender-ss.csv` files are on the same path in the file directory. 25 | 26 | ::: 27 | 28 | ::: {.cell .code} 29 | ```python 30 | import pandas as pd 31 | import matplotlib.pyplot as plt 32 | 33 | df = pd.read_csv("sender-ss.csv", names=['time', 'sender', 'retx_unacked', 'retx_cum', 'cwnd', 'ssthresh']) 34 | 35 | # exclude the "control" flow 36 | s = df.groupby('sender').size() 37 | df_filtered = df[df.groupby("sender")['sender'].transform('size') > 100] 38 | 39 | senders = df_filtered.sender.unique() 40 | 41 | time_min = df_filtered.time.min() 42 | cwnd_max = 1.1*df_filtered[df_filtered.time - time_min >=2].cwnd.max() 43 | dfs = [df_filtered[df_filtered.sender==senders[i]] for i in range(3)] 44 | 45 | fig, axs = plt.subplots(len(senders), sharex=True, figsize=(12,8)) 46 | fig.suptitle('CWND over time') 47 | for i in range(len(senders)): 48 | if i==len(senders)-1: 49 | axs[i].plot(dfs[i]['time']-time_min, dfs[i]['cwnd'], label="cwnd") 50 | axs[i].plot(dfs[i]['time']-time_min, dfs[i]['ssthresh'], label="ssthresh") 51 | axs[i].set_ylim([0,cwnd_max]) 52 | axs[i].set_xlabel("Time (s)"); 53 | else: 54 | axs[i].plot(dfs[i]['time']-time_min, dfs[i]['cwnd']) 55 | axs[i].plot(dfs[i]['time']-time_min, dfs[i]['ssthresh']) 56 | axs[i].set_ylim([0,cwnd_max]) 57 | 58 | 59 | plt.tight_layout(); 60 | fig.legend(loc='upper right', ncol=2); 61 | plt.savefig("sender-ss.png") 62 | ``` 63 | ::: 64 | 65 | ::: {.cell .markdown} 66 | 67 | You can return to this exercise and execute the above steps to visuaize results of TCP Cubic and TCP BBR. 68 | 69 | ::: -------------------------------------------------------------------------------- /lab-snmp-security/firewalls.md: -------------------------------------------------------------------------------- 1 | ## Exercises on firewalls 2 | 3 | For this experiment, we will reuse the same network as in the previous experiment. 4 | 5 | ### Exercise: Firewall with drop rule 6 | 7 | On "server", execute 8 | 9 | ``` 10 | sudo iptables -L -v 11 | ``` 12 | 13 | to list the existing rules in the filter table. Save the output for your lab report. 14 | 15 | Append a rule to the end of the INPUT chain by executing 16 | 17 | ``` 18 | sudo iptables -A INPUT -v -p TCP --dport 23 -j DROP 19 | ``` 20 | 21 | Run 22 | 23 | ``` 24 | sudo iptables -L -v 25 | ``` 26 | 27 | 28 | again to display the filter table. Save the output. 29 | 30 | On "romeo", run 31 | 32 | ``` 33 | sudo tcpdump -i eth1 -w iptables-drop-$(hostname -s).pcap 34 | ``` 35 | 36 | to capture traffic between "romeo" and "server". While this is running, initiate a `telnet` connection from "romeo" to "server" - on "romeo", run 37 | 38 | ``` 39 | telnet server 40 | ``` 41 | 42 | Wait until your `telnet` process terminates (this may take some time), then stop the `tcpdump` and transfer the packet capture to your laptop with `scp`. 43 | 44 | You can also "play back" the packet capture with 45 | 46 | ``` 47 | tcpdump -nv -r iptables-drop-$(hostname -s).pcap 48 | ``` 49 | 50 | **Lab report**: Can you `telnet` to the host from the remote machine? Explain. 51 | 52 | 53 | ### Exercise: Firewall with TCP RST reject 54 | 55 | Delete the rule created in the last exercise - on "server", execute 56 | 57 | ``` 58 | sudo iptables -D INPUT -v -p TCP --dport 23 -j DROP 59 | ``` 60 | 61 | Then, append a new rule to the INPUT chain: 62 | 63 | ``` 64 | sudo iptables -A INPUT -v -p TCP --dport 23 -j REJECT --reject-with tcp-reset 65 | ``` 66 | 67 | Run 68 | 69 | ``` 70 | sudo iptables -L -v 71 | ``` 72 | 73 | 74 | to display the filter table. Save the output. 75 | 76 | On "romeo", run 77 | 78 | ``` 79 | sudo tcpdump -i eth1 -w iptables-reset-$(hostname -s).pcap 80 | ``` 81 | 82 | to capture traffic between "server" and "romeo". While this is running, initiate a `telnet` connection from "romeo" to "server" - on "romeo", run 83 | 84 | ``` 85 | telnet server 86 | ``` 87 | 88 | Wait until your `telnet` process terminates, then stop the `tcpdump` and transfer the packet capture to your laptop with `scp`. 89 | 90 | You can also "play back" the packet capture with 91 | 92 | ``` 93 | tcpdump -nv -r iptables-reset-$(hostname -s).pcap 94 | ``` 95 | 96 | **Lab report**: Explain the different between the `tcpdump` output in this exercise and the previous exercise. 97 | -------------------------------------------------------------------------------- /rspecs/two-hosts-one-segment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /rspecs/two-hosts-one-segment-16.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lab-static-basic/fabric-transfer-static-basic.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from Static Routing experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | othello_exec = slice.get_node("othello") 21 | othello_name = othello_exec.execute("hostname", quiet=True)[0].strip() 22 | router1_exec = slice.get_node("router-1") 23 | router1_name = router1_exec.execute("hostname", quiet=True)[0].strip() 24 | router2_exec = slice.get_node("router-2") 25 | router2_name = router2_exec.execute("hostname", quiet=True)[0].strip() 26 | ``` 27 | ::: 28 | 29 | 30 | ::: {.cell .markdown} 31 | #### Packet Captures for Exercise - network unreachable 32 | 33 | ::: 34 | 35 | ::: {.cell .code} 36 | ```python 37 | romeo_net_pcap = "/home/ubuntu/%s-net-unreachable.pcap" % romeo_name 38 | romeo_exec.download_file(os.path.abspath('romeo-net-unreachable.pcap'), romeo_net_pcap) 39 | ``` 40 | ::: 41 | 42 | ::: {.cell .code} 43 | ```python 44 | romeo_host_pcap = "/home/ubuntu/%s-host-unreachable.pcap" % romeo_name 45 | romeo_exec.download_file(os.path.abspath('romeo-host-unreachable.pcap'), romeo_host_pcap) 46 | ``` 47 | ::: 48 | 49 | ::: {.cell .markdown} 50 | #### Packet Captures for Exercise - packet headers 51 | 52 | ::: 53 | 54 | ::: {.cell .code} 55 | ```python 56 | romeo_header_pcap = "/home/ubuntu/%s-static-headers.pcap" % romeo_name 57 | romeo_exec.download_file(os.path.abspath('romeo-static-headers.pcap'), romeo_header_pcap) 58 | ``` 59 | ::: 60 | 61 | ::: {.cell .code} 62 | ```python 63 | var_list = [ 64 | ("othello", othello_exec, othello_name), 65 | ("router-1", router1_exec, router1_name), 66 | ("router-2", router2_exec, router2_name) 67 | ] 68 | for node_name, host_exec, host_name in var_list: 69 | host_1_header_pcap = "/home/ubuntu/%s-1-static-headers.pcap" % host_name 70 | host_exec.download_file(os.path.abspath('%s-1-static-headers.pcap' % node_name), host_1_header_pcap) 71 | host_2_header_pcap = "/home/ubuntu/%s-2-static-headers.pcap" % host_name 72 | host_exec.download_file(os.path.abspath('%s-2-static-headers.pcap' % node_name), host_2_header_pcap) 73 | ``` 74 | ::: 75 | -------------------------------------------------------------------------------- /lab-fragment/iperf3.md: -------------------------------------------------------------------------------- 1 | ## Using `iperf3` 2 | 3 | 4 | On each host (romeo and juliet), install the `iperf3` package, which we'll use in this lab: 5 | 6 | ``` 7 | sudo apt update 8 | sudo apt -y install iperf3 9 | ``` 10 | 11 | ### Exercise - using iperf3 12 | 13 | 14 | In the first part of this lab, we will learn how to use the `iperf3` utility. This is a network testing tool which allows us to send TCP or UDP flows between two hosts, one of which is configured as a server (that listens for incoming connections and receives data), and one of which is configured as a client (that sends data). 15 | 16 | Configure "romeo" to act as an `iperf3` server; 17 | 18 | ``` 19 | iperf3 -s 20 | ``` 21 | 22 | Once this is running, the client can initiate a TCP or UDP flow to the server. On "juliet", run 23 | 24 | ``` 25 | iperf3 -c 10.0.0.100 26 | ``` 27 | 28 | to start the `iperf3` application in client mode, and specify the server's IP address. 29 | 30 | By default, `iperf3` will establish a TCP connection and run a test for ten seconds. The client process will terminate automatically when it's finished. To stop the `iperf3` server, use Ctrl+C. 31 | 32 | Use 33 | 34 | ``` 35 | iperf3 --help 36 | ``` 37 | 38 | or 39 | 40 | ``` 41 | man iperf3 42 | ``` 43 | 44 | to learn more about the other options available with `iperf3`. 45 | 46 | Next, you will observe some common errors that people make with `iperf3`. Once you learn the error messages that are associated with common mistakes, you will be able to diagnose and fix problems you may encounter when using `iperf3`. 47 | 48 | Make sure the `iperf3` server is running on "romeo". Open a second terminal window on "romeo", and run 49 | 50 | 51 | ``` 52 | iperf3 -s 53 | ``` 54 | 55 | in this terminal window. Note the error message that you observe. 56 | 57 | While the `iperf3` server is running in the first "romeo" terminal window, run 58 | 59 | ``` 60 | sudo killall iperf3 61 | ``` 62 | 63 | in the second "romeo" terminal window. What happened to the `iperf3` server in the first terminal window? Are you able to now run 64 | 65 | ``` 66 | iperf3 -s 67 | ``` 68 | 69 | in the second terminal window? 70 | 71 | Next, let's see what happens on the client side when we try to send `iperf3` traffic to a wrong address, wrong port, or to a host and port where no `iperf3` server is running. 72 | 73 | On "juliet", try running 74 | 75 | ``` 76 | iperf3 -c 10.0.0.102 77 | ``` 78 | 79 | and note the message that you observe. Also try running 80 | 81 | ``` 82 | iperf3 -c 10.0.0.100 -p 6000 83 | ``` 84 | 85 | and note the message. 86 | 87 | Finally, make sure there is no `iperf3` server on "romeo" - stop any running servers with Ctrl+C, and use 88 | 89 | ``` 90 | sudo killall iperf3 91 | ``` 92 | 93 | to kill any that might be running in the background. On "juliet", run 94 | 95 | ``` 96 | iperf3 -c 10.0.0.100 97 | ``` 98 | 99 | and note the error message that you observe. 100 | 101 | -------------------------------------------------------------------------------- /lab2/2-8-icmp-ping.md: -------------------------------------------------------------------------------- 1 | ## Exercise with ICMP Port Unreachable 2 | 3 | For data to be passed up from the transport layer to the application layer, the host must have an application listening for incoming communication on the IP address and transport layer port to which the traffic is sent. 4 | 5 | In this experiment, we'll see that when you send a UDP packet and there is *not* an application listening for incoming communication on that IP address and transport layer port, you'll get an ICMP port unreachable message. 6 | 7 | 8 | ### Exercise - port unreachable 9 | 10 | On "juliet" run 11 | 12 | ``` 13 | netstat -ln -u 14 | ``` 15 | 16 | to see what services are listening on UDP ports. Is there anything listening on UDP port 4000? Save this output for your lab report. 17 | 18 | 19 | While running 20 | 21 | ``` 22 | sudo tcpdump -i eth1 -w $(hostname -s)-wrong-port.pcap 23 | ``` 24 | 25 | in one terminal window on "romeo", open a second window on "romeo" and run 26 | 27 | 28 | ``` 29 | netcat -u 10.10.0.101 4000 30 | ``` 31 | 32 | You should then see a blinking cursor on the next line. Type a message at this cursor, and hit Enter. This will send a UDP packet carrying your message to the "juliet" host on port 4000. (As you have seen in the `netstat` output, there is no service listening on this port.) 33 | 34 | 35 | Stop the `tcpdump` and `netcat` with Ctrl+C. You can play back the summary of the packet capture with 36 | 37 | ``` 38 | tcpdump -enX -r $(hostname -s)-wrong-port.pcap 39 | ``` 40 | 41 | Also transfer the packet capture to your laptop with `scp`. 42 | 43 | 44 | Next, on the "juliet" host, run 45 | 46 | ``` 47 | netcat -l -u 4000 48 | ``` 49 | 50 | to start an application listening on UDP port 4000. In a second terminal on the "juliet" host, run 51 | 52 | 53 | ``` 54 | netstat -ln -u 55 | ``` 56 | 57 | to list listening UDP ports. Look for a service listening on UDP port 4000. Save this output for your lab report. 58 | 59 | 60 | 61 | Run 62 | 63 | ``` 64 | sudo tcpdump -i eth1 -w $(hostname -s)-open-port.pcap 65 | ``` 66 | 67 | in one terminal window on "romeo", and in a second window on "romeo" run 68 | 69 | 70 | ``` 71 | netcat -u 10.10.0.101 4000 72 | ``` 73 | 74 | You should then see a blinking cursor on the next line. Type a message at this cursor, and hit Enter. This will send a UDP packet carrying your message to the "juliet" host on port 4000. 75 | 76 | Stop the `tcpdump` and both `netcat` instances with Ctrl+C. You can play back the summary of the packet capture with 77 | 78 | ``` 79 | tcpdump -enX -r $(hostname -s)-open-port.pcap 80 | ``` 81 | 82 | Also transfer the packet capture to your laptop with `scp`. 83 | 84 | 85 | **Lab report**: Study the saved ICMP port unreachable message (see Fig. 2.7 in the text book). Why are the first bytes of the original IP datagram payload included in the ICMP message? 86 | 87 | 88 | **Lab report**: What transport layer protocol (UDP or TCP) and port number did you attempt to contact "juliet" on? Is any service listening on that port in the first case? Is any service listening on that port in the second case? Use the `netstat` and `tcpdump` output to explain. 89 | 90 | -------------------------------------------------------------------------------- /lab8/el5373-lab8-87.md: -------------------------------------------------------------------------------- 1 | ## HTTP exercises 2 | 3 | For this experiment, you will need two hosts on GENI, and one of them should be configured a web server. 4 | 5 | * If you still have access to resources from the "Basic home gateway services: DHCP, DNS, NAT" experiment, AND they are still configured as decribed there (including NAT), you can use one client node and the webserver from that experiment. 6 | * Alternatively, if you have lost access to those resources, reserve two nodes for this experiment using the following Rspec: [https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/two-hosts-one-public.xml](https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/two-hosts-one-public.xml). On the webserver, install Apache2: 7 | 8 | ``` 9 | sudo apt-get update 10 | sudo apt-get -y install apache2 11 | ``` 12 | 13 | 14 | Review the slice details in the GENI Portal and find the hostname assigned to the "website" host. For example, in the following screenshot, the hostname is `website.nat.ch-geni-net.instageni.research.umich.edu`: 15 | 16 | ![](https://witestlab.poly.edu/blog/content/images/2017/03/gateway-hostname.png) 17 | 18 | ### Exercise: send an HTTP request with telnet 19 | 20 | 21 | In this exercise, we will use `telnet` to manually write and send an HTTP request, and observe the response from the HTTP server. 22 | 23 | If you are using the network topology with a gateway, run 24 | 25 | ``` 26 | sudo tcpdump -i eth1 -w http-$(hostname -s).pcap 'tcp port 80' 27 | ``` 28 | 29 | on the "gateway". If you are using the topology with just one client and the web server, run 30 | 31 | ``` 32 | sudo tcpdump -i eth0 -w http-$(hostname -s).pcap 'tcp port 80' 33 | ``` 34 | 35 | on the client 36 | 37 | While this is running, run 38 | 39 | ``` 40 | telnet website.nat.ch-geni-net.instageni.research.umich.edu 80 41 | ``` 42 | 43 | on a "client" node, but substitute the hostname of your own "website" host. You should see the following indication of a successful connection: 44 | 45 | ``` 46 | Trying 199.109.64.53... 47 | Connected to pcvm2-3.instageni.nysernet.org. 48 | Escape character is '^]'. 49 | ``` 50 | 51 | (but with a different address and hostname.) 52 | 53 | At the console, type the following HTTP request line by line: 54 | 55 | ``` 56 | GET /index.html HTTP/1.0 57 | From: guest@client 58 | User-Agent: HTTPTool/1.0 59 | 60 | ``` 61 | 62 | Note that you need to type "Enter" to input the last line, which is blank, and then "Enter" again to send it. 63 | 64 | When the `telnet` process is terminated, save the output for your lab report. Identify the HTTP response header, and the HTML file sent from the HTTP server. 65 | 66 | Terminate `tcpdump` and transfer the packet capture to your laptop with `scp`. Analyze the captured HTTP packets. 67 | 68 | **Lab report**: Show the HTTP request and response *headers* (only the headers!). 69 | 70 | **Lab report**: In the HTTP response header, identify these key elements: 71 | 72 | * the version of the HTTP protocol 73 | * the status code and the status message (for a successful HTTP request, the standard is "200 OK") 74 | * the header fields that indicate the type of file that is returned, and its length 75 | -------------------------------------------------------------------------------- /lab-multicast-pim/fabric-define-multicast-pim.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for Multicast Routing with PIM experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="multicast-pim-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 11 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 12 | {'name': "hamlet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 13 | {'name': "ophelia", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 14 | {'name': "source1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 15 | {'name': "source2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['vlc']}, 16 | {'name': "rp", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 17 | {'name': "cr1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 18 | {'name': "cr2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 19 | {'name': "fhr1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 20 | {'name': "fhr2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 21 | {'name': "lhr1", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 22 | {'name': "lhr2", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []} 23 | ] 24 | net_conf = [ 25 | {"name": "net0", "subnet": "10.10.1.0/24", "nodes": [{"name": "rp", "addr": "10.10.1.100"}, {"name": "cr1", "addr": "10.10.1.1"}, {"name": "cr2", "addr": "10.10.1.2"}]}, 26 | {"name": "net1", "subnet": "10.10.11.0/24", "nodes": [{"name": "fhr1", "addr": "10.10.11.2"}, {"name": "cr1", "addr": "10.10.11.1"}]}, 27 | {"name": "net2", "subnet": "10.10.12.0/24", "nodes": [{"name": "fhr2", "addr": "10.10.12.2"}, {"name": "cr1", "addr": "10.10.12.1"}]}, 28 | {"name": "net3", "subnet": "10.10.21.0/24", "nodes": [{"name": "lhr1", "addr": "10.10.21.2"}, {"name": "cr2", "addr": "10.10.21.1"}]}, 29 | {"name": "net4", "subnet": "10.10.22.0/24", "nodes": [{"name": "lhr2", "addr": "10.10.22.2"}, {"name": "cr2", "addr": "10.10.22.1"}]}, 30 | {"name": "net5", "subnet": "10.10.101.0/24", "nodes": [{"name": "source1", "addr": "10.10.101.2"}, {"name": "fhr1", "addr": "10.10.101.1"}]}, 31 | {"name": "net6", "subnet": "10.10.102.0/24", "nodes": [{"name": "source2", "addr": "10.10.102.2"}, {"name": "fhr2", "addr": "10.10.102.1"}]}, 32 | {"name": "net7", "subnet": "10.10.103.0/24", "nodes": [{"name": "romeo", "addr": "10.10.103.2"}, {"name": "juliet", "addr": "10.10.103.3"}, {"name": "lhr1", "addr": "10.10.103.1"}]}, 33 | {"name": "net8", "subnet": "10.10.104.0/24", "nodes": [{"name": "hamlet", "addr": "10.10.104.2"}, {"name": "ophelia", "addr": "10.10.104.3"}, {"name": "lhr2", "addr": "10.10.104.1"}]} 34 | ] 35 | route_conf = [] 36 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 37 | ``` 38 | ::: -------------------------------------------------------------------------------- /lab-line-direct/iperf3.md: -------------------------------------------------------------------------------- 1 | ## Using `iperf3` 2 | 3 | 4 | On each host (romeo and juliet), install the `iperf3` package, which we'll use in this lab: 5 | 6 | ``` 7 | sudo apt-get update 8 | sudo apt-get -y install iperf3 9 | ``` 10 | 11 | Before you start, use `ip addr` to capture the network interface configuration of each host in this topology. Identify the IP address and MAC address of each interface. 12 | 13 | ### Exercise - using iperf3 14 | 15 | 16 | In the first part of this lab, we will learn how to use the `iperf3` utility. This is a network testing tool which allows us to send TCP or UDP flows between two hosts, one of which is configured as a server (that listens for incoming connections and receives data), and one of which is configured as a client (that sends data). 17 | 18 | Configure "romeo" to act as an `iperf3` server; 19 | 20 | ``` 21 | iperf3 -s 22 | ``` 23 | 24 | Once this is running, the client can initiate a TCP or UDP flow to the server. On "juliet", run 25 | 26 | ``` 27 | iperf3 -c 10.10.0.100 28 | ``` 29 | 30 | to start the `iperf3` application in client mode, and specify the server's IP address. 31 | 32 | By default, `iperf3` will establish a TCP connection and run a test for ten seconds. The client process will terminate automatically when it's finished. To stop the `iperf3` server, use Ctrl+C. 33 | 34 | Use 35 | 36 | ``` 37 | iperf3 --help 38 | ``` 39 | 40 | or 41 | 42 | ``` 43 | man iperf3 44 | ``` 45 | 46 | to learn more about the other options available with `iperf3`. 47 | 48 | Next, you will observe some common errors that people make with `iperf3`. Once you learn the error messages that are associated with common mistakes, you will be able to diagnose and fix problems you may encounter when using `iperf`. 49 | 50 | Make sure the `iperf3` server is running on "romeo". Open a second terminal window on "romeo", and run 51 | 52 | 53 | ``` 54 | iperf3 -s 55 | ``` 56 | 57 | in this terminal window. Note the error message that you observe. 58 | 59 | While the `iperf3` server is running in the first "romeo" terminal window, run 60 | 61 | ``` 62 | sudo killall iperf3 63 | ``` 64 | 65 | in the second "romeo" terminal window. What happened to the `iperf3` server in the first terminal window? Are you able to now run 66 | 67 | ``` 68 | iperf3 -s 69 | ``` 70 | 71 | in the second terminal window? 72 | 73 | Next, let's see what happens on the client side when we try to send `iperf3` traffic to a wrong address, wrong port, or to a host and port where no `iperf3` server is running. 74 | 75 | On "juliet", try running 76 | 77 | ``` 78 | iperf3 -c 10.10.0.102 79 | ``` 80 | 81 | and note the message that you observe. Also try running 82 | 83 | ``` 84 | iperf3 -c 10.10.0.100 -p 6000 85 | ``` 86 | 87 | and note the message. 88 | 89 | Finally, make sure there is no `iperf3` server on "romeo" - stop any running servers with Ctrl+C, and use 90 | 91 | ``` 92 | sudo killall iperf3 93 | ``` 94 | 95 | to kill any that might be running in the background. On "juliet", run 96 | 97 | ``` 98 | iperf3 -c 10.10.0.100 99 | ``` 100 | 101 | and note the error message that you observe. 102 | 103 | -------------------------------------------------------------------------------- /lab5/2-8-icmp-ping.md: -------------------------------------------------------------------------------- 1 | ## 2.8 Exercise with ICMP and Ping 2 | 3 | For this experiment, we will reuse the same network as in the previous experiment. 4 | 5 | We know that for data to be passed up from the transport layer to the application layer, the host must have an application listening for incoming communication on the IP address and transport layer port to which the traffic is sent. 6 | 7 | In this experiment, we'll see that when you send a UDP packet and there is *not* an application listening for incoming communication on that IP address and transport layer port, you'll get an ICMP port unreachable message. 8 | 9 | 10 | ### Exercise 9 - port unreachable 11 | 12 | On "juliet" run 13 | 14 | ``` 15 | netstat -ln -u 16 | ``` 17 | 18 | to see what services are listening on UDP ports. Is there anything listening on UDP port 4000? Save this output for your lab report. 19 | 20 | 21 | While running 22 | 23 | ``` 24 | sudo tcpdump -i eth1 -w $(hostname -s)-wrong-port.pcap 25 | ``` 26 | 27 | in one terminal window on "romeo", open a second window on "romeo" and run 28 | 29 | 30 | ``` 31 | netcat -u 10.10.0.101 4000 32 | ``` 33 | 34 | You should then see a blinking cursor on the next line. Type a message at this cursor, and hit Enter. This will send a UDP packet carrying your message to the "juliet" host on port 4000. (As you have seen in the `netstat` output, there is no service listening on this port.) 35 | 36 | 37 | Stop the `tcpdump` and `netcat` with Ctrl+C. You can play back the summary of the packet capture with 38 | 39 | ``` 40 | tcpdump -enX -r $(hostname -s)-wrong-port.pcap 41 | ``` 42 | 43 | Also transfer the packet capture to your laptop with `scp`. 44 | 45 | 46 | Next, on the "juliet" host, run 47 | 48 | ``` 49 | netcat -l -u 4000 50 | ``` 51 | 52 | to start an application listening on UDP port 4000. In a second terminal on the "juliet" host, run 53 | 54 | 55 | ``` 56 | netstat -ln -u 57 | ``` 58 | 59 | to list listening UDP ports. Look for a service listening on UDP port 4000. Save this output for your lab report. 60 | 61 | 62 | 63 | Run 64 | 65 | ``` 66 | sudo tcpdump -i eth1 -w $(hostname -s)-open-port.pcap 67 | ``` 68 | 69 | in one terminal window on "romeo", and in a second window on "romeo" run 70 | 71 | 72 | ``` 73 | netcat -u 10.10.0.101 4000 74 | ``` 75 | 76 | You should then see a blinking cursor on the next line. Type a message at this cursor, and hit Enter. This will send a UDP packet carrying your message to the "juliet" host on port 4000. 77 | 78 | Stop the `tcpdump` and both `netcat` instances with Ctrl+C. You can play back the summary of the packet capture with 79 | 80 | ``` 81 | tcpdump -enX -r $(hostname -s)-open-port.pcap 82 | ``` 83 | 84 | Also transfer the packet capture to your laptop with `scp`. 85 | 86 | 87 | **Lab report**: Study the saved ICMP port unreachable message (see Fig. 2.7 in the text book). Why are the first bytes of the original IP datagram payload included in the ICMP message? 88 | 89 | 90 | **Lab report**: What transport layer protocol (UDP or TCP) and port number did you attempt to contact "juliet" on? Is any service listening on that port in the first case? Is any service listening on that port in the second case? Use the `netstat` and `tcpdump` output to explain. 91 | 92 | -------------------------------------------------------------------------------- /lab-snmp-security/fabric-define-snmp-security.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Define configuration for SNMP and Network Security experiment 3 | ::: 4 | 5 | ::: {.cell .code} 6 | ```python 7 | slice_name="snmp-security-" + fablib.get_bastion_username() 8 | 9 | node_conf = [ 10 | {'name': "romeo", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['lynx']}, 11 | {'name': "router-int", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 12 | {'name': "server", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 13 | {'name': "vpn", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['openvpn']}, 14 | {'name': "router-ext", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': []}, 15 | {'name': "juliet", 'cores': 2, 'ram': 4, 'disk': 10, 'image': 'default_ubuntu_22', 'packages': ['openvpn']} 16 | ] 17 | net_conf = [ 18 | {"name": "net0", "subnet": "10.10.1.0/24", "nodes": [{"name": "romeo", "addr": "10.10.1.100"}, {"name": "router-int", "addr": "10.10.1.1"}]}, 19 | {"name": "net1", "subnet": "10.10.2.0/24", "nodes": [{"name": "server", "addr": "10.10.2.100"}, {"name": "router-int", "addr": "10.10.2.1"}]}, 20 | {"name": "net2", "subnet": "10.10.3.0/24", "nodes": [{"name": "vpn", "addr": "10.10.3.100"}, {"name": "router-int", "addr": "10.10.3.1"}]}, 21 | {"name": "net3", "subnet": "10.10.4.0/24", "nodes": [{"name": "vpn", "addr": "10.10.4.100"}, {"name": "router-ext", "addr": "10.10.4.1"}]}, 22 | {"name": "net4", "subnet": "10.10.5.0/24", "nodes": [{"name": "juliet", "addr": "10.10.5.100"}, {"name": "router-ext", "addr": "10.10.5.1"}]} 23 | ] 24 | route_conf = [ 25 | {"addr": "10.10.2.0/24", "gw": "10.10.1.1", "nodes": ["romeo"]}, 26 | {"addr": "10.10.3.0/24", "gw": "10.10.1.1", "nodes": ["romeo"]}, 27 | {"addr": "10.10.4.0/24", "gw": "10.10.1.1", "nodes": ["romeo"]}, 28 | {"addr": "10.10.5.0/24", "gw": "10.10.1.1", "nodes": ["romeo"]}, 29 | {"addr": "10.10.1.0/24", "gw": "10.10.2.1", "nodes": ["server"]}, 30 | {"addr": "10.10.3.0/24", "gw": "10.10.2.1", "nodes": ["server"]}, 31 | {"addr": "10.10.4.0/24", "gw": "10.10.2.1", "nodes": ["server"]}, 32 | {"addr": "10.10.5.0/24", "gw": "10.10.2.1", "nodes": ["server"]}, 33 | {"addr": "10.10.4.0/24", "gw": "10.10.3.100", "nodes": ["router-int"]}, 34 | {"addr": "10.10.5.0/24", "gw": "10.10.3.100", "nodes": ["router-int"]}, 35 | {"addr": "10.10.1.0/24", "gw": "10.10.3.1", "nodes": ["vpn"]}, 36 | {"addr": "10.10.2.0/24", "gw": "10.10.3.1", "nodes": ["vpn"]}, 37 | {"addr": "10.10.5.0/24", "gw": "10.10.4.1", "nodes": ["vpn"]}, 38 | {"addr": "10.10.1.0/24", "gw": "10.10.4.100", "nodes": ["router-ext"]}, 39 | {"addr": "10.10.2.0/24", "gw": "10.10.4.100", "nodes": ["router-ext"]}, 40 | {"addr": "10.10.3.0/24", "gw": "10.10.4.100", "nodes": ["router-ext"]}, 41 | {"addr": "10.10.1.0/24", "gw": "10.10.5.1", "nodes": ["juliet"]}, 42 | {"addr": "10.10.2.0/24", "gw": "10.10.5.1", "nodes": ["juliet"]}, 43 | {"addr": "10.10.3.0/24", "gw": "10.10.5.1", "nodes": ["juliet"]}, 44 | {"addr": "10.10.4.0/24", "gw": "10.10.5.1", "nodes": ["juliet"]} 45 | ] 46 | exp_conf = {'cores': sum([ n['cores'] for n in node_conf]), 'nic': sum([len(n['nodes']) for n in net_conf]) } 47 | ``` 48 | ::: -------------------------------------------------------------------------------- /lab3/README.md: -------------------------------------------------------------------------------- 1 | # TCP/IP Essentials: A Lab-Based Approach 2 | 3 | This repository includes the exercises in the textbook [TCP/IP Essentials: A Lab-Based Approach](https://www.amazon.com/TCP-IP-Essentials-Lab-Based-Approach/dp/052160124X), adapted to use the GENI testbed rather than an in-house lab. 4 | 5 | ### ARP, Bridges and LANs 6 | 7 | Unlike some other lab exercises, for this lab, the instructions do *not* include interspersed notes about what you will need to include/answer in your lab report. Instead, those instructions are listed at the end of the page in an "Exercise" section. Before you start each section, you should carefully read the associated part of the exercise at the end, and the notes below, so that you know what output to save and what questions you will need to answer. 8 | 9 | * [ARP exercises](3-arp.md) 10 | 11 | * [Operation of a basic Ethernet switch or bridge](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/). Note the questions that you will have to answer after some sections: 12 | * When you complete the [Set up the bridge](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#setupthebridge) section, answer the first question in the [Exercise](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#exercise) section. 13 | * When you complete the [Learning MAC addresses](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#learningmacaddresses) section, answer the second question in the [Exercise](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#exercise) section. 14 | * There is a question about the [Effect of a smaller collision domain](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#effectofasmallercollisiondomain) section, in the [Exercise](https://witestlab.poly.edu/blog/basic-ethernet-switch-operation/#exercise) section. However, you do *not* have to answer this question. 15 | 16 | * [Additional questions on bridge operation](3-5-simple-bridge.md) (This uses the same topology as "Operation of a basic Ethernet switch or bridge", so don't delete your resources until you finish this section.) 17 | * [Spanning tree protocol](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/). Note the questions that you will have to answer after some sections: 18 | * When you complete the [Create a broadcast storm](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#createabroadcaststorm) section, answer the first question in the [Exercise](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#exercise) section. 19 | * When you complete the [Set up bridges to use spanning tree algorithm](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#setupbridgestousespanningtreealgorithm) section, answer the second question in the [Exercise](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#exercise) section. You can use [this template](https://viewer.diagrams.net/?highlight=0000ff&edit=_blank&layers=1&nav=1&title=spanning-tree-template.drawio#Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fffund%2Ftcp-ip-essentials%2Fmaster%2Flab3%2Fspanning-tree-template.drawio) to create the spanning tree diagram. 20 | * When you complete the [Reacting to changes in the topology](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#reactingtochangesinthetopology) section, answer the third and fourth questions in the [Exercise](https://witestlab.poly.edu/blog/the-spanning-tree-protocol/#exercise) section. 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lab2/2-loopback.md: -------------------------------------------------------------------------------- 1 | ### Exercise - Loopback interface 2 | 3 | Now that you have learned how to use `tcpdump` and Wireshark, you will use these software tools to observe how processes *on the same host* communicate with each other using the *loopback interface*. The loopback interface does not send packets or receive packets from an actual network link. When a packet is "sent" to the loopback interface, it is simply placed on the loopback interface's input queue, and "received" from there. 4 | 5 | For example: Suppose you have a database server and a web server installed on the same host, and the web server is supposed to display dynamic information from the database on its web pages. 6 | 7 | * If the database server and web server were on two different hosts, they would communicate across a network, so that the web server could retrieve information from the database. 8 | * If the database server and web server are on the same host, they'll still communicate using network protocols, but these communications won't appear on any network link. Instead, they'll appear across the loopback interface. "Packets" sent on the loopback interface are not sent on any network, but are sent to other processes on the same host. 9 | 10 | In the `ifconfig` output on each host, you'll see an interface named `lo`, which is the loopback interface. This interface will typically be assigned the IPv4 address 127.0.0.1. However, any "local" address - an address assigned to any interface on the host - is treated like a loopback address, and packets sent to a local address from the host itself will be delivered by the loopback interface. 11 | 12 | On the "romeo" host, run 13 | 14 | ``` 15 | sudo tcpdump -n -i eth1 icmp 16 | ``` 17 | 18 | and leave it running. Open a second terminal window on "romeo". Run 19 | 20 | ``` 21 | ping -c 3 127.0.0.1 22 | ``` 23 | 24 | from the second window to send three ICMP requests to the address 127.0.0.1. 25 | 26 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 27 | 28 | Next, run 29 | 30 | ``` 31 | sudo tcpdump -n -i eth1 icmp 32 | ``` 33 | 34 | again, and leave it running. On the second terminal window on "romeo", run 35 | 36 | ``` 37 | ping -c 3 10.10.0.100 38 | ``` 39 | 40 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 41 | 42 | Now, we will repeat these steps, but with the `tcpdump` running on the loopback interface. Run 43 | 44 | ``` 45 | sudo tcpdump -n -i lo icmp 46 | ``` 47 | 48 | on "romeo", and leave it running. On the second terminal window on "romeo", run 49 | 50 | ``` 51 | ping -c 3 127.0.0.1 52 | ``` 53 | 54 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 55 | 56 | Finally, run 57 | 58 | ``` 59 | sudo tcpdump -n -i lo icmp 60 | ``` 61 | 62 | again, and leave it running, and on the second terminal window on "romeo", run 63 | 64 | ``` 65 | ping -c 3 10.10.0.100 66 | ``` 67 | 68 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 69 | 70 | 71 | **Lab report**: Show the output of the `tcpdump` in each case. Which network interface carries traffic from the host *to itself* when that traffic is sent to the 127.0.0.1 address? Which network interface carries traffic from the host *to itself* when that traffic is sent to the 10.10.0.100 address? Explain how the evidence from the `tcpdump` output supports your answer. 72 | -------------------------------------------------------------------------------- /lab1/1-x-loopback.md: -------------------------------------------------------------------------------- 1 | ### Exercise - Loopback interface 2 | 3 | Now that you have learned how to use `tcpdump` and Wireshark, you will use these software tools to observe how processes *on the same host* communicate with each other using the *loopback interface*. The loopback interface does not send packets or receive packets from an actual network link. When a packet is "sent" to the loopback interface, it is simply placed on the loopback interface's input queue, and "received" from there. 4 | 5 | For example: Suppose you have a database server and a web server installed on the same host, and the web server is supposed to display dynamic information from the database on its web pages. 6 | 7 | * If the database server and web server were on two different hosts, they would communicate across a network, so that the web server could retrieve information from the database. 8 | * If the database server and web server are on the same host, they'll still communicate using network protocols, but these communications won't appear on any network link. Instead, they'll appear across the loopback interface. "Packets" sent on the loopback interface are not sent on any network, but are sent to other processes on the same host. 9 | 10 | In the `ifconfig` output on each host, you'll see an interface named `lo`, which is the loopback interface. This interface will typically be assigned the IPv4 address 127.0.0.1. However, any "local" address - an address assigned to any interface on the host - is treated like a loopback address, and packets sent to a local address from the host itself will be delivered by the loopback interface. 11 | 12 | On the "romeo" host, run 13 | 14 | ``` 15 | sudo tcpdump -n -i eth1 icmp 16 | ``` 17 | 18 | and leave it running. Open a second terminal window on "romeo". Run 19 | 20 | ``` 21 | ping -c 3 127.0.0.1 22 | ``` 23 | 24 | from the second window to send three ICMP requests to the address 127.0.0.1. 25 | 26 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 27 | 28 | Next, run 29 | 30 | ``` 31 | sudo tcpdump -n -i eth1 icmp 32 | ``` 33 | 34 | again, and leave it running. On the second terminal window on "romeo", run 35 | 36 | ``` 37 | ping -c 3 10.10.0.100 38 | ``` 39 | 40 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 41 | 42 | Now, we will repeat these steps, but with the `tcpdump` running on the loopback interface. Run 43 | 44 | ``` 45 | sudo tcpdump -n -i lo icmp 46 | ``` 47 | 48 | on "romeo", and leave it running. On the second terminal window on "romeo", run 49 | 50 | ``` 51 | ping -c 3 127.0.0.1 52 | ``` 53 | 54 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 55 | 56 | Finally, run 57 | 58 | ``` 59 | sudo tcpdump -n -i lo icmp 60 | ``` 61 | 62 | again, and leave it running, and on the second terminal window on "romeo", run 63 | 64 | ``` 65 | ping -c 3 10.10.0.100 66 | ``` 67 | 68 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 69 | 70 | 71 | **Lab report**: Show the output of the `tcpdump` in each case. Which network interface carries traffic from the host *to itself* when that traffic is sent to the 127.0.0.1 address? Which network interface carries traffic from the host *to itself* when that traffic is sent to the 10.10.0.100 address? Explain how the evidence from the `tcpdump` output supports your answer. 72 | -------------------------------------------------------------------------------- /lab-loopback/loopback.md: -------------------------------------------------------------------------------- 1 | ### Exercise - Loopback interface 2 | 3 | Now that you have learned how to use `tcpdump` and Wireshark, you will use these software tools to observe how processes *on the same host* communicate with each other using the *loopback interface*. The loopback interface does not send packets or receive packets from an actual network link. When a packet is "sent" to the loopback interface, it is simply placed on the loopback interface's input queue, and "received" from there. 4 | 5 | For example: Suppose you have a database server and a web server installed on the same host, and the web server is supposed to display dynamic information from the database on its web pages. 6 | 7 | * If the database server and web server were on two different hosts, they would communicate across a network, so that the web server could retrieve information from the database. 8 | * If the database server and web server are on the same host, they'll still communicate using network protocols, but these communications won't appear on any network link. Instead, they'll appear across the loopback interface. "Packets" sent on the loopback interface are not sent on any network, but are sent to other processes on the same host. 9 | 10 | In the `ip addr` output on each host, you'll see an interface named `lo`, which is the loopback interface. This interface will typically be assigned the IPv4 address 127.0.0.1. However, any "local" address - an address assigned to any interface on the host - is treated like a loopback address, and packets sent to a local address from the host itself will be delivered by the loopback interface. 11 | 12 | On the "romeo" host, run 13 | 14 | ``` 15 | sudo tcpdump -n -i eth1 icmp 16 | ``` 17 | 18 | and leave it running. Open a second terminal window on "romeo". Run 19 | 20 | ``` 21 | ping -c 3 127.0.0.1 22 | ``` 23 | 24 | from the second window to send three ICMP requests to the address 127.0.0.1. 25 | 26 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 27 | 28 | Next, run 29 | 30 | ``` 31 | sudo tcpdump -n -i eth1 icmp 32 | ``` 33 | 34 | again, and leave it running. On the second terminal window on "romeo", run 35 | 36 | ``` 37 | ping -c 3 10.0.1.100 38 | ``` 39 | 40 | (note that 10.0.1.100 is the address assigned to the experiment interface on "romeo".) 41 | 42 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 43 | 44 | Now, we will repeat these steps, but with the `tcpdump` running on the loopback interface. Run 45 | 46 | ``` 47 | sudo tcpdump -n -i lo icmp 48 | ``` 49 | 50 | on "romeo", and leave it running. On the second terminal window on "romeo", run 51 | 52 | ``` 53 | ping -c 3 127.0.0.1 54 | ``` 55 | 56 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 57 | 58 | Finally, run 59 | 60 | ``` 61 | sudo tcpdump -n -i lo icmp 62 | ``` 63 | 64 | again, and leave it running, and on the second terminal window on "romeo", run 65 | 66 | ``` 67 | ping -c 3 10.0.1.100 68 | ``` 69 | 70 | When the `ping` finishes, use Ctrl+C to stop the `tcpdump`, then save the output for your lab report. 71 | 72 | 73 | **Lab report**: Show the output of the `tcpdump` in each case. Which network interface carries traffic from the host *to itself* when that traffic is sent to the 127.0.0.1 address? Which network interface carries traffic from the host *to itself* when that traffic is sent to the 10.0.1.100 address? Explain how the evidence from the `tcpdump` output supports your answer. 74 | -------------------------------------------------------------------------------- /lab-line-direct/fabric-transfer-udp.md: -------------------------------------------------------------------------------- 1 | ::: {.cell .markdown} 2 | ### Retrieve files from the experiment 3 | ::: 4 | 5 | 6 | ::: {.cell .markdown} 7 | 8 | As you complete each part of the experiment, you may choose to transfer packet captures from the remote hosts to this Jupyter environment. Then, you can download them from the Jupyter environment to open in Wireshark. 9 | 10 | To download a file from the Jupyter environment, use the file browser on the left side. You may need to use the "Refresh" button to see the updated file list after transferring a file. Then, you can right-click on a file and select "Download" to download it to your own computer. 11 | 12 | ::: 13 | 14 | 15 | ::: {.cell .code} 16 | ```python 17 | import os 18 | romeo_exec = slice.get_node("romeo") 19 | romeo_name = romeo_exec.execute("hostname", quiet=True)[0].strip() 20 | juliet_exec = slice.get_node("juliet") 21 | juliet_name = juliet_exec.execute("hostname", quiet=True)[0].strip() 22 | ``` 23 | ::: 24 | 25 | 26 | ::: {.cell .markdown} 27 | #### Packet Captures for Exercise - IP layer limit and fragmentation 28 | 29 | ::: 30 | 31 | 32 | ::: {.cell .code} 33 | ```python 34 | romeo_no_fragment_pcap = "/home/ubuntu/%s-no-ip-fragment.pcap" % romeo_name 35 | romeo_exec.download_file(os.path.abspath('romeo-no-ip-fragment.pcap'), romeo_no_fragment_pcap) 36 | ``` 37 | ::: 38 | 39 | 40 | ::: {.cell .code} 41 | ```python 42 | romeo_fragment_pcap = "/home/ubuntu/%s-ip-fragment.pcap" % romeo_name 43 | romeo_exec.download_file(os.path.abspath('romeo-ip-fragment.pcap'), romeo_fragment_pcap) 44 | ``` 45 | ::: 46 | 47 | 48 | ::: {.cell .markdown} 49 | #### Packet Captures for Exercise - FTP and TFTP operation 50 | 51 | ::: 52 | 53 | 54 | ::: {.cell .code} 55 | ```python 56 | romeo_ftp_pcap = "/home/ubuntu/%s-ftp-large.pcap" % romeo_name 57 | romeo_exec.download_file(os.path.abspath('romeo-ftp-large.pcap'), romeo_ftp_pcap) 58 | ``` 59 | ::: 60 | 61 | 62 | ::: {.cell .code} 63 | ```python 64 | romeo_tftp_pcap = "/home/ubuntu/%s-tftp-large.pcap" % romeo_name 65 | romeo_exec.download_file(os.path.abspath('romeo-tftp-large.pcap'), romeo_tftp_pcap) 66 | ``` 67 | ::: 68 | 69 | 70 | ::: {.cell .code} 71 | ```python 72 | romeo_tftp_blocksize_pcap = "/home/ubuntu/%s-tftp-large-blocksize.pcap" % romeo_name 73 | romeo_exec.download_file(os.path.abspath('romeo-tftp-large-blocksize.pcap'), romeo_tftp_blocksize_pcap) 74 | ``` 75 | ::: 76 | 77 | 78 | ::: {.cell .markdown} 79 | #### Packet Captures for Exercise - TFTP packets 80 | 81 | ::: 82 | 83 | 84 | ::: {.cell .code} 85 | ```python 86 | romeo_tftp_small_pcap = "/home/ubuntu/%s-tftp-small.pcap" % romeo_name 87 | romeo_exec.download_file(os.path.abspath('romeo-tftp-small.pcap'), romeo_tftp_small_pcap) 88 | ``` 89 | ::: 90 | 91 | 92 | ::: {.cell .markdown} 93 | #### Packet Captures for Exercise - FTP packets when not using passive mode 94 | 95 | ::: 96 | 97 | 98 | ::: {.cell .code} 99 | ```python 100 | romeo_ftp_small_pcap = "/home/ubuntu/%s-ftp-small.pcap" % romeo_name 101 | romeo_exec.download_file(os.path.abspath('romeo-ftp-small.pcap'), romeo_ftp_small_pcap) 102 | ``` 103 | ::: 104 | 105 | 106 | ::: {.cell .markdown} 107 | #### Packet Captures for Exercise - FTP packets in passive mode 108 | 109 | ::: 110 | 111 | 112 | ::: {.cell .code} 113 | ```python 114 | romeo_ftp_passive_pcap = "/home/ubuntu/%s-ftp-small-passive.pcap" % romeo_name 115 | romeo_exec.download_file(os.path.abspath('romeo-ftp-small-passive.pcap'), romeo_ftp_passive_pcap) 116 | ``` 117 | ::: -------------------------------------------------------------------------------- /lab-stp/stp-id.md: -------------------------------------------------------------------------------- 1 | ## Before beginning the spanning tree protocol 2 | 3 | Before we bring the bridges up _with_ the spanning tree protocol enabled, we'll first: 4 | 5 | * configure each bridge to use the spanning tree protocol 6 | * identify the bridge ID that each bridge will use for the spanning tree protocol 7 | * learn how to read the `brctl showstp` output 8 | * and set the priority of one bridge so that it will become the root bridge 9 | 10 | 11 | ### Configure bridge to use the spanning tree protocol 12 | 13 | On each _bridge_ node, bring down the bridge interface: 14 | 15 | ``` 16 | sudo ip link set br0 down 17 | ``` 18 | 19 | and then run 20 | 21 | ``` 22 | sudo brctl stp br0 on 23 | ``` 24 | 25 | to turn on the spanning tree algorithm. Run 26 | 27 | ``` 28 | brctl show br0 29 | ``` 30 | 31 | and confirm that you see a "yes" in the "STP enabled" column on each bridge. 32 | 33 | 34 | Also make a node of each bridge's bridge ID, which is displayed as 16 hex digits. The bridge ID is formed by concatenating a priority value and the MAC address of the `br0` interface: 35 | 36 | * The default priority is 32768, which is `8000` in hex digits. 37 | * The software bridge package we are using assigns to `br0` the lowest MAC address of all of the bridged interfaces, so this is the MAC address that will be used in the bridge ID. 38 | 39 | Identify the bridge that has the lowest bridge ID. This is the bridge that would be the root bridge, if all of the bridges were active. 40 | 41 | 42 | **Lab report**: Show the `brctl show br0` output for each bridge (include the prompt, so that it is evident which bridge each output is from). Which bridge would be elected the root bridge in the spanning tree (if you did not change any bridge priority)? 43 | 44 | ### Understanding the `showstp` outut 45 | 46 | We will monitor the progress of the spanning tree protocol on the bridges by watching the output of 47 | 48 | ``` 49 | brctl showstp br0 50 | ``` 51 | 52 | on each bridge. 53 | 54 | In this output, make a note of where to find: 55 | 56 | * the ID of the bridge whose configuration you are looking at 57 | * the ID of the current root bridge 58 | * the path cost to the root bridge 59 | * the root port (if this bridge is not the root) 60 | * for each bridge port: 61 | * the port ID 62 | * the ID of the designated bridge port on the network segment that this port is on 63 | * the root path cost (including the path to the root!) of the designated bridge port on the network segment that this port is on 64 | * the cost associated with forwarding through this port (not including the rest of the path to the root!) 65 | * the current state of the port. 66 | 67 | Initially, before you bring any bridge up, each bridge considers *itself* to be the root bridge. However, by exchanging BPDUs, they will eventually converge and all agree on the same root bridge. 68 | 69 | 70 | ### Change bridge priority 71 | 72 | The experiment procedure is easier to describe and follow along with as a group if we all have the same root bridge in our networks. Therefore, we will set the priority of one bridge to be lower than the rest, so that this bridge will definitely be the root bridge. 73 | 74 | On "bridge-2", run 75 | 76 | ``` 77 | sudo brctl setbridgeprio br0 0x7000 78 | ``` 79 | 80 | to set the bridge priority to `0x7000` (this is lower than the default `0x8000`, so this bridge will have the lowest bridge ID in the network and will become the root bridge). 81 | 82 | Run 83 | 84 | 85 | ``` 86 | brctl showstp br0 87 | ``` 88 | 89 | and verify that this change was applied. 90 | 91 | **Lab report**: After changing the priority on "bridge-2", which bridge do you expect will be the root bridge in the spanning tree? -------------------------------------------------------------------------------- /lab1/1-2-linux-navigating.md: -------------------------------------------------------------------------------- 1 | ## 1.2 Navigating the filesystem 2 | 3 | 4 | In this section, you will learn about the structure of the Linux filesystem, and some basic commands for navigating the filesystem: `pwd`, `ls`, `cd`, `mkdir` 5 | 6 | ### Exercise - Basic filesystem navigation 7 | 8 | First, check where you are currently located in the filesystem with the `pwd` 9 | ("**p**rint **w**orking **d**irectory") command: 10 | 11 | ``` 12 | pwd 13 | ``` 14 | Next, **l**i**s**t the contents of the directory you are in: 15 | 16 | ``` 17 | ls 18 | ``` 19 | 20 | To create a new directory inside our current directory, run `mkdir` and 21 | specify a name for the new directory, like 22 | 23 | ``` 24 | mkdir new 25 | ``` 26 | 27 | You can **c**hange **d**irectory by running `cd` and specifying the directory 28 | you want to change to. For example, to change to the directory you've just 29 | created, run 30 | 31 | ``` 32 | cd new 33 | ``` 34 | 35 | and then use 36 | 37 | ``` 38 | pwd 39 | ``` 40 | 41 | again to verify your current working directory. 42 | 43 | ### Exercise - Relative and absolute paths 44 | 45 | You may have noticed that when you run the `pwd` command, it gives you 46 | a full path with several directory names separated by a `/` character. 47 | This is a _full path_. For example, after running the commands above, I would see 48 | the following output for `pwd`: 49 | 50 | ``` 51 | /users/ff524/new 52 | ``` 53 | 54 | When you run commands that involve a file or directory, you can always 55 | give a full path, which starts with a `/` and contains the entire directory 56 | tree up until the file or directory you are interested in. For example, you can 57 | run 58 | 59 | ``` 60 | cd /users/ff524 61 | ``` 62 | 63 | to return to your home directory. Alternatively, you can give a path that is 64 | _relative_ to the directory you are in. For example, when I am inside my home 65 | directory (`/users/ff524` - yours will be different), which has a directory 66 | called `new` inside it, I can navigate into the `new` directory with 67 | a relative path: 68 | 69 | ``` 70 | cd new 71 | ``` 72 | 73 | or the absolute path: 74 | 75 | 76 | ``` 77 | cd /users/ff524/new 78 | ``` 79 | 80 | The concepts and commands in this section will be essential for future lab assignments. They will be especially important when you use `scp` to retrieve data from your experiments - you will need to be able to find out the absolute path of the file you want to retrieve, so that you can use it in your `scp` command. 81 | 82 | 83 | Some useful shortcuts for navigating the filesystem: 84 | 85 | * Running `cd` with no argument takes you to your home directory. 86 | * The shorthand `..` refers to "the directory that is one level higher" (can be 87 | used with `cd` and with other commands). 88 | * The shorthand `~` refers to the current user's home directory (can be used 89 | with `cd` and with other commands). 90 | * After navigating to a new directory with `cd`, you can then use `cd -` to 91 | return to the directory you were in previously. 92 | 93 | Try these commands. Before and after each `cd` command, run `pwd` to see 94 | where you have started and where you ended up after running the command. 95 | 96 | 97 | ```bash 98 | cd # takes you to your home directory 99 | cd .. # takes you one directory "higher" from where you were before 100 | cd ~ # takes you to your home directory 101 | cd ../.. # takes you two directories "higher" from where you were before 102 | cd - # takes you to the directory you were in before the last time you ran "cd" 103 | ``` 104 | 105 | 106 | Then, return to your home directory. 107 | -------------------------------------------------------------------------------- /key-concepts.md: -------------------------------------------------------------------------------- 1 | # ECE-GY 6353 key concepts 2 | 3 | ## 2: ARP, Bridges 4 | 5 | ### A. ARP 6 | 7 | 1. before sending a frame, a host checks its ARP table to find out the destination MAC address corresponding to the destination IP 8 | 2. if the IP address to MAC address mapping is already in the ARP table, the host uses that MAC address as the destination address of the frame 9 | 3. if the IP address to MAC address mapping is not already in the ARP table, the host sends an ARP request to try to resolve the address 10 | 4. an ARP request is sent with the broadcast address in the destination address field of the Ethernet header, so that everyone on the LAN will receive it 11 | 5. if a host receives an ARP request on an interface whose assigned IP address matches the "Target IP Address" field in the ARP request, it will return an ARP reply with the interface's MAC address 12 | 6. in an ARP reply, the destination address in the Ethernet header is the unicast address that was the source of the ARP request 13 | 7. the host that receives the ARP reply adds an entry to its ARP table with the IP address, MAC address, and interface name 14 | 8. the host that receives the ARP *request* and sends a response also adds an entry to its ARP table with the IP address, MAC address, and interface name from the ARP *request* 15 | 9. when an ARP table entry becomes "stale", a host can send a unicast "ARP poll" to confirm an existing ARP entry 16 | 10. when a host sends an ARP request and does not receive an ARP reply, it retransmits the ARP request several times, then gives up and returns an ICMP message of type Destination Unreachable with code Host Unreachable 17 | 18 | ### B. Basic bridge operation 19 | 20 | 1. a bridge operates at layer 2 and looks at Ethernet headers 21 | 2. a bridge does not change IP or MAC headers when it forwards a frame 22 | 3. when a bridge receives a frame whose destination MAC is not in its forwarding table (including broadcast), it will **flood** it out all ports except the one it is received on. 23 | 4. when a bridge receives a frame whose destination MAC is in its forwarding table, it will either **forward** it on the port where the destination is, or **drop** the frame (if it was received on the same port where the destination is) 24 | 5. when a bridge receives a frame whose source address is not in its forwarding table, it will add an entry for the source address and port number in its table 25 | 6. when a bridge receives a frame whose source address is in its forwarding table, it will reset the ageing timer for that entry 26 | 7. a bridge removes forwarding table entries that have aged out 27 | 8. a bridge can improve network performance by segmenting the network into multiple collision domains 28 | 29 | 30 | ## 3. Spanning tree 31 | 32 | 33 | 34 | ### A. Spanning tree protocol basics 35 | 36 | 1. bridges perform the spanning tree protocol by exchanging BPDUs 37 | 2. each bridge determines its own bridge ID by combining a priority number and the MAC address of the first bridge port interface 38 | 3. the bridge with the lowest bridge ID will become the root bridge 39 | 4. 40 | 41 | ### B. Broadcast storm 42 | 43 | 1. broadcast storms can occur in a network with bridge loops, if the bridges do not form a spanning tree 44 | 2. a broadcast storm can be triggered by any frame that will be flooded by bridges, including a frame with the broadcast address in the destination field 45 | 3. a "broadcast" storm can be triggered by a unicast frame if there is no device with that address in the network, since that frame will be flooded by all the bridges 46 | 3. a broadcast storm is not usually triggered by a frame with unicast destination address of a destination on the network, since eventually the host with that address may send a frame from which the bridges can learn -------------------------------------------------------------------------------- /rspecs/line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lab6/el5373-lab6-610.md: -------------------------------------------------------------------------------- 1 | ## 6.10 Exercises on TCP timers and retransmission 2 | 3 | For this experiment, we will reuse the same network as in the [previous experiment](el5373-lab6-67.md). 4 | 5 | ### Exercise 5 6 | 7 | On "romeo", execute 8 | 9 | ``` 10 | sudo sysctl -A | grep keepalive 11 | ``` 12 | 13 | to display the default values of the TCP kernel parameters that are related to the TCP keepalive timer. 14 | 15 | **Lab report**: What is the default value of the TCP keepalive timer? What is the maximum number of TCP keepalive probes a host can send? 16 | 17 | To observe TCP keepalive packets, we will reduce the time before TCP begins sending keepalive packets. On "juliet", run 18 | 19 | ``` 20 | sudo sysctl -w net.ipv4.tcp_keepalive_time=60 21 | ``` 22 | 23 | Also, to observe TCP keepalive packets, the application must be configured to use them - on "juliet", run 24 | 25 | ``` 26 | sudo nano /etc/xinetd.d/telnet 27 | ``` 28 | 29 | to modify the `telnet` configuration file. Change the line 30 | 31 | ``` 32 | flags = REUSE 33 | ``` 34 | 35 | to 36 | 37 | ``` 38 | flags = KEEPALIVE 39 | ``` 40 | 41 | To save the file, use Ctrl+O to write out to file (and hit Enter to confirm the output filename). Then use Ctrl+X to exit `nano`. Finally, run 42 | 43 | ``` 44 | sudo service xinetd restart 45 | ``` 46 | 47 | to restart the `xinetd` service with the net `telnet` settings. 48 | 49 | On juliet, start a `tcpdump`: 50 | 51 | 52 | ``` 53 | sudo tcpdump -S -i eth1 -w tcp-keepalive-$(hostname -s).pcap 54 | ``` 55 | 56 | Then, while `tcpdump` is capturing the traffic between "romeo" and "juliet", on "romeo", run 57 | 58 | ``` 59 | telnet 10.10.2.100 60 | ``` 61 | 62 | and enter the username and password when prompted. Don't type anything in the `telnet` session, and wait for the keepalive timer to elapse. 63 | 64 | When you're finished, use 65 | 66 | ``` 67 | exit 68 | ``` 69 | 70 | to end the telnet session. Then, restore the keepalive timer values to their defaults. Use a command similar to 71 | 72 | 73 | ``` 74 | sudo sysctl -w net.ipv4.tcp_keepalive_time=60 75 | ``` 76 | 77 | but instead of `60`, use the value you noted in Exercise 5. 78 | 79 | **Lab report**: Explain how TCP keepalive works, using your `tcpdump` output. 80 | 81 | ### Exercise 6 82 | 83 | Run `tcpdump` on _both end hosts_ to capture the packets between "romeo" and "juliet": 84 | 85 | ``` 86 | sudo tcpdump -S -s 68 -i eth1 -w tcp-connection-down-$(hostname -s).pcap 87 | ``` 88 | 89 | Note the `-s snaplen` argument, which tells `tcpdump` to capture `snaplen` bytes of each frame. 68 bytes should be sufficient to capture IP/UDP/TCP/ICMP headers, and by capturing only the headers, we keep the capture file small and make it easier to transfer from the remote host later. 90 | 91 | Then, start an `iperf3` server instance on "juliet": 92 | 93 | ``` 94 | iperf3 -s 95 | ``` 96 | 97 | Then, on "romeo", run 98 | 99 | ``` 100 | iperf3 -c 10.10.2.100 -t 90 101 | ``` 102 | 103 | to send TCP traffic to "juliet". 104 | 105 | While this is still running, we will temporarily break the connection between "romeo" and "juliet". On the "router" node, run 106 | 107 | ``` 108 | sudo ifconfig eth1 down 109 | sudo ifconfig eth2 down 110 | ``` 111 | 112 | After about ten seconds have passed, restore the link with 113 | 114 | ``` 115 | sudo ifconfig eth1 up 116 | sudo ifconfig eth2 up 117 | ``` 118 | 119 | Save the `tcpdump` output for the lab report. 120 | 121 | **Lab report**: From the `tcpdump` output, identify when the connection was broken. Describe how the retransmission timer changes after sending each retransmitted packet, during the period when the connection was broken. Explain how the number of data segments that the sender transmits at once (before getting an ACK) changes after the connection is reestablished. 122 | 123 | Once you are done with this part of the lab , proceed to the [next part](el5373-lab6-611.md) 124 | -------------------------------------------------------------------------------- /lab5/el5373-lab5-55.md: -------------------------------------------------------------------------------- 1 | ## Using `iperf3` 2 | 3 | 4 | For this experiment, we will use a topology with two workstations (named "romeo" and "juliet"), with IP addresses configured as follows: 5 | 6 | * romeo: 10.10.0.100 7 | * juliet: 10.10.0.101 8 | 9 | each with a netmask of 255.255.255.0. 10 | 11 | To set up this topology in the GENI Portal, create a slice, click on "Add Resources", and load the RSpec from the following URL: https://raw.githubusercontent.com/ffund/tcp-ip-essentials/gh-pages/rspecs/two-hosts-one-segment-16.xml 12 | 13 | Refer to the [monitor website](https://fedmon.fed4fire.eu/overview/instageni) to identify an InstaGENI site that has many "free VMs" available. Then bind to an InstaGENI site and reserve your resources. Wait for them to become available for login ("turn green" on your canvas) and then SSH into each, using the details given in the GENI Portal. 14 | 15 | On each host, install the `iperf3` package, which we'll use in this lab: 16 | 17 | ``` 18 | sudo apt-get update 19 | sudo apt-get -y install iperf3 20 | ``` 21 | 22 | Before you start, use `ifconfig -a` to capture the network interface configuration of each host in this topology. Identify the IP address and MAC address of each interface. 23 | 24 | ### Exercise - using iperf3 25 | 26 | 27 | In the first part of this lab, we will learn how to use the `iperf3` utility. This is a network testing tool which allows us to send TCP or UDP flows between two hosts, one of which is configured as a server (that listens for incoming connections and receives data), and one of which is configured as a client (that sends data). 28 | 29 | Configure "romeo" to act as an `iperf3` server; 30 | 31 | ``` 32 | iperf3 -s 33 | ``` 34 | 35 | Once this is running, the client can initiate a TCP or UDP flow to the server. On "juliet", run 36 | 37 | ``` 38 | iperf3 -c 10.10.0.100 39 | ``` 40 | 41 | to start the `iperf3` application in client mode, and specify the server's IP address. 42 | 43 | By default, `iperf3` will establish a TCP connection and run a test for ten seconds. The client process will terminate automatically when it's finished. To stop the `iperf3` server, use Ctrl+C. 44 | 45 | Use 46 | 47 | ``` 48 | iperf3 --help 49 | ``` 50 | 51 | or 52 | 53 | ``` 54 | man iperf3 55 | ``` 56 | 57 | to learn more about the other options available with `iperf3`. 58 | 59 | Next, you will observe some common errors that people make with `iperf3`. Once you learn the error messages that are associated with common mistakes, you will be able to diagnose and fix problems you may encounter when using `iperf`. 60 | 61 | Make sure the `iperf3` server is running on "romeo". Open a second terminal window on "romeo", and run 62 | 63 | 64 | ``` 65 | iperf3 -s 66 | ``` 67 | 68 | in this terminal window. Note the error message that you observe. 69 | 70 | While the `iperf3` server is running in the first "romeo" terminal window, run 71 | 72 | ``` 73 | sudo killall iperf3 74 | ``` 75 | 76 | in the second "romeo" terminal window. What happened to the `iperf3` server in the first terminal window? Are you able to now run 77 | 78 | ``` 79 | iperf3 -s 80 | ``` 81 | 82 | in the second terminal window? 83 | 84 | Next, let's see what happens on the client side when we try to send `iperf3` traffic to a wrong address, wrong port, or to a host and port where no `iperf3` server is running. 85 | 86 | On "juliet", try running 87 | 88 | ``` 89 | iperf3 -c 10.10.0.102 90 | ``` 91 | 92 | and note the message that you observe. Also try running 93 | 94 | ``` 95 | iperf3 -c 10.10.0.100 -p 6000 96 | ``` 97 | 98 | and note the message. 99 | 100 | Finally, make sure there is no `iperf3` server on "romeo" - stop any running servers with Ctrl+C, and use 101 | 102 | ``` 103 | sudo killall iperf3 104 | ``` 105 | 106 | to kill any that might be running in the background. On "juliet", run 107 | 108 | ``` 109 | iperf3 -c 10.10.0.100 110 | ``` 111 | 112 | and note the error message that you observe. 113 | 114 | -------------------------------------------------------------------------------- /lab0/1-0-prepare-workstation.md: -------------------------------------------------------------------------------- 1 | ## Prepare your workstation 2 | 3 | You'll need to prepare your workstation with all the software necessary to complete the lab assignments in this course. You will primarily need two pieces of software: 4 | 5 | * Wireshark 6 | * An appropriate terminal application 7 | 8 | ### Wireshark 9 | 10 | Wireshark is a software application for capturing, viewing, and analyzing network packets. Download Wireshark from [the Wireshark website](https://www.wireshark.org/download.html). 11 | 12 | Then, follow the instructions to install for your system: 13 | 14 | * [Instructions for installing Wireshark on Windows](https://www.wireshark.org/docs/wsug_html_chunked/ChBuildInstallWinInstall.html). (Note: you only need Wireshark, not the extra components that are bundled along with it.) 15 | * [Instructions for installing Wireshark on Mac](https://www.wireshark.org/docs/wsug_html_chunked/ChBuildInstallOSXInstall.html). 16 | * [Instructions for installing Wireshark on Linux](https://www.wireshark.org/docs/wsug_html_chunked/ChBuildInstallUnixInstallBins.html). 17 | 18 | ### Terminal software 19 | 20 | The primary software application you'll need is a terminal, which you will use to log in to remote hosts over SSH and carry out various exercises. 21 | 22 | You may have a terminal application already on your workstation, but it may not be ideal for this course. To complete these lab exercises, you will often have to run and monitor the output of multiple commands in several independent terminal sessions. It is therefore *strongly recommended* to use a terminal that lets you split one terminal window into multiple panes - for example, 23 | 24 | * [cmder](https://cmder.app/) for Windows. (Get the full version, not the mini version.) 25 | * [iTerm2](https://www.iterm2.com/) for Mac 26 | * [terminator](https://launchpad.net/terminator) for Linux 27 | 28 | Once you have downloaded and installed your terminal application, open it up and practice using it. Make sure you know: 29 | 30 | * How to split the pane in your terminal. 31 | * How to copy text from your terminal and paste into another application. This will be helpful when you need to save some terminal output for your lab report. 32 | * How to copy text from another application and paste into your terminal. This will be helpful when you need to copy a command from the lab instructions into your terminal, in order to run it. 33 | 34 | ### cmder on Windows 35 | 36 | If you are using cmder on Windows, you can split the pane as follows: 37 | 38 | 1. Click on the green + symbol near the bottom right side of the window. This will open a "Create new console" dialog. 39 | 2. Where it says "New console split", choose "to bottom" or "to right". You can leave other options at their default settings. 40 | 3. Click "Start". 41 | 42 | Note that if you need to split more than once, click on the pane that you want to split (so that it is the active pane) before using the green + symbol to split it again. 43 | 44 | To copy text from the terminal, select the text you want to copy. It will be automatically copied to your clipboard, and you can then paste it into any other application. 45 | 46 | To paste text into the terminal, place your cursor where you want to paste, and right click. 47 | 48 | 49 | #### iTerm2 on Mac 50 | 51 | If you are using iTerm2 on Mac, you can split the pane as follows: 52 | 53 | 1. To create a new vertical pane, use ⌘+D 54 | 2. To create a new horizontal pane, use ⌘+Shift+D 55 | 56 | To copy text from the terminal, select the text you want to copy and use ⌘+C to copy. 57 | 58 | To paste text into the terminal, place your cursor where you want to paste, and use ⌘+V to paste. 59 | 60 | #### Terminator on Linux 61 | 62 | If you are using `terminator` on Linux, you can split the pane either vertically or horizontally as follows: 63 | 64 | 1. Right-click anywhere inside the terminal window 65 | 2. Choose "Split pane horizontally" or "Split pane vertically" 66 | 3. You can resize panes by dragging the divider between panes 67 | 68 | To copy text from the terminal, select the text you want to copy and either 69 | 70 | * right-click, and choose Copy, or 71 | * use Ctrl+shift+C to copy 72 | 73 | To paste text into the terminal, place your cursor where you want to paste, and either 74 | 75 | * right-click, and choose Paste, or 76 | * use Ctrl+shift+P to paste 77 | 78 | -------------------------------------------------------------------------------- /rspecs/line-tso-off.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | --------------------------------------------------------------------------------