「🏗️」 wip: wtf is this
This commit is contained in:
@ -1,15 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef struct {
|
struct options{
|
||||||
char *name;
|
char *name;
|
||||||
char opt;
|
char opt;
|
||||||
char *doc;
|
char *doc;
|
||||||
uint8_t arg_nb;
|
uint8_t arg_nb;
|
||||||
uint8_t grp;
|
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
|
#define GRP 0 // AKA random useless sh*t
|
||||||
{"usage", 'u', "give a short usage message", 0, GRP},
|
{"usage", 'u', "give a short usage message", 0, GRP},
|
||||||
{"help", '?', "give this help list", 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},
|
{"count", 'c', "stop after sending NUMBER packets", 1, GRP},
|
||||||
{"size", 's', "send NUMBER data octets", 1, GRP},
|
{"size", 's', "send NUMBER data octets", 1, GRP},
|
||||||
{"timeout", 'w', "stop after N seconds", 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}
|
{"interval", 'i', "wait NUMBER seconds between sending each packet", 1, GRP}
|
||||||
#undef GRP
|
#undef GRP
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OPT_NB 9
|
#define OPT_NB 10
|
||||||
|
|
||||||
#define FT_PING_V "0.1"
|
#define FT_PING_V "0.1"
|
||||||
|
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "bits/types/struct_timeval.h"
|
||||||
|
#include "help.h"
|
||||||
|
#include "opt_parse.h"
|
||||||
#include <stdbool.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 {
|
typedef struct {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
int count;
|
uint32_t count;
|
||||||
int size;
|
uint16_t size;
|
||||||
int timeout;
|
uint16_t timeout;
|
||||||
int ttl;
|
uint16_t linger;
|
||||||
int interval;
|
uint16_t interval;
|
||||||
} ping_t;
|
} options_t;
|
||||||
|
|
||||||
#define DEFAULT_COUNT -1
|
|
||||||
#define DEFAULT_VERBOSE false
|
#define DEFAULT_VERBOSE false
|
||||||
#define DEFAULT_SIZE 0
|
|
||||||
#define DEFAULT_INTERVAL 0
|
#define DEFAULT_SIZE 64
|
||||||
#define DEFAULT_TIMEOUT 0
|
#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
3
includes/utils.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void append_time(double time);
|
12
src/main.c
12
src/main.c
@ -7,17 +7,20 @@
|
|||||||
#include <stdlib.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) {
|
void init_args_t(args_t *args) {
|
||||||
OPT_WHILE {
|
OPT_WHILE {
|
||||||
args->opts[i] = false;
|
args->opts[i] = false;
|
||||||
args->arg[i] = 0;
|
args->arg[i] = -1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
args->hosts = NULL;
|
args->hosts = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_options(args_t *args, char **av) {
|
int handle_options(args_t *args) {
|
||||||
if (args->opts[1]) {
|
if (args->opts[1]) {
|
||||||
print_help();
|
print_help();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@ -37,8 +40,11 @@ int handle_options(args_t *args, char **av) {
|
|||||||
|
|
||||||
int main(int ac, char **av) {
|
int main(int ac, char **av) {
|
||||||
exec_name = *av;
|
exec_name = *av;
|
||||||
|
|
||||||
args_t args;
|
args_t args;
|
||||||
|
|
||||||
init_args_t(&args);
|
init_args_t(&args);
|
||||||
|
|
||||||
if (ac > 1) {
|
if (ac > 1) {
|
||||||
int ret = opt_parse(av, &args);
|
int ret = opt_parse(av, &args);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
@ -48,7 +54,7 @@ int main(int ac, char **av) {
|
|||||||
free(args.hosts);
|
free(args.hosts);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
ret = handle_options(&args, av);
|
ret = handle_options(&args);
|
||||||
free(args.hosts);
|
free(args.hosts);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -57,20 +57,22 @@ void print_help(void) {
|
|||||||
void print_parse_err(error_t err, char *opt) {
|
void print_parse_err(error_t err, char *opt) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case MISSING_HOST:
|
case MISSING_HOST:
|
||||||
printf("%s: missing host operand\n", exec_name);
|
fprintf(stderr, "%s: missing host operand\n", exec_name);
|
||||||
break;
|
break;
|
||||||
case INVALID_OPT:
|
case INVALID_OPT:
|
||||||
printf("%s: invalid option -- %s\n", exec_name, opt);
|
fprintf(stderr, "%s: invalid option -- %s\n", exec_name, opt);
|
||||||
break;
|
break;
|
||||||
case NEED_ARG:
|
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;
|
break;
|
||||||
case ERR_ARG:
|
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;
|
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) {
|
void print_usage(void) {
|
67
src/ping/init_ping.c
Normal file
67
src/ping/init_ping.c
Normal 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
54
src/ping/send_icmp.c
Normal 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
47
src/ping/send_ping.c
Normal 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;
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
#include <opt_parse.h>
|
|
||||||
|
|
||||||
int send_ping(args_t *args) {
|
|
||||||
|
|
||||||
}
|
|
14
src/utils.c
Normal file
14
src/utils.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user