Commit import changed from vendor branch of ipfilter to -current head

This commit is contained in:
Darren Reed 2003-02-15 06:25:25 +00:00
parent 32c7da78f7
commit aeb497128e
13 changed files with 383 additions and 121 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -7,7 +7,7 @@
# define _KERNEL
#endif
#ifdef __sgi
#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <sys/errno.h>

View File

@ -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
mlen = mbuflen(m);
#else
# if SOLARIS
mlen = msgdsize(m);
# else
mlen = mbufchainlen(m);
# endif
#endif
off = fin->fin_hlen + (tcp->th_off << 2);
mlen -= off;
#if PROXY_DEBUG
# ifndef _KERNEL
mlen = mbuflen(m);
# else
# if SOLARIS
mlen = msgdsize(m);
# else
mlen = mbufchainlen(m);
# endif
# endif
mlen -= off;
printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen);
#endif

View File

@ -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

View File

@ -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 @@ fr_info_t *fin;
*/
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 @@ fr_info_t *fin;
*/
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;
}
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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 @@ fr_info_t *fin;
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 @@ fr_info_t *fin;
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);

View File

@ -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