app: link.ra_source router identification + brand icons + DEV build variant

link.ra_source answers "who advertises IPv6 here, and which box is it":
RA source per network, MAC recovered from the modified-EUI-64 link-local
(privacy addresses reported as such, not guessed), vendor via a curated
OUI table, UPnP/SSDP M-SEARCH for the gateway's server banner + device
description (manufacturer/model/friendly name), and reverse DNS. All SSDP
responders are recorded so a rogue RA sender that isn't the gateway can
still be matched; the MAC accompanies every identity source as the hook
for future LLDP/mDNS cross-matching. UI gains a "Router / IPv6 advertiser"
panel.

Icons: branding adaptive icon converted to vector drawables (+ PNG
mipmaps, monochrome layer). The debug build is now a separate app —
applicationIdSuffix .dev, label "Echolot DEV", DEV-badged icon — so it
installs alongside a production build and can't be confused with it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrambossek
2026-08-01 09:35:54 +02:00
co-authored by Claude Opus 5
parent dc094d1631
commit 38f8036252
43 changed files with 432 additions and 1 deletions
+26
View File
@@ -452,3 +452,29 @@ gained `POST /report`, `GET /reports`, `GET /report/<name>`), shows the result f
finishes itself — leaving the device as it was found. On upload failure it stays open so the
error is visible. Grant permissions once via `adb shell pm grant app.echo_lot.app
android.permission.ACCESS_FINE_LOCATION` so nothing blocks on a dialog.
## App: router identification, brand icons, DEV build variant (2026-08-01)
**`link.ra_source` — who is advertising IPv6 here, and what box is it?** New app-tier probe
(registry addition). Identification chain, each step recorded as evidence so nothing is guessed:
1. RA source = next-hop of the `::/0` route per network (a `fe80::` link-local).
2. **MAC recovered from the modified-EUI-64 link-local** (strip `ff:fe`, flip the U/L bit) —
e.g. `fe80::7a9a:18ff:fe54:b8f9` → `78:9a:18:54:b8:f9`. RFC 7217/privacy addresses don't encode
a MAC and are reported as such rather than guessed.
3. Vendor via a curated OUI table (`Oui.kt` — SOHO/router vendors; unknown OUIs are printed
verbatim). Locally-administered (randomized) MACs are flagged.
4. **UPnP/SSDP M-SEARCH** → the gateway's `SERVER:` banner + device-description XML gives
manufacturer / model / friendly name. This is what usually names the exact box.
5. Reverse DNS for both gateways.
All SSDP responders are recorded (not just the gateway) so a rogue RA sender that isn't the
gateway can still be matched — and the MAC travels with every identity source, which is the hook
for the future LLDP / mDNS cross-matching.
UI: a "Router / IPv6 advertiser" panel above the network list, leading with the identified
vendor/model.
**Icons + DEV variant.** The branding adaptive icon is now the app icon: `icon-adaptive-*.svg`
converted to Android vector drawables (SVG transform baked in, gradient background, monochrome
layer for themed icons) plus PNG mipmaps for legacy launchers. The **debug build is a separate
app**: `applicationIdSuffix .dev`, label "Echolot DEV", and a DEV-badged icon (layer-list =
production foreground + generated amber DEV ribbon) so it is unmistakable next to a real install
and both can be installed side by side.
NOTE for tooling: the dev package is `app.echo_lot.app.dev`, activity `app.echo_lot.app.MainActivity`.