summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2003-02-15 06:25:25 +0000
committerdarrenr <darrenr@FreeBSD.org>2003-02-15 06:25:25 +0000
commit6925466b63c6d8e3fcc363c622d16977df4b06ce (patch)
tree368fc370273730aa4dc2d8bba53bb536fe1a27a7 /sys/contrib/ipfilter
parent609b8035e83638a43ab09d02e66dde20d26d56af (diff)
downloadFreeBSD-src-6925466b63c6d8e3fcc363c622d16977df4b06ce.zip
FreeBSD-src-6925466b63c6d8e3fcc363c622d16977df4b06ce.tar.gz
Commit import changed from vendor branch of ipfilter to -current head
Diffstat (limited to 'sys/contrib/ipfilter')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.c6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h16
-rw-r--r--sys/contrib/ipfilter/netinet/ip_frag.c2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_ftp_pxy.c276
-rw-r--r--sys/contrib/ipfilter/netinet/ip_log.c27
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c86
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.c22
-rw-r--r--sys/contrib/ipfilter/netinet/ip_proxy.h1
-rw-r--r--sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c3
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c47
-rw-r--r--sys/contrib/ipfilter/netinet/ipl.h2
13 files changed, 379 insertions, 117 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index a439a68..b7e66ff 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -298,15 +298,9 @@ ip_t *ip;
cv_signal(&ipfauthwait);
#else
# if defined(BSD) && !defined(sparc) && (BSD >= 199306)
-<<<<<<< ip_auth.c
- if (!fin->fin_out) {
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
-=======
if (fin->fin_out == 0) {
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
->>>>>>> 1.1.1.11
}
# endif
fr_authpkts[i] = m;
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c
index c2961cc..ec4f041 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil.c
@@ -504,15 +504,9 @@ int ipl_disable()
int ipldetach()
# endif
{
-<<<<<<< ip_fil.c
- int s, i = FR_INQUE|FR_OUTQUE;
-#if defined(NETBSD_PF) && \
- ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011))
-=======
int s, i;
#if defined(NETBSD_PF) && \
((__NetBSD_Version__ >= 104200000) || (__FreeBSD_version >= 500011))
->>>>>>> 1.1.1.17
int error = 0;
# if __NetBSD_Version__ >= 105150000
struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index ae5025c..bf407c2 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -64,6 +64,7 @@
# define SIOCSTGET _IOWR('r', 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR('r', 82, struct natget)
# define SIOCGFRST _IOWR('r', 83, struct ipfrstat *)
+# define SIOCIPFL6 _IOWR('r', 84, int)
#else
# define SIOCADAFR _IOW(r, 60, struct frentry *)
# define SIOCRMAFR _IOW(r, 61, struct frentry *)
@@ -89,6 +90,7 @@
# define SIOCSTGET _IOWR(r, 81, struct ipstate_save *)
# define SIOCSTGSZ _IOWR(r, 82, struct natget)
# define SIOCGFRST _IOWR(r, 83, struct ipfrstat *)
+# define SIOCIPFL6 _IOWR(r, 84, int)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
@@ -413,14 +415,16 @@ typedef struct frgroup {
* structure which is then followed by any packet data.
*/
typedef struct iplog {
- u_32_t ipl_magic;
- u_int ipl_count;
- u_long ipl_sec;
- u_long ipl_usec;
- size_t ipl_dsize;
+ u_32_t ipl_magic;
+ u_int ipl_count;
+ struct timeval ipl_tv;
+ size_t ipl_dsize;
struct iplog *ipl_next;
} iplog_t;
+#define ipl_sec ipl_tv.tv_sec
+#define ipl_usec ipl_tv.tv_usec
+
#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
#define IPLOG_SIZE sizeof(iplog_t)
@@ -614,7 +618,7 @@ extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
extern int ipflog_read __P((minor_t, struct uio *));
-extern int frflush __P((minor_t, int));
+extern int frflush __P((minor_t, int, int));
extern void frsync __P((void));
extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
extern void fr_delgroup __P((u_32_t, u_32_t, minor_t, int));
diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c
index e789860..855087a 100644
--- a/sys/contrib/ipfilter/netinet/ip_frag.c
+++ b/sys/contrib/ipfilter/netinet/ip_frag.c
@@ -7,7 +7,7 @@
# define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
index b6644b9..56973da 100644
--- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
@@ -39,24 +39,30 @@ extern kmutex_t ipf_rw;
#define FTPXY_PASS_2 14
#define FTPXY_PAOK_2 15
+/*
+ * Values for FTP commands. Numerics cover 0-999
+ */
+#define FTPXY_C_PASV 1000
+
int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_complete __P((char *, size_t));
int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_init __P((void));
int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
+int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_valid __P((int, char *, size_t));
-int ippr_ftp_server_valid __P((char *, size_t));
-int ippr_ftp_client_valid __P((char *, size_t));
+int ippr_ftp_valid __P((ftpinfo_t *, int, char *, size_t));
+int ippr_ftp_server_valid __P((ftpside_t *, char *, size_t));
+int ippr_ftp_client_valid __P((ftpside_t *, char *, size_t));
u_short ippr_ftp_atoi __P((char **));
static frentry_t ftppxyfr;
int ippr_ftp_pasvonly = 0;
int ippr_ftp_insecure = 0;
+int ippr_ftp_forcepasv = 0;
/*
@@ -123,8 +129,13 @@ int dlen;
/*
* Check for client sending out PORT message.
*/
- if (dlen < IPF_MINPORTLEN)
+ if (dlen < IPF_MINPORTLEN) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", dlen);
+#endif
return 0;
+ }
off = fin->fin_hlen + (tcp->th_off << 2);
/*
* Skip the PORT command + space
@@ -134,23 +145,39 @@ int dlen;
* Pick out the address components, two at a time.
*/
a1 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(1) failed\n");
+#endif
return 0;
+ }
a2 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(2) failed\n");
+#endif
return 0;
+ }
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
- if (a1 != ntohl(nat->nat_inip.s_addr))
+ if (a1 != ntohl(nat->nat_inip.s_addr)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:a1 != nat->nat_inip\n");
+#endif
return 0;
+ }
a5 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(3) failed\n");
+#endif
return 0;
+ }
if (*s == ')')
s++;
@@ -162,8 +189,12 @@ int dlen;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
- } else
+ } else {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:missing cr-lf\n");
+#endif
return 0;
+ }
a5 >>= 8;
a5 &= 0xff;
/*
@@ -181,8 +212,13 @@ int dlen;
nlen = strlen(newbuf);
inc = nlen - olen;
- if ((inc + ip->ip_len) > 65535)
+ if ((inc + ip->ip_len) > 65535) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", inc);
+#endif
return 0;
+ }
#if !defined(_KERNEL)
m = *((mb_t **)fin->fin_mp);
@@ -253,8 +289,13 @@ int dlen;
* Don't allow the PORT command to specify a port < 1024 due to
* security crap.
*/
- if (sp < 1024)
+ if (sp < 1024) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_port:sp(%d) < 1024\n", sp);
+#endif
return 0;
+ }
+
/*
* The server may not make the connection back from port 20, but
* it is the most likely so use it here to check for a conflicting
@@ -369,11 +410,11 @@ int dlen;
}
-int ippr_ftp_pasv(fin, ip, nat, f, dlen)
+int ippr_ftp_pasv(fin, ip, nat, ftp, dlen)
fr_info_t *fin;
ip_t *ip;
nat_t *nat;
-ftpside_t *f;
+ftpinfo_t *ftp;
int dlen;
{
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
@@ -381,23 +422,45 @@ int dlen;
u_int a1, a2, a3, a4;
u_short a5, a6, dp;
fr_info_t fi;
+ ftpside_t *f;
nat_t *ipn;
int inc;
char *s;
+ if (ippr_ftp_forcepasv != 0 &&
+ ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
+ ftp->ftp_side[0].ftps_cmds);
+#endif
+ return 0;
+ }
+
+ f = &ftp->ftp_side[1];
+
#define PASV_REPLEN 24
/*
* Check for PASV reply message.
*/
- if (dlen < IPF_MIN227LEN)
+ if (dlen < IPF_MIN227LEN) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", dlen);
+#endif
return 0;
- else if (strncmp(f->ftps_rptr, "227 Entering Passive Mod", PASV_REPLEN))
+ } else if (strncmp(f->ftps_rptr,
+ "227 Entering Passive Mod", PASV_REPLEN)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:227 reply wrong\n");
+#endif
return 0;
+ }
tcp = (tcphdr_t *)fin->fin_dp;
/*
- * Skip the PORT command + space
+ * Skip the PASV reply + space
*/
s = f->ftps_rptr + PASV_REPLEN;
while (*s && !isdigit(*s))
@@ -406,11 +469,19 @@ int dlen;
* Pick out the address components, two at a time.
*/
a1 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(1) failed\n");
+#endif
return 0;
+ }
a2 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(2) failed\n");
+#endif
return 0;
+ }
/*
* check that IP address in the PORT/PASV reply is the same as the
@@ -418,12 +489,20 @@ int dlen;
*/
a1 <<= 16;
a1 |= a2;
- if (a1 != ntohl(nat->nat_oip.s_addr))
+ if (a1 != ntohl(nat->nat_oip.s_addr)) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:a1 != nat->nat_oip\n");
+#endif
return 0;
+ }
a5 = ippr_ftp_atoi(&s);
- if (!s)
+ if (s == NULL) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(3) failed\n");
+#endif
return 0;
+ }
if (*s == ')')
s++;
@@ -437,8 +516,12 @@ int dlen;
if ((*s == '\r') && (*(s + 1) == '\n')) {
s += 2;
a6 = a5 & 0xff;
- } else
+ } else {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_pasv:missing cr-lf\n");
+#endif
return 0;
+ }
a5 >>= 8;
/*
* Calculate new address parts for 227 reply
@@ -580,9 +663,9 @@ int dlen;
return 0;
if (ftp->ftp_passok == FTPXY_GO) {
if (!strncmp(rptr, "227 ", 4))
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen);
} else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) {
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
+ inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen);
} else if (*rptr == '5' || *rptr == '4')
ftp->ftp_passok = FTPXY_INIT;
else if (ftp->ftp_incok) {
@@ -608,6 +691,7 @@ int dlen;
}
}
ftp->ftp_incok = 0;
+
while ((*rptr++ != '\n') && (rptr < wptr))
;
f->ftps_rptr = rptr;
@@ -619,100 +703,150 @@ int dlen;
* Look to see if the buffer starts with something which we recognise as
* being the correct syntax for the FTP protocol.
*/
-int ippr_ftp_client_valid(buf, len)
+int ippr_ftp_client_valid(ftps, buf, len)
+ftpside_t *ftps;
char *buf;
size_t len;
{
register char *s, c;
register size_t i = len;
+ char cmd[5];
- if (i < 5)
+ if (i < 5) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
+#endif
return 2;
+ }
s = buf;
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[0] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[1] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[2] = toupper(c);
c = *s++;
i--;
if (isalpha(c)) {
+ cmd[3] = toupper(c);
c = *s++;
i--;
if ((c != ' ') && (c != '\r'))
- return 1;
+ goto bad_client_command;
} else if ((c != ' ') && (c != '\r'))
- return 1;
+ goto bad_client_command;
} else
- return 1;
+ goto bad_client_command;
} else
- return 1;
- } else
+ goto bad_client_command;
+ } else {
+bad_client_command:
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_client_valid:bad cmd:len %d i %d c 0x%x\n",
+ i, len, c);
+#endif
return 1;
+ }
+
for (; i; i--) {
c = *s++;
- if (c == '\n')
+ if (c == '\n') {
+ cmd[4] = '\0';
+ if (!strcmp(cmd, "PASV"))
+ ftps->ftps_cmds = FTPXY_C_PASV;
+ else
+ ftps->ftps_cmds = 0;
return 0;
+ }
}
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_client_valid:junk after cmd[%s]\n", buf);
+#endif
return 2;
}
-int ippr_ftp_server_valid(buf, len)
+int ippr_ftp_server_valid(ftps, buf, len)
+ftpside_t *ftps;
char *buf;
size_t len;
{
register char *s, c;
register size_t i = len;
+ int cmd;
if (i < 5)
return 2;
s = buf;
c = *s++;
+ cmd = 0;
i--;
if (isdigit(c)) {
+ cmd = (c - '0') * 100;
c = *s++;
i--;
if (isdigit(c)) {
+ cmd += (c - '0') * 10;
c = *s++;
i--;
if (isdigit(c)) {
+ cmd += (c - '0');
c = *s++;
i--;
if ((c != '-') && (c != ' '))
- return 1;
+ goto bad_server_command;
} else
- return 1;
+ goto bad_server_command;
} else
- return 1;
- } else
+ goto bad_server_command;
+ } else {
+bad_server_command:
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_server_valid:bad cmd:len %d i %d c 0x%x\n",
+ i, len, c);
+#endif
return 1;
+ }
+
for (; i; i--) {
c = *s++;
- if (c == '\n')
+ if (c == '\n') {
+ ftps->ftps_cmds = cmd;
return 0;
+ }
}
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout, "ippr_ftp_server_valid:junk after cmd[%s]\n", buf);
+#endif
return 2;
}
-int ippr_ftp_valid(side, buf, len)
+int ippr_ftp_valid(ftp, side, buf, len)
+ftpinfo_t *ftp;
int side;
char *buf;
size_t len;
{
+ ftpside_t *ftps;
int ret;
+ ftps = &ftp->ftp_side[side];
+
if (side == 0)
- ret = ippr_ftp_client_valid(buf, len);
+ ret = ippr_ftp_client_valid(ftps, buf, len);
else
- ret = ippr_ftp_server_valid(buf, len);
+ ret = ippr_ftp_server_valid(ftps, buf, len);
return ret;
}
@@ -814,9 +948,10 @@ int rv;
#endif
ok = 0;
- if (t->ftps_seq[0] == 0)
- t->ftps_seq[0] = thack, ok = 1;
- else {
+ if (t->ftps_seq[0] == 0) {
+ t->ftps_seq[0] = thack;
+ ok = 1;
+ } else {
if (ackoff == 0) {
if (t->ftps_seq[0] == thack)
ok = 1;
@@ -845,20 +980,24 @@ int rv;
#endif
if (!mlen) {
- if (t->ftps_seq[0] + ackoff != thack)
+ if (t->ftps_seq[0] + ackoff != thack) {
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_process:seq[0](%x) + ackoff(%x) != thack(%x)\n",
+ t->ftps_seq[0], ackoff, thack);
+#endif
return APR_ERR(1);
+ }
#if PROXY_DEBUG
printf("f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]);
#endif
if (tcp->th_flags & TH_FIN) {
- if (thseq + seqoff == f->ftps_seq[0] + 1 ||
- f->ftps_seq[0] + seqoff + 1 == thseq ||
- thseq + seqoff == f->ftps_seq[0] ||
- thseq == f->ftps_seq[0] + seqoff)
- ;
- else {
-#if PROXY_DEBUG
+ if (thseq == f->ftps_seq[1]) {
+ f->ftps_seq[0] = f->ftps_seq[1] - seqoff;
+ f->ftps_seq[1] = thseq + 1 - seqoff;
+ } else {
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
thseq, seqoff, f->ftps_seq[0]);
#endif
@@ -870,17 +1009,19 @@ int rv;
}
ok = 0;
- if (thseq == f->ftps_seq[0] || thseq == f->ftps_seq[1])
+ if ((thseq == f->ftps_seq[0]) || (thseq == f->ftps_seq[1])) {
ok = 1;
/*
* Retransmitted data packet.
*/
- else if (thseq + mlen == f->ftps_seq[0] ||
- thseq + mlen == f->ftps_seq[1])
+ } else if ((thseq + mlen == f->ftps_seq[0]) ||
+ (thseq + mlen == f->ftps_seq[1])) {
ok = 1;
+ }
+
if (ok == 0) {
inc = thseq - f->ftps_seq[0];
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("inc %d sel %d rv %d\n", inc, sel, rv);
printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
f->ftps_seq[1]);
@@ -917,10 +1058,12 @@ int rv;
wptr += len;
f->ftps_wptr = wptr;
if (f->ftps_junk == 2)
- f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
+ wptr - rptr);
while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(rv, rptr, wptr - rptr);
+ f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
+ wptr - rptr);
if (f->ftps_junk == 0) {
f->ftps_cmds++;
len = wptr - rptr;
@@ -942,6 +1085,10 @@ int rv;
*/
if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) {
/* f->ftps_seq[1] += inc; */
+#if !defined(_KERNEL) && !defined(KERNEL)
+ fprintf(stdout,
+ "ippr_ftp_process:cmds == 0 junk == 1\n");
+#endif
return APR_ERR(2);
}
@@ -985,18 +1132,17 @@ int rv;
/* f->ftps_seq[1] += inc; */
if (tcp->th_flags & TH_FIN)
f->ftps_seq[1]++;
-#ifndef _KERNEL
+#if PROXY_DEBUG
+# ifndef _KERNEL
mlen = mbuflen(m);
-#else
-# if SOLARIS
- mlen = msgdsize(m);
# else
+# if SOLARIS
+ mlen = msgdsize(m);
+# else
mlen = mbufchainlen(m);
+# endif
# endif
-#endif
- off = fin->fin_hlen + (tcp->th_off << 2);
mlen -= off;
-#if PROXY_DEBUG
printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen);
#endif
diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c
index 4e8488b..7edba02 100644
--- a/sys/contrib/ipfilter/netinet/ip_log.c
+++ b/sys/contrib/ipfilter/netinet/ip_log.c
@@ -105,6 +105,9 @@
# include <netinet/tcp.h>
# include <netinet/udp.h>
# include <netinet/ip_icmp.h>
+# ifdef USE_INET6
+# include <netinet/icmp6.h>
+# endif
# include <netinet/ip_var.h>
# ifndef _KERNEL
# include <syslog.h>
@@ -217,6 +220,26 @@ mb_t *m;
break;
}
}
+#ifdef USE_INET6
+ else if (p == IPPROTO_ICMPV6) {
+ struct icmp6_hdr *icmp;
+
+ icmp = (struct icmp6_hdr *)fin->fin_dp;
+
+ /*
+ * For ICMPV6, if the packet is an error packet, also
+ * include the information about the packet which
+ * caused the error.
+ */
+ if (icmp->icmp6_type < 128) {
+ hlen += MIN(sizeof(struct icmp6_hdr) + 8,
+ fin->fin_dlen);
+ } else {
+ hlen += MIN(sizeof(struct icmp6_hdr),
+ fin->fin_dlen);
+ }
+ }
+#endif
}
/*
* Get the interface number and name to which this packet is
@@ -340,10 +363,10 @@ int *types, cnt;
ipl->ipl_dsize = len;
# ifdef _KERNEL
# if SOLARIS || defined(sun)
- uniqtime((struct timeval *)&ipl->ipl_sec);
+ uniqtime(&ipl->ipl_tv);
# else
# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
- microtime((struct timeval *)&ipl->ipl_sec);
+ microtime(&ipl->ipl_tv);
# endif
# endif
# else
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index ef109b1..90fd20d 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -10,7 +10,7 @@
#define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -150,6 +150,7 @@ static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr));
static void nat_hostmapdel __P((struct hostmap *));
+static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *));
int nat_init()
@@ -458,8 +459,9 @@ int mode;
/*
* For add/delete, look to see if the NAT entry is already present
*/
- if (getlock == 1)
+ if (getlock == 1) {
WRITE_ENTER(&ipf_nat);
+ }
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
nat = &natd;
nat->in_flags &= IPN_USERFLAGS;
@@ -728,8 +730,9 @@ int mode;
error = EINVAL;
break;
}
- if (getlock == 1)
+ if (getlock == 1) {
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
+ }
done:
if (nt)
KFREE(nt);
@@ -1467,6 +1470,7 @@ int direction;
nat->nat_p = fin->fin_p;
nat->nat_bytes = 0;
nat->nat_pkts = 0;
+ nat->nat_mssclamp = np->in_mssclamp;
nat->nat_fr = fin->fin_fr;
if (nat->nat_fr != NULL) {
ATOMIC_INC32(nat->nat_fr->fr_ref);
@@ -2519,6 +2523,16 @@ maskloop:
*/
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
+
+ /*
+ * Do a MSS CLAMPING on a SYN packet,
+ * only deal IPv4 for now.
+ */
+ if (nat->nat_mssclamp &&
+ (tcp->th_flags & TH_SYN) != 0)
+ nat_mssclamp(tcp, nat->nat_mssclamp,
+ fin, csump);
+
MUTEX_EXIT(&nat->nat_lock);
} else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
@@ -2730,6 +2744,15 @@ maskloop:
*/
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
+ /*
+ * Do a MSS CLAMPING on a SYN packet,
+ * only deal IPv4 for now.
+ */
+ if (nat->nat_mssclamp &&
+ (tcp->th_flags & TH_SYN) != 0)
+ nat_mssclamp(tcp, nat->nat_mssclamp,
+ fin, csump);
+
MUTEX_EXIT(&nat->nat_lock);
} else if (fin->fin_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
@@ -2929,3 +2952,60 @@ void *ifp;
return;
}
#endif
+
+
+/*
+ * Check for MSS option and clamp it if necessary.
+ */
+static void nat_mssclamp(tcp, maxmss, fin, csump)
+tcphdr_t *tcp;
+u_32_t maxmss;
+fr_info_t *fin;
+u_short *csump;
+{
+ u_char *cp, *ep, opt;
+ int hlen, advance;
+ u_32_t mss, sumd;
+ u_short v;
+
+ hlen = tcp->th_off << 2;
+ if (hlen > sizeof(*tcp)) {
+ cp = (u_char *)tcp + sizeof(*tcp);
+ ep = (u_char *)tcp + hlen;
+
+ while (cp < ep) {
+ opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ else if (opt == TCPOPT_NOP) {
+ cp++;
+ continue;
+ }
+
+ if (&cp[1] >= ep)
+ break;
+ advance = cp[1];
+ if (&cp[advance] >= ep)
+ break;
+ switch (opt) {
+ case TCPOPT_MAXSEG:
+ if (advance != 4)
+ break;
+ bcopy(&cp[2], &v, sizeof(v));
+ mss = ntohs(v);
+ if (mss > maxmss) {
+ v = htons(maxmss);
+ bcopy(&v, &cp[2], sizeof(v));
+ CALC_SUMD(mss, maxmss, sumd);
+ fix_outcksum(fin, csump, sumd);
+ }
+ break;
+ default:
+ /* ignore unknown options */
+ break;
+ }
+
+ cp += advance;
+ }
+ }
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 2462e61..6b3fe66 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -85,6 +85,7 @@ typedef struct nat {
u_short nat_use;
u_char nat_tcpstate[2];
u_char nat_p; /* protocol for NAT */
+ u_32_t nat_mssclamp; /* if != zero clamp MSS to this */
struct ipnat *nat_ptr; /* pointer back to the rule */
struct hostmap *nat_hm;
struct nat *nat_next;
@@ -114,6 +115,7 @@ typedef struct ipnat {
u_short in_pnext;
u_short in_ippip; /* IP #'s per IP# */
u_32_t in_flags; /* From here to in_dport must be reflected */
+ u_32_t in_mssclamp; /* if != zero clamp MSS to this */
u_short in_spare;
u_short in_ppip; /* ports per IP */
u_short in_port[2]; /* correctly in IPN_CMPSIZ */
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c
index d612adf..da90a9d 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.c
@@ -8,7 +8,7 @@
# define _KERNEL
#endif
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -312,7 +312,7 @@ nat_t *nat;
sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
#endif
if (sum != tcp->th_sum) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy tcp checksum failure\n");
#endif
frstats[fin->fin_out].fr_tcpbad++;
@@ -320,8 +320,8 @@ nat_t *nat;
}
/*
- * Don't both the proxy with these...or in fact, should
- * we free up proxy stuff when seen?
+ * Don't bother the proxy with these...or in fact,
+ * should we free up proxy stuff when seen?
*/
if ((tcp->th_flags & TH_RST) != 0)
return 0;
@@ -339,13 +339,13 @@ nat_t *nat;
rv = APR_EXIT(err);
if (rv == 1) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy says bad packet received\n");
#endif
return -1;
}
if (rv == 2) {
-#if PROXY_DEBUG
+#if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
printf("proxy says free app proxy data\n");
#endif
appr_free(apr);
@@ -421,7 +421,7 @@ ap_session_t *aps;
apr = aps->aps_apr;
if ((apr != NULL) && (apr->apr_del != NULL))
(*apr->apr_del)(aps);
-
+
if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
@@ -465,7 +465,7 @@ int inc;
sel, !sel, seq1, aps->aps_seqmin[!sel]);
#endif
sel = aps->aps_sel[out] = !sel;
-}
+ }
if (aps->aps_seqoff[sel]) {
seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
@@ -500,7 +500,7 @@ int inc;
sel, !sel, seq1, aps->aps_ackmin[!sel]);
#endif
sel = aps->aps_sel[1 - out] = !sel;
-}
+ }
if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
seq2 = aps->aps_ackoff[sel];
@@ -519,7 +519,7 @@ int inc;
sel, !sel, seq1, aps->aps_ackmin[!sel]);
#endif
sel = aps->aps_sel[out] = !sel;
-}
+ }
if (aps->aps_ackoff[sel]) {
seq2 = aps->aps_ackmin[sel] - aps->aps_ackoff[sel];
@@ -554,7 +554,7 @@ int inc;
sel, !sel, seq1, aps->aps_seqmin[!sel]);
#endif
sel = aps->aps_sel[1 - out] = !sel;
-}
+ }
if (aps->aps_seqoff[sel] != 0) {
#if PROXY_DEBUG
diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h
index d293f17..8488188 100644
--- a/sys/contrib/ipfilter/netinet/ip_proxy.h
+++ b/sys/contrib/ipfilter/netinet/ip_proxy.h
@@ -100,6 +100,7 @@ typedef struct ftpside {
u_32_t ftps_len;
int ftps_junk;
int ftps_cmds;
+ int ftps_cmd;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;
diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
index 1d6bc71..6715b07 100644
--- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
+++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
@@ -1,5 +1,5 @@
/*
- * $Id: ip_rcmd_pxy.c,v 1.4.2.5 2001/10/30 16:38:14 darrenr Exp $
+ * $Id: ip_rcmd_pxy.c,v 1.4.2.6 2002/10/01 15:24:59 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@@ -144,6 +144,7 @@ nat_t *nat;
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_off = 5;
+ tcp2->th_flags = TH_SYN;
fi.fin_data[1] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_dlen = sizeof(*tcp2);
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index b649058..ef4d361 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -4,7 +4,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#ifdef __sgi
+#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>
@@ -119,8 +119,8 @@ static frentry_t *fr_checkicmp6matchingstate __P((ip6_t *, fr_info_t *));
static int fr_matchsrcdst __P((ipstate_t *, union i6addr, union i6addr,
fr_info_t *, tcphdr_t *));
static frentry_t *fr_checkicmpmatchingstate __P((ip_t *, fr_info_t *));
-static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *));
-static int fr_state_flush __P((int));
+static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *, int));
+static int fr_state_flush __P((int, int));
static ips_stat_t *fr_statetstats __P((void));
static void fr_delstate __P((ipstate_t *));
static int fr_state_remove __P((caddr_t));
@@ -205,8 +205,8 @@ static ips_stat_t *fr_statetstats()
* starting at > 4 days idle and working back in successive half-
* days to at most 12 hours old.
*/
-static int fr_state_flush(which)
-int which;
+static int fr_state_flush(which, proto)
+int which, proto;
{
ipstate_t *is, **isp;
#if defined(_KERNEL) && !SOLARIS
@@ -218,6 +218,9 @@ int which;
for (isp = &ips_list; (is = *isp); ) {
delete = 0;
+ if ((proto != 0) && (is->is_v != proto))
+ continue;
+
switch (which)
{
case 0 :
@@ -339,12 +342,26 @@ int mode;
break;
if (arg == 0 || arg == 1) {
WRITE_ENTER(&ipf_state);
- ret = fr_state_flush(arg);
+ ret = fr_state_flush(arg, 4);
RWLOCK_EXIT(&ipf_state);
error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
} else
error = EINVAL;
break;
+#ifdef USE_INET6
+ case SIOCIPFL6 :
+ error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
+ if (error)
+ break;
+ if (arg == 0 || arg == 1) {
+ WRITE_ENTER(&ipf_state);
+ ret = fr_state_flush(arg, 6);
+ RWLOCK_EXIT(&ipf_state);
+ error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
+ } else
+ error = EINVAL;
+ break;
+#endif
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
@@ -1120,7 +1137,7 @@ tcphdr_t *tcp;
return 1;
}
-static int fr_matchicmpqueryreply(v, is, icmp)
+static int fr_matchicmpqueryreply(v, is, icmp, rev)
int v;
ipstate_t *is;
icmphdr_t *icmp;
@@ -1130,8 +1147,8 @@ icmphdr_t *icmp;
* If we matched its type on the way in, then when going out
* it will still be the same type.
*/
- if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
+ if ((!rev && (icmp->icmp_type == is->is_type)) ||
+ (rev && (icmpreplytype4[is->is_type] == icmp->icmp_type))) {
if (icmp->icmp_type != ICMP_ECHOREPLY)
return 1;
if ((icmp->icmp_id == is->is_icmp.ics_id) &&
@@ -1141,8 +1158,8 @@ icmphdr_t *icmp;
}
#ifdef USE_INET6
else if (is->is_v == 6) {
- if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype6[is->is_type] == icmp->icmp_type))) {
+ if ((!rev && (icmp->icmp_type == is->is_type)) ||
+ (rev && (icmpreplytype6[is->is_type] == icmp->icmp_type))) {
if (icmp->icmp_type != ICMP6_ECHO_REPLY)
return 1;
if ((icmp->icmp_id == is->is_icmp.ics_id) &&
@@ -1280,7 +1297,7 @@ fr_info_t *fin;
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == 4) &&
fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
- fr_matchicmpqueryreply(is->is_v, is, icmp)) {
+ fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
ips_stats.iss_hits++;
is->is_pkts++;
is->is_bytes += ip->ip_len;
@@ -1462,7 +1479,7 @@ icmp6again:
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, NULL) &&
- fr_matchicmpqueryreply(v, is, ic)) {
+ fr_matchicmpqueryreply(v, is, ic, fin->fin_rev)) {
rev = fin->fin_rev;
if (is->is_frage[rev] != 0)
is->is_age = is->is_frage[rev];
@@ -1517,7 +1534,7 @@ icmp6again:
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, NULL) &&
- fr_matchicmpqueryreply(v, is, ic)) {
+ fr_matchicmpqueryreply(v, is, ic, fin->fin_rev)) {
rev = fin->fin_rev;
if (is->is_frage[rev] != 0)
is->is_age = is->is_frage[rev];
@@ -1752,7 +1769,7 @@ void fr_timeoutstate()
} else
isp = &is->is_next;
if (fr_state_doflush) {
- (void) fr_state_flush(2);
+ (void) fr_state_flush(2, 0);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h
index d1d69a5..d618986 100644
--- a/sys/contrib/ipfilter/netinet/ipl.h
+++ b/sys/contrib/ipfilter/netinet/ipl.h
@@ -10,6 +10,6 @@
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter: v3.4.29"
+#define IPL_VERSION "IP Filter: v3.4.31"
#endif
OpenPOWER on IntegriCloud