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>
