hello -
i have a couple of problems when running ipfilter. (at least one is an
eccentricity of the OS i'm on, but the "fix" is potentially more generally
useful, so i'll mention it even though it's unlikely that anyone else cares...
:-)
1) i have some rules that use proto=tcp (or proto=udp). when packets arrive,
the fr_info_t that's built sets FI_TCPUDP for a tcp packet, and also for a udp
packet. however, that means the fin_p field for the packet doesn't match the
fr_proto field in the rule's frentry_t. invalidating the "TCPUDP means match
either TCP or UDP"...
in fil.c: fr_ipfcheck()
old:
i = ((*lip & *lm) != *ld);
if (i)
return 1;
my copy:
i = ((*lip & *lm) != *ld);
if (i) {
if (((*lip & FI_TCPUDP) != FI_TCPUDP) ||
(((*ld & 0xff) != IPPROTO_TCP) && ((*ld & 0xff) != IPPROTO_UDP)))
{EXITF(12);
return 1;
}
}
i glanced at 4.1.6 and it looks to have the same problem.
2) the eccentricity mentioned above is that for some reason, if you try to get
the ifnet* from an ifname too many times (too rapidly in sequence?), it returns
NULL. this causes a problem in ip_state.c, when creating a new state entry.
the entry is initialized in fr_addstate, and the ifps in the rule are copied
into the state entry (along with the ifnames). after lots of initialization,
shortly before fr_addstate returns, it calls fr_stinsert. the first thing
fr_stinsert does is loop through the ifnames and try to lookup the ifp
associated with each ifname - but it overwrites the previously copied (correct)
ifnet* from the rule.with whatever is returned. my "fix" is to skip the
GETIFP() call if the associated ifp is already initialized:
ip_state.c: fr_stinsert()
old:
for (i = 0; i < 4; i++) {
name = is->is_ifname[i];
my copy:
for (i = 0; i < 4; i++) {
if (is->is_ifp[i] != NULL)
continue;
name = is->is_ifname[i];
3) and 4) these are problematic. i think the issue is quite likely not a bug
in ipfilter, but in the way it's being used. but it's also very possible that
i just don't understand how this is supposed to work! it's an issue with 'keep
state', and while i did go back and look through a couple of years' worth of
the archive, i didn't see anything that answered my question...
the switch i'm working on needs a very limited firewall on the management
interface. it needs to accept connections for about half a dozen server
applications, and block everything else. management connections will be
infrequent in practice, though i use up to about 10 simultaneously in testing.
all outbound traffic is explicitly allowed - no ports, no keep-states, no
per-protocol rules. so i only have 12 in rules, and the guts of ipfilter never
even sees outbound packets at all. if you want an explicit example of my rules:
pass in quick on mgt0 proto tcp/udp from any to any port = telnet keep state
that's one, and most of the rest look pretty similar. i ran into 2 issues with
this, and since no one else has these problems it seems likely that they're due
to not examining outbound traffic or maybe something wrong in my understanding
of how this part of the code works...
3) when a new packet is received that matches a state entry, fr_matchsrcdst()
only updates the is_[sd]end and is_max[sd]end if the ports are wild. is it
updated elsewhere if they're not wild?? i couldn't see where it might be, and
thus fr_tcpinwindow() always says "no" after the first byte of data is
exchanged.
4) same sort of thing - when is_max[sd]end does get updated, it gets set to
is_[sd]end+1 - so the first packet with more than 1 byte of data in it fails to
pass the SEQ_GE test. why is it not set to is_[sd]end+is_max[sd]win? why is
that not a reasonable thing to do? (also, when the state is created, they're
assigned is_[sd]end - same problem for the first packet with any data)
ii'm interested in understanding the last 2, not complaining or reporting bugs.
am i right in guessing that things would happen magically somehow if i let
ipfilter look at outbound packets too, or am i just confused about the whole
is_end/seq/ack/maxwin tcp thing??
thanks for any help!
-rhonda