diff options
| author | Julian Elischer <julian@FreeBSD.org> | 1998-05-25 10:37:48 +0000 |
|---|---|---|
| committer | Julian Elischer <julian@FreeBSD.org> | 1998-05-25 10:37:48 +0000 |
| commit | bb60f459a0577f2159b498164b72a36f5e98c3e8 (patch) | |
| tree | 855a17205dc7a0daa31c684dd21d9b21759dfab7 | |
| parent | 6c920910277d960fc34edcc84de1eb1d058dfa6f (diff) | |
Notes
| -rw-r--r-- | sys/conf/options | 4 | ||||
| -rw-r--r-- | sys/netinet/ip_divert.c | 45 | ||||
| -rw-r--r-- | sys/netinet/ip_fw.c | 37 | ||||
| -rw-r--r-- | sys/netinet/ip_input.c | 27 | ||||
| -rw-r--r-- | sys/netinet/ip_output.c | 10 | ||||
| -rw-r--r-- | sys/netinet/ip_var.h | 11 |
6 files changed, 126 insertions, 8 deletions
diff --git a/sys/conf/options b/sys/conf/options index fac1f87f241e..4293ef408f1e 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -1,4 +1,4 @@ -# $Id: options,v 1.73 1998/05/19 08:58:42 phk Exp $ +# $Id: options,v 1.74 1998/05/24 01:29:52 jkh Exp $ # # On the handling of kernel options # @@ -173,6 +173,8 @@ IPFIREWALL opt_ipfw.h IPFIREWALL_VERBOSE opt_ipfw.h IPFIREWALL_VERBOSE_LIMIT opt_ipfw.h IPFIREWALL_DEFAULT_TO_ACCEPT opt_ipfw.h +#temp option to change ipfw/divert semantics. Should become standard. +IPFW_DIVERT_RESTART opt_ipfw.h IPX opt_ipx.h IPXIP opt_ipx.h IPTUNNEL opt_ipx.h diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 484d687b7eaf..5410e8affe9f 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -30,10 +30,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ip_divert.c,v 1.24 1998/05/25 07:41:23 julian Exp $ + * $Id: ip_divert.c,v 1.25 1998/05/25 08:44:31 julian Exp $ */ #include "opt_inet.h" +#include "opt_ipfw.h" #ifndef INET #error "IPDIVERT requires INET." @@ -81,11 +82,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 */ @@ -149,7 +168,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; @@ -249,12 +273,20 @@ div_output(so, m, addr, control) if (control) m_freem(control); /* XXX */ - /* 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) { @@ -282,6 +314,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 @@ -311,11 +344,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 bcdfda0afb57..112d9ca47c00 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.82 1998/04/21 18:54:53 julian Exp $ + * $Id: ip_fw.c,v 1.83 1998/05/19 14:04:29 dg Exp $ */ /* @@ -103,8 +103,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:"; @@ -381,7 +386,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: @@ -393,8 +402,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; @@ -405,8 +419,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 */ +#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; if (oif) { @@ -556,6 +586,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: @@ -565,6 +596,7 @@ got_match: break; } +#endif /* IPFW_DIVERT_RESTART */ /* Update statistics */ f->fw_pcnt += 1; f->fw_bcnt += ip->ip_len; @@ -581,6 +613,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 f80c483b38f6..fe0b3a46e67f 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.83 1998/05/19 14:04:32 dg Exp $ + * $Id: ip_input.c,v 1.84 1998/05/24 14:59:57 dg Exp $ * $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $ */ @@ -362,8 +362,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; @@ -594,6 +601,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 /* @@ -669,6 +682,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; @@ -723,8 +739,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 @@ -772,6 +792,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 158aba5f2046..da061bbc8351 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. * * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * $Id: ip_output.c,v 1.65 1998/02/20 13:37:38 bde Exp $ + * $Id: ip_output.c,v 1.66 1998/03/21 11:34:20 peter Exp $ */ #define _IP_VHL +#include "opt_ipfw.h" #include "opt_ipdivert.h" #include "opt_ipfilter.h" @@ -370,9 +371,16 @@ sendit: */ if (ip_fw_chk_ptr) { #ifdef IPDIVERT +#ifndef IPFW_DIVERT_RESTART ip_divert_port = (*ip_fw_chk_ptr)(&ip, hlen, ifp, ip_divert_ignore, &m); ip_divert_ignore = 0; +#else + ip_divert_in_cookie = 0; + ip_divert_port = (*ip_fw_chk_ptr)(&ip, + hlen, ifp, ip_divert_out_cookie, &m); + ip_divert_out_cookie = 0; +#endif /* IPFW_DIVERT_RESTART */ if (ip_divert_port) { /* Divert packet */ (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, 0); goto done; diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 985e17ec82b9..a0aaeeff86ac 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.36 1998/05/19 14:19:03 dg Exp $ + * $Id: ip_var.h,v 1.37 1998/05/19 15:53:50 pb 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 }; @@ -207,7 +210,13 @@ void div_init __P((void)); void div_input __P((struct mbuf *, int)); extern struct pr_usrreqs div_usrreqs; 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 */ |
