stuff
This commit is contained in:
parent
728fc5b296
commit
c90606706b
2 changed files with 75 additions and 58 deletions
|
|
@ -27,6 +27,27 @@
|
||||||
|
|
||||||
# define PACKETSIZE 64
|
# define PACKETSIZE 64
|
||||||
|
|
||||||
|
typedef struct s_ping t_ping;
|
||||||
|
|
||||||
|
struct s_ping
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
t_rs rs;
|
||||||
|
int pkt_sent;
|
||||||
|
int pkt_recv;
|
||||||
|
int sock;
|
||||||
|
struct addrinfo *sa;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char ip4[INET_ADDRSTRLEN];
|
||||||
|
char ip6[INET6_ADDRSTRLEN];
|
||||||
|
} ip;
|
||||||
|
#define ip4 ip.ip4
|
||||||
|
#define ip6 ip.ip6
|
||||||
|
};
|
||||||
|
|
||||||
|
extern t_ping g_ping;
|
||||||
|
|
||||||
struct s_packet
|
struct s_packet
|
||||||
{
|
{
|
||||||
struct icmp hdr;
|
struct icmp hdr;
|
||||||
|
|
|
||||||
112
ping/srcs/ping.c
112
ping/srcs/ping.c
|
|
@ -15,86 +15,78 @@
|
||||||
#define TIME_END 1
|
#define TIME_END 1
|
||||||
#define TIME_TRIPTIME 2
|
#define TIME_TRIPTIME 2
|
||||||
|
|
||||||
int g_pid = -1;
|
t_ping g_ping =
|
||||||
int g_pkt_rec = 0;
|
{
|
||||||
char g_domain[256];
|
.pid = -1,
|
||||||
struct s_stats g_rs;
|
.pkt_sent = -1,
|
||||||
|
.pkt_recv = 0,
|
||||||
|
};
|
||||||
|
|
||||||
void display(void *buf, int bytes, struct sockaddr_in *addr)
|
void display(void *buf, int bytes, struct sockaddr_in *addr)
|
||||||
{
|
{
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
struct icmp *icmp;
|
struct icmp *icmp;
|
||||||
struct s_packet *pkt;
|
struct s_packet *pkt;
|
||||||
int hlen;
|
int hlen;
|
||||||
double triptime;
|
double triptime;
|
||||||
|
char strbuf[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
ip = buf;
|
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;
|
||||||
if (icmp->icmp_id != g_pid)
|
if (icmp->icmp_id != g_ping.pid)
|
||||||
return ;
|
return ;
|
||||||
triptime = time_milli() - *(double*)&pkt->msg;
|
triptime = time_milli() - *(double*)&pkt->msg;
|
||||||
rs_push(triptime);
|
rs_push(&g_ping.rs, triptime);
|
||||||
g_pkt_rec++;
|
g_ping.pkt_recv++;
|
||||||
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), g_domain, INET_ADDRSTRLEN),
|
inet_ntop(AF_INET, &(addr->sin_addr), strbuf, INET_ADDRSTRLEN),
|
||||||
icmp->icmp_seq, ip->ip_ttl, triptime);
|
icmp->icmp_seq, ip->ip_ttl, triptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ping(struct sockaddr_in *addr)
|
void ping(int signo)
|
||||||
{
|
{
|
||||||
int sd;
|
|
||||||
int cnt;
|
|
||||||
struct s_packet pkt;
|
struct s_packet pkt;
|
||||||
double epoch;
|
double epoch;
|
||||||
|
|
||||||
if ((sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
(void)signo;
|
||||||
return (perror("sender socket"));
|
bzero(&pkt, sizeof(pkt));
|
||||||
if (setsockopt(sd, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0)
|
pkt.hdr.icmp_type = ICMP_ECHO;
|
||||||
perror("set TTL option");
|
pkt.hdr.icmp_id = g_ping.pid;
|
||||||
cnt = 0;
|
pkt.hdr.icmp_seq = ++g_ping.pkt_sent;
|
||||||
while (1)
|
epoch = time_milli();
|
||||||
{
|
ft_memcpy(pkt.msg, (void*)&epoch, sizeof(epoch));
|
||||||
bzero(&pkt, sizeof(pkt));
|
pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt));
|
||||||
pkt.hdr.icmp_type = ICMP_ECHO;
|
sendto(g_ping.sock, &pkt, sizeof(pkt), 0, g_ping.sa->ai_addr,
|
||||||
pkt.hdr.icmp_id = g_pid;
|
sizeof(struct sockaddr));
|
||||||
pkt.hdr.icmp_seq = cnt++;
|
|
||||||
epoch = time_milli();
|
|
||||||
ft_memcpy(pkt.msg, (void*)&epoch, sizeof(epoch));
|
|
||||||
pkt.hdr.icmp_cksum = cksum(&pkt, sizeof(pkt));
|
|
||||||
if (sendto(sd, &pkt, sizeof(pkt), 0,
|
|
||||||
(struct sockaddr*)addr, sizeof(*addr)) <= 0)
|
|
||||||
return (perror("sendto"));
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stats_recap(int signo)
|
void stats_recap(int signo)
|
||||||
{
|
{
|
||||||
double loss;
|
double loss;
|
||||||
|
|
||||||
(void)signo;
|
(void)signo;
|
||||||
rs_calcmore();
|
rs_final(&g_ping.rs);
|
||||||
loss = FT_PCT(g_pkt_rec, g_rs.count);
|
loss = FT_PCT(g_ping.pkt_recv, g_ping.pkt_sent);
|
||||||
printf("\n--- %s ping statistics ---", g_domain);
|
printf("\n--- %s ping statistics ---", g_ping.ip4);
|
||||||
printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss",
|
printf("\n%d packets transmitted, %d packets received, %0.1f%% packet loss",
|
||||||
g_rs.count, g_pkt_rec, loss);
|
g_ping.rs.count, g_ping.pkt_recv, loss);
|
||||||
printf("\nround-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms",
|
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_ping.rs.min, g_ping.rs.avg, g_ping.rs.max, g_ping.rs.stdev);
|
||||||
|
freeaddrinfo(g_ping.sa);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct addrinfo *resolve_host(char *hostname)
|
int resolve_host(char *hostname, t_ping *ping)
|
||||||
{
|
{
|
||||||
struct addrinfo *result;
|
struct addrinfo *result;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct sockaddr_in *addr;
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = PF_UNSPEC;
|
hints.ai_family = PF_INET;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags |= AI_CANONNAME;
|
hints.ai_flags |= AI_CANONNAME;
|
||||||
if (getaddrinfo(hostname, NULL, &hints, &result) != 0)
|
if (getaddrinfo(hostname, NULL, &hints, &result) != 0)
|
||||||
|
|
@ -102,35 +94,39 @@ struct addrinfo *resolve_host(char *hostname)
|
||||||
perror("getaddrinfo");
|
perror("getaddrinfo");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
addr = (struct sockaddr_in*)result->ai_addr;
|
ping->sa = result;
|
||||||
inet_ntop(AF_INET, &(addr->sin_addr), g_domain, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &(((struct sockaddr_in*)ping->sa->ai_addr)->sin_addr), ping->ip4, INET_ADDRSTRLEN);
|
||||||
if (result->ai_canonname)
|
return (0);
|
||||||
ft_strcpy(g_domain, result->ai_canonname);
|
|
||||||
return (result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
struct addrinfo *result;
|
|
||||||
|
|
||||||
if (ac != 2)
|
if (ac != 2)
|
||||||
{
|
{
|
||||||
ft_usage("%s <addr>\n", av[0]);
|
ft_usage("%s <addr>\n", av[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
g_pid = getpid();
|
resolve_host(av[1], &g_ping);
|
||||||
result = resolve_host(av[1]);
|
if (g_ping.sa->ai_canonname)
|
||||||
if (result->ai_canonname)
|
|
||||||
printf("PING %s (%s): %i data bytes\n",
|
printf("PING %s (%s): %i data bytes\n",
|
||||||
result->ai_canonname, g_domain, PACKETSIZE);
|
g_ping.sa->ai_canonname, g_ping.ip4, PACKETSIZE);
|
||||||
else
|
else
|
||||||
printf("PING %s: %i data bytes\n", g_domain, PACKETSIZE);
|
printf("PING %s: %i data bytes\n", g_ping.ip4, PACKETSIZE);
|
||||||
if (fork() == 0)
|
if ((g_ping.sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||||||
{
|
{
|
||||||
signal(SIGINT, stats_recap);
|
ft_dprintf(2, "socket(2) error\n");
|
||||||
rs_clear();
|
exit(1);
|
||||||
listener(PF_INET, SOCK_RAW, IPPROTO_ICMP, &display);
|
|
||||||
}
|
}
|
||||||
ping((struct sockaddr_in*)result->ai_addr);
|
if (setsockopt(g_ping.sock, 0, IP_TTL, (int[]){255, 0}, sizeof(int)) != 0)
|
||||||
|
{
|
||||||
|
ft_dprintf(2, "setsockopt(2) error\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
g_ping.pid = getpid();
|
||||||
|
rs_init(&g_ping.rs);
|
||||||
|
signal(SIGINT, stats_recap);
|
||||||
|
signal(SIGALRM, ping);
|
||||||
|
alarm(1);
|
||||||
|
listener(PF_INET, SOCK_RAW, IPPROTO_ICMP, &display);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue