diff --git a/includes/internal/cli/options.h b/includes/internal/cli/options.h index 83b5000..e3e68d6 100644 --- a/includes/internal/cli/options.h +++ b/includes/internal/cli/options.h @@ -9,6 +9,7 @@ enum { OPT_ARG_SECONDS = OPT_ARG_STRING + 1, OPT_ARG_BYTES, OPT_ARG_TTL, + OPT_ARG_PATTERN, }; #define PING_OPTIONS_LIST \ @@ -107,6 +108,14 @@ enum { cli_handle_dont_fragment, \ OPT_ARG_NONE, \ "Set the Don't Fragment bit" \ + ) \ + X( \ + 'p', \ + "pattern", \ + required_argument, \ + cli_handle_pattern, \ + OPT_ARG_PATTERN, \ + "Fill packet payload with hex pattern" \ ) #undef X diff --git a/includes/internal/cli/parse_utils.h b/includes/internal/cli/parse_utils.h index ab25ace..606dd3f 100644 --- a/includes/internal/cli/parse_utils.h +++ b/includes/internal/cli/parse_utils.h @@ -1,10 +1,13 @@ #ifndef CLI_INTERNAL_PARSE_UTILS #define CLI_INTERNAL_PARSE_UTILS +#include #include int cli_parse_uint64(const char *s, uint64_t *out); int cli_parse_float(const char *s, float *out); int cli_parse_ufloat(const char *s, float *out); +int cli_parse_hex(const char *str, uint8_t *out, size_t max_len, size_t + *out_len); #endif diff --git a/includes/internal/ping/cli_handlers.h b/includes/internal/ping/cli_handlers.h index c7a31b6..0e1d9c2 100644 --- a/includes/internal/ping/cli_handlers.h +++ b/includes/internal/ping/cli_handlers.h @@ -6,6 +6,7 @@ extern const struct option_descriptor g_options[]; int cli_handle_count(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); int cli_handle_flood(const char *arg, void *config); diff --git a/includes/ping/ping.h b/includes/ping/ping.h index 0fc6580..3c9ade6 100644 --- a/includes/ping/ping.h +++ b/includes/ping/ping.h @@ -22,6 +22,10 @@ struct ping_config double timeout; double deadline; + /* Pattern (-p) */ + uint8_t pattern[16]; + uint8_t pattern_len; + /* Flags */ uint8_t flags; }; diff --git a/libcli b/libcli index ae7fdf2..ad6a542 160000 --- a/libcli +++ b/libcli @@ -1 +1 @@ -Subproject commit ae7fdf2f94a7c3c759d449ee1c4d3439473c6e42 +Subproject commit ad6a542969dda29afe5431d0e674eca8d8794141 diff --git a/src/ping/Makefile.am b/src/ping/Makefile.am index 0d954f6..a856257 100644 --- a/src/ping/Makefile.am +++ b/src/ping/Makefile.am @@ -44,6 +44,7 @@ FORCE: libping_core_la_SOURCES = \ cli/parse.c \ cli/handlers/handle_count.c \ + cli/handlers/handle_pattern.c \ cli/handlers/handle_dont_fragment.c \ cli/handlers/handle_deadline.c \ cli/handlers/handle_flood.c \ diff --git a/src/ping/cli/handlers/handle_pattern.c b/src/ping/cli/handlers/handle_pattern.c new file mode 100644 index 0000000..46b475b --- /dev/null +++ b/src/ping/cli/handlers/handle_pattern.c @@ -0,0 +1,14 @@ +#include "ping/cli.h" +#include "internal/cli/parse_utils.h" + +int +cli_handle_pattern(const char *arg, void *config_void) +{ + struct ping_config *config = (struct ping_config *)config_void; + size_t pattern_len; + + if (0 != cli_parse_hex(arg, config->pattern, 16, &pattern_len)) + return CLI_ERROR; + config->pattern_len = (uint8_t)pattern_len; + return CLI_SUCCESS; +} diff --git a/src/ping/cli/messages/help.c b/src/ping/cli/messages/help.c index 548bd0f..a5fd05a 100644 --- a/src/ping/cli/messages/help.c +++ b/src/ping/cli/messages/help.c @@ -39,6 +39,7 @@ option_arg_type_to_str(int type) case OPT_ARG_SECONDS: return ""; case OPT_ARG_BYTES: return ""; case OPT_ARG_TTL: return ""; + case OPT_ARG_PATTERN: return ""; case OPT_ARG_STRING: return ""; default: return ""; } diff --git a/src/ping/core/send.c b/src/ping/core/send.c index b5cac1a..3aeb7d0 100644 --- a/src/ping/core/send.c +++ b/src/ping/core/send.c @@ -12,7 +12,8 @@ #include "ping/ft_ping_flags.h" /* Forward declarations */ -static inline void fill_payload(uint8_t *payload, size_t payload_len); +static inline void fill_payload(uint8_t *payload, size_t len, const struct + ping_config *config); static int ping_send_one(struct ping_state *state, uint16_t seq, const uint8_t *payload, size_t payload_len, struct timespec *ts); /* -------------------- */ @@ -25,7 +26,7 @@ do_send(struct ping_state *state, size_t payload_len) int ret; state->send_flag = 0; - fill_payload(payload, payload_len); + fill_payload(payload, payload_len, state->config); ret = ping_send_one(state, state->seq, payload, payload_len, &ts); if (-1 == ret) dprintf(STDERR_FILENO, "%s: %s\n", @@ -68,8 +69,16 @@ ping_send_one(struct ping_state *state, uint16_t seq, } static inline void -fill_payload(uint8_t *payload, size_t payload_len) +fill_payload(uint8_t *payload, size_t len, const struct ping_config *config) { - for (size_t i = 0; i < payload_len; ++i) - payload[i] = (uint8_t)('a' + (i % 26)); + if (0 == config->pattern_len) + { + for (size_t i = 0; i < len; ++i) + payload[i] = (uint8_t)('a' + (i % 26)); + } + else + { + for (size_t i = 0; i < len; ++i) + payload[i] = config->pattern[i % config->pattern_len]; + } }