From 7f01a9e22f8a19109daf56356a0bb8636af67a84 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 17 Jul 2026 15:23:03 +0200 Subject: net: ping resolves hostnames (ping sl0p.foo, not just ping 1.2.3.4) 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 --- c/ping.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/c/ping.c b/c/ping.c index 68c4c86..f8d5bf7 100644 --- a/c/ping.c +++ b/c/ping.c @@ -1,26 +1,14 @@ -#include "sock.h" -/* ping - originate ICMP echo requests via the kernel socket layer. No SLIP, - no IP, no checksums here: the kernel owns all of that. Usage: ping [A.B.C.D] - (default 10.0.0.1, the SLIP peer/host; reaches real hosts through NAT). */ +#include "resolve.h" +/* ping HOST|IP - originate ICMP echo requests via the kernel socket layer. + Resolves a hostname via DNS first (resolve.h); default target 10.0.0.1. No + SLIP/IP/checksums here - the kernel owns all of that. */ -/* rbuf is declared first (and large) so the parse target dst[] lands well past - the argument string the shell leaves at 0xA000 - writing dst must not clobber - the arg while we're still reading it. */ +/* rbuf is first + large so namebuf/dst land past the arg string at 0xA000 */ static unsigned char rbuf[96]; +static unsigned char namebuf[64]; static unsigned char dst[4]; static unsigned char payload[4]; -static unsigned char parse_ip(char *s, unsigned char *out) { - unsigned char i, v; - for (i = 0; i < 4; i++) { - if (*s < '0' || *s > '9') return 0; - v = 0; - while (*s >= '0' && *s <= '9') { v = (unsigned char)(v * 10 + (*s - '0')); s++; } - out[i] = v; - if (i < 3) { if (*s != '.') return 0; s++; } - } - return 1; -} static void put_ip(unsigned char *ip) { unsigned char i; for (i = 0; i < 4; i++) { putu(ip[i]); if (i < 3) putc('.'); } @@ -28,10 +16,16 @@ static void put_ip(unsigned char *ip) { void main(void) { char *arg; - unsigned char s, seq, got = 0; + unsigned char s, seq, got = 0, i; arg = getargs(); if (!arg || !*arg) { dst[0] = 10; dst[1] = 0; dst[2] = 0; dst[3] = 1; } - else if (!parse_ip(arg, dst)) { puts("ping: bad address"); nl(); sexit(1); } + else { + for (i = 0; arg[i] && i < 63; i++) namebuf[i] = (unsigned char)arg[i]; + namebuf[i] = 0; + if (!resolve((char *)namebuf, dst)) { + puts("ping: cannot resolve "); puts((char *)namebuf); nl(); sexit(1); + } + } payload[0] = 'g'; payload[1] = 'b'; payload[2] = 'o'; payload[3] = 's'; s = net_socket(SOCK_ICMP); @@ -41,7 +35,7 @@ void main(void) { puts("PING "); put_ip(dst); nl(); for (seq = 1; seq <= 4; seq++) { net_send(s, payload, 4); - if (net_recv(s, rbuf, sizeof(rbuf)) != 0xFF) { + if (net_recv(s, rbuf, (unsigned char)sizeof(rbuf)) != 0xFF) { got++; puts(" reply from "); put_ip(dst); puts(" seq="); putu(seq); nl(); } else { -- cgit v1.3.1-sl0p