/*
- * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ * 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.
#define IPFILTER_VERSION 5000004
#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
#if HAVE_SYS_IOCCOM_H
#include <sys/ioccom.h>
#endif
&lookup,
&len) != 0) {
if (!silent) {
- debugs(89, DBG_IMPORTANT, "ERROR: NF getsockopt(ORIGINAL_DST) failed on " << newConn << ": " << xstrerror());
+ int xerrno = errno;
+ debugs(89, DBG_IMPORTANT, "ERROR: NF getsockopt(ORIGINAL_DST) failed on " << newConn << ": " << xstrerr(xerrno));
lastReported_ = squid_curtime;
}
debugs(89, 9, "address: " << newConn);
/* Trust the user configured properly. If not no harm done.
* We will simply attempt a bind outgoing on our own IP.
*/
- newConn->remote.port(0); // allow random outgoing port to prevent address clashes
debugs(89, 5, HERE << "address TPROXY: " << newConn);
return true;
#else
// all fields must be set to 0
memset(&natLookup, 0, sizeof(natLookup));
// for NAT lookup set local and remote IP:port's
- natLookup.nl_inport = htons(newConn->local.port());
+ if (newConn->remote.isIPv6()) {
+#if HAVE_NATLOOKUP_NL_INIPADDR_IN6
+ natLookup.nl_v = 6;
+ newConn->local.getInAddr(natLookup.nl_inipaddr.in6);
+ newConn->remote.getInAddr(natLookup.nl_outipaddr.in6);
+ }
+ else {
+ natLookup.nl_v = 4;
+ newConn->local.getInAddr(natLookup.nl_inipaddr.in4);
+ newConn->remote.getInAddr(natLookup.nl_outipaddr.in4);
+ }
+#else
+ // warn once every 10 at critical level, then push down a level each repeated event
+ static int warningLevel = DBG_CRITICAL;
+ debugs(89, warningLevel, "Your IPF (IPFilter) NAT does not support IPv6. Please upgrade it.");
+ warningLevel = (warningLevel + 1) % 10;
+ return false;
+ }
newConn->local.getInAddr(natLookup.nl_inip);
- natLookup.nl_outport = htons(newConn->remote.port());
newConn->remote.getInAddr(natLookup.nl_outip);
+#endif
+ natLookup.nl_inport = htons(newConn->local.port());
+ natLookup.nl_outport = htons(newConn->remote.port());
// ... and the TCP flag
natLookup.nl_flags = IPN_TCP;
if (natfd < 0) {
if (!silent) {
- debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT open failed: " << xstrerror());
+ int xerrno = errno;
+ debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT open failed: " << xstrerr(xerrno));
lastReported_ = squid_curtime;
return false;
}
#endif
if (x < 0) {
- if (errno != ESRCH) {
+ int xerrno = errno;
+ if (xerrno != ESRCH) {
if (!silent) {
- debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT lookup failed: ioctl(SIOCGNATL) (v=" << IPFILTER_VERSION << "): " << xstrerror());
+ debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT lookup failed: ioctl(SIOCGNATL) (v=" << IPFILTER_VERSION << "): " << xstrerr(xerrno));
lastReported_ = squid_curtime;
}
debugs(89, 9, HERE << "address: " << newConn);
return false;
} else {
+#if HAVE_NATLOOKUP_NL_REALIPADDR_IN6
+ if (newConn->remote.isIPv6())
+ newConn->local = natLookup.nl_realipaddr.in6;
+ else
+ newConn->local = natLookup.nl_realipaddr.in4;
+#else
newConn->local = natLookup.nl_realip;
+#endif
newConn->local.port(ntohs(natLookup.nl_realport));
debugs(89, 5, HERE << "address NAT: " << newConn);
return true;
if (pffd < 0) {
if (!silent) {
- debugs(89, DBG_IMPORTANT, HERE << "PF open failed: " << xstrerror());
+ int xerrno = errno;
+ debugs(89, DBG_IMPORTANT, MYNAME << "PF open failed: " << xstrerr(xerrno));
lastReported_ = squid_curtime;
}
return false;
}
memset(&nl, 0, sizeof(struct pfioc_natlook));
- newConn->remote.getInAddr(nl.saddr.v4);
- nl.sport = htons(newConn->remote.port());
- newConn->local.getInAddr(nl.daddr.v4);
+ if (newConn->remote.isIPv6()) {
+ newConn->remote.getInAddr(nl.saddr.v6);
+ newConn->local.getInAddr(nl.daddr.v6);
+ nl.af = AF_INET6;
+ } else {
+ newConn->remote.getInAddr(nl.saddr.v4);
+ newConn->local.getInAddr(nl.daddr.v4);
+ nl.af = AF_INET;
+ }
+
+ nl.sport = htons(newConn->remote.port());
nl.dport = htons(newConn->local.port());
- nl.af = AF_INET;
nl.proto = IPPROTO_TCP;
nl.direction = PF_OUT;
if (ioctl(pffd, DIOCNATLOOK, &nl)) {
- if (errno != ENOENT) {
+ int xerrno = errno;
+ if (xerrno != ENOENT) {
if (!silent) {
- debugs(89, DBG_IMPORTANT, HERE << "PF lookup failed: ioctl(DIOCNATLOOK)");
+ debugs(89, DBG_IMPORTANT, HERE << "PF lookup failed: ioctl(DIOCNATLOOK): " << xstrerr(xerrno));
lastReported_ = squid_curtime;
}
close(pffd);
debugs(89, 9, HERE << "address: " << newConn);
return false;
} else {
- newConn->local = nl.rdaddr.v4;
+ if (newConn->remote.isIPv6())
+ newConn->local = nl.rdaddr.v6;
+ else
+ newConn->local = nl.rdaddr.v4;
newConn->local.port(ntohs(nl.rdport));
debugs(89, 5, HERE << "address NAT: " << newConn);
return true;