stuff
This commit is contained in:
parent
66d9a2a514
commit
ff629391b0
4 changed files with 70 additions and 112 deletions
|
|
@ -10,6 +10,8 @@
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
SHELL := bash
|
||||||
|
|
||||||
NAME = ft_ping
|
NAME = ft_ping
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
@ -44,7 +46,8 @@ $(NAME): $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(CLIENT_OBJ)
|
||||||
@$(CC) $(OBJS) -o $@ \
|
@$(CC) $(OBJS) -o $@ \
|
||||||
-I $(INC_DIR) \
|
-I $(INC_DIR) \
|
||||||
-I $(LIBFT_INC) \
|
-I $(LIBFT_INC) \
|
||||||
$(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS)
|
$(LIBFT_LIB) $(CLIENT_OBJ) $(FLAGS) \
|
||||||
|
-lm
|
||||||
@printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n"
|
@printf "\r\033[38;5;117m✓ MAKE $@ \033[0m\033[K\n"
|
||||||
|
|
||||||
$(LIBFT_LIB):
|
$(LIBFT_LIB):
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# include <netinet/ip.h>
|
# include <netinet/ip.h>
|
||||||
# include <netinet/ip_icmp.h>
|
# include <netinet/ip_icmp.h>
|
||||||
|
# include <sys/wait.h>
|
||||||
|
|
||||||
#define PACKETSIZE 64
|
#define PACKETSIZE 64
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 23c69f13242ecbff493356c57cb1384eb1dd45f5
|
Subproject commit 57475bdafefca069981276b44dd8c5d8998b5a13
|
||||||
164
ping/srcs/ping.c
164
ping/srcs/ping.c
|
|
@ -6,177 +6,131 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */
|
/* Created: 2017/04/22 14:10:24 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/04/23 18:18:41 by jhalford ### ########.fr */
|
/* Updated: 2017/10/08 14:26:15 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ping.h"
|
#include "ping.h"
|
||||||
|
#define TIME_START 0
|
||||||
|
#define TIME_END 1
|
||||||
|
#define TIME_TRIPTIME 2
|
||||||
|
|
||||||
int g_pid=-1;
|
int g_pid = -1;
|
||||||
int g_pkt_rec=0;
|
int g_pkt_rec = 0;
|
||||||
char g_domain[256];
|
char g_domain[256];
|
||||||
|
struct s_stats g_rs;
|
||||||
unsigned short checksum(void *b, int len)
|
|
||||||
{
|
|
||||||
unsigned short *buf = b;
|
|
||||||
unsigned int sum=0;
|
|
||||||
unsigned short result;
|
|
||||||
|
|
||||||
for (sum = 0; len > 1; len -= 2)
|
|
||||||
sum += *buf++;
|
|
||||||
if (len == 1)
|
|
||||||
sum += *(unsigned char*)buf;
|
|
||||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
|
||||||
sum += (sum >> 16);
|
|
||||||
result = ~sum;
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display(void *buf, int bytes, struct sockaddr_in *addr)
|
void display(void *buf, int bytes, struct sockaddr_in *addr)
|
||||||
{
|
{
|
||||||
struct ip *ip = buf;
|
struct ip *ip;
|
||||||
struct icmp *icmp;
|
struct icmp *icmp;
|
||||||
struct s_packet *pkt;
|
struct s_packet *pkt;
|
||||||
int hlen;
|
int hlen;
|
||||||
char addrstr[INET_ADDRSTRLEN];
|
double triptime;
|
||||||
struct timeval start, end, triptime;
|
|
||||||
double diff;
|
|
||||||
|
|
||||||
|
ip = buf;
|
||||||
(void)bytes;
|
(void)bytes;
|
||||||
hlen = ip->ip_hl << 2;
|
hlen = ip->ip_hl << 2;
|
||||||
pkt = (struct s_packet*)(buf + hlen);
|
pkt = (struct s_packet*)(buf + hlen);
|
||||||
icmp = &pkt->hdr;
|
icmp = &pkt->hdr;
|
||||||
start = *(struct timeval*)&pkt->msg;
|
if (icmp->icmp_id != g_pid)
|
||||||
|
|
||||||
if (gettimeofday(&end, NULL) != 0)
|
|
||||||
return ;
|
return ;
|
||||||
timersub(&end, &start, &triptime);
|
triptime = time_milli() - *(double*)&pkt->msg;
|
||||||
diff = (triptime.tv_sec + triptime.tv_usec / 1000000.0) * 1000.0;
|
rs_push(triptime);
|
||||||
rs_push(diff);
|
|
||||||
g_pkt_rec++;
|
g_pkt_rec++;
|
||||||
printf("%d bytes from %s: icmp_seq=%d ttl=%i time=%.3f ms\n",
|
printf("%d bytes from %s: icmp_seq=%d ttl=%i time=%.3f ms\n",
|
||||||
ip->ip_len,
|
ip->ip_len,
|
||||||
inet_ntop(AF_INET, &(addr->sin_addr), addrstr, INET_ADDRSTRLEN),
|
inet_ntop(AF_INET, &(addr->sin_addr), g_domain, INET_ADDRSTRLEN),
|
||||||
icmp->icmp_seq, ip->ip_ttl, diff);
|
icmp->icmp_seq, ip->ip_ttl, triptime);
|
||||||
}
|
|
||||||
|
|
||||||
void listener(void)
|
|
||||||
{ int sd;
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
unsigned char buf[1024];
|
|
||||||
|
|
||||||
sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP);
|
|
||||||
if ( sd < 0 )
|
|
||||||
{
|
|
||||||
perror("socket");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
for (;;)
|
|
||||||
{ int bytes;
|
|
||||||
socklen_t len=sizeof(addr);
|
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
|
||||||
bytes = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
|
|
||||||
if ( bytes > 0 )
|
|
||||||
display(buf, bytes, &addr);
|
|
||||||
else
|
|
||||||
perror("recvfrom");
|
|
||||||
}
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ping(struct sockaddr_in *addr)
|
void ping(struct sockaddr_in *addr)
|
||||||
{
|
{
|
||||||
const int val = 255;
|
|
||||||
int i;
|
|
||||||
int sd;
|
int sd;
|
||||||
int cnt;
|
int cnt;
|
||||||
socklen_t len;
|
|
||||||
struct s_packet pkt;
|
struct s_packet pkt;
|
||||||
struct sockaddr_in r_addr;
|
double epoch;
|
||||||
struct timeval time;
|
|
||||||
|
|
||||||
if ((sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_ICMP)) < 0)
|
if ((sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||||||
{
|
return (perror("sender socket"));
|
||||||
perror("socket");
|
if (setsockopt(sd, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0)
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (setsockopt(sd, 0, IP_TTL, &val, sizeof(val)) != 0)
|
|
||||||
perror("set TTL option");
|
perror("set TTL option");
|
||||||
if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0)
|
|
||||||
perror("Request non blocking IO");
|
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
len = sizeof(r_addr);
|
|
||||||
bzero(&pkt, sizeof(pkt));
|
bzero(&pkt, sizeof(pkt));
|
||||||
pkt.hdr.icmp_type = ICMP_ECHO;
|
pkt.hdr.icmp_type = ICMP_ECHO;
|
||||||
pkt.hdr.icmp_id = g_pid;
|
pkt.hdr.icmp_id = g_pid;
|
||||||
pkt.hdr.icmp_seq = cnt++;
|
pkt.hdr.icmp_seq = cnt++;
|
||||||
|
epoch = time_milli();
|
||||||
for (i=0; i < (int)sizeof(pkt.msg); i++)
|
ft_memcpy(pkt.msg, (void*)&epoch, sizeof(epoch));
|
||||||
pkt.msg[i] = i+'0';
|
pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt));
|
||||||
pkt.msg[i] = 0;
|
if (sendto(sd, &pkt, sizeof(pkt), 0,
|
||||||
if (gettimeofday(&time, NULL) != 0)
|
(struct sockaddr*)addr, sizeof(*addr)) <= 0)
|
||||||
return ;
|
return (perror("sendto"));
|
||||||
ft_memcpy(pkt.msg, (void*)&time, sizeof(time));
|
|
||||||
time = *(struct timeval*)&pkt.msg;
|
|
||||||
pkt.hdr.icmp_cksum = checksum(&pkt, sizeof(pkt));
|
|
||||||
if (sendto(sd, &pkt, sizeof(pkt), 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0)
|
|
||||||
perror("sendto");
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigint_handler(int signo)
|
void stats_recap(int signo)
|
||||||
{
|
{
|
||||||
double loss;
|
double loss;
|
||||||
|
|
||||||
(void)signo;
|
(void)signo;
|
||||||
rs_calcmore();
|
rs_calcmore();
|
||||||
loss = g_rs.count ? 100 * ((float) (g_rs.count - g_pkt_rec) / (float)g_rs.count) : 0;
|
loss = FT_PCT(g_pkt_rec, g_rs.count);
|
||||||
printf("\n--- %s ping statistics ---", g_domain);
|
printf("\n--- %s ping statistics ---", g_domain);
|
||||||
printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss", g_rs.count, g_pkt_rec, loss);
|
printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss",
|
||||||
printf("\nround-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms", g_rs.min, g_rs.avg, g_rs.max, g_rs.stdev);
|
g_rs.count, g_pkt_rec, loss);
|
||||||
|
printf("\nround-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms",
|
||||||
|
g_rs.min, g_rs.avg, g_rs.max, g_rs.stdev);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
struct addrinfo *resolve_host(char *hostname)
|
||||||
{
|
{
|
||||||
|
struct addrinfo *result;
|
||||||
|
struct addrinfo hints;
|
||||||
struct sockaddr_in *addr;
|
struct sockaddr_in *addr;
|
||||||
struct addrinfo *result, hints;
|
|
||||||
char addrstr[INET_ADDRSTRLEN];
|
|
||||||
|
|
||||||
if (ac != 2)
|
memset(&hints, 0, sizeof(hints));
|
||||||
{
|
|
||||||
printf("usage: %s <addr>\n", av[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset (&hints, 0, sizeof (hints));
|
|
||||||
hints.ai_family = PF_UNSPEC;
|
hints.ai_family = PF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags |= AI_CANONNAME;
|
hints.ai_flags |= AI_CANONNAME;
|
||||||
if (getaddrinfo(av[1], NULL, &hints, &result) != 0)
|
if (getaddrinfo(hostname, NULL, &hints, &result) != 0)
|
||||||
{
|
{
|
||||||
perror("getaddrinfo");
|
perror("getaddrinfo");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
addr = (struct sockaddr_in*)result->ai_addr;
|
addr = (struct sockaddr_in*)result->ai_addr;
|
||||||
inet_ntop(AF_INET, &(addr->sin_addr), addrstr, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &(addr->sin_addr), g_domain, INET_ADDRSTRLEN);
|
||||||
g_pid = getpid();
|
|
||||||
ft_strcpy(g_domain, addrstr);
|
|
||||||
if (result->ai_canonname)
|
if (result->ai_canonname)
|
||||||
ft_strcpy(g_domain, result->ai_canonname);
|
ft_strcpy(g_domain, result->ai_canonname);
|
||||||
printf("PING %s (%s): %i data bytes\n", FT_TRY(result->ai_canonname, addrstr), addrstr, 64);
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
struct addrinfo *result;
|
||||||
|
|
||||||
|
if (ac != 2)
|
||||||
|
{
|
||||||
|
ft_usage("%s <addr>\n", av[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
g_pid = getpid();
|
||||||
|
result = resolve_host(av[1]);
|
||||||
|
if (result->ai_canonname)
|
||||||
|
printf("PING %s (%s): %i data bytes\n",
|
||||||
|
result->ai_canonname, g_domain, 64);
|
||||||
|
else
|
||||||
|
printf("PING %s: %i data bytes\n", g_domain, 64);
|
||||||
if (fork() == 0)
|
if (fork() == 0)
|
||||||
{
|
{
|
||||||
signal(SIGINT, sigint_handler);
|
signal(SIGINT, stats_recap);
|
||||||
rs_clear();
|
rs_clear();
|
||||||
listener();
|
listener(PF_INET, SOCK_RAW, IPPROTO_ICMP, &display);
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
else
|
ping((struct sockaddr_in*)result->ai_addr);
|
||||||
ping(addr);
|
|
||||||
wait(0);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue