feat: traceroute skel
This commit is contained in:
parent
25ee8ad4c6
commit
3717e01ab9
24 changed files with 469 additions and 1 deletions
|
|
@ -60,6 +60,7 @@ AC_CONFIG_FILES([
|
|||
Makefile
|
||||
src/Makefile
|
||||
src/ping/Makefile
|
||||
src/traceroute/Makefile
|
||||
tests/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
|
|
|||
14
includes/internal/traceroute/cli_handlers.h
Normal file
14
includes/internal/traceroute/cli_handlers.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef TRACEROUTE_CLI_HANDLERS_H
|
||||
#define TRACEROUTE_CLI_HANDLERS_H
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
extern const struct option_descriptor g_options[];
|
||||
|
||||
int cli_handle_help(const char *arg, void *config);
|
||||
int cli_handle_version(const char *arg, void *config);
|
||||
int cli_handle_verbose(const char *arg, void *config);
|
||||
int cli_handle_max_ttl(const char *arg, void *config);
|
||||
int cli_handle_waittime(const char *arg, void *config);
|
||||
|
||||
#endif
|
||||
65
includes/internal/traceroute/options.h
Normal file
65
includes/internal/traceroute/options.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef TRACEROUTE_CLI_OPT_H
|
||||
#define TRACEROUTE_CLI_OPT_H
|
||||
|
||||
#include <getopt.h>
|
||||
#include "cli.h"
|
||||
|
||||
enum {
|
||||
OPT_TR_ARG_HOPS = OPT_ARG_STRING + 1,
|
||||
OPT_TR_ARG_SECONDS,
|
||||
};
|
||||
|
||||
#define TRACEROUTE_OPTIONS_LIST \
|
||||
X( \
|
||||
'h', \
|
||||
"help", \
|
||||
no_argument, \
|
||||
cli_handle_help, \
|
||||
OPT_ARG_NONE, \
|
||||
"Display this help and exit" \
|
||||
) \
|
||||
X( \
|
||||
'V', \
|
||||
"version", \
|
||||
no_argument, \
|
||||
cli_handle_version, \
|
||||
OPT_ARG_NONE, \
|
||||
"Display version information and exit" \
|
||||
) \
|
||||
X( \
|
||||
'v', \
|
||||
"verbose", \
|
||||
no_argument, \
|
||||
cli_handle_verbose, \
|
||||
OPT_ARG_NONE, \
|
||||
"Verbose output" \
|
||||
) \
|
||||
X( \
|
||||
'm', \
|
||||
"max-ttl", \
|
||||
required_argument, \
|
||||
cli_handle_max_ttl, \
|
||||
OPT_TR_ARG_HOPS, \
|
||||
"Set the max number of hops" \
|
||||
) \
|
||||
X( \
|
||||
'w', \
|
||||
"waittime", \
|
||||
required_argument, \
|
||||
cli_handle_waittime, \
|
||||
OPT_TR_ARG_SECONDS, \
|
||||
"Set the time to wait for a response" \
|
||||
)
|
||||
|
||||
#undef X
|
||||
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) + 1
|
||||
enum { TR_OPT_LEN = (0 TRACEROUTE_OPTIONS_LIST) };
|
||||
|
||||
#undef X
|
||||
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
|
||||
+ (1 * (has_arg == no_argument) \
|
||||
+ (2 * (has_arg == required_argument) \
|
||||
+ (3 * (has_arg == optional_argument))))
|
||||
enum { TR_OPTSTR_LEN = (2 TRACEROUTE_OPTIONS_LIST) };
|
||||
|
||||
#endif
|
||||
9
includes/internal/traceroute/parse_utils.h
Normal file
9
includes/internal/traceroute/parse_utils.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef TRACEROUTE_CLI_PARSE_UTILS_H
|
||||
#define TRACEROUTE_CLI_PARSE_UTILS_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "traceroute/traceroute.h"
|
||||
|
||||
int cli_parse_destination(const char *s, struct traceroute_config *config);
|
||||
|
||||
#endif
|
||||
11
includes/traceroute/cli.h
Normal file
11
includes/traceroute/cli.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef TRACEROUTE_CLI_H
|
||||
#define TRACEROUTE_CLI_H
|
||||
|
||||
#include <cli.h>
|
||||
#include "traceroute/traceroute.h"
|
||||
|
||||
enum cli_code cli_parse_arguments(int argc, char **argv, struct
|
||||
traceroute_config *config);
|
||||
void cli_config_free(struct traceroute_config *config);
|
||||
|
||||
#endif
|
||||
11
includes/traceroute/ft_traceroute_const.h
Normal file
11
includes/traceroute/ft_traceroute_const.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef FT_TRACEROUTE_CONST_H
|
||||
#define FT_TRACEROUTE_CONST_H
|
||||
|
||||
#define DEFAULT_MAX_TTL 30
|
||||
#define DEFAULT_NQUERIES 3
|
||||
#define DEFAULT_WAITTIME 5.0
|
||||
|
||||
#define MAX_TRACEROUTE_TTL 255
|
||||
#define MAX_NQUERIES 10
|
||||
|
||||
#endif
|
||||
10
includes/traceroute/ft_traceroute_flags.h
Normal file
10
includes/traceroute/ft_traceroute_flags.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef FT_TRACEROUTE_FLAGS_H
|
||||
#define FT_TRACEROUTE_FLAGS_H
|
||||
|
||||
#define FLAG_TR_VERBOSE (1 << 0)
|
||||
#define FLAG_TR_NO_DNS (1 << 1)
|
||||
|
||||
#define HAS_FLAG(flags, flag) ((flags) & (flag))
|
||||
#define SET_FLAG(flags, flag) ((flags) |= (flag))
|
||||
|
||||
#endif
|
||||
18
includes/traceroute/traceroute.h
Normal file
18
includes/traceroute/traceroute.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef TRACEROUTE_H
|
||||
#define TRACEROUTE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct traceroute_config {
|
||||
const char *destination;
|
||||
struct in_addr dest_ip;
|
||||
uint8_t max_ttl;
|
||||
uint8_t nqueries;
|
||||
double waittime;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
int traceroute_run(const struct traceroute_config *config);
|
||||
|
||||
#endif
|
||||
|
|
@ -1 +1 @@
|
|||
SUBDIRS = ping
|
||||
SUBDIRS = ping traceroute
|
||||
|
|
|
|||
54
src/traceroute/Makefile.am
Normal file
54
src/traceroute/Makefile.am
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
bin_PROGRAMS = ft_traceroute
|
||||
noinst_LTLIBRARIES = libtraceroute_core.la
|
||||
|
||||
TRACEROUTE_VERSION = 0.0.1
|
||||
VERSION_HEADER = $(top_srcdir)/includes/version_gen.h
|
||||
|
||||
BUILT_SOURCES = $(VERSION_HEADER)
|
||||
|
||||
libtraceroute_core_la_SOURCES = \
|
||||
cli/parse.c \
|
||||
cli/config_free.c \
|
||||
cli/handlers/option_map.c \
|
||||
cli/handlers/handle_help.c \
|
||||
cli/handlers/handle_version.c \
|
||||
cli/handlers/handle_verbose.c \
|
||||
cli/handlers/handle_max_ttl.c \
|
||||
cli/handlers/handle_waittime.c \
|
||||
cli/messages/help.c \
|
||||
cli/messages/version.c \
|
||||
cli/messages/error.c \
|
||||
cli/parse_utils/parse_destination.c \
|
||||
core/traceroute.c
|
||||
|
||||
BASE_CFLAGS = -std=c99 $(STRICT_CFLAGS)
|
||||
|
||||
if ENABLE_DEBUG
|
||||
EXTRA_CFLAGS = -g -O0
|
||||
else
|
||||
EXTRA_CFLAGS =
|
||||
endif
|
||||
|
||||
if ENABLE_SANITIZERS
|
||||
SANITIZER_FLAGS = -fsanitize=address,undefined
|
||||
else
|
||||
SANITIZER_FLAGS =
|
||||
endif
|
||||
|
||||
TRACEROUTE_CPPFLAGS = \
|
||||
-I $(top_srcdir)/includes \
|
||||
-I $(top_srcdir)/libcli/include \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
TRACEROUTE_CFLAGS = $(BASE_CFLAGS) $(EXTRA_CFLAGS) $(SANITIZER_FLAGS)
|
||||
|
||||
libtraceroute_core_la_CPPFLAGS = $(TRACEROUTE_CPPFLAGS)
|
||||
libtraceroute_core_la_CFLAGS = $(TRACEROUTE_CFLAGS)
|
||||
|
||||
ft_traceroute_SOURCES = main.c
|
||||
ft_traceroute_CPPFLAGS = $(TRACEROUTE_CPPFLAGS)
|
||||
ft_traceroute_CFLAGS = $(TRACEROUTE_CFLAGS)
|
||||
ft_traceroute_LDFLAGS = $(SANITIZER_FLAGS)
|
||||
ft_traceroute_LDADD = \
|
||||
libtraceroute_core.la \
|
||||
$(top_builddir)/libcli/src/libcli.la
|
||||
7
src/traceroute/cli/config_free.c
Normal file
7
src/traceroute/cli/config_free.c
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "traceroute/cli.h"
|
||||
|
||||
void
|
||||
cli_config_free(struct traceroute_config *config)
|
||||
{
|
||||
config->destination = NULL;
|
||||
}
|
||||
14
src/traceroute/cli/handlers/handle_help.c
Normal file
14
src/traceroute/cli/handlers/handle_help.c
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "compiler.h"
|
||||
#include "traceroute/cli.h"
|
||||
#include "internal/traceroute/cli_handlers.h"
|
||||
|
||||
/* Forward declaration */
|
||||
void print_help(void);
|
||||
/* ------------------- */
|
||||
|
||||
int
|
||||
cli_handle_help(__unused const char *arg, __unused void *config)
|
||||
{
|
||||
print_help();
|
||||
return CLI_EXIT_SUCCESS;
|
||||
}
|
||||
15
src/traceroute/cli/handlers/handle_max_ttl.c
Normal file
15
src/traceroute/cli/handlers/handle_max_ttl.c
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "traceroute/cli.h"
|
||||
#include "traceroute/ft_traceroute_const.h"
|
||||
#include "internal/cli/parse_utils.h"
|
||||
|
||||
int
|
||||
cli_handle_max_ttl(const char *arg, void *config_void)
|
||||
{
|
||||
struct traceroute_config *config = (struct traceroute_config *)config_void;
|
||||
uint64_t val;
|
||||
|
||||
if (0 != cli_parse_uint64(arg, &val) || 0 == val || val > MAX_TRACEROUTE_TTL)
|
||||
return CLI_ERROR;
|
||||
config->max_ttl = (uint8_t)val;
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
11
src/traceroute/cli/handlers/handle_verbose.c
Normal file
11
src/traceroute/cli/handlers/handle_verbose.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "compiler.h"
|
||||
#include "traceroute/cli.h"
|
||||
#include "traceroute/ft_traceroute_flags.h"
|
||||
|
||||
int
|
||||
cli_handle_verbose(__unused const char *arg, void *config_void)
|
||||
{
|
||||
struct traceroute_config *config = (struct traceroute_config *)config_void;
|
||||
SET_FLAG(config->flags, FLAG_TR_VERBOSE);
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
13
src/traceroute/cli/handlers/handle_version.c
Normal file
13
src/traceroute/cli/handlers/handle_version.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "compiler.h"
|
||||
#include "traceroute/cli.h"
|
||||
|
||||
/* Forward declaration */
|
||||
void print_version(void);
|
||||
/* ------------------- */
|
||||
|
||||
int
|
||||
cli_handle_version(__unused const char *arg, __unused void *config)
|
||||
{
|
||||
print_version();
|
||||
return CLI_EXIT_SUCCESS;
|
||||
}
|
||||
14
src/traceroute/cli/handlers/handle_waittime.c
Normal file
14
src/traceroute/cli/handlers/handle_waittime.c
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "traceroute/cli.h"
|
||||
#include "internal/cli/parse_utils.h"
|
||||
|
||||
int
|
||||
cli_handle_waittime(const char *arg, void *config_void)
|
||||
{
|
||||
struct traceroute_config *config = (struct traceroute_config *)config_void;
|
||||
float val;
|
||||
|
||||
if (0 != cli_parse_ufloat(arg, &val) || val <= 0.0f)
|
||||
return CLI_ERROR;
|
||||
config->waittime = (double)val;
|
||||
return CLI_SUCCESS;
|
||||
}
|
||||
13
src/traceroute/cli/handlers/option_map.c
Normal file
13
src/traceroute/cli/handlers/option_map.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "internal/traceroute/cli_handlers.h"
|
||||
#include "internal/traceroute/options.h"
|
||||
|
||||
#undef X
|
||||
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
|
||||
{ short_opt, long_opt, has_arg, handler, arg_type, desc },
|
||||
|
||||
const struct option_descriptor g_options[] = {
|
||||
TRACEROUTE_OPTIONS_LIST
|
||||
{0, NULL, 0, NULL, OPT_ARG_NONE, NULL}
|
||||
};
|
||||
|
||||
#undef X
|
||||
32
src/traceroute/cli/messages/error.c
Normal file
32
src/traceroute/cli/messages/error.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "traceroute/cli.h"
|
||||
#include "version_gen.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static inline void print_suggest_help(void);
|
||||
/* ------------------- */
|
||||
|
||||
enum cli_code
|
||||
error_missing_dest(void)
|
||||
{
|
||||
dprintf(STDERR_FILENO, "%s: usage error: Destination address required\n",
|
||||
g_prog_name);
|
||||
print_suggest_help();
|
||||
return CLI_ERROR;
|
||||
}
|
||||
|
||||
enum cli_code
|
||||
error_invalid_dest(void)
|
||||
{
|
||||
dprintf(STDERR_FILENO, "%s: unknown host\n", g_prog_name);
|
||||
return CLI_ERROR;
|
||||
}
|
||||
|
||||
static inline void
|
||||
print_suggest_help(void)
|
||||
{
|
||||
dprintf(STDERR_FILENO, "Try '%s --help' for more information.\n",
|
||||
g_prog_name);
|
||||
}
|
||||
40
src/traceroute/cli/messages/help.c
Normal file
40
src/traceroute/cli/messages/help.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "internal/traceroute/cli_handlers.h"
|
||||
#include "internal/traceroute/options.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static inline const char *option_arg_type_to_str(int type);
|
||||
/* ------------------- */
|
||||
|
||||
void
|
||||
print_help(void)
|
||||
{
|
||||
printf("ft_traceroute - Trace the route to a network host\n");
|
||||
printf("Usage: ft_traceroute [options] <destination>\n\n");
|
||||
printf("Options:\n");
|
||||
|
||||
for (size_t i = 0; i < TR_OPT_LEN; ++i)
|
||||
{
|
||||
const struct option_descriptor *opt = &g_options[i];
|
||||
const char *argstr = option_arg_type_to_str(opt->arg_type);
|
||||
|
||||
printf(" -%c, --%-10s %-8s %s\n",
|
||||
opt->short_opt,
|
||||
opt->long_opt,
|
||||
argstr[0] ? argstr : "",
|
||||
opt->description);
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
option_arg_type_to_str(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OPT_ARG_NONE: return "";
|
||||
case OPT_TR_ARG_HOPS: return "<HOPS>";
|
||||
case OPT_TR_ARG_SECONDS: return "<SEC>";
|
||||
default: return "<ARG>";
|
||||
}
|
||||
}
|
||||
19
src/traceroute/cli/messages/version.c
Normal file
19
src/traceroute/cli/messages/version.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "version_gen.h"
|
||||
|
||||
void
|
||||
print_version(void)
|
||||
{
|
||||
printf("%s version %s\n", g_prog_name, PING_VERSION);
|
||||
printf("Copyright (C) 2026 lohhiicccc\n");
|
||||
printf("License GPLv3+:");
|
||||
printf("GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\n");
|
||||
printf("This is free software: ");
|
||||
printf("you are free to change and redistribute it.\n");
|
||||
printf("There is NO WARRANTY, to the extent permitted by law.\n");
|
||||
printf("\n");
|
||||
#if PING_HAS_GIT_COMMIT
|
||||
printf("Build: %s (commit %s)\n", PING_BUILD_DATE, PING_GIT_COMMIT);
|
||||
#endif
|
||||
}
|
||||
39
src/traceroute/cli/parse.c
Normal file
39
src/traceroute/cli/parse.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "traceroute/cli.h"
|
||||
#include "traceroute/ft_traceroute_const.h"
|
||||
#include "internal/traceroute/cli_handlers.h"
|
||||
#include "internal/traceroute/parse_utils.h"
|
||||
#include "internal/traceroute/options.h"
|
||||
#include "internal/cli/messages.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static void init_config(struct traceroute_config *config);
|
||||
/* ------------------- */
|
||||
|
||||
enum cli_code
|
||||
cli_parse_arguments(int argc, char **argv, struct traceroute_config *config)
|
||||
{
|
||||
char opt_str[TR_OPTSTR_LEN];
|
||||
struct option long_opts[TR_OPT_LEN + 1];
|
||||
enum cli_code ret;
|
||||
|
||||
init_config(config);
|
||||
ret = cli_parse(argc, argv, config, g_options, TR_OPT_LEN,
|
||||
opt_str, long_opts);
|
||||
if (CLI_SUCCESS != ret)
|
||||
return ret;
|
||||
if (optind >= argc)
|
||||
return error_missing_dest();
|
||||
return cli_parse_destination(argv[optind], config);
|
||||
}
|
||||
|
||||
static void
|
||||
init_config(struct traceroute_config *config)
|
||||
{
|
||||
memset(config, 0, sizeof(struct traceroute_config));
|
||||
config->max_ttl = DEFAULT_MAX_TTL;
|
||||
config->nqueries = DEFAULT_NQUERIES;
|
||||
config->waittime = DEFAULT_WAITTIME;
|
||||
}
|
||||
25
src/traceroute/cli/parse_utils/parse_destination.c
Normal file
25
src/traceroute/cli/parse_utils/parse_destination.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "traceroute/traceroute.h"
|
||||
#include "internal/traceroute/parse_utils.h"
|
||||
#include "internal/cli/messages.h"
|
||||
|
||||
int
|
||||
cli_parse_destination(const char *s, struct traceroute_config *config)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
bzero(&hints, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (0 != getaddrinfo(s, NULL, &hints, &res))
|
||||
return error_invalid_dest();
|
||||
memcpy(&sin, res->ai_addr, sizeof(sin));
|
||||
freeaddrinfo(res);
|
||||
config->dest_ip = sin.sin_addr;
|
||||
config->destination = s;
|
||||
return 0;
|
||||
}
|
||||
8
src/traceroute/core/traceroute.c
Normal file
8
src/traceroute/core/traceroute.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "compiler.h"
|
||||
#include "traceroute/traceroute.h"
|
||||
|
||||
int
|
||||
traceroute_run(__unused const struct traceroute_config *config)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
25
src/traceroute/main.c
Normal file
25
src/traceroute/main.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "traceroute/cli.h"
|
||||
#include "version_gen.h"
|
||||
|
||||
char *g_prog_name = NULL;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct traceroute_config config = {0};
|
||||
int ret = CLI_ERROR;
|
||||
|
||||
g_prog_name = argv[0];
|
||||
cli_set_prog_name(g_prog_name);
|
||||
ret = cli_parse_arguments(argc, argv, &config);
|
||||
if (ret != CLI_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
ret = traceroute_run(&config);
|
||||
|
||||
cleanup:
|
||||
cli_config_free(&config);
|
||||
return (ret == CLI_ERROR) ? 2 : EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue