diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c index d24280a3c3e1..d8f49340b125 100644 --- a/sbin/ipfw/ipfw.c +++ b/sbin/ipfw/ipfw.c @@ -453,7 +453,7 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth) if (chain->fw_ipflg & IP_FW_IF_IPVER) printf(" ipversion %u", chain->fw_ipver); - if (chain->fw_tcpf & IP_FW_TCPF_ESTAB) + if (chain->fw_ipflg & IP_FW_IF_TCPEST) printf(" established"); else if (chain->fw_tcpf == IP_FW_TCPF_SYN && chain->fw_tcpnf == IP_FW_TCPF_ACK) @@ -2025,8 +2025,7 @@ add(ac,av) } if (rule.fw_prot == IPPROTO_TCP) { if (!strncmp(*av,"established",strlen(*av))) { - rule.fw_tcpf |= IP_FW_TCPF_ESTAB; - rule.fw_ipflg |= IP_FW_IF_TCPFLG; + rule.fw_ipflg |= IP_FW_IF_TCPEST; av++; ac--; continue; } if (!strncmp(*av,"setup",strlen(*av))) { diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 7e69223a8558..3f3d325b4d08 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -244,10 +244,16 @@ static int tcpflg_match(struct tcphdr *tcp, struct ip_fw *f) { u_char flg_set, flg_clr; - - if ((f->fw_tcpf & IP_FW_TCPF_ESTAB) && - (tcp->th_flags & (IP_FW_TCPF_RST | IP_FW_TCPF_ACK))) - return 1; + + /* + * If an established connection is required, reject packets that + * have only SYN of RST|ACK|SYN set. Otherwise, fall through to + * other flag requirements. + */ + if ((f->fw_ipflg & IP_FW_IF_TCPEST) && + ((tcp->th_flags & (IP_FW_TCPF_RST | IP_FW_TCPF_ACK | + IP_FW_TCPF_SYN)) == IP_FW_TCPF_SYN)) + return 0; flg_set = tcp->th_flags & f->fw_tcpf; flg_clr = tcp->th_flags & f->fw_tcpnf; @@ -1243,7 +1249,9 @@ ip_fw_chk(struct ip **pip, int hlen, if (f->fw_ipflg & IP_FW_IF_TCPOPT && !tcpopts_match(tcp, f)) continue; - if (f->fw_ipflg & IP_FW_IF_TCPFLG && !tcpflg_match(tcp, f)) + if (((f->fw_ipflg & IP_FW_IF_TCPFLG) || + (f->fw_ipflg & IP_FW_IF_TCPEST)) && + !tcpflg_match(tcp, f)) continue; if (f->fw_ipflg & IP_FW_IF_TCPSEQ && tcp->th_seq != f->fw_tcpseq) continue; diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index f61abd1450e4..a642d7206998 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -222,7 +222,8 @@ struct ipfw_dyn_rule { #define IP_FW_IF_TCPSEQ 0x00000004 /* tcp sequence number */ #define IP_FW_IF_TCPACK 0x00000008 /* tcp acknowledgement number */ #define IP_FW_IF_TCPWIN 0x00000010 /* tcp window size */ -#define IP_FW_IF_TCPMSK 0x0000001f /* mask of all tcp values */ +#define IP_FW_IF_TCPEST 0x00000020 /* established TCP connection */ +#define IP_FW_IF_TCPMSK 0x0000003f /* mask of all tcp values */ #define IP_FW_IF_IPOPT 0x00000100 /* ip options */ #define IP_FW_IF_IPLEN 0x00000200 /* ip length */ @@ -274,7 +275,6 @@ struct ipfw_dyn_rule { #define IP_FW_TCPF_PSH TH_PUSH #define IP_FW_TCPF_ACK TH_ACK #define IP_FW_TCPF_URG TH_URG -#define IP_FW_TCPF_ESTAB 0x40 /* * Main firewall chains definitions and global var's definitions. diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h index 6c214e80b557..3b72094025c6 100644 --- a/sys/netinet/tcp.h +++ b/sys/netinet/tcp.h @@ -67,7 +67,9 @@ struct tcphdr { #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 -#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) +#define TH_ECE 0x40 +#define TH_CWR 0x80 +#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short th_sum; /* checksum */