From 91edc33c5d89f82339bc1b178ba92166487a8336 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 20 Jun 1998 18:18:05 +0000 Subject: Import ipfilter 3.2.7 kernel components --- sys/netinet/fil.c | 62 +++++++++++++------- sys/netinet/ip_auth.c | 5 +- sys/netinet/ip_compat.h | 14 ++++- sys/netinet/ip_fil.c | 7 ++- sys/netinet/ip_fil.h | 3 +- sys/netinet/ip_frag.h | 3 +- sys/netinet/ip_ftp_pxy.c | 14 ++--- sys/netinet/ip_nat.c | 20 +++---- sys/netinet/ip_nat.h | 11 ++-- sys/netinet/ip_proxy.c | 42 +++++++++----- sys/netinet/ip_state.c | 148 +++++++++++++++++++++++++++++++++++++---------- sys/netinet/ip_state.h | 16 +++-- sys/netinet/ipl.h | 2 +- sys/netinet/mlf_ipl.c | 6 +- 14 files changed, 251 insertions(+), 102 deletions(-) (limited to 'sys/netinet') diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c index 58c28e14..f2b19a5 100644 --- a/sys/netinet/fil.c +++ b/sys/netinet/fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.9 1997/12/02 13:56:06 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.14 1998/05/23 19:20:30 darrenr Exp $"; #endif #include @@ -21,6 +21,7 @@ static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.9 1997/12/02 13:56:06 d #else # include # include +# include #endif #include #if !defined(__SVR4) && !defined(__svr4__) @@ -194,6 +195,7 @@ fr_info_t *fin; { struct optlist *op; tcphdr_t *tcp; + icmphdr_t *icmp; fr_ip_t *fi = &fin->fin_fi; u_short optmsk = 0, secmsk = 0, auth = 0; int i, mv, ol, off; @@ -214,6 +216,7 @@ fr_info_t *fin; fin->fin_hlen = hlen; fin->fin_dlen = ip->ip_len - hlen; tcp = (tcphdr_t *)((char *)ip + hlen); + icmp = (icmphdr_t *)tcp; fin->fin_dp = (void *)tcp; (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4)); (*(((u_32_t *)fi) + 1)) = (*(((u_32_t *)ip) + 3)); @@ -226,12 +229,20 @@ fr_info_t *fin; switch (ip->ip_p) { case IPPROTO_ICMP : - if ((!IPMINLEN(ip, icmp) && !off) || + { + int minicmpsz = sizeof(struct icmp); + + if (!off && ip->ip_len > ICMP_MINLEN + hlen && + (icmp->icmp_type == ICMP_ECHOREPLY || + icmp->icmp_type == ICMP_UNREACH)) + minicmpsz = ICMP_MINLEN; + if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || (off && off < sizeof(struct icmp))) fi->fi_fl |= FI_SHORT; if (fin->fin_dlen > 1) fin->fin_data[0] = *(u_short *)tcp; break; + } case IPPROTO_TCP : fi->fi_fl |= FI_TCPUDP; if ((!IPMINLEN(ip, tcphdr) && !off) || @@ -418,7 +429,7 @@ void *m; off = ip->ip_off & 0x1fff; pass |= (fi->fi_fl << 24); - if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off) + if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off) portcmp = 1; for (rulen = 0; fr; fr = fr->fr_next, rulen++) { @@ -475,24 +486,22 @@ void *m; * If a fragment, then only the first has what we're looking * for here... */ + if (!portcmp && (fr->fr_dcmp || fr->fr_scmp || fr->fr_tcpf || + fr->fr_tcpfm)) + continue; if (fi->fi_fl & FI_TCPUDP) { - if (portcmp) { - if (!fr_tcpudpchk(fr, fin)) - continue; - } else if (fr->fr_dcmp || fr->fr_scmp || fr->fr_tcpf || - fr->fr_tcpfm) + if (!fr_tcpudpchk(fr, fin)) continue; - } else if (fi->fi_p == IPPROTO_ICMP) { - if (!off && (fin->fin_dlen > 1)) { - if ((fin->fin_data[0] & fr->fr_icmpm) != - fr->fr_icmp) { - FR_DEBUG(("i. %#x & %#x != %#x\n", - fin->fin_data[0], - fr->fr_icmpm, fr->fr_icmp)); - continue; - } - } else if (fr->fr_icmpm || fr->fr_icmp) + } else if (fr->fr_icmpm || fr->fr_icmp) { + if ((fi->fi_p != IPPROTO_ICMP) || off || + (fin->fin_dlen < 2)) continue; + if ((fin->fin_data[0] & fr->fr_icmpm) != fr->fr_icmp) { + FR_DEBUG(("i. %#x & %#x != %#x\n", + fin->fin_data[0], fr->fr_icmpm, + fr->fr_icmp)); + continue; + } } FR_VERBOSE(("*")); /* @@ -571,6 +580,15 @@ int out; # endif int up; +#ifdef M_CANFASTFWD + /* + * XXX For now, IP Filter and fast-forwarding of cached flows + * XXX are mutually exclusive. Eventually, IP Filter should + * XXX get a "can-fast-forward" filter rule. + */ + m->m_flags &= ~M_CANFASTFWD; +#endif /* M_CANFASTFWD */ + if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_ICMP)) { int plen = 0; @@ -887,7 +905,7 @@ u_short ipf_cksum(addr, len) register u_short *addr; register int len; { - register u_long sum = 0; + register u_32_t sum = 0; for (sum = 0; len > 1; len -= 2) sum += *addr++; @@ -920,7 +938,7 @@ int len; u_char c[2]; u_short s; } bytes; - u_long sum; + u_32_t sum; u_short *sp; # if SOLARIS || defined(__sgi) int add, hlen; @@ -1019,7 +1037,7 @@ int len; #endif /* SOLARIS */ if (len < 2) break; - if((u_long)sp & 1) { + if((u_32_t)sp & 1) { bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); sum += bytes.s; } else @@ -1073,7 +1091,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.0.2.41.2.9 1997/12/02 13:56:06 darrenr Exp $ + * $Id: fil.c,v 2.0.2.41.2.14 1998/05/23 19:20:30 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, diff --git a/sys/netinet/ip_auth.c b/sys/netinet/ip_auth.c index 2640a77..bdb3114 100644 --- a/sys/netinet/ip_auth.c +++ b/sys/netinet/ip_auth.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.2 1997/11/12 10:45:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.3 1998/04/08 13:43:29 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) @@ -86,6 +86,9 @@ extern struct ifqueue ipintrq; /* ip packet input queue */ #include "netinet/ip_auth.h" #if !SOLARIS && !defined(linux) # include +# ifdef __FreeBSD__ +# include +# endif #endif diff --git a/sys/netinet/ip_compat.h b/sys/netinet/ip_compat.h index 1fe90c3..1f91cf3 100644 --- a/sys/netinet/ip_compat.h +++ b/sys/netinet/ip_compat.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_compat.h 1.8 1/14/96 - * $Id: ip_compat.h,v 2.0.2.31.2.8 1997/12/02 13:42:52 darrenr Exp $ + * $Id: ip_compat.h,v 2.0.2.31.2.11 1998/05/23 14:29:36 darrenr Exp $ */ #ifndef __IP_COMPAT_H__ @@ -123,7 +123,7 @@ typedef unsigned int u_32_t; # else typedef unsigned long u_32_t; # endif -#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */ #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) @@ -369,6 +369,9 @@ typedef struct mbuf mb_t; * not be in other places or maybe one day linux will grow up and some * of these will turn up there too. */ +#ifndef ICMP_MINLEN +# define ICMP_MINLEN 8 +#endif #ifndef ICMP_UNREACH # define ICMP_UNREACH ICMP_DEST_UNREACH #endif @@ -680,6 +683,12 @@ typedef struct uio { # undef UINT_MAX # undef LONG_MAX # undef ULONG_MAX +# define s8 __s8 +# define u8 __u8 +# define s16 __s16 +# define u16 __u16 +# define s32 __s32 +# define u32 __u32 # include # undef __KERNEL__ # endif @@ -714,4 +723,5 @@ struct ether_addr { #ifndef ICMP_ROUTERSOLICIT # define ICMP_ROUTERSOLICIT 10 #endif + #endif /* __IP_COMPAT_H__ */ diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c index d518d17..09c4b6e 100644 --- a/sys/netinet/ip_fil.c +++ b/sys/netinet/ip_fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.5 1997/11/24 10:02:02 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:49 darrenr Exp $"; #endif #ifndef SOLARIS @@ -164,7 +164,7 @@ struct devsw iplsw = { }; #endif /* _BSDI_VERSION >= 199510 && _KERNEL */ -#if defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701) # include # if defined(NETBSD_PF) # include @@ -933,7 +933,8 @@ frdest_t *fdp; if (ro->ro_rt->rt_flags & RTF_GATEWAY) dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway; } - ro->ro_rt->rt_use++; + if (ro->ro_rt) + ro->ro_rt->rt_use++; /* * For input packets which are being "fastrouted", they won't diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h index 2e2aaa7..edbd685 100644 --- a/sys/netinet/ip_fil.h +++ b/sys/netinet/ip_fil.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ip_fil.h,v 2.0.2.39.2.10 1997/12/03 10:02:30 darrenr Exp $ + * $Id: ip_fil.h,v 2.0.2.39.2.11 1998/05/23 14:29:37 darrenr Exp $ */ #ifndef __IP_FIL_H__ @@ -518,4 +518,5 @@ extern int iplused[IPL_LOGMAX + 1]; extern struct frentry *ipfilter[2][2], *ipacct[2][2]; extern struct frgroup *ipfgroups[3][2]; extern struct filterstats frstats[]; + #endif /* __IP_FIL_H__ */ diff --git a/sys/netinet/ip_frag.h b/sys/netinet/ip_frag.h index ade7139..9122f17 100644 --- a/sys/netinet/ip_frag.h +++ b/sys/netinet/ip_frag.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_frag.h 1.5 3/24/96 - * $Id: ip_frag.h,v 2.0.2.12 1997/10/23 14:56:01 darrenr Exp $ + * $Id: ip_frag.h,v 2.0.2.12.2.1 1998/05/23 14:29:39 darrenr Exp $ */ #ifndef __IP_FRAG_H__ @@ -55,4 +55,5 @@ extern void ipfr_slowtimer __P((void)); #else extern int ipfr_slowtimer __P((void)); #endif + #endif /* __IP_FIL_H__ */ diff --git a/sys/netinet/ip_ftp_pxy.c b/sys/netinet/ip_ftp_pxy.c index 5d6ce1f..7ff8adb 100644 --- a/sys/netinet/ip_ftp_pxy.c +++ b/sys/netinet/ip_ftp_pxy.c @@ -54,18 +54,18 @@ tcphdr_t *tcp; ap_session_t *aps; nat_t *nat; { - u_long sum1, sum2; + u_32_t sum1, sum2; short sel; if (tcp->th_sport == aps->aps_dport) { - sum2 = (u_long)ntohl(tcp->th_ack); + sum2 = (u_32_t)ntohl(tcp->th_ack); sel = aps->aps_sel; if ((aps->aps_after[!sel] > aps->aps_after[sel]) && (sum2 > aps->aps_after[!sel])) { sel = aps->aps_sel = !sel; /* switch to other set */ } if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) { - sum1 = (u_long)aps->aps_seqoff[sel]; + sum1 = (u_32_t)aps->aps_seqoff[sel]; tcp->th_ack = htonl(sum2 - sum1); return 2; } @@ -110,7 +110,7 @@ tcphdr_t *tcp; ap_session_t *aps; nat_t *nat; { - register u_long sum1, sum2; + register u_32_t sum1, sum2; char newbuf[IPF_MAXPORTLEN+1]; char portbuf[IPF_MAXPORTLEN+1], *s; int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2); @@ -243,17 +243,17 @@ nat_t *nat; adjust_seqack: if (tcp->th_dport == aps->aps_dport) { - sum2 = (u_long)ntohl(tcp->th_seq); + sum2 = (u_32_t)ntohl(tcp->th_seq); off = aps->aps_sel; if ((aps->aps_after[!off] > aps->aps_after[off]) && (sum2 > aps->aps_after[!off])) { off = aps->aps_sel = !off; /* switch to other set */ } if (aps->aps_seqoff[off]) { - sum1 = (u_long)aps->aps_after[off] - + sum1 = (u_32_t)aps->aps_after[off] - aps->aps_seqoff[off]; if (sum2 > sum1) { - sum1 = (u_long)aps->aps_seqoff[off]; + sum1 = (u_32_t)aps->aps_seqoff[off]; sum2 += sum1; tcp->th_seq = htonl(sum2); ch = 1; diff --git a/sys/netinet/ip_nat.c b/sys/netinet/ip_nat.c index 0b6c07f..102d57f 100644 --- a/sys/netinet/ip_nat.c +++ b/sys/netinet/ip_nat.c @@ -9,7 +9,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.7 1997/12/02 13:54:27 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.10 1998/05/23 19:05:29 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) @@ -130,10 +130,10 @@ static int nat_ifpaddr __P((nat_t *, void *, struct in_addr *)); void fix_outcksum(sp, n) u_short *sp; -u_long n; +u_32_t n; { register u_short sumshort; - register u_long sum1; + register u_32_t sum1; if (!n) return; @@ -149,10 +149,10 @@ u_long n; void fix_incksum(sp, n) u_short *sp; -u_long n; +u_32_t n; { register u_short sumshort; - register u_long sum1; + register u_32_t sum1; if (!n) return; @@ -456,7 +456,7 @@ struct in_addr *inp; struct in_addr in; #if SOLARIS - in.s_addr = ill->ill_ipif->ipif_local_addr; + in.s_addr = ntohl(ill->ill_ipif->ipif_local_addr); #else /* SOLARIS */ # if linux ; @@ -521,7 +521,7 @@ fr_info_t *fin; u_short flags; int direction; { - register u_long sum1, sum2, sumd, l; + register u_32_t sum1, sum2, sumd, l; u_short port = 0, sport = 0, dport = 0, nport = 0; struct in_addr in; tcphdr_t *tcp = NULL; @@ -779,7 +779,7 @@ int *nflags; */ if (flags & IPN_TCPUDP) { tcphdr_t *tcp = (tcphdr_t *)(oip + 1); - u_long sum1, sum2, sumd; + u_32_t sum1, sum2, sumd; struct in_addr in; if (nat->nat_dir == NAT_OUTBOUND) { @@ -964,7 +964,7 @@ int hlen; fr_info_t *fin; { register ipnat_t *np; - register u_long ipa; + register u_32_t ipa; tcphdr_t *tcp = NULL; u_short nflags = 0, sport = 0, dport = 0, *csump = NULL; struct ifnet *ifp; @@ -1281,7 +1281,7 @@ void *ifp; #endif { register nat_t *nat; - register u_long sum1, sum2, sumd; + register u_32_t sum1, sum2, sumd; struct in_addr in; ipnat_t *np; #if defined(_KERNEL) && !SOLARIS diff --git a/sys/netinet/ip_nat.h b/sys/netinet/ip_nat.h index f0cb517..49f5d50 100644 --- a/sys/netinet/ip_nat.h +++ b/sys/netinet/ip_nat.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_nat.h 1.5 2/4/96 - * $Id: ip_nat.h,v 2.0.2.23.2.1 1997/11/05 11:08:18 darrenr Exp $ + * $Id: ip_nat.h,v 2.0.2.23.2.3 1998/05/23 18:52:44 darrenr Exp $ */ #ifndef __IP_NAT_H__ @@ -44,8 +44,8 @@ typedef struct nat { u_long nat_age; int nat_flags; - u_long nat_sumd; - u_long nat_ipsumd; + u_32_t nat_sumd; + u_32_t nat_ipsumd; void *nat_data; struct in_addr nat_inip; struct in_addr nat_outip; @@ -175,6 +175,7 @@ extern int ip_natout __P((ip_t *, int, fr_info_t *)); extern int ip_natin __P((ip_t *, int, fr_info_t *)); extern void ip_natunload __P((void)), ip_natexpire __P((void)); extern void nat_log __P((struct nat *, u_short)); -extern void fix_incksum __P((u_short *, u_long)); -extern void fix_outcksum __P((u_short *, u_long)); +extern void fix_incksum __P((u_short *, u_32_t)); +extern void fix_outcksum __P((u_short *, u_32_t)); + #endif /* __IP_NAT_H__ */ diff --git a/sys/netinet/ip_proxy.c b/sys/netinet/ip_proxy.c index cc3b9a0..0fb7e95 100644 --- a/sys/netinet/ip_proxy.c +++ b/sys/netinet/ip_proxy.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.6 1997/11/28 00:41:25 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.7 1998/05/18 11:15:22 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) @@ -111,15 +111,37 @@ ipnat_t *nat; } +static int +ap_matchsrcdst(aps, src, dst, tcp, sport, dport) +ap_session_t *aps; +struct in_addr src, dst; +void *tcp; +u_short sport, dport; +{ + if (aps->aps_dst.s_addr == dst.s_addr) { + if ((aps->aps_src.s_addr == src.s_addr) && + (!tcp || (sport == aps->aps_sport) && + (dport == aps->aps_dport))) + return 1; + } else if (aps->aps_dst.s_addr == src.s_addr) { + if ((aps->aps_src.s_addr == dst.s_addr) && + (!tcp || (sport == aps->aps_dport) && + (dport == aps->aps_sport))) + return 1; + } + return 0; +} + + static ap_session_t *ap_find(ip, tcp) ip_t *ip; tcphdr_t *tcp; { - struct in_addr src, dst; - register u_long hv; - register u_short sp, dp; - register ap_session_t *aps; register u_char p = ip->ip_p; + register ap_session_t *aps; + register u_short sp, dp; + register u_long hv; + struct in_addr src, dst; src = ip->ip_src, dst = ip->ip_dst; sp = dp = 0; /* XXX gcc -Wunitialized */ @@ -136,14 +158,8 @@ tcphdr_t *tcp; for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next) if ((aps->aps_p == p) && - IPPAIR(aps->aps_src, aps->aps_dst, src, dst)) { - if (tcp) { - if (PAIRS(aps->aps_sport, aps->aps_dport, - sp, dp)) - break; - } else - break; - } + ap_matchsrcdst(aps, src, dst, tcp, sp, dp)) + break; return aps; } diff --git a/sys/netinet/ip_state.c b/sys/netinet/ip_state.c index bffb17b..89a2c3b 100644 --- a/sys/netinet/ip_state.c +++ b/sys/netinet/ip_state.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.4 1997/11/19 11:44:09 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.14 1998/05/24 03:53:04 darrenr Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__) @@ -85,6 +85,11 @@ ips_stat_t ips_stats; extern kmutex_t ipf_state; #endif +static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr, + fr_info_t *, void *, u_short, u_short)); +static int fr_state_flush __P((int)); +static ips_stat_t *fr_statetstats __P((void)); + #define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */ @@ -97,7 +102,7 @@ u_long fr_tcpidletimeout = FIVE_DAYS, fr_icmptimeout = 120; -ips_stat_t *fr_statetstats() +static ips_stat_t *fr_statetstats() { ips_stats.iss_active = ips_num; ips_stats.iss_table = ips_table; @@ -111,7 +116,7 @@ ips_stat_t *fr_statetstats() * which == 1 : flush TCP connections which have started to close but are * stuck for some reason. */ -int fr_state_flush(which) +static int fr_state_flush(which) int which; { register int i; @@ -134,10 +139,10 @@ int which; break; case 1 : if ((is->is_p == IPPROTO_TCP) && - ((is->is_state[0] <= TCPS_ESTABLISHED) && - (is->is_state[1] > TCPS_ESTABLISHED)) || - ((is->is_state[1] <= TCPS_ESTABLISHED) && - (is->is_state[0] > TCPS_ESTABLISHED))) + (((is->is_state[0] <= TCPS_ESTABLISHED) && + (is->is_state[1] > TCPS_ESTABLISHED)) || + ((is->is_state[1] <= TCPS_ESTABLISHED) && + (is->is_state[0] > TCPS_ESTABLISHED)))) delete = 1; break; } @@ -237,7 +242,7 @@ u_int pass; switch (ic->icmp_type) { case ICMP_ECHO : - is->is_icmp.ics_type = 0; + is->is_icmp.ics_type = ICMP_ECHOREPLY; /* XXX */ hv += (is->is_icmp.ics_id = ic->icmp_id); hv += (is->is_icmp.ics_seq = ic->icmp_seq); break; @@ -301,11 +306,33 @@ u_int pass; bcopy((char *)&ips, (char *)is, sizeof(*is)); hv %= IPSTATE_SIZE; MUTEX_ENTER(&ipf_state); - is->is_next = ips_table[hv]; - ips_table[hv] = is; + is->is_pass = pass; is->is_pkts = 1; is->is_bytes = ip->ip_len; + /* + * Copy these from the rule itself. + */ + is->is_opt = fin->fin_fr->fr_ip.fi_optmsk; + is->is_optmsk = fin->fin_fr->fr_mip.fi_optmsk; + is->is_sec = fin->fin_fr->fr_ip.fi_secmsk; + is->is_secmsk = fin->fin_fr->fr_mip.fi_secmsk; + is->is_auth = fin->fin_fr->fr_ip.fi_auth; + is->is_authmsk = fin->fin_fr->fr_mip.fi_auth; + is->is_flags = fin->fin_fr->fr_ip.fi_fl; + is->is_flags |= fin->fin_fr->fr_mip.fi_fl << 4; + /* + * add into table. + */ + is->is_next = ips_table[hv]; + ips_table[hv] = is; + if (fin->fin_out) { + is->is_ifpin = NULL; + is->is_ifpout = fin->fin_ifp; + } else { + is->is_ifpin = fin->fin_ifp; + is->is_ifpout = NULL; + } if (pass & FR_LOGFIRST) is->is_pass &= ~(FR_LOGFIRST|FR_LOG); ips_num++; @@ -324,12 +351,11 @@ u_int pass; * change timeout depending on whether new packet is a SYN-ACK returning for a * SYN or a RST or FIN which indicate time to close up shop. */ -int fr_tcpstate(is, fin, ip, tcp, sport) +int fr_tcpstate(is, fin, ip, tcp) register ipstate_t *is; fr_info_t *fin; ip_t *ip; tcphdr_t *tcp; -u_short sport; { register int seqskew, ackskew; register u_short swin, dwin; @@ -341,7 +367,7 @@ u_short sport; */ seq = ntohl(tcp->th_seq); ack = ntohl(tcp->th_ack); - source = (sport == is->is_sport); + source = (ip->ip_src.s_addr == is->is_src.s_addr); if (!(tcp->th_flags & TH_ACK)) /* Pretend an ack was sent */ ack = source ? is->is_ack : is->is_seq; @@ -385,7 +411,7 @@ u_short sport; swin = is->is_dwin; } - if ((seqskew <= swin) && (ackskew <= dwin)) { + if ((seqskew <= dwin) && (ackskew <= swin)) { if (source) { is->is_seq = seq; is->is_ack = ack; @@ -401,14 +427,81 @@ u_short sport; /* * Nearing end of connection, start timeout. */ - fr_tcp_age(&is->is_age, is->is_state, ip, fin, - tcp->th_sport == is->is_sport); + fr_tcp_age(&is->is_age, is->is_state, ip, fin, source); return 1; } return 0; } +static int fr_matchsrcdst(is, src, dst, fin, tcp, sp, dp) +ipstate_t *is; +struct in_addr src, dst; +fr_info_t *fin; +void *tcp; +u_short sp, dp; +{ + int ret = 0, rev, out; + void *ifp; + + rev = (is->is_dst.s_addr != dst.s_addr); + ifp = fin->fin_ifp; + out = fin->fin_out; + + if (!rev) { + if (out) { + if (!is->is_ifpout) + is->is_ifpout = ifp; + } else { + if (!is->is_ifpin) + is->is_ifpin = ifp; + } + } else { + if (out) { + if (!is->is_ifpin) + is->is_ifpin = ifp; + } else { + if (!is->is_ifpout) + is->is_ifpout = ifp; + } + } + + if (!rev) { + if (((out && is->is_ifpout == ifp) || + (!out && is->is_ifpin == ifp)) && + (is->is_dst.s_addr == dst.s_addr) && + (is->is_src.s_addr == src.s_addr) && + (!tcp || (sp == is->is_sport) && + (dp == is->is_dport))) { + ret = 1; + } + } else { + if (((out && is->is_ifpin == ifp) || + (!out && is->is_ifpout == ifp)) && + (is->is_dst.s_addr == src.s_addr) && + (is->is_src.s_addr == dst.s_addr) && + (!tcp || (sp == is->is_dport) && + (dp == is->is_sport))) { + ret = 1; + } + } + + /* + * Whether or not this should be here, is questionable, but the aim + * is to get this out of the main line. + */ + if (ret) { + if (((fin->fin_fi.fi_optmsk & is->is_optmsk) != is->is_opt) || + ((fin->fin_fi.fi_secmsk & is->is_secmsk) != is->is_sec) || + ((fin->fin_fi.fi_auth & is->is_authmsk) != is->is_auth) || + ((fin->fin_fi.fi_fl & (is->is_flags >> 4)) != + (is->is_flags & 0xf))) + ret = 0; + } + return ret; +} + + /* * Check if a packet has a registered state. */ @@ -447,13 +540,8 @@ fr_info_t *fin; if ((is->is_p == pr) && (ic->icmp_id == is->is_icmp.ics_id) && (ic->icmp_seq == is->is_icmp.ics_seq) && - IPPAIR(src, dst, is->is_src, is->is_dst)) { - /* - * If we have type 0 stored, allow any icmp - * replies through. - */ - if (is->is_icmp.ics_type && - is->is_icmp.ics_type != ic->icmp_type) + fr_matchsrcdst(is, src, dst, fin, NULL, 0, 0)) { + if (is->is_icmp.ics_type != ic->icmp_type) continue; is->is_age = fr_icmptimeout; is->is_pkts++; @@ -473,11 +561,11 @@ fr_info_t *fin; hv += sport; hv %= IPSTATE_SIZE; MUTEX_ENTER(&ipf_state); - for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) { + for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) if ((is->is_p == pr) && - PAIRS(sport, dport, is->is_sport, is->is_dport) && - IPPAIR(src, dst, is->is_src, is->is_dst)) - if (fr_tcpstate(is, fin, ip, tcp, sport)) { + fr_matchsrcdst(is, src, dst, fin, tcp, + sport, dport)) { + if (fr_tcpstate(is, fin, ip, tcp)) { pass = is->is_pass; #ifdef _KERNEL MUTEX_EXIT(&ipf_state); @@ -491,7 +579,7 @@ fr_info_t *fin; #endif return pass; } - } + } MUTEX_EXIT(&ipf_state); break; } @@ -508,8 +596,8 @@ fr_info_t *fin; MUTEX_ENTER(&ipf_state); for (is = ips_table[hv]; is; is = is->is_next) if ((is->is_p == pr) && - PAIRS(sport, dport, is->is_sport, is->is_dport) && - IPPAIR(src, dst, is->is_src, is->is_dst)) { + fr_matchsrcdst(is, src, dst, fin, + tcp, sport, dport)) { ips_stats.iss_hits++; is->is_pkts++; is->is_bytes += ip->ip_len; diff --git a/sys/netinet/ip_state.h b/sys/netinet/ip_state.h index 3d87a21..f2ae94b 100644 --- a/sys/netinet/ip_state.h +++ b/sys/netinet/ip_state.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed - * $Id: ip_state.h,v 2.0.2.14.2.1 1997/11/06 21:23:15 darrenr Exp $ + * $Id: ip_state.h,v 2.0.2.14.2.6 1998/05/24 05:18:04 darrenr Exp $ */ #ifndef __IP_STATE_H__ #define __IP_STATE_H__ @@ -47,10 +47,18 @@ typedef struct ipstate { u_int is_pass; U_QUAD_T is_pkts; U_QUAD_T is_bytes; + void *is_ifpin; + void *is_ifpout; struct in_addr is_src; struct in_addr is_dst; u_char is_p; u_char is_flags; + u_32_t is_opt; + u_32_t is_optmsk; + u_short is_sec; + u_short is_secmsk; + u_short is_auth; + u_short is_authmsk; union { icmpstate_t is_ics; tcpstate_t is_ts; @@ -120,14 +128,11 @@ extern u_long fr_tcptimeout; extern u_long fr_tcpclosed; extern u_long fr_udptimeout; extern u_long fr_icmptimeout; -extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, - tcphdr_t *, u_short)); -extern ips_stat_t *fr_statetstats __P((void)); +extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *)); extern int fr_addstate __P((ip_t *, fr_info_t *, u_int)); extern int fr_checkstate __P((ip_t *, fr_info_t *)); extern void fr_timeoutstate __P((void)); extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int)); -extern int fr_state_flush __P((int)); extern void fr_stateunload __P((void)); extern void ipstate_log __P((struct ipstate *, u_short)); #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -135,4 +140,5 @@ extern int fr_state_ioctl __P((caddr_t, u_long, int)); #else extern int fr_state_ioctl __P((caddr_t, int, int)); #endif + #endif /* __IP_STATE_H__ */ diff --git a/sys/netinet/ipl.h b/sys/netinet/ipl.h index 4ad6bd3..d92ec79 100644 --- a/sys/netinet/ipl.h +++ b/sys/netinet/ipl.h @@ -11,6 +11,6 @@ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter v3.2.3" +#define IPL_VERSION "IP Filter v3.2.7" #endif diff --git a/sys/netinet/mlf_ipl.c b/sys/netinet/mlf_ipl.c index d6601ba..3cda6c1 100644 --- a/sys/netinet/mlf_ipl.c +++ b/sys/netinet/mlf_ipl.c @@ -27,6 +27,9 @@ # include # ifdef DEVFS # include +# if defined(IPFILTER) && defined(_KERNEL) +# include "opt_devfs.h" +# endif # endif /*DEVFS*/ #endif #include @@ -375,7 +378,8 @@ static void ipl_drvinit __P((void *unused)) } } -# ifdef IPFILTER_LKM +# if defined(IPFILTER_LKM) || \ + defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) # endif /* IPFILTER_LKM */ #endif /* _FreeBSD_version */ -- cgit v1.1