# Read the routes in your first RPL DODAG

Identify the selected next hop, test its reachability, and separate route-table evidence from end-to-end delivery.

## Run on Linux x86-64 with Docker and X11

The image, Java, compiler and simulator ran on this host under Apptainer.
Docker is unavailable here: the laptop Docker invocation is syntax-reviewed,
not claimed as laptop-tested. Windows, macOS and ARM display setup is outside
this recipe. No paid service or account is required.

Download `lab-files.tar.gz` from this lab page. In a terminal:

```bash
mkdir cooja-lab
cd cooja-lab
tar -xzf ~/Downloads/lab-files.tar.gz
git clone --depth 1 --branch release/v4.9 https://github.com/contiki-ng/contiki-ng.git contiki-ng
test "$(git -C contiki-ng rev-parse HEAD)" = c20b12cd2db707d6c07918f8b26cfeb52cf298ca
git -C contiki-ng submodule update --init --depth 1 tools/cooja
test "$(git -C contiki-ng/tools/cooja rev-parse HEAD)" = 33d41ae9f8acd6075fb903b0bcd5b4122bad8d8f
mkdir -p jdk17 home/contiki-ng
curl -fL 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.20.1%2B1/OpenJDK17U-jdk_x64_linux_hotspot_17.0.20.1_1.tar.gz' -o jdk17.tar.gz
echo '3808d1d15e3ec6bd5b84057fb5d84c33d8a1536a258146bcea2e603fc726e08e  jdk17.tar.gz' | sha256sum -c -
tar -xzf jdk17.tar.gz --strip-components=1 -C jdk17
xhost +si:localuser:$(id -un)
bash cooja-rpl-first-dodag/docker-launch.sh
# After closing Cooja:
xhost -si:localuser:$(id -un)
```

The launcher binds the packet at `/lab`. Cooja loads `/lab/cooja-rpl-first-dodag.csc`
and compiles the included unmodified upstream C files. The project header enables
logging and any explicitly documented parameter changes. The supplied Makefiles
expect the recipe's `/home/user/contiki-ng` mount. The first Gradle build requires
Internet. To use your own native Java 17 installation, set CONTIKI in the supplied
Makefiles to your checkout and open the CSC with that release's Cooja.

The script starts automatically and stops at `TEST OK` or `TEST FAILED`. The GUI
stays open. Use **Mote output → Filter** to show the rows named in the steps;
clear the filter to inspect other messages. **File → Open simulation → Browse...**
loads another CSC. Reopen the original CSC for a fresh seed-1 run.
Times are simulated times, not wall-clock times. `expected-output.txt` is the
unaltered headless serial/test log, including actual measurements and the test result.

For headless Docker execution, replace `--gui --autostart` in the launcher with
`--no-gui --logdir=/lab/run-output` and remove the display requirement/mount.
Cooja writes `COOJA.testlog` under that writable output directory.

## Experiment and acceptance record

Six motes, seed 1, UDGM transmit range 50 m and interference range 100 m,
unit transmit/receive success ratios. Coordinates in metres: root 1 (0,0),
2 (-30,25), 3 (30,25), 4 (-60,55), 5 (0,55), 6 (60,55).
All are native Cooja motes running unchanged upstream rpl-udp; the shell is
an upstream module. MRHOF and Non-storing are reported by `rpl-status`.
Do not interpret this idealized distance model as measured building RF coverage.

The ScriptRunner performs `ip-addr` on mote 4 at 60 s, `routes` on 4 at 61 s
and root 1 at 62 s, `rpl-nbr` on 4 at 63 s, and `rpl-status` at 64 s.
It pings the next hop at 65 s, root at 70 s, and absent destination at 76 s.
The timeout test requires all five clients to send and receive, the correct
mote-4 default route, both successful pings, and the absent-destination timeout.

Fill one row per claim: input/destination; candidate routes; selected prefix;
next hop and interface; observation time; request/reply identity; conclusion;
limitation. Save only the supporting lines, plus the complete original log.
The native Cooja radio is the outgoing interface. Root-held `Routing links`
represent Non-storing source-route knowledge, not a Linux route-table dump.

## Legacy worksheet: connected, static and default routes

This paper exercise preserves the original route-reading lab. These IPv4
entries are worksheet inputs, not routes installed into this IPv6 mesh:
`192.168.1.0/24 dev wlan0` and `default via 192.168.1.1 dev wlan0`.
For `192.168.1.50`, select the connected /24 and reject the default.
For `203.0.113.20`, no specific route matches, so select the default.
A route row proves a lookup decision; it does not prove the gateway is alive.

Now use A=`0.0.0.0/0`, B=`10.0.0.0/8`, C=`10.2.0.0/16`,
D=`10.2.4.0/24`. List **every** matching prefix before choosing:

| Destination | Matching lengths | Selected gateway |
|---|---|---|
| 10.2.4.77 | /0, /8, /16, /24 | D |
| 10.2.9.12 | /0, /8, /16 | C |
| 10.8.1.5 | /0, /8 | B |
| 198.51.100.20 | /0 | A |

Even a smaller metric on B cannot override D’s more-specific /24 match.
For a proposed static `198.51.100.0/24 via 192.168.1.254`, and local
`192.168.1.10/24`, the gateway is on-subnet. Mark the remaining checks
**unproven** until neighbor resolution, gateway reachability, installation,
destination and return path are actually tested. The scheduled IPv6 next-hop
ping demonstrates the same evidence ordering without changing laptop routes.

## Legacy worksheet: read a trace without overclaiming

For the written sample `hop 1: 1 ms; hop 2: * * *; hop 3: 82 ms;
hop 4: destination replies`, the silent second hop did not answer the probe;
later replies show the path continued. The latency jump could have several
causes and does not establish packet loss. A trace reaching its target does
not prove application success or symmetric routing. Record the target, time,
responding/silent hops, first jump, endpoint result and limitation.

This Cooja shell provides ping, not traceroute. Its measured return TTLs 64
(one hop) and 63 (two hops) illustrate hop decrement; they are not a captured
traceroute. Do not label the paper sample a simulator result.


## Tested version

Contiki-NG release/v4.9 c20b12cd, Cooja 4.8 (2022071901), Temurin 17.0.20.1, image sha256:b14d5afb0a2a852d9e72bbed607ead03f6ccc5f4d4dee44f0799110be2f4b609
