diff options
author | julian <julian@FreeBSD.org> | 1998-05-25 10:37:48 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1998-05-25 10:37:48 +0000 |
commit | 8c304384d07abcd64cb1542078a26c103aca8a0c (patch) | |
tree | 86945df8f3fb0f7337ec7ff3582e6b50d430cb7c /sys/netinet/ip_input.c | |
parent | bf79f2c5a4a882aa62556198a11b4823281da1f7 (diff) | |
download | FreeBSD-src-8c304384d07abcd64cb1542078a26c103aca8a0c.zip FreeBSD-src-8c304384d07abcd64cb1542078a26c103aca8a0c.tar.gz |
Add optional code to change the way that divert and ipfw work together.
Prior to this change, Accidental recursion protection was done by
the diverted daemon feeding back the divert port number it got
the packet on, as the port number on a sendto(). IPFW knew not to
redivert a packet to this port (again). Processing of the ruleset
started at the beginning again, skipping that divert port.
The new semantic (which is how we should have done it the first time)
is that the port number in the sendto() is the rule number AFTER which
processing should restart, and on a recvfrom(), the port number is the
rule number which caused the diversion. This is much more flexible,
and also more intuitive. If the user uses the same sockaddr received
when resending, processing resumes at the rule number following that
that caused the diversion. The user can however select to resume rule
processing at any rule. (0 is restart at the beginning)
To enable the new code use
option IPFW_DIVERT_RESTART
This should become the default as soon as people have looked at it a bit
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index f80c483..fe0b3a4 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 /* |