Go to the documentation of this file.
   27 #if HAVE_NETINET_IP6_H 
   28 #include <netinet/ip6.h> 
   37     static const char *icmp6LowPktStr[] = {
 
   39         "Destination Unreachable",  
 
   47         return icmp6LowPktStr[(
int)(v&0x7f)];
 
   50     static const char *icmp6HighPktStr[] = {
 
   53         "Multicast Listener Query",         
 
   54         "Multicast Listener Report",            
 
   55         "Multicast Listener Done",          
 
   56         "Router Solicitation",              
 
   57         "Router Advertisement",             
 
   58         "Neighbor Solicitation",            
 
   59         "Neighbor Advertisement",           
 
   62         "ICMP Node Information Query",          
 
   63         "ICMP Node Information Response",       
 
   64         "Inverse Neighbor Discovery Solicitation",  
 
   65         "Inverse Neighbor Discovery Advertisement", 
 
   66         "Version 2 Multicast Listener Report",      
 
   67         "Home Agent Address Discovery Request",     
 
   68         "Home Agent Address Discovery Reply",       
 
   69         "Mobile Prefix Solicitation",           
 
   70         "Mobile Prefix Advertisement",          
 
   71         "Certification Path Solicitation",      
 
   72         "Certification Path Advertisement",     
 
   73         "ICMP Experimental (150)",          
 
   74         "Multicast Router Advertisement",       
 
   75         "Multicast Router Solicitation",        
 
   76         "Multicast Router Termination",         
 
   80     if (127 < v && v < 154)
 
   81         return icmp6HighPktStr[(
int)(v&0x7f)];
 
   85     snprintf(buf, 
sizeof(buf), 
"ICMPv6 %u", v);
 
  124     struct icmp6_hdr *icmp = 
nullptr;
 
  126     struct addrinfo *S = 
nullptr;
 
  127     size_t icmp6_pktsize = 0;
 
  129     static_assert(
sizeof(*icmp) + 
sizeof(*echo) <= 
sizeof(pkt), 
"our custom ICMPv6 Echo payload fits the packet buffer");
 
  132     icmp = (
struct icmp6_hdr *)pkt;
 
  143     icmp->icmp6_type = ICMP6_ECHO_REQUEST;
 
  144     icmp->icmp6_code = 0;
 
  145     icmp->icmp6_cksum = 0;
 
  150     icmp6_pktsize = 
sizeof(
struct icmp6_hdr);
 
  153     echo = 
reinterpret_cast<icmpEchoData *
>(
reinterpret_cast<char *
>(pkt) + 
sizeof(*icmp));
 
  154     echo->
opcode = (
unsigned char) opcode;
 
  157     icmp6_pktsize += 
sizeof(
struct timeval) + sizeof(char);
 
  163         memcpy(echo->
payload, payload, len);
 
  165         icmp6_pktsize += len;
 
  168     icmp->icmp6_cksum = 
CheckSum((
unsigned short *) icmp, icmp6_pktsize);
 
  173     ((sockaddr_in6*)S->ai_addr)->sin6_port = 0;
 
  177     debugs(42, 5, 
"Send Icmp6 packet to " << to << 
".");
 
  192     Log(to, 0, 
"", 0, 0);
 
  203     struct addrinfo *from = 
nullptr;
 
  205     static char *pkt = 
nullptr;
 
  206     struct icmp6_hdr *icmp6header = 
nullptr;
 
  216     if (pkt == 
nullptr) {
 
  234     if (n < 
static_cast<int>(
sizeof(
struct icmp6_hdr))) {
 
  241 #if GETTIMEOFDAY_NO_TZP 
  247     gettimeofday(&now, 
nullptr);
 
  251     debugs(42, 8, n << 
" bytes from " << preply.from);
 
  280     icmp6header = (
struct icmp6_hdr *) pkt;
 
  282     if (icmp6header->icmp6_type != ICMP6_ECHO_REPLY) {
 
  284         switch (icmp6header->icmp6_type) {
 
  292             debugs(42, 8, preply.from << 
" said: " << icmp6header->icmp6_type << 
"/" << (
int)icmp6header->icmp6_code << 
" " <<
 
  299     if (ntohs(icmp6header->icmp6_id) != 
static_cast<uint16_t
>(
icmp_ident)) {
 
  300         debugs(42, 8, 
"dropping Icmp6 read. IDENT check failed. ident=='" << 
icmp_ident << 
"'=='" << icmp6header->icmp6_id << 
"'");
 
  305     const auto meta = 
static_cast<int>(
sizeof(
struct icmp6_hdr) + sizeof(struct timeval) + sizeof(unsigned char));
 
  310     echo = (
icmpEchoData *)(pkt + 
sizeof(
struct icmp6_hdr));
 
  315     memcpy(&tv, &echo->
tv, 
sizeof(
struct timeval));
 
  326     auto payload_len = n - meta;
 
  331     preply.psize = payload_len;
 
  332     if (preply.psize > 0) {
 
  333         memcpy(preply.payload, echo->
payload, preply.psize);
 
  337         icmp6header->icmp6_type,
 
  
const char * xstrerr(int error)
#define LOCAL_ARRAY(type, name, size)
#define PINGER_PAYLOAD_SZ
IcmpPinger control
pinger helper contains one of these as a global object.
int Open() override
Start pinger helper and initiate control channel.
static void FreeAddr(struct addrinfo *&ai)
virtual void Close()
Shutdown pinger helper and control channel.
int tvSubMsec(struct timeval t1, struct timeval t2)
ssize_t xrecvfrom(int socketFd, void *buf, size_t bufLength, int flags, struct sockaddr *from, socklen_t *fromLength)
POSIX recvfrom(2) equivalent.
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
void SendEcho(Ip::Address &, int, const char *, int) override
char payload[MAX_PAYLOAD]
static const char * IcmpPacketType(uint8_t v)
#define Assure(condition)
int xsocket(int domain, int type, int protocol)
POSIX socket(2) equivalent.
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
void SendResult(pingerReplyData &preply, int len)
Send ICMP results back to squid.
ssize_t xsendto(int socketFd, const void *buf, size_t bufLength, int flags, const struct sockaddr *to, socklen_t toLength)
POSIX sendto(2) equivalent.
int CheckSum(unsigned short *ptr, int size)
Calculate a packet checksum.
#define debugs(SECTION, LEVEL, CONTENT)
void Log(const Ip::Address &addr, const uint8_t type, const char *pkt_str, const int rtt, const int hops)
Log the packet.
static void InitAddr(struct addrinfo *&ai)