Compare commits

..

2 commits

Author SHA1 Message Date
lohhiiccc
606069df82 chore: update LICENSE 2026-04-23 13:00:45 +02:00
lohhiiccc
4b4750cb59 feat: --preload option 2026-04-23 12:59:08 +02:00
11 changed files with 87 additions and 21 deletions

View file

@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
net-tools Copyright (C) 2026 lohhiiccc
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

View file

@ -109,6 +109,14 @@ enum {
OPT_ARG_NONE, \
"Set the Don't Fragment bit" \
) \
X( \
'l', \
"preload", \
required_argument, \
cli_handle_preload, \
OPT_ARG_UINT, \
"Send N packets in burst before normal loop" \
) \
X( \
'p', \
"pattern", \

View file

@ -6,6 +6,7 @@
extern const struct option_descriptor g_options[];
int cli_handle_count(const char *arg, void *config);
int cli_handle_preload(const char *arg, void *config);
int cli_handle_pattern(const char *arg, void *config);
int cli_handle_dont_fragment(const char *arg, void *config);
int cli_handle_deadline(const char *arg, void *config);

View file

@ -3,6 +3,7 @@
/* Default configuration values */
#define DEFAULT_COUNT 0
#define DEFAULT_PRELOAD 1
#define DEFAULT_INTERVAL 1.0
#define DEFAULT_TTL 64
#define DEFAULT_PACKET_SIZE 56

View file

@ -16,6 +16,7 @@ struct ping_config
/* Options */
uint64_t count;
uint64_t preload;
double interval;
uint8_t ttl;
size_t packet_size;

2
libcli

@ -1 +1 @@
Subproject commit ad6a542969dda29afe5431d0e674eca8d8794141
Subproject commit d39210fe74135e806adba7a6ea18696a901ba2d0

@ -1 +1 @@
Subproject commit a9bdaf33f22b60b8643871b2522721cd041ac885
Subproject commit e6693c97cc22b82adc3be85c72a5d5f655c69eb1

View file

@ -44,6 +44,7 @@ FORCE:
libping_core_la_SOURCES = \
cli/parse.c \
cli/handlers/handle_count.c \
cli/handlers/handle_preload.c \
cli/handlers/handle_pattern.c \
cli/handlers/handle_dont_fragment.c \
cli/handlers/handle_deadline.c \

View file

@ -0,0 +1,14 @@
#include "ping/cli.h"
#include "internal/cli/parse_utils.h"
int
cli_handle_preload(const char *arg, void *config_void)
{
struct ping_config *config = (struct ping_config *)config_void;
uint64_t preload;
if (0 != cli_parse_uint64(arg, &preload))
return CLI_ERROR;
config->preload = preload;
return CLI_SUCCESS;
}

View file

@ -31,6 +31,7 @@ init_config(struct ping_config *config)
{
memset(config, 0, sizeof(struct ping_config));
config->count = DEFAULT_COUNT;
config->preload = DEFAULT_PRELOAD;
config->interval = DEFAULT_INTERVAL;
config->ttl = DEFAULT_TTL;
config->packet_size = DEFAULT_PACKET_SIZE;

View file

@ -1,3 +1,4 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
@ -9,11 +10,13 @@
#include "internal/ping/loop.h"
/* Forward declarations */
static int ping_one(const struct ping_config *config,
struct destinations *dest, icmp_handle_t *handle);
static icmp_handle_t *ping_create_handle(const struct ping_config *config);
static int ping_one(const struct ping_config *config, struct destinations
*dest, icmp_handle_t *handle);
static void ping_init_state(struct ping_state *state, struct ping_stats *stats,
struct ping_tracker *tracker, const struct ping_config *config,
struct in_addr dest, icmp_handle_t *handle);
static int ping_preload(struct ping_state *state, size_t payload_len);
/* -------------------- */
int
@ -25,31 +28,41 @@ ping_run(const struct ping_config *config)
if (0 == config->nb_destinations)
return 1;
handle = icmp_create();
handle = ping_create_handle(config);
if (NULL == handle)
{
dprintf(STDERR_FILENO, "%s: requires CAP_NET_RAW or root privileges\n",
g_prog_name);
return 1;
}
if (HAS_FLAG(config->flags, FLAG_DONT_FRAGMENT)
&& 0 != icmp_set_dont_fragment(handle))
{
ret = 1;
goto cleanup;
}
while (i < config->nb_destinations)
{
if (0 != ping_one(config, &config->destinations[i], handle))
ret = 1;
i++;
}
cleanup:
icmp_destroy(handle);
return ret;
}
static icmp_handle_t *
ping_create_handle(const struct ping_config *config)
{
icmp_handle_t *handle;
handle = icmp_create();
if (NULL == handle)
{
dprintf(STDERR_FILENO, "%s: requires CAP_NET_RAW or root privileges\n",
g_prog_name);
return NULL;
}
if (HAS_FLAG(config->flags, FLAG_DONT_FRAGMENT)
&& 0 != icmp_set_dont_fragment(handle))
{
dprintf(STDERR_FILENO, "%s: %s\n", g_prog_name, icmp_strerror(handle));
icmp_destroy(handle);
return NULL;
}
return handle;
}
static int
ping_one(const struct ping_config *config, struct destinations *dest,
icmp_handle_t *handle)
@ -62,9 +75,14 @@ ping_one(const struct ping_config *config, struct destinations *dest,
ping_init_state(&state, &stats, &tracker, config, dest->ip, handle);
payload_len = config->packet_size;
if (0 != ping_scheduler_init(&state))
{
dprintf(STDERR_FILENO, "%s: sigaction: %s\n",
g_prog_name, strerror(errno));
return 1;
}
ping_output_start(config, dest, payload_len);
do_send(&state, payload_len);
if (0 != ping_preload(&state, payload_len))
return 1;
ping_loop(&state, payload_len);
ping_output_summary(&state, dest);
return tracker.nb_recv <= state.nb_errors;
@ -86,3 +104,24 @@ ping_init_state(struct ping_state *state, struct ping_stats *stats,
state->handle = handle;
icmp_get_time(&state->start_time);
}
static int
ping_preload(struct ping_state *state, size_t payload_len)
{
const struct ping_config *config = state->config;
uint64_t i = 0;
while (i < config->preload && (0 == config->count ||
state->tracker->nb_sent < config->count))
{
do_send(state, payload_len);
i++;
}
if (0 == config->preload && 0 != ping_scheduler_arm(config))
{
dprintf(STDERR_FILENO, "%s: setitimer: %s\n",
g_prog_name, strerror(errno));
return 1;
}
return 0;
}