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
|
#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). */
/* 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. */
static unsigned char rbuf[96];
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('.'); }
}
void main(void) {
char *arg;
unsigned char s, seq, got = 0;
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); }
payload[0] = 'g'; payload[1] = 'b'; payload[2] = 'o'; payload[3] = 's';
s = net_socket(SOCK_ICMP);
if (s == 0xFF) { puts("ping: no socket"); nl(); sexit(1); }
net_connect(s, dst, 0);
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) {
got++;
puts(" reply from "); put_ip(dst); puts(" seq="); putu(seq); nl();
} else {
puts(" seq="); putu(seq); puts(" timeout"); nl();
}
if (seq < 4) msleep(800); /* pace like real ping */
}
puts("-- "); putu(got); puts("/4 received"); nl();
net_close(s);
}
|