🏗️」 wip: wtf is this

This commit is contained in:
2025-08-15 18:11:48 +02:00
parent f71753ffa8
commit 4c6fc1ecb1
11 changed files with 243 additions and 31 deletions

View File

@ -1,15 +1,27 @@
#pragma once
#include <stdint.h>
typedef struct {
struct options{
char *name;
char opt;
char *doc;
uint8_t arg_nb;
uint8_t grp;
} options_t;
};
static options_t options[] = {
typedef enum {
USAGE,
HELP,
VERSION,
VERBOSE,
COUNT,
SIZE,
TIMEOUT,
LINGER,
INTERVAL
} options_nb_t;
static struct options options[] = {
#define GRP 0 // AKA random useless sh*t
{"usage", 'u', "give a short usage message", 0, GRP},
{"help", '?', "give this help list", 0, GRP},
@ -22,12 +34,12 @@ static options_t options[] = {
{"count", 'c', "stop after sending NUMBER packets", 1, GRP},
{"size", 's', "send NUMBER data octets", 1, GRP},
{"timeout", 'w', "stop after N seconds", 1, GRP},
{"ttl", 't', "specify N as time-to-live", 1, GRP},
{"linger", 'W', "number of seconds to wait for response", 1, GRP},
{"interval", 'i', "wait NUMBER seconds between sending each packet", 1, GRP}
#undef GRP
};
#define OPT_NB 9
#define OPT_NB 10
#define FT_PING_V "0.1"

View File

@ -1,20 +1,32 @@
#pragma once
#include "bits/types/struct_timeval.h"
#include "help.h"
#include "opt_parse.h"
#include <stdbool.h>
#include <stdint.h>
extern char *exec_name;
extern char *exec_name;
extern int tx_count;
extern int rx_count;
extern char *address;
extern double *times;
typedef struct {
bool verbose;
int count;
int size;
int timeout;
int ttl;
int interval;
} ping_t;
bool verbose;
uint32_t count;
uint16_t size;
uint16_t timeout;
uint16_t linger;
uint16_t interval;
} options_t;
#define DEFAULT_COUNT -1
#define DEFAULT_VERBOSE false
#define DEFAULT_SIZE 0
#define DEFAULT_INTERVAL 0
#define DEFAULT_TIMEOUT 0
#define DEFAULT_SIZE 64
#define DEFAULT_INTERVAL 1
#define DEFAULT_TIMEOUT -1
#define DEFAULT_COUNT -1
#define DEFAULT_LINGER 10
int send_ping(args_t *args);

3
includes/utils.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void append_time(double time);

View File

@ -6,18 +6,21 @@
#include <stdio.h>
#include <stdlib.h>
char *exec_name;
char *exec_name;
double *times = NULL;
int rx_count = 0;
int tx_count = 0;
void init_args_t(args_t *args) {
OPT_WHILE {
args->opts[i] = false;
args->arg[i] = 0;
args->arg[i] = -1;
i++;
}
args->hosts = NULL;
}
int handle_options(args_t *args, char **av) {
int handle_options(args_t *args) {
if (args->opts[1]) {
print_help();
return EXIT_SUCCESS;
@ -37,8 +40,11 @@ int handle_options(args_t *args, char **av) {
int main(int ac, char **av) {
exec_name = *av;
args_t args;
init_args_t(&args);
if (ac > 1) {
int ret = opt_parse(av, &args);
if (ret == -1) {
@ -48,7 +54,7 @@ int main(int ac, char **av) {
free(args.hosts);
return ret;
} else {
ret = handle_options(&args, av);
ret = handle_options(&args);
free(args.hosts);
return ret;
}

View File

@ -57,20 +57,22 @@ void print_help(void) {
void print_parse_err(error_t err, char *opt) {
switch (err) {
case MISSING_HOST:
printf("%s: missing host operand\n", exec_name);
fprintf(stderr, "%s: missing host operand\n", exec_name);
break;
case INVALID_OPT:
printf("%s: invalid option -- %s\n", exec_name, opt);
fprintf(stderr, "%s: invalid option -- %s\n", exec_name, opt);
break;
case NEED_ARG:
printf("%s: option '%s' requires an argument\n", exec_name, opt);
fprintf(stderr, "%s: option '%s' requires an argument\n", exec_name,
opt);
break;
case ERR_ARG:
printf("%s: option '%s' invalid argument \n", exec_name, opt);
fprintf(stderr, "%s: option '%s' invalid argument \n", exec_name, opt);
break;
}
printf("Try 'ping --help' or 'ping --usage' for more information.\n");
fprintf(stderr,
"Try 'ping --help' or 'ping --usage' for more information.\n");
}
void print_usage(void) {

67
src/ping/init_ping.c Normal file
View File

@ -0,0 +1,67 @@
#include "help.h"
#include "opt_parse.h"
#include <ping.h>
#include <bits/types/struct_timeval.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
struct icmp test;
int init_socket(args_t *args) {
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0) {
fprintf(stderr,
"%s: can't create socket maybe try in root next time :D",
exec_name);
return -1;
}
struct linger linger;
linger.l_linger =
args->arg[LINGER] == -1 ? DEFAULT_TIMEOUT : args->arg[LINGER];
linger.l_onoff = true;
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) < 0) {
fprintf(stderr,
"can't setsockopt for the linger maybe try a different one");
return -1;
}
return sock;
}
unsigned short gen_checksum(unsigned short *addr, int count) {
unsigned long sum = 0;
while (count > 1) {
sum += *addr++;
count -= 2;
}
if (count > 0) {
sum += *(unsigned char *)addr;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return (~sum);
}
void init_packet(char *buf, int seq, uint32_t size) {
memset(buf, 0, size);
struct icmp *packet = (struct icmp *)buf;
packet->icmp_type = ICMP_ECHO;
packet->icmp_code = 0;
packet->icmp_id = getpid() & 0xFFFF;
packet->icmp_seq = seq;
memset(buf + sizeof(struct icmphdr), 0x42, size - sizeof(struct icmphdr));
packet->icmp_cksum = 0;
packet->icmp_cksum = gen_checksum((unsigned short *)packet, size);
}

54
src/ping/send_icmp.c Normal file
View File

@ -0,0 +1,54 @@
#include <utils.h>
#include <opt_parse.h>
#include <ping.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int send_icmp(int socket, char *buf, struct sockaddr_in *addr, uint32_t size) {
int bytes_send = sendto(socket, buf, (unsigned long)size, 0,
(struct sockaddr *)addr, sizeof(*addr));
if (bytes_send < 0) {
fprintf(stderr, "sendto failed can't send packet");
return -1;
}
return bytes_send;
}
int receive_icmp(int socket, char *buf, uint32_t size,
struct sockaddr_in *addr) {
socklen_t addr_len = sizeof(*addr);
int bytes =
recvfrom(socket, buf, size, 0, (struct sockaddr *)addr, &addr_len);
return bytes;
}
void process_icmp(char *buf, int bytes, struct sockaddr_in *addr, int seq,
struct timeval *tv_start, struct timeval *tv_end) {
struct ip *ip = (struct ip *)buf;
int len = ip->ip_hl << 2;
struct icmp *icmp = (struct icmp *)(buf + len);
if (icmp->icmp_type == ICMP_ECHOREPLY &&
icmp->icmp_type == (getpid() & 0xFFFF)) {
rx_count++;
double rtt = (tv_end->tv_sec - tv_start->tv_sec) / 1000.0 +
(tv_end->tv_usec - tv_start->tv_usec) * 1000.0;
append_time(rtt);
printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f", bytes - len,
inet_ntoa(addr->sin_addr), icmp->icmp_seq, ip->ip_ttl, rtt);
}
}

47
src/ping/send_ping.c Normal file
View File

@ -0,0 +1,47 @@
#include "help.h"
#include <opt_parse.h>
#include <ping.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
void sigint(int sig) {
printf("--- %s ping statistics ---", address);
printf("%d packets transmitted, %d packets received, %f%% packet loss",
tx_count, rx_count, (tx_count - rx_count / 2.0) * 100);
printf("round-trip min/avg/max/stddev = %d/%d/%d/%d");
}
options_t init_opt(args_t *args) {
options_t opt;
opt.verbose = args->opts[VERBOSE] != false ? true : DEFAULT_VERBOSE;
opt.count = args->arg[COUNT] != -1 ? args->arg[COUNT] : DEFAULT_COUNT;
opt.size = args->arg[SIZE] != -1 ? args->arg[SIZE] : DEFAULT_SIZE;
opt.timeout =
args->arg[TIMEOUT] != -1 ? args->arg[TIMEOUT] : DEFAULT_TIMEOUT;
opt.interval =
args->arg[INTERVAL] != -1 ? args->arg[INTERVAL] : DEFAULT_INTERVAL;
opt.linger = args->arg[LINGER] != -1 ? args->arg[LINGER] : DEFAULT_LINGER;
return opt;
}
int send_ping(args_t *args) {
options_t opt = init_opt(args);
struct timeval loop_start;
struct timeval loop_end;
gettimeofday(&loop_start, 0);
while () {
}
return EXIT_SUCCESS;
}

View File

@ -1,5 +0,0 @@
#include <opt_parse.h>
int send_ping(args_t *args) {
}

14
src/utils.c Normal file
View File

@ -0,0 +1,14 @@
#include <ping.h>
#include <unistd.h>
#include <stdlib.h>
void append_time(double time) {
if (times == NULL) {
times = malloc(sizeof(double));
times[0] = time;
} else {
times = reallocarray(times, rx_count, sizeof(double));
times[rx_count - 1] = time;
}
}