# FILE: ipfw2state.patch # PATCHES: /usr/src/sys/netinet/ip_fw2.c # WRITTEN BY: Aaron D. Gifford - http://www.adg.us/ # PURPOSE: Patch the FreeBSD kernel's (Luigi's) ipfw2 system so # that it more tightly controls bogus traffic, and # warns the firewall administrator when there's fishy # TCP traffic (or there's a buggy rule set). # --- /usr/src/sys/netinet/ip_fw2.c.orig Tue Jul 23 21:21:23 2002 +++ /usr/src/sys/netinet/ip_fw2.c Thu Aug 1 09:52:50 2002 @@ -771,16 +771,36 @@ q->expire = time_second + dyn_fin_lifetime; break; default: -#if 0 - /* - * reset or some invalid combination, but can also - * occur if we use keep-state the wrong way. - */ - if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0) - printf("invalid state: 0x%x\n", q->state); -#endif - q->expire = time_second + dyn_rst_lifetime; - break; + if ( (q->state & ((TH_RST << 8)|TH_RST)) != 0) { + /* Reset */ + q->expire = time_second + dyn_rst_lifetime; + break; + } else if (q->state == (TH_SYN | TH_ACK)) { + /* + * Both forward SYN and ACK packets have been + * seen, without a reverse SYN+ACK packet, + * because of bogus traffic, a buggy rule set, + * or alternate packet paths bypassing this + * firewall. + */ + if (fw_verbose) { + log(LOG_SECURITY | LOG_NOTICE, + "ipfw: Dynamic TCP rule (%d) expired " + "due to missing SYN+ACK during three-" + "way TCP handshake.\n", + q->rule->rulenum); + } + } else { + /* Any other state is also invalid. */ + if (fw_verbose) { + log(LOG_SECURITY | LOG_NOTICE, + "ipfw: Dynamic TCP rule (%d) expired " + "due to invalid TCP state: 0x%x\n", + q->rule->rulenum, q->state); + } + } + q->expire = 0; /* Expire dynamic rule and act */ + return NULL; /* as if there was no match found */ } } else if (pkt->proto == IPPROTO_UDP) { q->expire = time_second + dyn_udp_lifetime;