now sends ICMP_ECHO_REQUEST and recvs ICMP_ECHO_RESPONSE
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"C_Cpp.errorSquiggles": "disabled"
|
||||||
|
}
|
@ -13,6 +13,9 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <netinet/ip_icmp.h>
|
#include <netinet/ip_icmp.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
struct arguments {
|
struct arguments {
|
||||||
char* args[1];
|
char* args[1];
|
||||||
|
77
srcs/main.c
77
srcs/main.c
@ -49,6 +49,8 @@ int sock = 0;
|
|||||||
|
|
||||||
static struct sockaddr_in destination;
|
static struct sockaddr_in destination;
|
||||||
|
|
||||||
|
struct timespec sendt;
|
||||||
|
|
||||||
unsigned long xmit = 0;
|
unsigned long xmit = 0;
|
||||||
unsigned long recvd = 0;
|
unsigned long recvd = 0;
|
||||||
|
|
||||||
@ -56,31 +58,45 @@ double min = 0;
|
|||||||
double max = 0;
|
double max = 0;
|
||||||
double avg = 0;
|
double avg = 0;
|
||||||
|
|
||||||
uint16_t calc_checksum(void * b, const size_t l) {
|
uint16_t calc_checksum(void* b, size_t len) {
|
||||||
uint16_t sum = 0;
|
unsigned short* buf = b;
|
||||||
|
unsigned int sum = 0;
|
||||||
|
unsigned short result;
|
||||||
|
|
||||||
for (size_t i = 0; i < l; i++) {
|
for (sum = 0; len > 1; len -= 2) {
|
||||||
sum += *((uint16_t*)b + i);
|
sum += *buf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ~sum;
|
if (len == 1) {
|
||||||
|
sum += *(unsigned char*)buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||||
|
sum += (sum >> 16);
|
||||||
|
result = ~sum;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_ping() {
|
void send_ping() {
|
||||||
struct ping_pkt packet = {0};
|
struct ping_pkt packet = {0};
|
||||||
|
|
||||||
packet.hdr.type = ICMP_ECHO;
|
packet.hdr.type = ICMP_ECHO;
|
||||||
|
packet.hdr.code = 0;
|
||||||
packet.hdr.un.echo.id = getpid();
|
packet.hdr.un.echo.id = getpid();
|
||||||
packet.hdr.un.echo.sequence = xmit++;
|
packet.hdr.un.echo.sequence = xmit++;
|
||||||
|
|
||||||
for (long unsigned i = 0; i < sizeof(packet.msg) - 1; ++i) {
|
struct timeval tmp_tv;
|
||||||
packet.msg[i] = (char)i;
|
gettimeofday(&tmp_tv, NULL);
|
||||||
|
|
||||||
|
memcpy(packet.msg, &tmp_tv, sizeof(tmp_tv));
|
||||||
|
for (long unsigned i = 0; i < sizeof(packet.msg) - sizeof(tmp_tv); ++i) {
|
||||||
|
packet.msg[sizeof(tmp_tv) + i] = (char)i;
|
||||||
}
|
}
|
||||||
packet.msg[sizeof(packet.msg) - 1] = '\0';
|
|
||||||
|
|
||||||
packet.hdr.checksum = calc_checksum(&packet, sizeof(packet));
|
packet.hdr.checksum = calc_checksum(&packet, sizeof(packet));
|
||||||
|
|
||||||
sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr*)&destination, sizeof(destination));
|
sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr*)&destination, sizeof(destination));
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &sendt);
|
||||||
alarm(1);
|
alarm(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +110,10 @@ void sig_handler(int sig) {
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
struct arguments arguments;
|
struct arguments arguments;
|
||||||
|
int timeout = 3000;
|
||||||
|
struct timespec recvt;
|
||||||
|
struct pollfd fds[1];
|
||||||
|
|
||||||
arguments.verbose = 0;
|
arguments.verbose = 0;
|
||||||
arguments.ttl = 64;
|
arguments.ttl = 64;
|
||||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||||
@ -121,6 +141,9 @@ int main(int argc, char** argv) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fds[0].fd = sock;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
|
||||||
struct sigaction sig_handle;
|
struct sigaction sig_handle;
|
||||||
|
|
||||||
sig_handle.sa_handler = sig_handler;
|
sig_handle.sa_handler = sig_handler;
|
||||||
@ -128,17 +151,49 @@ int main(int argc, char** argv) {
|
|||||||
sigaction(SIGINT, &sig_handle, 0);
|
sigaction(SIGINT, &sig_handle, 0);
|
||||||
sigaction(SIGALRM, &sig_handle, 0);
|
sigaction(SIGALRM, &sig_handle, 0);
|
||||||
|
|
||||||
alarm(1);
|
send_ping();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
int ret = poll(fds, 1, timeout);
|
||||||
|
if (ret > 0) {
|
||||||
|
if (fds[0].revents & POLLIN) {
|
||||||
|
char buf[100];
|
||||||
|
|
||||||
|
long int bytes_received = recvfrom(sock, buf, 100, 0, NULL, NULL);
|
||||||
|
|
||||||
|
if (bytes_received < 0) {
|
||||||
|
perror("recvfrom failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &recvt);
|
||||||
|
|
||||||
|
struct ip* ip_header = (struct ip*)buf;
|
||||||
|
struct icmphdr* icmp_reply = (struct icmphdr*)(buf + (ip_header->ip_hl << 2));
|
||||||
|
|
||||||
|
int rtt_n =
|
||||||
|
((recvt.tv_sec * 1000 + recvt.tv_nsec / 1000000) - (sendt.tv_sec * 1000 + sendt.tv_nsec / 1000000));
|
||||||
|
int rtt_r = ((recvt.tv_nsec - sendt.tv_nsec) % 1000000 / 1000);
|
||||||
|
|
||||||
|
printf("%zd bytes from %s: icmp_seq=%d ttl=%d time=%d.%d ms \n", bytes_received, arguments.args[0],
|
||||||
|
icmp_reply->un.echo.sequence, ip_header->ip_ttl, rtt_n, rtt_r);
|
||||||
|
recvd++;
|
||||||
|
}
|
||||||
|
} else if (ret == 0) {
|
||||||
|
printf("No reply received within the timeout period\n");
|
||||||
|
} else {
|
||||||
|
perror("Poll failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
pause();
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
printf("---- %s ping statistics ----\n", arguments.args[0]);
|
||||||
printf("%zu packets transmitted, %zu packets received, %%zu%% packet loss\n", xmit,
|
printf("%zu packets transmitted, %zu packets received, %zu%% packet loss\n", xmit, recvd,
|
||||||
recvd /*, (xmit - recv) / xmit * 100*/);
|
(xmit - recvd) / xmit * 100);
|
||||||
// printf("round-trip min/avg/max/stddev = %f/%f/%f/%f ms\n");
|
// printf("round-trip min/avg/max/stddev = %f/%f/%f/%f ms\n");
|
||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
Reference in New Issue
Block a user