<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gbos.git/c/ping.c, branch master</title>
<subtitle>gbos - a tiny Unix-flavored OS for the Game Boy Color (kernel, shell, coreutils in C, RAM filesystem)</subtitle>
<id>https://git.sl0p.foo/gbos.git/atom/c/ping.c?h=master</id>
<link rel='self' href='https://git.sl0p.foo/gbos.git/atom/c/ping.c?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/'/>
<updated>2026-07-17T22:38:38Z</updated>
<entry>
<title>refactor: c/ -&gt; usr/, compiled program blobs out of the source tree</title>
<updated>2026-07-17T22:38:38Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T22:38:38Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c'/>
<id>urn:sha1:ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c</id>
<content type='text'>
Userland sources live in usr/ (fits the Unix theme better than 'c').
SDCC output .bin blobs land in build/usr/ with the other build artifacts
instead of littering the source dir; programs.asm INCBINs them from there.
Byte-identical ROM.
</content>
</entry>
<entry>
<title>net: unbreak ping against hosts that intermittently drop ICMP</title>
<updated>2026-07-17T17:45:13Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T17:45:13Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=4f038ecad87777bc1d74f8f93f267da8cd396446'/>
<id>urn:sha1:4f038ecad87777bc1d74f8f93f267da8cd396446</id>
<content type='text'>
Pinging sl0p.foo through gbhub looked hung: DNS resolved, then nothing.
Packet-tracing showed the echo request leaving the hub's TUN and eth0
correctly NATed every time - but 80.78.19.56 blackholes ICMP for all
ids in windows of tens of seconds (provider rate limiting). One lost
reply wedged ping for minutes because net_recv's pump-counted timeout
is effectively unbounded at native emulation speed.

Two fixes:

- NET_RECVNB (op 8): non-blocking recv - one RX pump, $FE if nothing
  buffered, same delivery/EOF semantics as NET_RECV otherwise. ping now
  waits &lt;=~2s per seq (net_recv_nb + msleep loop), prints 'seq=N
  timeout' and moves on, like real ping.

- ICMP echo id was hardcoded $1234 for every GB, every boot, so all
  sessions produced byte-identical flows - hostile to NAT conntrack
  (keyed on icmp id). wNetEchoId is now our host octet + rDIV timing
  noise sampled at DHCP lease, distinct per GB and per boot.

Verified: 8 back-to-back native-speed gbhub runs, zero hangs; a run
that hit a blackhole window printed seq=1 timeout then recovered to
3/4 received. GB&lt;-&gt;GB ping and DNS/DHCP unaffected.
</content>
</entry>
<entry>
<title>net: ping resolves hostnames (ping sl0p.foo, not just ping 1.2.3.4)</title>
<updated>2026-07-17T13:23:03Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T13:23:03Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=7f01a9e22f8a19109daf56356a0bb8636af67a84'/>
<id>urn:sha1:7f01a9e22f8a19109daf56356a0bb8636af67a84</id>
<content type='text'>
ping used parse_ip only, so a hostname gave "bad address". It now uses resolve.h
(like wget/nslookup): dotted-quad is used as-is, a name is looked up via DNS
first. Copies the arg to a safe buffer before resolving (the 0xA000 arg/_DATA
overlap dance).

Verified through DHCP + NAT:
    /# ping sl0p.foo
    PING 80.78.19.56
      reply from 80.78.19.56 seq=1 ... -- 4/4 received
</content>
</entry>
<entry>
<title>kernel: sys_sleep - a cooperative delay off the DIV timer (+ ping pacing)</title>
<updated>2026-07-17T11:43:10Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T11:43:10Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=b52f37602968768901d2dd83ccf966d953a532f0'/>
<id>urn:sha1:b52f37602968768901d2dd83ccf966d953a532f0</id>
<content type='text'>
There was no time source at all (IRQ vectors just reti; scheduler is purely
cooperative). The DIV register (FF04) free-runs at 16384 Hz regardless of
interrupts, so sys_sleep accumulates DIV deltas across SchedYields (other procs
keep running) until the requested number of 1/64-second units elapse.

- SYS_SLEEP(34): B = 1/64s units; libc gsleep(units) / msleep(ms) wrappers.
- ping now msleep(800) between echoes, so it paces like real ping instead of
  blasting all four at once.

Verified real-time (capped emulator): replies land ~0.85s apart. In --uncapped
runs the delay is GB-time (fast wall-clock), as expected.
</content>
</entry>
<entry>
<title>net: proper socket API in the kernel (SYS_NET) - no more SLIP in userland</title>
<updated>2026-07-17T10:39:01Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T10:39:01Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=09ae37313a8b6d567a05a3ae886de78e88cd1afe'/>
<id>urn:sha1:09ae37313a8b6d567a05a3ae886de78e88cd1afe</id>
<content type='text'>
The network stack moves into the kernel. src/socket.asm owns SLIP framing,
IPv4, RFC1071 checksums, and ICMP; programs now speak a socket API through one
syscall (SYS_NET, DE=&amp;netreq dispatched by op): net_socket/connect/send/recv/
close/poll (c/sock.h). No program touches SLIP, IP headers, or checksums.

- Socket table (4 sockets) + tx/rx buffers in WRAM0; our IP = 10.0.0.2.
- net_pump: drains the link, reassembles SLIP frames, demuxes IPv4. Inbound
  ICMP echo requests are auto-answered in-kernel, so the GB replies to pings
  whenever any process pumps RX.
- ICMP sockets: send() emits an echo request to the connected peer; recv()
  returns the matching reply (with a spin/yield timeout).

ping.c is now a ~15-line socket client; netd.c is just `for(;;){net_poll();
yield();}`. Verified over tunbridge:
    /# ping 1.1.1.1     -&gt; replies from the real internet (kernel builds it all)
    host# ping 10.0.0.2 -&gt; 4/4, 0% loss (kernel auto-answers)

Gotchas recorded: gbos.inc isn't a make dep (touch asm after editing); this
crt0 doesn't copy initializers (fill arrays at runtime); and the arg string at
0xA000 overlaps _DATA, so parse targets must sit past it (big buffer first).
UDP and TCP sockets build on this same core next.
</content>
</entry>
<entry>
<title>net: ping - GB-originated ICMP echo (a Game Boy pings the real internet)</title>
<updated>2026-07-17T10:15:09Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T10:15:09Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=d102366e6808f74ef98044374d744e453efdbefa'/>
<id>urn:sha1:d102366e6808f74ef98044374d744e453efdbefa</id>
<content type='text'>
New `ping [A.B.C.D]` program (PROG_PING=27, bank 29): builds and sends ICMP
echo requests from 10.0.0.2, then reads replies off the link port. It keeps
reading SLIP frames until it finds *our* echo reply, skipping the IGMP/mDNS/
SSDP multicast noise that shares 10.0.0.0/24. Reply wait uses a generous
srecv_nb spin budget since the emulator runs uncapped (no timer syscall yet).

Verified over the tunbridge (with NAT):
    /# ping 10.0.0.1        -&gt; 4/4 received, ttl=64   (the SLIP peer/host)
    /# ping 1.1.1.1         -&gt; 4/4 received, ttl=56   (Cloudflare, real net!)

ttl=56 is a real internet round trip (64 minus the hops). Combined with the
host being able to ping the GB, the Game Boy is now a full two-way ICMP host.
</content>
</entry>
</feed>
