Skip to content

Instantly share code, notes, and snippets.

@plonk
Last active June 6, 2020 19:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plonk/633aa81e55889a292c30f68587b7623e to your computer and use it in GitHub Desktop.
Save plonk/633aa81e55889a292c30f68587b7623e to your computer and use it in GitHub Desktop.
Simple ping
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <sys/time.h>
const char *TYPE_STRING[256] = {
[0] = "Echo Reply",
[3] = "Destination Unreachable",
[4] = "Source Quench",
[8] = "Echo Request",
};
int main(int argc, char **argv)
{
char *dest=0;
for (int i = 1; i < argc; i++) {
if (dest) {
fprintf(stderr,"Error: Multiple destinations.\n");
exit(1);
}
dest = argv[i];
}
if (!dest) {
fprintf(stderr,"Usage: (sudo) ping DESTINATION\n");
exit(1);
}
struct hostent *he = gethostbyname(dest);
if (!he) {
fprintf(stderr, "Error while looking up host %s\n", dest);
exit(1);
}
// ---------------------------------------------------------
int raw_socket = socket(AF_INET, SOCK_RAW, 1 /* ICMP */);
if (raw_socket == -1) {
perror("socket");
exit(1);
}
#define BUFFER_SIZE 100
unsigned char buf[BUFFER_SIZE] = {
8, 0,
0, 0, /* checksum */
0x71, 0x44, /* ID */
0, 1, /* seq. number */
'A','B','C','D', /* payload */
};
int size = 8 + 4;
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = *(uint32_t*)he->h_addr;
int sum = 0;
for (int i = 0; i < size; i += 2) {
sum += *(unsigned short*)(buf+i);
if (sum >= 0x10000) {
sum &= 0xffff;
sum += 1;
}
}
/* set checksum */
buf[2] = ~sum;
buf[3] = ~sum >> 8;
struct timeval start;
gettimeofday(&start, NULL);
int r;
r = sendto(raw_socket, buf, size, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
printf("%d bytes sent\n", r);
struct sockaddr_in addr2;
int addrlen;
r = recvfrom(raw_socket, buf, sizeof(buf), 0,
(struct sockaddr*)&addr2, &addrlen);
printf("%d bytes read (including 20-byte IP header)\n", r);
struct timeval end;
gettimeofday(&end, NULL);
const int type = buf[20];
const int code = buf[21];
printf("Type: %d (%s)\n", type, TYPE_STRING[type]);
printf("Code: %d\n", code);
if (type == 0 && code == 0) {
printf("Round-trip time: %.03f ms\n",
((end.tv_sec + end.tv_usec/1000000.0) -
(start.tv_sec + start.tv_usec/1000000.0)) * 1000);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment