Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Apr 2005 08:22:13 +0000
From:      Sergey Lyubka <valenok@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   transparent squid proxy + bridge
Message-ID:  <72c3a95705042001227812f6e6@mail.gmail.com>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hi there,
Recently I tried to make a transparent web proxy on a machine
that run in bridging mode. At last, I decided to make a patch.
Here it is for those who want to do the same.
One interface should be given an IP address so squid may do
a requests. Squid listens on 127.0.0.1:8080.
I am using pf firewall, with this redirection rule:
rdr on $int proto tcp from any to any port 80 -> (lo0) port 8080

This is what the patch does:

static void ether_input()
{
    ...
   if (packet_is_IP_packet && pf_enabled && mbuf_copy = copy_the_mbuf) {
        strip_ethernet_headers;
        run_the_firewall;
        if (packet_redirected_to_127.0.0.1)
            bypass_the_bridge
       free_the_mbuf_copy;

   }
  ...
}

The patch is small, so I include it inline.
Tested on 5.4

[-- Attachment #2 --]
--- /usr/src/sys/net/if_ethersubr.c.orig	Thu Mar 31 14:58:36 2005
+++ /usr/src/sys/net/if_ethersubr.c	Tue Apr 19 13:50:05 2005
@@ -66,8 +66,10 @@
 #if defined(INET) || defined(INET6)
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#include <netinet/in_systm.h>
 #include <netinet/if_ether.h>
 #include <netinet/ip_fw.h>
+#include <netinet/ip.h>
 #include <netinet/ip_dummynet.h>
 #endif
 #ifdef INET6
@@ -485,6 +487,8 @@
 }
 #endif
 
+#include <net/pfil.h>
+extern struct pfil_head inet_pfil_hook;
 /*
  * Process a received Ethernet packet; the packet is in the
  * mbuf chain m with the ethernet header at the front.
@@ -493,7 +497,9 @@
 ether_input(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ether_header *eh;
+	struct mbuf *m2;
 	u_short etype;
+	int tolocal = 0;
 
 	/*
 	 * Do consistency checks to verify assumptions
@@ -576,8 +582,50 @@
 			return;
 	}
 
+#if 1
+	/*************** UGLY HACK !! *******************/
+	if (etype == 0x800 &&
+	    inet_pfil_hook.ph_busy_count != -1 &&
+	    (m2 = m_dup(m, M_DONTWAIT)) != NULL) {
+		struct ip *ip;
+		
+		m_adj(m2, ETHER_HDR_LEN);	/* remove ether hdr */
+		ip = mtod(m2, struct ip *);
+
+		ip->ip_len = ntohs(ip->ip_len);
+		ip->ip_off = ntohs(ip->ip_off);		
+		
+		if (m2->m_pkthdr.len > ip->ip_len) {
+			if (m2->m_len == m2->m_pkthdr.len) {
+				m2->m_len = ip->ip_len;
+				m2->m_pkthdr.len = ip->ip_len;
+			} else
+				m_adj(m2, ip->ip_len - m2->m_pkthdr.len);
+		}
+		
+		if (pfil_run_hooks(&inet_pfil_hook, &m2, m2->m_pkthdr.rcvif,
+		    PFIL_IN, NULL) != 0) {
+			m_freem(m);
+			return;
+		}
+
+		if (m2 == NULL)	{
+			m_freem(m);
+			return;
+		}
+		
+		ip = mtod(m2, struct ip *);
+		if (ip->ip_dst.s_addr == ntohl(INADDR_LOOPBACK))
+			tolocal = 1;
+
+		
+		m_freem(m2);
+	}
+	/*************** END OF UGLY HACK *******************/
+#endif
+
 	/* Check for bridging mode */
-	if (BDG_ACTIVE(ifp) ) {
+	if (BDG_ACTIVE(ifp) && tolocal == 0) {
 		struct ifnet *bif;
 
 		/*
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?72c3a95705042001227812f6e6>