]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/icmp/Icmp4.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / icmp / Icmp4.cc
index 3b79d2116f513b69f81b3858060ac287d34ec116..9500215b56cb5647baf8a63b59297607ebc751ae 100644 (file)
@@ -1,34 +1,13 @@
 /*
- * 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"
 #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()
 {
@@ -78,7 +69,8 @@ Icmp4::Open(void)
     icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
 
     if (icmp_sock < 0) {
-        debugs(50, DBG_CRITICAL, HERE << " icmp_sock: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << " icmp_sock: " << xstrerr(xerrno));
         return -1;
     }
 
@@ -151,11 +143,12 @@ Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
                S->ai_addrlen);
 
     if (x < 0) {
-        debugs(42, DBG_IMPORTANT, 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::FreeAddrInfo(S);
+    Ip::Address::FreeAddr(S);
 }
 
 void
@@ -179,7 +172,7 @@ Icmp4::Recv(void)
     if (pkt == NULL)
         pkt = (char *)xmalloc(MAX_PKT4_SZ);
 
-    Ip::Address::InitAddrInfo(from);
+    Ip::Address::InitAddr(from);
     n = recvfrom(icmp_sock,
                  (void *)pkt,
                  MAX_PKT4_SZ,
@@ -187,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
@@ -222,12 +221,12 @@ Icmp4::Recv(void)
     icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
 
     if (icmp->icmp_type != ICMP_ECHOREPLY) {
-        Ip::Address::FreeAddrInfo(from);
+        Ip::Address::FreeAddr(from);
         return;
     }
 
     if (icmp->icmp_id != icmp_ident) {
-        Ip::Address::FreeAddrInfo(from);
+        Ip::Address::FreeAddr(from);
         return;
     }
 
@@ -243,10 +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);
-    Ip::Address::FreeAddrInfo(from);
+    Log(preply.from, icmp->icmp_type, IcmpPacketType(icmp->icmp_type), preply.rtt, preply.hops);
+    Ip::Address::FreeAddr(from);
 }
 
 #endif /* USE_ICMP */
+