1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 37    ICMP Routines */
10 
11 #ifndef _INCLUDE_ICMP_H
12 #define _INCLUDE_ICMP_H
13 
14 #include "ip/Address.h"
15 
16 #define PINGER_PAYLOAD_SZ   8192
17 
18 #define MAX_PAYLOAD 256 // WAS: SQUIDHOSTNAMELEN
19 #define MAX_PKT4_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
20 #define MAX_PKT6_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmp6_hdr) + 1)
21 
22 #if USE_ICMP
23 
24 /* This is a line-data format struct. DO NOT alter. */
25 struct pingerEchoData
26 {
pingerEchoDatapingerEchoData27     pingerEchoData() { memset(&payload, 0, sizeof(payload)); }
28     Ip::Address to;
29     unsigned char opcode = '\0';
30     int psize = 0;
31     char payload[PINGER_PAYLOAD_SZ];
32 };
33 
34 /* This is a line-data format struct. DO NOT alter. */
35 struct pingerReplyData {
pingerReplyDatapingerReplyData36     pingerReplyData() { memset(&payload, 0, sizeof(payload)); }
37     Ip::Address from;
38     unsigned char opcode = '\0';
39     int rtt = 0;
40     int hops = 0;
41     int psize = 0;
42     char payload[PINGER_PAYLOAD_SZ];
43 };
44 
45 struct icmpEchoData {
46     struct timeval tv;
47     unsigned char opcode;
48     char payload[MAX_PAYLOAD];
49 };
50 
51 extern int icmp_pkts_sent;
52 
53 #endif /* USE_ICMP */
54 
55 /**
56  * Implements the squid interface to access ICMP operations
57  *
58  \par
59  * Child implementations define specific parts of these operations
60  * using these methods as a naming and parameter template.
61  *
62  * IcmpSquid - implements the squid side of squid-pinger interface
63  * IcmpPinger - implements the pinger side of the squid-pinger interface
64  * Icmpv4 - implements pinger helper for Icmpv4
65  * Icmpv6 - implements pinger helper for Icmpv6
66  */
67 class Icmp
68 {
69 public:
70     Icmp();
~Icmp()71     virtual ~Icmp() {}
72 
73     /// Start pinger helper and initiate control channel
74     virtual int Open() =0;
75 
76     /// Shutdown pinger helper and control channel
77     virtual void Close();
78 
79 #if USE_ICMP
80 
81     /**
82      * Construct and Send an ECHO request
83      *
84      \param to        Destination address being 'pinged'
85      \param opcode    Specific code for ECHO request, see RFC ????.
86      \param payload   A payload MAY be sent in the ICMP message.
87      *                Content longer than MAX_PAYLOAD will be truncated.
88      \param len       Length of the payload in bytes if any is to be sent or 0.
89      */
90     virtual void SendEcho(Ip::Address &to, int opcode, const char *payload=NULL, int len=0) =0;
91 
92     /// Handle ICMP responses.
93     virtual void Recv(void) =0;
94 
95 protected:
96     /* shared internal methods */
97 
98     /// Calculate a packet checksum
99     int CheckSum(unsigned short *ptr, int size);
100 
101     /**
102      * Translate TTL to a hop distance
103      *
104      \param ttl negative     : n > 33
105      \param ttl n(0...32)    : 32 >= n >= 1
106      \param ttl n(33...62)   : 32 >= n >= 1
107      \param ttl n(63...64)   : 2 >= n >= 1
108      \param ttl n(65...128)  : 64 >= n >= 1
109      \param ttl n(129...192) : 64 >= n >= 1
110      \param ttl n(193...)    : n < 255
111      *
112      \bug BUG? ttl<0 can produce high hop values
113      \bug BUG? ttl>255 can produce zero or negative hop values
114      */
115     int ipHops(int ttl);
116 
117     /// Log the packet.
118     void Log(const Ip::Address &addr, const uint8_t type, const char* pkt_str, const int rtt, const int hops);
119 
120     /* no use wasting memory */
121     int icmp_sock;
122     int icmp_ident;
123 #endif /* USE_ICMP */
124 };
125 
126 #endif
127 
128