aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>1998-03-21 10:11:54 +0000
committerPeter Wemm <peter@FreeBSD.org>1998-03-21 10:11:54 +0000
commit27064bb1595ba86624494176675c7c36450d121f (patch)
tree456b6f9d1dc026b74410390d2d40f4e7a007558f
parent52aef1787c0595837b11765452444e18c4687baa (diff)
downloadsrc-27064bb1595ba86624494176675c7c36450d121f.tar.gz
src-27064bb1595ba86624494176675c7c36450d121f.zip
Import kernel parts of ipfilter v3.2.3
Notes
Notes: svn path=/vendor-sys/ipfilter/dist-old/; revision=34742
-rw-r--r--sys/netinet/fil.c52
-rw-r--r--sys/netinet/ip_compat.h23
-rw-r--r--sys/netinet/ip_fil.c23
-rw-r--r--sys/netinet/ip_fil.h24
-rw-r--r--sys/netinet/ip_ftp_pxy.c161
-rw-r--r--sys/netinet/ip_log.c8
-rw-r--r--sys/netinet/ip_nat.c29
-rw-r--r--sys/netinet/ip_proxy.c25
-rw-r--r--sys/netinet/ip_proxy.h3
-rw-r--r--sys/netinet/ip_state.c4
-rw-r--r--sys/netinet/ipl.h4
-rw-r--r--sys/netinet/mlf_ipl.c52
12 files changed, 269 insertions, 139 deletions
diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c
index 4c0f8c1b74d6..58c28e14126b 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.3 1997/11/12 10:44:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.9 1997/12/02 13:56:06 darrenr Exp $";
#endif
#include <sys/errno.h>
@@ -73,7 +73,7 @@ extern int opts;
second; }
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
-# define SEND_RESET(ip, qif, if) send_reset(ip, if)
+# define SEND_RESET(ip, qif, if, m) send_reset(ip, if)
# define IPLLOG(a, c, d, e) ipllog()
# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
# if SOLARIS
@@ -98,7 +98,12 @@ extern kmutex_t ipf_mutex, ipf_auth;
icmp_error(ip, t, c, if, src)
# else /* SOLARIS */
# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
-# define SEND_RESET(ip, qif, if) send_reset((struct tcpiphdr *)ip)
+# ifdef linux
+# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip,\
+ ifp)
+# else
+# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip)
+# endif
# ifdef __sgi
# define ICMP_ERROR(b, ip, t, c, if, src) \
icmp_error(b, t, c, if, src, if)
@@ -553,7 +558,7 @@ int out;
fr_info_t frinfo, *fc;
register fr_info_t *fin = &frinfo;
frentry_t *fr = NULL;
- int pass, changed, apass;
+ int pass, changed, apass, error = EHOSTUNREACH;
#if !SOLARIS || !defined(_KERNEL)
register mb_t *m = *mp;
#endif
@@ -767,10 +772,11 @@ logit:
# else
# ifndef linux
mc = m_copy(m, 0, M_COPYALL);
+# else
+ ;
# endif
# endif
#endif
-
if (pass & FR_PASS)
frstats[out].fr_pass++;
else if (pass & FR_BLOCK) {
@@ -811,6 +817,9 @@ logit:
frstats[1].fr_ret++;
}
#endif
+ } else {
+ if (pass & FR_RETRST)
+ error = ECONNRESET;
}
}
@@ -842,8 +851,8 @@ logit:
m_copyback(m, 0, up, hbuf);
# endif
# endif /* !linux */
- return (pass & FR_PASS) ? 0 : -1;
-# else /* !SOLARIS */
+ return (pass & FR_PASS) ? 0 : error;
+# else /* !SOLARIS */
if (fr) {
frdest_t *fdp = &fr->fr_tif;
@@ -855,7 +864,7 @@ logit:
if (mc)
ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif);
}
- return (pass & FR_PASS) ? changed : -1;
+ return (pass & FR_PASS) ? changed : error;
# endif /* !SOLARIS */
#else /* _KERNEL */
if (pass & FR_NOMATCH)
@@ -872,6 +881,7 @@ logit:
/*
* ipf_cksum
* addr should be 16bit aligned and len is in bytes.
+ * length is in bytes
*/
u_short ipf_cksum(addr, len)
register u_short *addr;
@@ -900,10 +910,11 @@ register int len;
* and the TCP header. We also assume that data blocks aren't allocated in
* odd sizes.
*/
-u_short fr_tcpsum(m, ip, tcp)
+u_short fr_tcpsum(m, ip, tcp, len)
mb_t *m;
ip_t *ip;
tcphdr_t *tcp;
+int len;
{
union {
u_char c[2];
@@ -911,7 +922,6 @@ tcphdr_t *tcp;
} bytes;
u_long sum;
u_short *sp;
- int len;
# if SOLARIS || defined(__sgi)
int add, hlen;
# endif
@@ -926,9 +936,9 @@ tcphdr_t *tcp;
/*
* Add up IP Header portion
*/
- len = ip->ip_len - (ip->ip_hl << 2);
bytes.c[0] = 0;
bytes.c[1] = IPPROTO_TCP;
+ len -= (ip->ip_hl << 2);
sum = bytes.s;
sum += htons((u_short)len);
sp = (u_short *)&ip->ip_src;
@@ -994,13 +1004,13 @@ tcphdr_t *tcp;
goto nodata;
while (len > 0) {
#if SOLARIS
- if ((caddr_t)sp >= (caddr_t)m->b_wptr) {
+ while ((caddr_t)sp >= (caddr_t)m->b_wptr) {
m = m->b_cont;
PANIC((!m),("fr_tcpsum: not enough data"));
sp = (u_short *)m->b_rptr;
}
#else
- if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len)
+ while (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len)
{
m = m->m_next;
PANIC((!m),("fr_tcpsum: not enough data"));
@@ -1009,7 +1019,11 @@ tcphdr_t *tcp;
#endif /* SOLARIS */
if (len < 2)
break;
- sum += *sp++;
+ if((u_long)sp & 1) {
+ bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s));
+ sum += bytes.s;
+ } else
+ sum += *sp++;
len -= 2;
}
if (len) {
@@ -1059,7 +1073,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.0.2.41.2.3 1997/11/12 10:44:22 darrenr Exp $
+ * $Id: fil.c,v 2.0.2.41.2.9 1997/12/02 13:56:06 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1258,11 +1272,11 @@ frentry_t *list, **listp;
}
-void frflush(unit, data)
+void frflush(unit, result)
int unit;
-caddr_t data;
+int *result;
{
- int flags = *(int *)data, flushed = 0, set = fr_active;
+ int flags = *result, flushed = 0, set = fr_active;
bzero((char *)frcache, sizeof(frcache[0]) * 2);
@@ -1286,5 +1300,5 @@ caddr_t data;
}
}
- *(int *)data = flushed;
+ *result = flushed;
}
diff --git a/sys/netinet/ip_compat.h b/sys/netinet/ip_compat.h
index 3866ef083540..1fe90c3cb677 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.4 1997/11/12 10:48:43 darrenr Exp $
+ * $Id: ip_compat.h,v 2.0.2.31.2.8 1997/12/02 13:42:52 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -50,17 +50,18 @@ struct ether_addr {
};
#endif
-#ifdef __sgi
-# ifdef IPFILTER_LKM
-# define IPL_PRFX ipl
-# define IPL_EXTERN(ep) ipl##ep
-# else
-# define IPL_PRFX ipfilter
+#if defined(__sgi) && !defined(IPFILTER_LKM)
+# ifdef __STDC__
# define IPL_EXTERN(ep) ipfilter##ep
+# else
+# define IPL_EXTERN(ep) ipfilter/**/ep
# endif
#else
-# define IPL_PRFX ipl
-# define IPL_EXTERN(ep) ipl##ep
+# ifdef __STDC__
+# define IPL_EXTERN(ep) ipl##ep
+# else
+# define IPL_EXTERN(ep) ipl/**/ep
+# endif
#endif
#ifdef linux
@@ -110,7 +111,8 @@ struct ether_addr {
/*
* These operating systems already take care of the problem for us.
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
+ defined(__sgi)
typedef u_int32_t u_32_t;
#else
/*
@@ -689,6 +691,7 @@ typedef struct icmp icmphdr_t;
typedef struct ip ip_t;
typedef struct ether_header ether_header_t;
#endif /* linux */
+typedef struct tcpiphdr tcpiphdr_t;
#if defined(hpux) || defined(linux)
struct ether_addr {
diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c
index c3c758e74396..d518d1793af0 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.2 1997/11/12 10:49:25 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.5 1997/11/24 10:02:02 darrenr Exp $";
#endif
#ifndef SOLARIS
@@ -275,7 +275,7 @@ int ipldetach()
fr_checkp = fr_savep;
inetsw[0].pr_slowtimo = fr_saveslowtimo;
- frflush(IPL_LOGIPF, (caddr_t)&i);
+ frflush(IPL_LOGIPF, &i);
ipl_inited = 0;
# ifdef NETBSD_PF
@@ -339,7 +339,7 @@ struct proc *p;
)
#endif
dev_t dev;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
u_long cmd;
#else
int cmd;
@@ -351,7 +351,7 @@ int mode;
#if defined(_KERNEL) && !SOLARIS
int s;
#endif
- int error = 0, unit = 0;
+ int error = 0, unit = 0, tmp;
#ifdef _KERNEL
unit = GET_MINOR(dev);
@@ -460,8 +460,11 @@ int mode;
case SIOCIPFFL :
if (!(mode & FWRITE))
error = EPERM;
- else
- frflush(unit, data);
+ else {
+ IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
+ frflush(unit, &tmp);
+ IWCOPY((caddr_t)&tmp, data, sizeof(tmp));
+ }
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
@@ -786,7 +789,7 @@ struct tcpiphdr *ti;
struct tcpiphdr *tp;
struct tcphdr *tcp;
struct mbuf *m;
- int tlen = 0;
+ int tlen = 0, err;
ip_t *ip;
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
struct route ro;
@@ -837,16 +840,16 @@ struct tcpiphdr *ti;
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
bzero((char *)&ro, sizeof(ro));
- (void) ip_output(m, (struct mbuf *)0, &ro, 0, 0);
+ err = ip_output(m, (struct mbuf *)0, &ro, 0, 0);
if (ro.ro_rt)
RTFREE(ro.ro_rt);
# else
/*
* extra 0 in case of multicast
*/
- (void) ip_output(m, (struct mbuf *)0, 0, 0, 0);
+ err = ip_output(m, (struct mbuf *)0, 0, 0, 0);
# endif
- return 0;
+ return err;
}
diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h
index 39cca349e319..2e2aaa7cb28d 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.4 1997/11/12 10:50:02 darrenr Exp $
+ * $Id: ip_fil.h,v 2.0.2.39.2.10 1997/12/03 10:02:30 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@@ -94,10 +94,10 @@ typedef struct fr_ip {
u_short fi_auth;
} fr_ip_t;
-#define FI_OPTIONS 0x01
-#define FI_TCPUDP 0x02 /* TCP/UCP implied comparison involved */
-#define FI_FRAG 0x04
-#define FI_SHORT 0x08
+#define FI_OPTIONS (FF_OPTIONS >> 24)
+#define FI_TCPUDP (FF_TCPUDP >> 24) /* TCP/UCP implied comparison*/
+#define FI_FRAG (FF_FRAG >> 24)
+#define FI_SHORT (FF_SHORT >> 24)
typedef struct fr_info {
struct fr_ip fin_fi;
@@ -381,7 +381,7 @@ extern int ipf_log __P((void));
extern void ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
extern struct ifnet *get_unit __P((char *));
# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
-# if defined(__NetBSD__) || defined(__OpenBSD__)
+# if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
extern int iplioctl __P((dev_t, u_long, caddr_t, int));
# else
extern int iplioctl __P((dev_t, int, caddr_t, int));
@@ -423,7 +423,11 @@ extern int iplread __P((dev_t, struct uio *, cred_t *));
# else /* SOLARIS */
extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-extern int send_reset __P((struct tcpiphdr *));
+# ifdef linux
+extern int send_reset __P((tcpiphdr_t *, struct ifnet *));
+# else
+extern int send_reset __P((tcpiphdr_t *));
+# endif
extern void ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
extern size_t mbufchainlen __P((mb_t *));
# ifdef __sgi
@@ -442,7 +446,7 @@ extern int iplidentify __P((char *));
# endif
# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
(NetBSD >= 199511)
-# ifdef __NetBSD__
+# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701)
extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
# else
extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
@@ -491,12 +495,12 @@ extern int iplread(struct inode *, struct file *, char *, int);
#endif
extern int ipldetach __P((void));
-extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
+extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *, int));
#define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
extern int fr_scanlist __P((int, ip_t *, fr_info_t *, void *));
extern u_short ipf_cksum __P((u_short *, int));
extern int fr_copytolog __P((int, char *, int));
-extern void frflush __P((int, caddr_t));
+extern void frflush __P((int, int *));
extern frgroup_t *fr_addgroup __P((u_short, frentry_t *, int, int));
extern frgroup_t *fr_findgroup __P((u_short, u_32_t, int, int, frgroup_t ***));
extern void fr_delgroup __P((u_short, u_32_t, int, int));
diff --git a/sys/netinet/ip_ftp_pxy.c b/sys/netinet/ip_ftp_pxy.c
index 48196e97fd0f..5d6ce1fc002d 100644
--- a/sys/netinet/ip_ftp_pxy.c
+++ b/sys/netinet/ip_ftp_pxy.c
@@ -1,5 +1,6 @@
/*
- * Simple FTP transparent proxy for in-kernel.
+ * Simple FTP transparent proxy for in-kernel use. For use with the NAT
+ * code.
*/
#define isdigit(x) ((x) >= '0' && (x) <= '9')
@@ -10,6 +11,29 @@
#define IPF_MAXPORTLEN 30
+int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+u_short ipf_ftp_atoi __P((char **));
+
+
+int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+
+u_short ipf_ftp_atoi __P((char **));
+
+
+
+/*
+ * FTP application proxy initialization.
+ */
int ippr_ftp_init(fin, ip, tcp, aps, nat)
fr_info_t *fin;
ip_t *ip;
@@ -30,13 +54,18 @@ tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
- int ch = 0;
u_long sum1, sum2;
+ short sel;
- if (tcp->th_dport != aps->aps_dport) {
+ if (tcp->th_sport == aps->aps_dport) {
sum2 = (u_long)ntohl(tcp->th_ack);
- if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
- sum1 = (u_long)aps->aps_seqoff;
+ 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];
tcp->th_ack = htonl(sum2 - sum1);
return 2;
}
@@ -45,6 +74,12 @@ nat_t *nat;
}
+/*
+ * ipf_ftp_atoi - implement a version of atoi which processes numbers in
+ * pairs separated by commas (which are expected to be in the range 0 - 255),
+ * returning a 16 bit number combining either side of the , as the MSB and
+ * LSB.
+ */
u_short ipf_ftp_atoi(ptr)
char **ptr;
{
@@ -75,42 +110,38 @@ tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
- register u_long sum1, sum2, sumd;
+ register u_long sum1, sum2;
char newbuf[IPF_MAXPORTLEN+1];
- char portbuf[IPF_MAXPORTLEN+1], *s, c;
- int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2), len;
+ char portbuf[IPF_MAXPORTLEN+1], *s;
+ int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2);
u_int a1, a2, a3, a4;
u_short a5, a6;
- int olen, dlen, nlen, inc = 0, blen;
+ int olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
void *savep;
nat_t *ipn;
struct in_addr swip;
+ mb_t *m = *(mb_t **)fin->fin_mp;
+
#if SOLARIS
- mblk_t *m1, *m = *(mblk_t **)fin->fin_mp;
+ mb_t *m1;
- dlen = m->b_wptr - m->b_rptr - off;
- blen = m->b_datap->db_lim - m->b_datap->db_base;
+ /* skip any leading M_PROTOs */
+ while(m && (MTYPE(m) != M_DATA))
+ m = m->b_cont;
+ PANIC((!m),("ippr_ftp_out: no M_DATA"));
+
+ dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));
- copyout_mblk(m, off, portbuf, MIN(sizeof(portbuf), dlen));
+ copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
- struct mbuf *m1, *m = *(struct mbuf **)fin->fin_mp;
-
- dlen = m->m_len - off;
-# if BSD >= 199306
- blen = (MLEN - m->m_len) - (m->m_data - m->m_dat);
-# else
- blen = (MLEN - m->m_len) - m->m_off;
-# endif
- if (blen < 0)
- panic("blen < 0 - size of mblk/mbuf wrong");
+ dlen = mbufchainlen(m) - off;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
portbuf[IPF_MAXPORTLEN] = '\0';
- len = MIN(32, dlen);
- if ((len < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
+ if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
goto adjust_seqack;
/*
@@ -149,30 +180,48 @@ nat_t *nat;
a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
- if (tcp->th_seq > aps->aps_after) {
- aps->aps_after = ntohl(tcp->th_seq) + dlen;
- aps->aps_seqoff += inc;
- }
#if SOLARIS
- if (inc && dlen)
- if ((inc < 0) || (blen >= dlen)) {
- bcopy(m->b_rptr + off,
- m->b_rptr + off + aps->aps_seqoff, dlen);
- }
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
- m1->b_wptr += inc;
- copyin_mblk(m, off, newbuf, strlen(newbuf));
+ if (inc > 0) {
+ mblk_t *nm;
+
+ /* alloc enough to keep same trailer space for lower driver */
+ nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, BPRI_MED);
+ PANIC((!nm),("ippr_ftp_out: allocb failed"));
+
+ nm->b_band = m1->b_band;
+ nm->b_wptr += nlen;
+
+ m1->b_wptr -= olen;
+ PANIC((m1->b_wptr < m1->b_rptr),("ippr_ftp_out: cannot handle fragmented data block"));
+
+ linkb(m1, nm);
+ } else {
+ m1->b_wptr += inc;
+ }
+ copyin_mblk(m, off, nlen, newbuf);
#else
- if (inc && dlen)
- if ((inc < 0) || (blen >= dlen)) {
- bcopy((char *)ip + off,
- (char *)ip + off + aps->aps_seqoff, dlen);
- }
- m->m_len += inc;
+ if (inc < 0)
+ m_adj(m, inc);
+ /* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
#endif
- ip->ip_len += inc;
+ if (inc) {
+#if SOLARIS || defined(__sgi)
+ sum1 = ip->ip_len;
+ sum2 = ip->ip_len + inc;
+
+ /* Because ~1 == -2, We really need ~1 == -1 */
+ if (sum1 > sum2)
+ sum2--;
+ sum2 -= sum1;
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+
+ fix_outcksum(&ip->ip_sum, sum2);
+#endif
+ ip->ip_len += inc;
+ }
ch = 1;
/*
@@ -181,24 +230,40 @@ nat_t *nat;
*/
savep = fin->fin_dp;
fin->fin_dp = (char *)tcp2;
+ bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(a5 << 8 | a6);
tcp2->th_dport = htons(20);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND)))
ipn->nat_age = fr_defnatage;
+ (void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE);
ip->ip_src = swip;
fin->fin_dp = (char *)savep;
adjust_seqack:
if (tcp->th_dport == aps->aps_dport) {
sum2 = (u_long)ntohl(tcp->th_seq);
- if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
- sum1 = (u_long)aps->aps_seqoff;
- tcp->th_seq = htonl(sum2 + sum1);
- ch = 1;
+ 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] -
+ aps->aps_seqoff[off];
+ if (sum2 > sum1) {
+ sum1 = (u_long)aps->aps_seqoff[off];
+ sum2 += sum1;
+ tcp->th_seq = htonl(sum2);
+ ch = 1;
+ }
}
- }
+ if (inc && (sum2 > aps->aps_after[!off])) {
+ aps->aps_after[!off] = sum2 + nlen - 1;
+ aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc;
+ }
+ }
return ch ? 2 : 0;
}
diff --git a/sys/netinet/ip_log.c b/sys/netinet/ip_log.c
index 6440124c6f91..81e89e5c022b 100644
--- a/sys/netinet/ip_log.c
+++ b/sys/netinet/ip_log.c
@@ -5,17 +5,17 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * $Id: ip_log.c,v 2.0.2.13.2.2 1997/11/12 10:52:21 darrenr Exp $
+ * $Id: ip_log.c,v 2.0.2.13.2.3 1997/11/20 12:41:40 darrenr Exp $
*/
#ifdef IPFILTER_LOG
# ifndef SOLARIS
# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
# endif
+# if defined(KERNEL) && !defined(_KERNEL)
+# define _KERNEL
+# endif
# ifdef __FreeBSD__
-# if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-# endif
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
# else
diff --git a/sys/netinet/ip_nat.c b/sys/netinet/ip_nat.c
index e1774b34bb05..0b6c07fc9b4f 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.3 1997/11/12 10:53:29 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.7 1997/12/02 13:54:27 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@@ -317,6 +317,7 @@ int mode;
break;
}
ret = nat_flushtable();
+ (void) ap_unload();
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case SIOCCNATL :
@@ -513,18 +514,14 @@ struct in_addr *inp;
/*
* Create a new NAT table entry.
*/
-#ifdef __STDC__
-nat_t *nat_new(ipnat_t *np, ip_t *ip, fr_info_t *fin, u_short flags, int direction)
-#else
nat_t *nat_new(np, ip, fin, flags, direction)
ipnat_t *np;
ip_t *ip;
fr_info_t *fin;
u_short flags;
int direction;
-#endif
{
- register u_long sum1, sum2, sumd;
+ register u_long sum1, sum2, sumd, l;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in;
tcphdr_t *tcp = NULL;
@@ -554,13 +551,22 @@ int direction;
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
*/
+ l = 0;
do {
+ l++;
port = 0;
in.s_addr = np->in_nip;
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
- if (nat_ifpaddr(nat, fin->fin_ifp, &in) == -1)
+ if ((l > 1) ||
+ nat_ifpaddr(nat, fin->fin_ifp, &in) == -1) {
+ KFREE(nat);
return NULL;
+ }
} else if (!in.s_addr && !np->in_outmsk) {
+ if (l > 1) {
+ KFREE(nat);
+ return NULL;
+ }
in.s_addr = ntohl(ip->ip_src.s_addr);
if (nflags & IPN_TCPUDP)
port = sport;
@@ -609,7 +615,7 @@ int direction;
* internal port.
*/
in.s_addr = ntohl(np->in_inip);
- if (!(nport = htons(np->in_pnext)))
+ if (!(nport = np->in_pnext))
nport = dport;
nat->nat_inip.s_addr = htonl(in.s_addr);
@@ -1083,7 +1089,7 @@ fr_info_t *fin;
(void) ap_check(ip, tcp, fin, nat);
nat_stats.ns_mapped[1]++;
MUTEX_EXIT(&ipf_nat);
- return 1;
+ return -2;
}
MUTEX_EXIT(&ipf_nat);
return 0;
@@ -1212,7 +1218,7 @@ fr_info_t *fin;
}
nat_stats.ns_mapped[0]++;
MUTEX_EXIT(&ipf_nat);
- return 1;
+ return -2;
}
MUTEX_EXIT(&ipf_nat);
return 0;
@@ -1257,6 +1263,9 @@ void ip_natexpire()
nat_delete(nat);
nat_stats.ns_expire++;
}
+
+ ap_expire();
+
MUTEX_EXIT(&ipf_nat);
SPL_X(s);
}
diff --git a/sys/netinet/ip_proxy.c b/sys/netinet/ip_proxy.c
index cea27f6ca0cb..cc3b9a0d032e 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.2 1997/11/12 10:54:11 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.6 1997/11/28 00:41:25 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@@ -226,7 +226,7 @@ nat_t *nat;
* don't do anything with this packet.
*/
if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp,
- ip, tcp)) {
+ ip, tcp, ip->ip_len)) {
frstats[fin->fin_out].fr_tcpbad++;
return -1;
}
@@ -246,7 +246,8 @@ nat_t *nat;
aps, nat);
}
if (err == 2) {
- tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
+ tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip,
+ tcp, ip->ip_len);
err = 0;
}
return err;
@@ -298,3 +299,21 @@ void ap_unload()
aps_free(aps);
}
}
+
+
+void ap_expire()
+{
+ ap_session_t *aps, **apsp;
+ int i;
+
+ for (i = 0; i < AP_SESS_SIZE; i++)
+ for (apsp = &ap_sess_tab[i]; (aps = *apsp); ) {
+ aps->aps_tout--;
+ if (!aps->aps_tout) {
+ ap_sess_tab[i] = aps->aps_next;
+ aps_free(aps);
+ *apsp = aps->aps_next;
+ } else
+ apsp = &aps->aps_next;
+ }
+}
diff --git a/sys/netinet/ip_proxy.h b/sys/netinet/ip_proxy.h
index 2f71316a6800..a361e9368ada 100644
--- a/sys/netinet/ip_proxy.h
+++ b/sys/netinet/ip_proxy.h
@@ -5,7 +5,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * $Id: ip_proxy.h,v 2.0.2.10 1997/10/19 15:39:23 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.0.2.10.2.1 1997/11/27 09:33:27 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -88,5 +88,6 @@ extern void ap_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
extern aproxy_t *ap_match __P((u_char, char *));
+extern void ap_expire __P((void));
#endif /* __IP_PROXY_H__ */
diff --git a/sys/netinet/ip_state.c b/sys/netinet/ip_state.c
index cc14c1a9d9e6..bffb17b7fa45 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.3 1997/11/12 10:55:34 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.4 1997/11/19 11:44:09 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__)
@@ -179,9 +179,7 @@ int mode;
case SIOCIPFFL :
IRCOPY(data, (caddr_t)&arg, sizeof(arg));
if (arg == 0 || arg == 1) {
- MUTEX_ENTER(&ipf_state);
ret = fr_state_flush(arg);
- MUTEX_EXIT(&ipf_state);
IWCOPY((caddr_t)&ret, data, sizeof(ret));
} else
error = EINVAL;
diff --git a/sys/netinet/ipl.h b/sys/netinet/ipl.h
index a7a582800b0c..4ad6bd312f5d 100644
--- a/sys/netinet/ipl.h
+++ b/sys/netinet/ipl.h
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -11,6 +11,6 @@
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter v3.2alpha7"
+#define IPL_VERSION "IP Filter v3.2.3"
#endif
diff --git a/sys/netinet/mlf_ipl.c b/sys/netinet/mlf_ipl.c
index 3a8ee905620b..d6601ba2ebc6 100644
--- a/sys/netinet/mlf_ipl.c
+++ b/sys/netinet/mlf_ipl.c
@@ -135,6 +135,10 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
&fr_defaultauthage, 0, "");
#endif
+#ifdef DEVFS
+void *ipf_devfs[IPL_LOGMAX + 1];
+#endif
+
#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
int ipl_major = 0;
@@ -156,6 +160,7 @@ static struct cdevsw ipl_cdevsw = {
static int iplaction __P((struct lkm_table *, int));
+static void ipl_drvinit __P((void *));
static int iplaction(lkmtp, cmd)
@@ -188,13 +193,27 @@ int cmd;
args->lkm_offset = i; /* slot in cdevsw[] */
#endif
printf("IP Filter: loaded into slot %d\n", ipl_major);
- return if_ipl_load(lkmtp, cmd);
+ err = if_ipl_load(lkmtp, cmd);
+ if (!err)
+ ipl_drvinit((void *)NULL);
+ return err;
break;
case LKM_E_UNLOAD :
err = if_ipl_unload(lkmtp, cmd);
- if (!err)
+ if (!err) {
printf("IP Filter: unloaded from slot %d\n",
ipl_major);
+# ifdef DEVFS
+ if (ipf_devfs[IPL_LOGIPF])
+ devfs_remove_dev(ipf_devfs[IPL_LOGIPF]);
+ if (ipf_devfs[IPL_LOGNAT])
+ devfs_remove_dev(ipf_devfs[IPL_LOGNAT]);
+ if (ipf_devfs[IPL_LOGSTATE])
+ devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]);
+ if (ipf_devfs[IPL_LOGAUTH])
+ devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]);
+# endif
+ }
return err;
case LKM_E_STAT :
break;
@@ -326,42 +345,37 @@ int cmd, ver;
{
DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
}
-# else
-
-#ifdef DEVFS
-static void *ipf_devfs_token[IPL_LOGMAX + 1];
-#endif
+# endif
static ipl_devsw_installed = 0;
static void ipl_drvinit __P((void *unused))
{
dev_t dev;
-#ifdef DEVFS
- void **tp = ipf_devfs_token;
-#endif
+# ifdef DEVFS
+ void **tp = ipf_devfs;
+# endif
if (!ipl_devsw_installed ) {
dev = makedev(CDEV_MAJOR, 0);
cdevsw_add(&dev, &ipl_cdevsw, NULL);
ipl_devsw_installed = 1;
-#ifdef DEVFS
+# ifdef DEVFS
tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF,
- DV_CHR, 0, 0, 0600,
- "ipf", IPL_LOGIPF);
+ DV_CHR, 0, 0, 0600, "ipf");
tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT,
- DV_CHR, 0, 0, 0600,
- "ipnat", IPL_LOGNAT);
+ DV_CHR, 0, 0, 0600, "ipnat");
tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE,
DV_CHR, 0, 0, 0600,
- "ipstate", IPL_LOGSTATE);
+ "ipstate");
tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH,
- DV_CHR, 0, 0, 0600,
- "ipstate", IPL_LOGAUTH);
-#endif
+ DV_CHR, 0, 0, 0600,
+ "ipauth");
+# endif
}
}
+# ifdef IPFILTER_LKM
SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL)
# endif /* IPFILTER_LKM */
#endif /* _FreeBSD_version */