From owner-freebsd-hackers Tue Nov 5 01:42:16 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id BAA22375 for hackers-outgoing; Tue, 5 Nov 1996 01:42:16 -0800 (PST) Received: from mpool.st.simbirsk.su (root@mpool.st.simbirsk.su [193.124.96.129]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id BAA22096 for ; Tue, 5 Nov 1996 01:39:26 -0800 (PST) Received: by mpool.st.simbirsk.su id AA26920 (5.65/IDA-simtel); Tue, 5 Nov 1996 12:30:09 +0300 From: Viacheslav Andreev Message-Id: <199611050930.AA26920@mpool.st.simbirsk.su> Subject: ip_fw.c - bug or feature ? To: freebsd-hackers@FreeBSD.ORG Date: Tue, 5 Nov 1996 12:30:08 +0300 (MVW) Organization: Systemotechnika Center, Dimitrovgrad X-Mailer: ELM [version 2.4 PL24 ME8a] Content-Type: text Sender: owner-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk Hi! I am not shure, this is a bug or feature. While trying to disable tcp traffic for some port, f.e. ipfw add 1070 deny log tcp from any to 192.168.0.1 80 , there are false dropping of fragmented (i.e. 2-nd and next-s without tcp port info) packets of ftp traffic. IMHO, it is a result of matching fragments over firewall rules with tcp port specs : -----------/sys/netinet/ip_fw.c----------------------------- /* Check TCP flags and TCP/UDP ports only if packet is not fragment */ if (!(ip->ip_off & IP_OFFMASK)) { /* TCP, a little more checking */ if (prt == IP_FW_F_TCP && (f->fw_tcpf != f->fw_tcpnf) && (!tcpflg_match(tcp, f))) continue; if (!port_match(&f->fw_pts[0], f->fw_nsp, src_port, f->fw_flg & IP_FW_F_SRNG)) continue; if (!port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port, f->fw_flg & IP_FW_F_DRNG)) continue; } !!! fragmented packets matches here with rules with tcp port spec. got_match: f->fw_pcnt++; f->fw_bcnt+=ip->ip_len; f->timestamp = time.tv_sec; if (f->fw_flg & IP_FW_F_PRN) { IMHO, to sovle this porblem, source should look like this : /* Check TCP flags and TCP/UDP ports only if packet is not fragment */ if (!(ip->ip_off & IP_OFFMASK)) { /* TCP, a little more checking */ if (prt == IP_FW_F_TCP && (f->fw_tcpf != f->fw_tcpnf) && (!tcpflg_match(tcp, f))) continue; if (!port_match(&f->fw_pts[0], f->fw_nsp, src_port, f->fw_flg & IP_FW_F_SRNG)) continue; if (!port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port, f->fw_flg & IP_FW_F_DRNG)) continue; } else { /* fragment here */ if (f->fw_ndp > 0 || f->fw_nsp > 0) { continue; /* don't match fragment with "precize" rule */ } } -- Viacheslav Andreev Dimitrovgrad town, Middle Volga, Russia.