Files
my-os-project2/kernel/picotcp/test/examples/ping.c
2025-10-29 14:29:06 +01:00

139 lines
3.6 KiB
C

#include "utils.h"
#include <pico_ipv4.h>
#include <pico_ipv6.h>
#include <pico_icmp4.h>
#include <pico_icmp6.h>
/*** START PING ***/
#ifdef PICO_SUPPORT_PING
#define NUM_PING 10
void cb_ping(struct pico_icmp4_stats *s)
{
char host[30];
pico_ipv4_to_string(host, s->dst.addr);
if (s->err == 0) {
dbg("%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu ms\n", s->size, host, s->seq,
s->ttl, (long unsigned int)s->time);
if (s->seq >= NUM_PING)
exit(0);
} else {
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
exit(1);
}
}
#ifdef PICO_SUPPORT_IPV6
void cb_ping6(struct pico_icmp6_stats *s)
{
char host[50];
pico_ipv6_to_string(host, s->dst.addr);
if (s->err == 0) {
dbg("%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu ms\n", s->size, host, s->seq,
s->ttl, (long unsigned int)s->time);
if (s->seq >= NUM_PING)
exit(0);
} else {
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
exit(1);
}
}
#endif
void ping_abort_timer(pico_time now, void *_id)
{
int *id = (int *) _id;
printf("Ping: aborting...\n");
if (!IPV6_MODE)
pico_icmp4_ping_abort(*id);
#ifdef PICO_SUPPORT_IPV6
else
pico_icmp6_ping_abort(*id);
#endif
}
void app_ping(char *arg)
{
char *dest = NULL;
char *next = NULL;
char *abort = NULL;
char *delay = NULL;
char *asize = NULL;
int initial_delay = 0;
struct pico_ip6 dst;
static int id;
int timeout = 0;
int size = 64;
next = cpy_arg(&dest, arg);
if (!dest) {
fprintf(stderr, "ping needs the following format: ping:dst_addr:[size:[abort after N sec:[wait N sec before start]]]\n");
exit(255);
}
pico_string_to_ipv6(dest, dst.addr);
if (next) {
next = cpy_arg(&asize, next);
size = atoi(asize);
free(asize);
if (size <= 0) {
size = 64; /* Default */
}
}
if (next) {
next = cpy_arg(&abort, next);
if (strlen(abort) > 0) {
printf("Got arg: '%s'\n", abort);
timeout = atoi(abort);
if (timeout < 0) {
fprintf(stderr, "ping needs the following format: ping:dst_addr:[size:[abort after N sec:[wait N sec before start]]]\n");
exit(255);
}
printf("Aborting ping after %d seconds\n", timeout);
}
}
if (next) {
next = cpy_arg(&delay, next);
if (strlen(delay) > 0) {
initial_delay = atoi(delay);
if (initial_delay > 0) {
printf("Initial delay: %d seconds\n", initial_delay);
initial_delay = PICO_TIME_MS() + initial_delay * 1000;
while (PICO_TIME_MS() < initial_delay) {
pico_stack_tick();
usleep(10000);
}
}
}
free(delay);
}
printf("Starting ping.\n");
if (!IPV6_MODE)
id = pico_icmp4_ping(dest, NUM_PING, 1000, 10000, size, cb_ping);
#ifdef PICO_SUPPORT_IPV6
else
id = pico_icmp6_ping(dest, NUM_PING, 1000, 10000, size, cb_ping6, pico_ipv6_source_dev_find(&dst));
#endif
if (timeout > 0) {
printf("Adding abort timer after %d seconds for id %d\n", timeout, id);
if (!pico_timer_add(timeout * 1000, ping_abort_timer, &id)) {
printf("Failed to set ping abort timeout, aborting ping\n");
ping_abort_timer((pico_time)0, &id);
exit(1);
}
}
/* free copied args */
if (dest)
free(dest);
if (abort)
free(abort);
}
#endif
/*** END PING ***/