diff options
| author | Julian Elischer <julian@FreeBSD.org> | 1998-06-05 21:38:12 +0000 |
|---|---|---|
| committer | Julian Elischer <julian@FreeBSD.org> | 1998-06-05 21:38:12 +0000 |
| commit | b7c5bc5cb64b9708b39c17e9b6b68a38f1704745 (patch) | |
| tree | 5ed2875811b38202d2ac216f3fa08c000b16bd6f /sys/netinet | |
| parent | 6b82e09364aca67fdbb27204fd7546913aafb4f0 (diff) | |
Notes
Diffstat (limited to 'sys/netinet')
| -rw-r--r-- | sys/netinet/ip_divert.c | 50 | ||||
| -rw-r--r-- | sys/netinet/ip_fw.c | 39 | ||||
| -rw-r--r-- | sys/netinet/ip_input.c | 27 | ||||
| -rw-r--r-- | sys/netinet/ip_output.c | 4 | ||||
| -rw-r--r-- | sys/netinet/ip_var.h | 11 |
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 */ |
