27 static const char *icmpPktStr[] = {
31 "Destination Unreachable",
50 snprintf(buf,
sizeof(buf),
"ICMP %u (invalid)", v);
92 size_t icmp_pktsize =
sizeof(
struct icmphdr);
93 struct addrinfo *S =
nullptr;
95 static_assert(
sizeof(*icmp) +
sizeof(*echo) <=
sizeof(pkt),
"our custom ICMPv4 Echo payload fits the packet buffer");
99 icmp = (
struct icmphdr *) (
void *) pkt;
112 icmp->icmp_cksum = 0;
118 echo =
reinterpret_cast<icmpEchoData *
>(
reinterpret_cast<char *
>(pkt) +
sizeof(*icmp));
119 echo->
opcode = (
unsigned char) opcode;
128 memcpy(echo->
payload, payload, len);
133 icmp->icmp_cksum =
CheckSum((
unsigned short *) icmp, icmp_pktsize);
138 ((sockaddr_in*)S->ai_addr)->sin_port = 0;
141 debugs(42, 5,
"Send ICMP packet to " << to <<
".");
155 Log(to,
' ',
"", 0, 0);
163 struct addrinfo *from =
nullptr;
164 int iphdrlen =
sizeof(
iphdr);
165 struct iphdr *ip =
nullptr;
166 struct icmphdr *icmp =
nullptr;
167 static char *pkt =
nullptr;
196#if GETTIMEOFDAY_NO_TZP
202 gettimeofday(&now,
nullptr);
206 debugs(42, 8, n <<
" bytes from " << preply.
from);
208 ip = (
struct iphdr *) (
void *) pkt;
209 if (n <
static_cast<int>(
sizeof(*ip))) {
210 debugs(42, 2,
"short packet: only " << n <<
" bytes; expecting at least " <<
sizeof(*ip) <<
"-byte IP header");
215#if HAVE_STRUCT_IPHDR_IP_HL
217 iphdrlen = ip->ip_hl << 2;
222 iphdrlen = (ip->ip_vhl >> 4) << 2;
226 iphdrlen = (ip->ip_vhl & 0xF) << 2;
231 if (iphdrlen < 20 || n < iphdrlen) {
232 debugs(42, 2,
"bogus IP header length " << iphdrlen <<
" in " << n <<
"-byte packet");
236 icmp = (
struct icmphdr *) (
void *) (pkt + iphdrlen);
237 const int icmpAvail = n - iphdrlen;
238 if (icmpAvail <
static_cast<int>(
sizeof(*icmp))) {
239 debugs(42, 2,
"short ICMP header: only " << icmpAvail <<
" bytes available; expecting at least " <<
sizeof(*icmp));
257 const auto icmpDataLen = icmpAvail -
sizeof(*icmp);
258 if (icmpDataLen < echoHdr) {
259 debugs(42, 2,
"short ICMP echo data: " << icmpDataLen <<
" bytes; expecting " << echoHdr);
264 preply.
opcode = echo->opcode;
269 memcpy(&tv, &echo->tv,
sizeof(
struct timeval));
273 preply.
psize = icmpDataLen - echoHdr;
277 if (preply.
psize < 0) {
#define Assure(condition)
static const char * IcmpPacketType(uint8_t v)
IcmpPinger control
pinger helper contains one of these as a global object.
#define PINGER_PAYLOAD_SZ
void SendEcho(Ip::Address &, int, const char *, int) override
void Recv(void) override
Handle ICMP responses.
int Open() override
Start pinger helper and initiate control channel.
void SendResult(pingerReplyData &preply, int len)
Send ICMP results back to squid.
virtual void Close()
Shutdown pinger helper and control channel.
int CheckSum(unsigned short *ptr, int size)
Calculate a packet checksum.
static void InitAddr(struct addrinfo *&ai)
static void FreeAddr(struct addrinfo *&ai)
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
#define debugs(SECTION, LEVEL, CONTENT)
int xsocket(int domain, int type, int protocol)
POSIX socket(2) equivalent.
ssize_t xsendto(int socketFd, const void *buf, size_t bufLength, int flags, const struct sockaddr *to, socklen_t toLength)
POSIX sendto(2) equivalent.
ssize_t xrecvfrom(int socketFd, void *buf, size_t bufLength, int flags, struct sockaddr *from, socklen_t *fromLength)
POSIX recvfrom(2) equivalent.
#define LOCAL_ARRAY(type, name, size)
char payload[MAX_PAYLOAD]
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
int tvSubMsec(struct timeval t1, struct timeval t2)
const char * xstrerr(int error)