]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/icmp/Icmp4.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / icmp / Icmp4.cc
index ce221f9e7ed9a189a2f2582fd943e9f306adc5f8..9500215b56cb5647baf8a63b59297607ebc751ae 100644 (file)
@@ -1,67 +1,57 @@
 /*
- * $Id$
- *
- * DEBUG: section 42    ICMP Pinger program
- * AUTHOR: Duane Wessels, Amos Jeffries
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
+
+/* DEBUG: section 42    ICMP Pinger program */
+
 //#define SQUID_HELPER 1
 
 #include "squid.h"
 
 #if USE_ICMP
 
-#include "SquidTime.h"
+#include "Debug.h"
 #include "Icmp4.h"
 #include "IcmpPinger.h"
-#include "Debug.h"
+#include "leakcheck.h"
+#include "SquidTime.h"
 
-const char *icmpPktStr[] = {
-    "Echo Reply",
-    "ICMP 1",
-    "ICMP 2",
-    "Destination Unreachable",
-    "Source Quench",
-    "Redirect",
-    "ICMP 6",
-    "ICMP 7",
-    "Echo",
-    "ICMP 9",
-    "ICMP 10",
-    "Time Exceeded",
-    "Parameter Problem",
-    "Timestamp",
-    "Timestamp Reply",
-    "Info Request",
-    "Info Reply",
-    "Out of Range Type"
-};
+static const char *
+IcmpPacketType(uint8_t v)
+{
+    static const char *icmpPktStr[] = {
+        "Echo Reply",
+        "ICMP 1",
+        "ICMP 2",
+        "Destination Unreachable",
+        "Source Quench",
+        "Redirect",
+        "ICMP 6",
+        "ICMP 7",
+        "Echo",
+        "ICMP 9",
+        "ICMP 10",
+        "Time Exceeded",
+        "Parameter Problem",
+        "Timestamp",
+        "Timestamp Reply",
+        "Info Request",
+        "Info Reply",
+        "Out of Range Type"
+    };
+
+    if (v > 17) {
+        static char buf[50];
+        snprintf(buf, sizeof(buf), "ICMP %u (invalid)", v);
+        return buf;
+    }
+
+    return icmpPktStr[v];
+}
 
 Icmp4::Icmp4() : Icmp()
 {
@@ -79,12 +69,13 @@ Icmp4::Open(void)
     icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
 
     if (icmp_sock < 0) {
-        debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << " icmp_sock: " << xstrerr(xerrno));
         return -1;
     }
 
     icmp_ident = getpid() & 0xffff;
-    debugs(42, 1, "pinger: ICMP socket opened.");
+    debugs(42, DBG_IMPORTANT, "pinger: ICMP socket opened.");
 
     return icmp_sock;
 }
@@ -117,7 +108,8 @@ Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
     icmp->icmp_code = 0;
     icmp->icmp_cksum = 0;
     icmp->icmp_id = icmp_ident;
-    icmp->icmp_seq = (u_short) icmp_pkts_sent++;
+    icmp->icmp_seq = (unsigned short) icmp_pkts_sent;
+    ++icmp_pkts_sent;
 
     // Construct ICMP packet data content
     echo = (icmpEchoData *) (icmp + 1);
@@ -130,18 +122,18 @@ Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
         if (len > MAX_PAYLOAD)
             len = MAX_PAYLOAD;
 
-        xmemcpy(echo->payload, payload, len);
+        memcpy(echo->payload, payload, len);
 
         icmp_pktsize += len;
     }
 
-    icmp->icmp_cksum = CheckSum((u_short *) icmp, icmp_pktsize);
+    icmp->icmp_cksum = CheckSum((unsigned short *) icmp, icmp_pktsize);
 
-    to.GetAddrInfo(S);
+    to.getAddrInfo(S);
     ((sockaddr_in*)S->ai_addr)->sin_port = 0;
     assert(icmp_pktsize <= MAX_PKT4_SZ);
 
-    debugs(42, 2, HERE << "Send ICMP packet to " << to << ".");
+    debugs(42, 5, HERE << "Send ICMP packet to " << to << ".");
 
     x = sendto(icmp_sock,
                (const void *) pkt,
@@ -151,10 +143,12 @@ Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
                S->ai_addrlen);
 
     if (x < 0) {
-        debugs(42, 1, HERE << "Error sending to ICMP packet to " << to << ". ERR: " << xstrerror());
+        int xerrno = errno;
+        debugs(42, DBG_IMPORTANT, MYNAME << "ERROR: sending to ICMP packet to " << to << ": " << xstrerr(xerrno));
     }
 
     Log(to, ' ', NULL, 0, 0);
+    Ip::Address::FreeAddr(S);
 }
 
 void
@@ -171,14 +165,14 @@ Icmp4::Recv(void)
     static pingerReplyData preply;
 
     if (icmp_sock < 0) {
-        debugs(42, 0, HERE << "No socket! Recv() should not be called.");
+        debugs(42, DBG_CRITICAL, HERE << "No socket! Recv() should not be called.");
         return;
     }
 
     if (pkt == NULL)
         pkt = (char *)xmalloc(MAX_PKT4_SZ);
 
-    preply.from.InitAddrInfo(from);
+    Ip::Address::InitAddr(from);
     n = recvfrom(icmp_sock,
                  (void *)pkt,
                  MAX_PKT4_SZ,
@@ -186,6 +180,12 @@ Icmp4::Recv(void)
                  from->ai_addr,
                  &from->ai_addrlen);
 
+    if (n <= 0) {
+        debugs(42, DBG_CRITICAL, HERE << "Error when calling recvfrom() on ICMP socket.");
+        Ip::Address::FreeAddr(from);
+        return;
+    }
+
     preply.from = *from;
 
 #if GETTIMEOFDAY_NO_TZP
@@ -220,11 +220,15 @@ Icmp4::Recv(void)
 
     icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
 
-    if (icmp->icmp_type != ICMP_ECHOREPLY)
+    if (icmp->icmp_type != ICMP_ECHOREPLY) {
+        Ip::Address::FreeAddr(from);
         return;
+    }
 
-    if (icmp->icmp_id != icmp_ident)
+    if (icmp->icmp_id != icmp_ident) {
+        Ip::Address::FreeAddr(from);
         return;
+    }
 
     echo = (icmpEchoData *) (void *) (icmp + 1);
 
@@ -238,9 +242,17 @@ Icmp4::Recv(void)
 
     preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT4_SZ);
 
+    if (preply.psize < 0) {
+        debugs(42, DBG_CRITICAL, HERE << "Malformed ICMP packet.");
+        Ip::Address::FreeAddr(from);
+        return;
+    }
+
     control.SendResult(preply, (sizeof(pingerReplyData) - MAX_PKT4_SZ + preply.psize) );
 
-    Log(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops);
+    Log(preply.from, icmp->icmp_type, IcmpPacketType(icmp->icmp_type), preply.rtt, preply.hops);
+    Ip::Address::FreeAddr(from);
 }
 
 #endif /* USE_ICMP */
+