summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>1998-06-05 21:38:12 +0000
committerJulian Elischer <julian@FreeBSD.org>1998-06-05 21:38:12 +0000
commitb7c5bc5cb64b9708b39c17e9b6b68a38f1704745 (patch)
tree5ed2875811b38202d2ac216f3fa08c000b16bd6f /sys/netinet
parent6b82e09364aca67fdbb27204fd7546913aafb4f0 (diff)
Notes
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_divert.c50
-rw-r--r--sys/netinet/ip_fw.c39
-rw-r--r--sys/netinet/ip_input.c27
-rw-r--r--sys/netinet/ip_output.c4
-rw-r--r--sys/netinet/ip_var.h11
5 files changed, 122 insertions, 9 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 8a2ecf7dad49..5a267f78e2fa 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -30,9 +30,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ip_divert.c,v 1.1.2.6 1998/05/28 06:17:57 julian Exp $
+ * $Id: ip_divert.c,v 1.1.2.7 1998/05/28 06:28:49 julian Exp $
*/
+#include "opt_ipfw.h"
+
+#ifndef INET
+#error "IPDIVERT requires INET."
+#endif
+
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/malloc.h>
@@ -74,11 +80,29 @@
u_short ip_divert_port;
/*
+ * #ifndef IPFW_DIVERT_RESTART
* We set this value to a non-zero port number when we want the call to
* ip_fw_chk() in ip_input() or ip_output() to ignore ``divert <port>''
* chain entries. This is stored in host order.
+ * #else
+ * A 16 bit cookie is passed to the user process.
+ * The user process can send it back to help the caller know something
+ * about where the packet came from.
+ *
+ * If IPFW is the caller then the IN cookie is the rule that sent
+ * us here and the OUT cookie is the rule after which processing
+ * should continue. Leaving it the same will make processing start
+ * at the rule number after that which sent it here. Setting it to
+ * 0 will restart processing at the beginning.
+ * #endif
*/
+#ifndef IPFW_DIVERT_RESTART
u_short ip_divert_ignore;
+#else
+
+u_short ip_divert_in_cookie;
+u_short ip_divert_out_cookie;
+#endif /* IPFW_DIVERT_RESTART */
/* Internal variables */
@@ -139,7 +163,12 @@ div_input(struct mbuf *m, int hlen)
ip = mtod(m, struct ip *);
/* Record divert port */
+#ifndef IPFW_DIVERT_RESTART
divsrc.sin_port = htons(ip_divert_port);
+#else
+ divsrc.sin_port = ip_divert_in_cookie;
+ ip_divert_in_cookie = 0;
+#endif /* IPFW_DIVERT_RESTART */
/* Restore packet header fields */
ip->ip_len += hlen;
@@ -240,12 +269,20 @@ div_output(so, m, addr, control)
if (addr)
sin = mtod(addr, struct sockaddr_in *);
- /* Loopback avoidance option */
+ /* Loopback avoidance */
+#ifndef IPFW_DIVERT_RESTART
if (sin) {
ip_divert_ignore = ntohs(sin->sin_port);
} else {
ip_divert_ignore = 0;
}
+#else
+ if (sin) {
+ ip_divert_out_cookie = sin->sin_port;
+ } else {
+ ip_divert_out_cookie = 0;
+ }
+#endif /* IPFW_DIVERT_RESTART */
/* Reinject packet into the system as incoming or outgoing */
if (!sin || sin->sin_addr.s_addr == 0) {
@@ -273,6 +310,7 @@ div_output(so, m, addr, control)
char *c = sin->sin_zero;
sin->sin_port = 0;
+
/*
* Find receive interface with the given name or IP address.
* The name is user supplied data so don't trust it's size or
@@ -302,11 +340,19 @@ div_output(so, m, addr, control)
}
/* Reset for next time (and other packets) */
+#ifndef IPFW_DIVERT_RESTART
ip_divert_ignore = 0;
+#else
+ ip_divert_out_cookie = 0;
+#endif /* IPFW_DIVERT_RESTART */
return error;
cantsend:
+#ifndef IPFW_DIVERT_RESTART
ip_divert_ignore = 0;
+#else
+ ip_divert_out_cookie = 0;
+#endif /* IPFW_DIVERT_RESTART */
m_freem(m);
return error;
}
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index f9f40adc7d59..2138fecc0ffa 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.51.2.12 1998/02/13 01:58:13 alex Exp $
+ * $Id: ip_fw.c,v 1.51.2.13 1998/03/29 15:01:13 alex Exp $
*/
/*
@@ -94,8 +94,13 @@ static ip_fw_chk_t *old_chk_ptr;
static ip_fw_ctl_t *old_ctl_ptr;
#endif
+#ifndef IPFW_DIVERT_RESTART
static int ip_fw_chk __P((struct ip **pip, int hlen,
struct ifnet *oif, int ignport, struct mbuf **m));
+#else
+static int ip_fw_chk __P((struct ip **pip, int hlen,
+ struct ifnet *oif, int pastrule, struct mbuf **m));
+#endif /* IPFW_DIVERT_RESTART */
static int ip_fw_ctl __P((int stage, struct mbuf **mm));
static char err_prefix[] = "ip_fw_ctl:";
@@ -371,7 +376,11 @@ ipfw_report(struct ip_fw *f, struct ip *ip,
* ip Pointer to packet header (struct ip *)
* hlen Packet header length
* oif Outgoing interface, or NULL if packet is incoming
+ * #ifndef IPFW_DIVERT_RESTART
* ignport Ignore all divert/tee rules to this port (if non-zero)
+ * #else
+ * pastrule Skip up to the first rule past this rule number;
+ * #endif
* *m The packet; we set to NULL when/if we nuke it.
*
* Return value:
@@ -383,8 +392,13 @@ ipfw_report(struct ip_fw *f, struct ip *ip,
*/
static int
+#ifndef IPFW_DIVERT_RESTART
ip_fw_chk(struct ip **pip, int hlen,
struct ifnet *oif, int ignport, struct mbuf **m)
+#else
+ip_fw_chk(struct ip **pip, int hlen,
+ struct ifnet *oif, int pastrule, struct mbuf **m)
+#endif /* IPFW_DIVERT_RESTART */
{
struct ip_fw_chain *chain;
struct ip_fw *rule = NULL;
@@ -395,8 +409,24 @@ ip_fw_chk(struct ip **pip, int hlen,
/*
* Go down the chain, looking for enlightment
+ * #ifdef IPFW_DIVERT_RESTART
+ * If we've been asked to start at a given rule immediatly, do so.
+ * #endif
*/
- for (chain=ip_fw_chain.lh_first; chain; chain = chain->chain.le_next) {
+#ifndef IPFW_DIVERT_RESTART
+ for (chain=LIST_FIRST(&ip_fw_chain); chain; chain = LIST_NEXT(chain, chain)) {
+#else
+ chain=LIST_FIRST(&ip_fw_chain);
+ if ( pastrule ) {
+ if (pastrule >= 65535)
+ goto dropit;
+ while (chain && (chain->rule->fw_number <= pastrule)) {
+ chain = LIST_NEXT(chain, chain);
+ }
+ if (! chain) goto dropit;
+ }
+ for (; chain; chain = LIST_NEXT(chain, chain)) {
+#endif /* IPFW_DIVERT_RESTART */
register struct ip_fw *const f = chain->rule;
/* Check direction inbound */
@@ -544,6 +574,7 @@ bogusfrag:
}
got_match:
+#ifndef IPFW_DIVERT_RESTART
/* Ignore divert/tee rule if socket port is "ignport" */
switch (f->fw_flg & IP_FW_F_COMMAND) {
case IP_FW_F_DIVERT:
@@ -553,6 +584,7 @@ got_match:
break;
}
+#endif /* IPFW_DIVERT_RESTART */
/* Update statistics */
f->fw_pcnt += 1;
f->fw_bcnt += ip->ip_len;
@@ -569,6 +601,9 @@ got_match:
case IP_FW_F_COUNT:
continue;
case IP_FW_F_DIVERT:
+#ifdef IPFW_DIVERT_RESTART
+ ip_divert_in_cookie = f->fw_number;
+#endif /* IPFW_DIVERT_RESTART */
return(f->fw_divert_port);
case IP_FW_F_TEE:
/*
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 46e8a272ccba..38d85b97005b 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.50.2.13 1998/02/26 17:17:09 dima Exp $
+ * $Id: ip_input.c,v 1.50.2.14 1998/05/25 05:26:43 dg Exp $
* $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $
*/
@@ -335,8 +335,15 @@ tooshort:
#ifdef IPDIVERT
u_short port;
+#ifndef IPFW_DIVERT_RESTART
port = (*ip_fw_chk_ptr)(&ip, hlen, NULL, ip_divert_ignore, &m);
ip_divert_ignore = 0;
+#else
+ ip_divert_in_cookie = 0;
+ port = (*ip_fw_chk_ptr)(&ip, hlen, NULL,
+ ip_divert_out_cookie, &m);
+ ip_divert_out_cookie = 0;
+#endif /* IPFW_DIVERT_RESTART */
if (port) { /* Divert packet */
frag_divert_port = port;
goto ours;
@@ -565,6 +572,12 @@ found:
ipstat.ips_noproto++;
goto bad;
}
+
+ /* Don't let packets divert themselves */
+ if (ip->ip_p == IPPROTO_DIVERT) {
+ ipstat.ips_noproto++;
+ goto bad;
+ }
#endif
/*
@@ -640,6 +653,9 @@ ip_reass(ip, fp, where)
fp->ipq_dst = ((struct ip *)ip)->ip_dst;
#ifdef IPDIVERT
fp->ipq_divert = 0;
+#ifdef IPFW_DIVERT_RESTART
+ fp->ipq_div_cookie = 0;
+#endif /* IPFW_DIVERT_RESTART */
#endif
q = (struct ipasfrag *)fp;
goto insert;
@@ -694,8 +710,12 @@ insert:
/*
* Any fragment diverting causes the whole packet to divert
*/
- if (frag_divert_port != 0)
+ if (frag_divert_port != 0) {
fp->ipq_divert = frag_divert_port;
+#ifdef IPFW_DIVERT_RESTART
+ fp->ipq_div_cookie = ip_divert_in_cookie;
+#endif /* IPFW_DIVERT_RESTART */
+ }
frag_divert_port = 0;
#endif
@@ -743,6 +763,9 @@ insert:
* Record divert port for packet, if any
*/
frag_divert_port = fp->ipq_divert;
+#ifdef IPFW_DIVERT_RESTART
+ ip_divert_in_cookie = fp->ipq_div_cookie;
+#endif /* IPFW_DIVERT_RESTART */
#endif
/*
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 31b05102e4c4..38de902da52c 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
- * $Id: ip_output.c,v 1.44.2.6 1997/06/20 23:05:38 julian Exp $
+ * $Id$
*/
#define _IP_VHL
@@ -331,7 +331,7 @@ ip_output(m0, opt, ro, flags, imo)
}
sendit:
- /*
+ /*
* IpHack's section.
* - Xlate: translate packet's addr/port (NAT).
* - Firewall: deny/allow/etc.
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 634c860df20f..b64223d9b98c 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_var.h 8.2 (Berkeley) 1/9/95
- * $Id: ip_var.h,v 1.24.2.2 1996/11/12 11:28:59 phk Exp $
+ * $Id: ip_var.h,v 1.24.2.3 1997/09/16 12:03:45 ache Exp $
*/
#ifndef _NETINET_IP_VAR_H_
@@ -65,6 +65,9 @@ struct ipq {
struct in_addr ipq_src,ipq_dst;
#ifdef IPDIVERT
u_short ipq_divert; /* divert protocol port */
+#ifdef IPFW_DIVERT_RESTART
+ u_short ipq_div_cookie; /* divert protocol cookie */
+#endif /* IPFW_DIVERT_RESTART */
#endif
};
@@ -203,7 +206,13 @@ void div_input __P((struct mbuf *, int));
int div_usrreq __P((struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *));
extern u_short ip_divert_port;
+#ifndef IPFW_DIVERT_RESTART
extern u_short ip_divert_ignore;
+#else
+extern u_short ip_divert_in_cookie;
+extern u_short ip_divert_out_cookie;
+
+#endif /* IPFW_DIVERT_RESTART */
#endif /* IPDIVERT */
#endif /* KERNEL */