summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1996-07-10 19:44:30 +0000
committerjulian <julian@FreeBSD.org>1996-07-10 19:44:30 +0000
commit9277e63302140b5062d96a9394cdec2b83b2e70a (patch)
tree5affe14a214c46b4bd58b410a49350e34137ed18 /sys/netinet/ip_input.c
parent366bddd7f5f46d8b7d51ff94c668b40ccecbbc23 (diff)
downloadFreeBSD-src-9277e63302140b5062d96a9394cdec2b83b2e70a.zip
FreeBSD-src-9277e63302140b5062d96a9394cdec2b83b2e70a.tar.gz
Adding changes to ipfw and the kernel to support ip packet diversion..
This stuff should not be too destructive if the IPDIVERT is not compiled in.. be aware that this changes the size of the ip_fw struct so ipfw needs to be recompiled to use it.. more changes coming to clean this up.
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c71
1 files changed, 66 insertions, 5 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 5db23ec..2a17342 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * $Id: ip_input.c,v 1.43 1996/06/08 08:18:57 bde Exp $
+ * $Id: ip_input.c,v 1.44 1996/06/12 19:34:33 gpalmer Exp $
*/
#include "opt_ipfw.h"
@@ -129,6 +129,15 @@ static struct ip_srcrt {
struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
} ip_srcrt;
+#ifdef IPDIVERT
+/*
+ * Shared variable between ip_input() and ip_reass() to communicate
+ * about which packets, once assembled from fragments, get diverted,
+ * and to which port.
+ */
+static u_short frag_divert_port;
+#endif
+
static void save_rte __P((u_char *, struct in_addr));
static void ip_deq __P((struct ipasfrag *));
static int ip_dooptions __P((struct mbuf *));
@@ -255,14 +264,31 @@ ip_input(struct mbuf *m)
* Right now when no processing on packet has done
* and it is still fresh out of network we do our black
* deals with it.
- * - Firewall: deny/allow
+ * - Firewall: deny/allow/divert
* - Wrap: fake packet's addr/port <unimpl.>
* - Encapsulate: put it in another IP and send out. <unimp.>
*/
- if (ip_fw_chk_ptr &&
- !(*ip_fw_chk_ptr)(&ip, hlen, m->m_pkthdr.rcvif, 0, &m))
- return;
+ if (ip_fw_chk_ptr) {
+ int action;
+
+#ifdef IPDIVERT
+ action = (*ip_fw_chk_ptr)(&ip, hlen,
+ m->m_pkthdr.rcvif, ip_divert_ignore, &m);
+#else
+ action = (*ip_fw_chk_ptr)(&ip, hlen, m->m_pkthdr.rcvif, 0, &m);
+#endif
+ if (action == -1)
+ return;
+ if (action != 0) {
+#ifdef IPDIVERT
+ frag_divert_port = action;
+ goto ours;
+#else
+ goto bad; /* ipfw said divert but we can't */
+#endif
+ }
+ }
/*
* Process options and, if not destined for us,
@@ -386,6 +412,9 @@ ours:
if (m->m_flags & M_EXT) { /* XXX */
if ((m = m_pullup(m, sizeof (struct ip))) == 0) {
ipstat.ips_toosmall++;
+#ifdef IPDIVERT
+ frag_divert_port = 0;
+#endif
return;
}
ip = mtod(m, struct ip *);
@@ -432,6 +461,18 @@ found:
} else
ip->ip_len -= hlen;
+#ifdef IPDIVERT
+ /*
+ * Divert packets here to the divert protocol if required
+ */
+ if (frag_divert_port) {
+ ip_divert_port = frag_divert_port;
+ frag_divert_port = 0;
+ (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, hlen);
+ return;
+ }
+#endif
+
/*
* Switch out to protocol's input routine.
*/
@@ -501,6 +542,9 @@ ip_reass(ip, fp)
fp->ipq_next = fp->ipq_prev = (struct ipasfrag *)fp;
fp->ipq_src = ((struct ip *)ip)->ip_src;
fp->ipq_dst = ((struct ip *)ip)->ip_dst;
+#ifdef IPDIVERT
+ fp->ipq_divert = 0;
+#endif
q = (struct ipasfrag *)fp;
goto insert;
}
@@ -546,6 +590,16 @@ ip_reass(ip, fp)
}
insert:
+
+#ifdef IPDIVERT
+ /*
+ * Any fragment diverting causes the whole packet to divert
+ */
+ if (frag_divert_port != 0)
+ fp->ipq_divert = frag_divert_port;
+ frag_divert_port = 0;
+#endif
+
/*
* Stick new segment in its place;
* check for complete reassembly.
@@ -575,6 +629,13 @@ insert:
m_cat(m, t);
}
+#ifdef IPDIVERT
+ /*
+ * Record divert port for packet, if any
+ */
+ frag_divert_port = fp->ipq_divert;
+#endif
+
/*
* Create header for new ip packet by
* modifying header of first packet;
OpenPOWER on IntegriCloud