Date: Tue, 10 Feb 1998 21:12:21 -0600 (CST) From: Alex Nash <nash@mcs.net> To: avalon@coombs.anu.edu.au Cc: archie@whistle.com, freebsd-hackers@FreeBSD.ORG Subject: Re: ipfw logs ports for fragments Message-ID: <199802110312.VAA08417@nash.pr.mcs.net> In-Reply-To: <199802102235.QAA26217@Mailbox.mcs.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 11 Feb, Darren Reed wrote:
>> Now the question is.. which exception to make?
>>
>> #1 Don't even TRY to match rules containing port ranges and/or flags
>> to non-zero offset fragments.
>
> Correct.
>
>> #2 Match port range/flag rules to non-zero offset fragments by testing
>> the rule AS IF it did not contain the port range and/or flag
>> restrictions.
>
> Wrong.
I think Darren and I are in agreement on this. The patches below
modify ipfw to:
- Not match fragmented packets (where offset != 0) if the rule
specifies a port and/or TCP flags
- Match fragmented packets (where offset != 0) if the rule does
not specify a port and/or TCP flags
Naturally, the standard source, dest, protocol, interface, etc. fields
must also match in the above cases.
Alex
Index: ip_fw.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.c,v
retrieving revision 1.77
diff -c -r1.77 ip_fw.c
*** ip_fw.c 1998/02/09 06:10:10 1.77
--- ip_fw.c 1998/02/11 02:58:35
***************
*** 459,466 ****
if (offset == 1) /* cf. RFC 1858 */
goto bogusfrag;
! if (offset != 0) /* Flags, ports aren't valid */
break;
PULLUP_TO(hlen + 14);
tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
--- 459,476 ----
if (offset == 1) /* cf. RFC 1858 */
goto bogusfrag;
! if (offset != 0) {
! /*
! * TCP flags and ports aren't available in this
! * packet -- if this rule specified either one,
! * we consider the rule a non-match.
! */
! if (f->fw_nports != 0 ||
! f->fw_tcpf != f->fw_tcpnf)
! continue;
!
break;
+ }
PULLUP_TO(hlen + 14);
tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
***************
*** 474,481 ****
{
struct udphdr *udp;
! if (offset != 0) /* Ports aren't valid */
break;
PULLUP_TO(hlen + 4);
udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
src_port = ntohs(udp->uh_sport);
--- 484,500 ----
{
struct udphdr *udp;
! if (offset != 0) {
! /*
! * Port specification is unavailable -- if this
! * rule specifies a port, we consider the rule
! * a non-match.
! */
! if (f->fw_nports != 0)
! continue;
!
break;
+ }
PULLUP_TO(hlen + 4);
udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
src_port = ntohs(udp->uh_sport);
***************
*** 866,871 ****
--- 885,903 ----
(frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) {
dprintf(("%s rule never matches\n", err_prefix));
return(NULL);
+ }
+
+ if ((frwl->fw_flg & IP_FW_F_FRAG) &&
+ (frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
+ if (frwl->fw_nports) {
+ dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
+ return(NULL);
+ }
+ if (frwl->fw_prot == IPPROTO_TCP &&
+ frwl->fw_tcpf != frwl->fw_tcpnf) {
+ dprintf(("%s cannot mix 'frag' with TCP flags\n", err_prefix));
+ return(NULL);
+ }
}
/* Check command specific stuff */
Index: ipfw.8
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v
retrieving revision 1.37
diff -c -r1.37 ipfw.8
*** ipfw.8 1998/01/07 02:23:03 1.37
--- ipfw.8 1998/02/11 02:57:41
***************
*** 289,294 ****
--- 289,300 ----
.Pa /usr/src/sys/netinet/ip_fw.h )
ports.
.Pp
+ Fragmented packets which have a non-zero offset (i.e. not the first
+ fragment) will never match a rule which has one or more port
+ specifications. See the
+ .Ar frag
+ option for details on matching fragmented packets.
+ .Pp
Rules can apply to packets when they are incoming, or outgoing, or both.
The
.Ar in
***************
*** 360,365 ****
--- 366,375 ----
.It frag
Matches if the packet is a fragment and this is not the first fragment
of the datagram.
+ .Ar frag
+ may not be used in conjunction with either
+ .Ar tcpflags
+ or TCP/UDP port specifications.
.It in
Matches if this packet was on the way in.
.It out
***************
*** 399,404 ****
--- 409,420 ----
.Ar urg .
The absence of a particular flag may be denoted
with a ``!''.
+ A rule which contains a
+ .Ar tcpflags
+ specification can never match a fragmented packet which has
+ a non-zero offset. See the
+ .Ar frag
+ option for details on matching fragmented packets.
.It icmptypes Ar types
Matches if the ICMP type is in the list
.Ar types .
Index: ipfw.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.c,v
retrieving revision 1.53
diff -c -r1.53 ipfw.c
*** ipfw.c 1998/01/08 03:03:50 1.53
--- ipfw.c 1998/02/11 02:57:54
***************
*** 1108,1113 ****
--- 1108,1122 ----
} else if ((rule.fw_flg & IP_FW_F_OIFACE) && (rule.fw_flg & IP_FW_F_IN))
show_usage("can't check xmit interface of incoming packets");
+ /* frag may not be used in conjunction with ports or TCP flags */
+ if (rule.fw_flg & IP_FW_F_FRAG) {
+ if (rule.fw_tcpf || rule.fw_tcpnf)
+ errx(EX_USAGE, "can't mix 'frag' and tcpflags");
+
+ if (rule.fw_nports)
+ errx(EX_USAGE, "can't mix 'frag' and port specifications");
+ }
+
if (!do_quiet)
show_ipfw(&rule, 10, 10);
i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802110312.VAA08417>
