Dimitri Papadopoulos
2026-07-12 21:34:08 +02:00
parent 6d4f96aa72
commit e41d351d02
+30 -30
View File
@@ -80,10 +80,11 @@
#include <netinet/ip_icmp.h> #include <netinet/ip_icmp.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <stdint.h>
#include <gnutls/crypto.h> #include <gnutls/crypto.h>
#include "icmp-ping.h" #include "icmp-ping.h"
#include <poll.h> #include <poll.h>
@@ -96,18 +97,19 @@
#endif #endif
#endif #endif
// clang-format off
/* I see RENUMBERED constants in bits/in.h - !!? /* I see RENUMBERED constants in bits/in.h - !!?
* What a fuck is going on with libc? Is it a glibc joke? */ * What a fuck is going on with libc? Is it a glibc joke? */
#ifdef IPV6_2292HOPLIMIT #ifdef IPV6_2292HOPLIMIT
#undef IPV6_HOPLIMIT # undef IPV6_HOPLIMIT
#define IPV6_HOPLIMIT IPV6_2292HOPLIMIT # define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
#endif #endif
// clang-format on
enum { enum {
DEFDATALEN = 56, DEFDATALEN = 56,
MAXIPLEN = 60, MAXIPLEN = 60,
MAXICMPLEN = 76, MAXICMPLEN = 76,
MAXPACKET = 65468,
MAX_DUP_CHK = (8 * 128), MAX_DUP_CHK = (8 * 128),
MAXWAIT = 10, MAXWAIT = 10,
PINGINTERVAL = 1, /* 1 second */ PINGINTERVAL = 1, /* 1 second */
@@ -115,28 +117,34 @@ enum {
/* common routines */ /* common routines */
static int in_cksum(unsigned short *buf, int sz) // clang-format off
static uint16_t inet_cksum(const void *ptr, int nleft)
{ {
int nleft = sz; const uint16_t *addr = ptr;
int sum = 0;
unsigned short *w = buf;
unsigned short ans = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator,
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
unsigned sum = 0;
while (nleft > 1) { while (nleft > 1) {
sum += *w++; sum += *addr++;
nleft -= 2; nleft -= 2;
} }
if (nleft == 1) { /* Mop up an odd byte, if necessary */
*(unsigned char *)(&ans) = *(unsigned char *)w; if (nleft == 1)
sum += ans; sum += *(uint8_t *)addr;
}
sum = (sum >> 16) + (sum & 0xFFFF); /* Add back carry outs from top 16 bits to low 16 bits */
sum += (sum >> 16); sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
ans = ~sum; sum += (sum >> 16); /* add carry */
return ans;
return (uint16_t)~sum;
} }
// clang-format on
inline static int retry(int e) inline static int retry(int e)
{ {
@@ -151,17 +159,9 @@ inline static int retry(int e)
static ssize_t recvfrom_timeout(int sockfd, void *buf, size_t len, int flags, static ssize_t recvfrom_timeout(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen) struct sockaddr *src_addr, socklen_t *addrlen)
{ {
int ret; struct pollfd pfd = { sockfd, POLLIN, 0 };
struct pollfd pfd;
pfd.fd = sockfd; if (poll(&pfd, 1, 250) > 0)
pfd.events = POLLIN;
pfd.revents = 0;
ret = poll(&pfd, 1, 250);
if (ret == -1)
return -1;
else if (ret > 0)
return recvfrom(sockfd, buf, len, 0, src_addr, addrlen); return recvfrom(sockfd, buf, len, 0, src_addr, addrlen);
else else
return -1; return -1;
@@ -199,14 +199,14 @@ int icmp_ping4(main_server_st *s, struct sockaddr_in *addr1)
memset(pkt, 0, sizeof(packet1)); memset(pkt, 0, sizeof(packet1));
pkt->icmp_type = ICMP_ECHO; pkt->icmp_type = ICMP_ECHO;
pkt->icmp_id = id1; pkt->icmp_id = id1;
pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet1)); pkt->icmp_cksum = inet_cksum((uint16_t *)pkt, sizeof(packet1));
while (sendto(pingsock, packet1, DEFDATALEN + ICMP_MINLEN, 0, while (sendto(pingsock, packet1, DEFDATALEN + ICMP_MINLEN, 0,
(struct sockaddr *)addr1, sizeof(*addr1)) == -1 && (struct sockaddr *)addr1, sizeof(*addr1)) == -1 &&
retry(errno)) retry(errno))
; ;
/* listen for replies */
/* listen for replies */
now = time(NULL); now = time(NULL);
while (time(NULL) - now < PING_TIMEOUT && while (time(NULL) - now < PING_TIMEOUT &&
(unreachable + gotreply) < 2) { (unreachable + gotreply) < 2) {