fix conflicts

This commit is contained in:
Darren Reed 2001-02-04 14:26:56 +00:00
parent ddd584a728
commit f590526d0a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=72006
20 changed files with 359 additions and 135 deletions

View File

@ -136,6 +136,8 @@ struct frgroup *ipfgroups[3][2];
int fr_flags = IPF_LOGGING;
int fr_active = 0;
int fr_chksrc = 0;
int fr_minttl = 3;
int fr_minttllog = 1;
#if defined(IPFILTER_DEFAULT_BLOCK)
int fr_pass = FR_NOMATCH|FR_BLOCK;
#else
@ -269,6 +271,40 @@ fr_info_t *fin;
switch (p)
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
{
int minicmpsz = sizeof(struct icmp6_hdr);
struct icmp6_hdr *icmp6;
if (fin->fin_dlen > 1) {
fin->fin_data[0] = *(u_short *)tcp;
icmp6 = (struct icmp6_hdr *)tcp;
switch (icmp6->icmp6_type)
{
case ICMP6_ECHO_REPLY :
case ICMP6_ECHO_REQUEST :
minicmpsz = ICMP6ERR_MINPKTLEN;
break;
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
minicmpsz = ICMP6ERR_IPICMPHLEN;
break;
default :
break;
}
}
if (!(plen >= hlen + minicmpsz))
fi->fi_fl |= FI_SHORT;
break;
}
#endif
case IPPROTO_ICMP :
{
int minicmpsz = sizeof(struct icmp);
@ -747,8 +783,8 @@ int out;
#endif
#ifdef _KERNEL
int p, len, drop = 0, logit = 0;
mb_t *mc = NULL;
int p, len;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
@ -802,11 +838,17 @@ int out;
break;
/* 96 - enough for complete ICMP error IP header */
case IPPROTO_ICMP:
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
# endif
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
* XXX does not take intermediate header
* into account
*/
plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
break;
# endif
}
up = MIN(hlen + plen, len);
@ -865,22 +907,37 @@ int out;
# ifdef USE_INET6
if (v == 6) {
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
logit = -2;
}
} else
# endif
if (!out && fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
if (!out) {
if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
if (fr_chksrc == 2)
logit = -2;
} else if (ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
logit = -3;
}
}
if (drop) {
# ifdef IPFILTER_LOG
if (fr_chksrc == 2) {
fin->fin_group = -2;
pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
(void) IPLLOG(pass, ip, fin, m);
}
if (logit) {
fin->fin_group = logit;
pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
(void) IPLLOG(pass, ip, fin, m);
}
# endif
# if !SOLARIS
m_freem(m);
m_freem(m);
# endif
return error;
}
return error;
}
#endif
pass = fr_pass;
if (fin->fin_fi.fi_fl & FI_SHORT) {
@ -1401,7 +1458,7 @@ tcphdr_t *tcp;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.35.2.27 2000/10/26 21:20:54 darrenr Exp $
* $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,

View File

@ -335,6 +335,7 @@ typedef struct filterstats {
u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
u_long fr_badsrc; /* source received doesn't match route */
u_long fr_badttl; /* TTL in packet doesn't reach minimum */
#if SOLARIS
u_long fr_notdata; /* PROTO/PCPROTO that have no data */
u_long fr_nodata; /* mblks that have no data */
@ -612,6 +613,8 @@ extern int fr_pass;
extern int fr_flags;
extern int fr_active;
extern int fr_chksrc;
extern int fr_minttl;
extern int fr_minttllog;
extern fr_info_t frcache[2];
extern char ipfilter_version[];
extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];

View File

@ -91,6 +91,8 @@ struct flags tcpfl[] = {
{ TH_FIN, 'F' },
{ TH_URG, 'U' },
{ TH_PUSH,'P' },
{ TH_ECN, 'E' },
{ TH_CWR, 'C' },
{ 0, '\0' }
};
@ -144,6 +146,7 @@ static char **tcp_ports = NULL;
#define OPT_FILTER 0x200
#define OPT_PORTNUM 0x400
#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER)
#define OPT_LOGBODY 0x800
#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b))
@ -401,6 +404,8 @@ int blen;
strcpy(t, "NAT:RDR ");
else if (nl->nl_type == NL_EXPIRE)
strcpy(t, "NAT:EXPIRE ");
else if (nl->nl_type == NL_FLUSH)
strcpy(t, "NAT:FLUSH ");
else if (nl->nl_type == NL_NEWBIMAP)
strcpy(t, "NAT:BIMAP ");
else if (nl->nl_type == NL_NEWBLOCK)
@ -834,6 +839,8 @@ int blen;
dumphex(log, (u_char *)buf, sizeof(iplog_t) + sizeof(*ipf));
if (opts & OPT_HEXBODY)
dumphex(log, (u_char *)ip, ipf->fl_plen + ipf->fl_hlen);
else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY))
dumphex(log, (u_char *)ip + ipf->fl_hlen, ipf->fl_plen);
}
@ -945,7 +952,7 @@ char *argv[];
iplfile[1] = IPNAT_NAME;
iplfile[2] = IPSTATE_NAME;
while ((c = getopt(argc, argv, "?aDf:FhnN:o:O:pP:sS:tvxX")) != -1)
while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
case 'a' :
@ -954,6 +961,9 @@ char *argv[];
fdt[1] = IPL_LOGNAT;
fdt[2] = IPL_LOGSTATE;
break;
case 'b' :
opts |= OPT_LOGBODY;
break;
case 'D' :
make_daemon = 1;
break;

View File

@ -348,6 +348,12 @@ char **argv;
printf("Options: %d\n", olen);
ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
if(!ti)
{
fprintf(stderr,"malloc failed\n");
exit(2);
}
bcopy((char *)ip, (char *)ti, sizeof(*ip));
ip = (ip_t *)ti;
ip->ip_hl = (olen >> 2);

View File

@ -8,7 +8,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: sock.c,v 2.1 1999/08/04 17:31:16 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.1 2000/12/16 21:05:44 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>

View File

@ -140,14 +140,22 @@ kernel.
.SH STATE TOP
Using the \fB\-t\fP option \fBipfstat\fP will enter the state top mode. In
this mode the state table is displayed similar to the way \fBtop\fP displays
the process table. The \fB\-C\fP, \fB\-D\fP, \fB\-P\fP, \fB\-S\fP and\fB\-T\fP
the process table. The \fB\-C\fP, \fB\-D\fP, \fB\-P\fP, \fB\-S\fP and \fB\-T\fP
commandline options can be used to restrict the state entries that will be
shown and to specify the frequency of display updates.
.PP
In state top mode, the following keys can be used to influence the displayed
information. \fBl\fP can be used to redraw the screen. \fBq\fP is used to
quit the program. \fBs\fP can be used to change the sorting criterion and
\fBr\fP can be used to reverse the sorting criterion.
information:
.TP
\fBd\fP select information to display.
.TP
\fBl\fP redraw the screen.
.TP
\fBq\fP quit the program.
.TP
\fBs\fP switch between different sorting criterion.
.TP
\fBr\fP reverse the sorting criterion.
.PP
States can be sorted by protocol number, by number of IP packets, by number
of bytes and by time-to-live of the state entry. The default is to sort by

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
/* static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.16 2000/01/27 08:49:37 darrenr Exp $"; */
static const char rcsid[] = "@(#)$FreeBSD$";
#endif
@ -139,6 +139,8 @@ struct frgroup *ipfgroups[3][2];
int fr_flags = IPF_LOGGING;
int fr_active = 0;
int fr_chksrc = 0;
int fr_minttl = 3;
int fr_minttllog = 1;
#if defined(IPFILTER_DEFAULT_BLOCK)
int fr_pass = FR_NOMATCH|FR_BLOCK;
#else
@ -272,6 +274,40 @@ fr_info_t *fin;
switch (p)
{
#ifdef USE_INET6
case IPPROTO_ICMPV6 :
{
int minicmpsz = sizeof(struct icmp6_hdr);
struct icmp6_hdr *icmp6;
if (fin->fin_dlen > 1) {
fin->fin_data[0] = *(u_short *)tcp;
icmp6 = (struct icmp6_hdr *)tcp;
switch (icmp6->icmp6_type)
{
case ICMP6_ECHO_REPLY :
case ICMP6_ECHO_REQUEST :
minicmpsz = ICMP6ERR_MINPKTLEN;
break;
case ICMP6_DST_UNREACH :
case ICMP6_PACKET_TOO_BIG :
case ICMP6_TIME_EXCEEDED :
case ICMP6_PARAM_PROB :
minicmpsz = ICMP6ERR_IPICMPHLEN;
break;
default :
break;
}
}
if (!(plen >= hlen + minicmpsz))
fi->fi_fl |= FI_SHORT;
break;
}
#endif
case IPPROTO_ICMP :
{
int minicmpsz = sizeof(struct icmp);
@ -750,8 +786,8 @@ int out;
#endif
#ifdef _KERNEL
int p, len, drop = 0, logit = 0;
mb_t *mc = NULL;
int p, len;
# if !defined(__SVR4) && !defined(__svr4__)
# ifdef __sgi
char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
@ -805,11 +841,17 @@ int out;
break;
/* 96 - enough for complete ICMP error IP header */
case IPPROTO_ICMP:
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
# endif
plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
break;
# ifdef USE_INET6
case IPPROTO_ICMPV6 :
/*
* XXX does not take intermediate header
* into account
*/
plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
break;
# endif
}
up = MIN(hlen + plen, len);
@ -870,22 +912,37 @@ int out;
# ifdef USE_INET6
if (v == 6) {
ATOMIC_INCL(frstats[0].fr_ipv6[out]);
if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
logit = -2;
}
} else
# endif
if (!out && fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
if (!out) {
if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
ATOMIC_INCL(frstats[0].fr_badsrc);
if (fr_chksrc == 2)
logit = -2;
} else if (ip->ip_ttl < fr_minttl) {
ATOMIC_INCL(frstats[0].fr_badttl);
if (fr_minttllog)
logit = -3;
}
}
if (drop) {
# ifdef IPFILTER_LOG
if (fr_chksrc == 2) {
fin->fin_group = -2;
pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
(void) IPLLOG(pass, ip, fin, m);
}
if (logit) {
fin->fin_group = logit;
pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
(void) IPLLOG(pass, ip, fin, m);
}
# endif
# if !SOLARIS
m_freem(m);
m_freem(m);
# endif
return error;
}
return error;
}
#endif
pass = fr_pass;
if (fin->fin_fi.fi_fl & FI_SHORT) {
@ -1408,7 +1465,7 @@ tcphdr_t *tcp;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.35.2.27 2000/10/26 21:20:54 darrenr Exp $
* $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,

View File

@ -350,7 +350,7 @@ frentry_t *fr, **frptr;
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data,
sizeof(fr_info_t));
sizeof(frauth_t));
RWLOCK_EXIT(&ipf_auth);
if (error)
break;

View File

@ -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.1.2.3 1999/11/18 13:55:26 darrenr Exp $
* $Id: ip_compat.h,v 2.26.2.9 2001/01/14 14:58:01 darrenr Exp $
* $FreeBSD$
*/
@ -975,8 +975,6 @@ struct ether_addr {
#define A_A &
#endif
#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG)
#ifndef ICMP_ROUTERADVERT
# define ICMP_ROUTERADVERT 9
#endif
@ -996,6 +994,20 @@ struct ether_addr {
#define ICMPERR_IPICMPHLEN (20 + 8)
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
#define ICMP6ERR_MINPKTLEN (20 + 8)
#define ICMP6ERR_MINPKTLEN (40 + 8)
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
/*
* ECN is a new addition to TCP - RFC 2481
*/
#ifndef TH_ECN
# define TH_ECN 0x40
#endif
#ifndef TH_CWR
# define TH_CWR 0x80
#endif
#define TH_ECNALL (TH_ECN|TH_CWR)
#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECN|TH_CWR)
#endif /* __IP_COMPAT_H__ */

View File

@ -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.29.2.3 2000/06/05 13:12:42 darrenr Exp $
* $Id: ip_fil.h,v 2.29.2.4 2000/11/12 11:54:53 darrenr Exp $
* $FreeBSD$
*/
@ -336,6 +336,7 @@ typedef struct filterstats {
u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
u_long fr_badsrc; /* source received doesn't match route */
u_long fr_badttl; /* TTL in packet doesn't reach minimum */
#if SOLARIS
u_long fr_notdata; /* PROTO/PCPROTO that have no data */
u_long fr_nodata; /* mblks that have no data */
@ -615,6 +616,8 @@ extern int fr_pass;
extern int fr_flags;
extern int fr_active;
extern int fr_chksrc;
extern int fr_minttl;
extern int fr_minttllog;
extern fr_info_t frcache[2];
extern char ipfilter_version[];
extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];

View File

@ -7,7 +7,6 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
/*static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.4 2000/06/06 15:49:15 darrenr Exp $";*/
static const char rcsid[] = "@(#)$FreeBSD$";
#endif
@ -157,6 +156,7 @@ ipfr_t *table[];
idx += ip->ip_src.s_addr;
frag.ipfr_dst.s_addr = ip->ip_dst.s_addr;
idx += ip->ip_dst.s_addr;
frag.ipfr_ifp = fin->fin_ifp;
idx *= 127;
idx %= IPFT_SIZE;
@ -271,6 +271,7 @@ ipfr_t *table[];
idx += ip->ip_src.s_addr;
frag.ipfr_dst.s_addr = ip->ip_dst.s_addr;
idx += ip->ip_dst.s_addr;
frag.ipfr_ifp = fin->fin_ifp;
idx *= 127;
idx %= IPFT_SIZE;
@ -329,16 +330,13 @@ fr_info_t *fin;
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
nat = ipf->ipfr_data;
if (nat->nat_ifp == fin->fin_ifp) {
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
} else
nat = NULL;
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
} else
nat = NULL;
RWLOCK_EXIT(&ipf_natfrag);

View File

@ -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.2 1999/08/06 06:26:38 darrenr Exp $
* $Id: ip_frag.h,v 2.4.2.2 2000/11/10 13:10:54 darrenr Exp $
* $FreeBSD$
*/
@ -20,6 +20,7 @@ typedef struct ipfr {
void *ipfr_data;
struct in_addr ipfr_src;
struct in_addr ipfr_dst;
void *ipfr_ifp;
u_short ipfr_id;
u_char ipfr_p;
u_char ipfr_tos;

View File

@ -1,6 +1,7 @@
/*
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $FreeBSD$
*/
#if SOLARIS && defined(_KERNEL)
@ -237,7 +238,7 @@ int dlen;
*/
dp = htons(fin->fin_data[1] - 1);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
ip->ip_dst, (dp << 16) | sp, 0);
if (ipn == NULL) {
int slen;
@ -253,7 +254,9 @@ int dlen;
fi.fin_data[1] = 0;
fi.fin_dlen = sizeof(*tcp2);
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
swip = ip->ip_src;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
NAT_OUTBOUND);
@ -455,7 +458,7 @@ int dlen;
sp = 0;
dp = htons(fin->fin_data[1] - 1);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
ip->ip_dst, (dp << 16) | sp, 0);
if (ipn == NULL) {
int slen;
@ -466,13 +469,16 @@ int dlen;
tcp2->th_win = htons(8192);
tcp2->th_sport = 0; /* XXX - fake it for nat_new */
tcp2->th_off = 5;
fi.fin_data[0] = a5 << 8 | a6;
fi.fin_data[1] = a5 << 8 | a6;
fi.fin_dlen = sizeof(*tcp2);
tcp2->th_dport = htons(fi.fin_data[0]);
fi.fin_data[1] = 0;
tcp2->th_dport = htons(fi.fin_data[1]);
fi.fin_data[0] = 0;
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &natfr;
swip = ip->ip_src;
swip2 = ip->ip_dst;
fi.fin_fi.fi_daddr = ip->ip_src.s_addr;
fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
ip->ip_dst = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_SPORT,
@ -613,14 +619,18 @@ int rv;
#else
mlen = mbufchainlen(m) - off;
#endif
t = &ftp->ftp_side[1 - rv];
f = &ftp->ftp_side[rv];
if (!mlen) {
t->ftps_seq = ntohl(tcp->th_ack);
if (!t->ftps_seq ||
(int)ntohl(tcp->th_ack) - (int)t->ftps_seq > 0)
t->ftps_seq = ntohl(tcp->th_ack);
f->ftps_len = 0;
return 0;
}
inc = 0;
f = &ftp->ftp_side[rv];
rptr = f->ftps_rptr;
wptr = f->ftps_wptr;
@ -634,9 +644,12 @@ int rv;
* that it is out of order (and there is no real danger in doing so
* apart from causing packets to go through here ordered).
*/
if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq))
f->ftps_seq = ntohl(tcp->th_seq);
else if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
return APR_ERR(-1);
}
f->ftps_len = mlen;
while (mlen > 0) {
len = MIN(mlen, FTP_BUFSZ / 2);

View File

@ -8,7 +8,7 @@
* Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com)
*/
#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.37.2.32 2001/01/10 06:19:11 darrenr Exp $";
/*static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.16 2000/07/18 13:57:40 darrenr Exp $";*/
static const char rcsid[] = "@(#)$FreeBSD$";
#endif
@ -130,7 +130,7 @@ u_long fr_defnatage = DEF_NAT_AGE,
natstat_t nat_stats;
int fr_nat_lock = 0;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_rw, ipf_hostmap;
extern kmutex_t ipf_rw;
extern KRWLOCK_T ipf_nat;
#endif
@ -144,7 +144,7 @@ static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t));
static void nat_tabmove __P((nat_t *));
static void nat_tabmove __P((nat_t *, u_32_t));
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));
@ -251,6 +251,8 @@ ipnat_t *n;
/*
* check if an ip address has already been allocated for a given mapping that
* is not doing port based translation.
*
* Must be called with ipf_nat held as a write lock.
*/
static struct hostmap *nat_hostmap(np, real, map)
ipnat_t *np;
@ -260,13 +262,11 @@ struct in_addr map;
hostmap_t *hm;
u_int hv;
MUTEX_ENTER(&ipf_hostmap);
hv = real.s_addr % HOSTMAP_SIZE;
for (hm = maptable[hv]; hm; hm = hm->hm_next)
if ((hm->hm_realip.s_addr == real.s_addr) &&
(np == hm->hm_ipnat)) {
hm->hm_ref++;
MUTEX_EXIT(&ipf_hostmap);
return hm;
}
@ -282,15 +282,16 @@ struct in_addr map;
hm->hm_mapip = map;
hm->hm_ref = 1;
}
MUTEX_EXIT(&ipf_hostmap);
return hm;
}
/*
* Must be called with ipf_nat held as a write lock.
*/
static void nat_hostmapdel(hm)
struct hostmap *hm;
{
MUTEX_ENTER(&ipf_hostmap);
ATOMIC_DEC32(hm->hm_ref);
if (hm->hm_ref == 0) {
if (hm->hm_next)
@ -298,7 +299,6 @@ struct hostmap *hm;
*hm->hm_pnext = hm->hm_next;
KFREE(hm);
}
MUTEX_EXIT(&ipf_hostmap);
}
@ -699,9 +699,9 @@ int mode;
break;
case FIONREAD :
#ifdef IPFILTER_LOG
arg = (int)iplused[IPL_LOGNAT];
MUTEX_DOWNGRADE(&ipf_nat);
error = IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data,
sizeof(iplused[IPL_LOGNAT]));
error = IWCOPY((caddr_t)&arg, (caddr_t)data, sizeof(arg));
if (error)
error = EFAULT;
#endif
@ -1069,6 +1069,9 @@ static int nat_flushtable()
for (natp = &nat_instances; (nat = *natp); ) {
*natp = nat->nat_next;
#ifdef IPFILTER_LOG
nat_log(nat, NL_FLUSH);
#endif
nat_delete(nat);
j++;
}
@ -1296,7 +1299,7 @@ int direction;
inb.s_addr = htonl(in.s_addr);
natl = nat_inlookup(fin->fin_ifp, flags & ~FI_WILDP,
(u_int)ip->ip_p, ip->ip_dst, inb,
(port << 16) | dport);
(port << 16) | dport, 1);
/*
* Has the search wrapped around and come back to the
@ -1445,6 +1448,9 @@ int direction;
tcp->th_dport = nport;
}
np->in_use++;
#ifdef IPFILTER_LOG
nat_log(nat, (u_int)np->in_redir);
#endif
return nat;
badnat:
nat_stats.ns_badnat++;
@ -1566,18 +1572,18 @@ int dir;
if (dir == NAT_INBOUND)
return nat_inlookup(fin->fin_ifp, flags,
(u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
(tcp->th_sport << 16) | tcp->th_dport);
(tcp->th_sport << 16) | tcp->th_dport, 0);
else
return nat_outlookup(fin->fin_ifp, flags,
(u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
(tcp->th_sport << 16) | tcp->th_dport);
(tcp->th_sport << 16) | tcp->th_dport, 0);
}
if (dir == NAT_INBOUND)
return nat_inlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
oip->ip_dst, oip->ip_src, 0);
oip->ip_dst, oip->ip_src, 0, 0);
else
return nat_outlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
oip->ip_dst, oip->ip_src, 0);
oip->ip_dst, oip->ip_src, 0, 0);
}
@ -1591,7 +1597,7 @@ fr_info_t *fin;
u_int *nflags;
int dir;
{
u_32_t sum1, sum2, sumd;
u_32_t sum1, sum2, sumd, sumd2 = 0;
struct in_addr in;
icmphdr_t *icmp;
udphdr_t *udp;
@ -1640,7 +1646,7 @@ int dir;
* in the first 8 bytes, so it will not be available in most cases.
*/
if (nat->nat_dir == NAT_OUTBOUND) {
if (oip->ip_dst.s_addr == nat->nat_oip.s_addr) {
sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
in = nat->nat_inip;
oip->ip_src = in;
@ -1692,7 +1698,7 @@ int dir;
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
sumd2 = sumd;
}
#if 0
@ -1751,7 +1757,7 @@ int dir;
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
sumd2 = sumd;
}
#if 0
@ -1797,7 +1803,7 @@ int dir;
* device that returns more than 8 data bytes on icmp error)
*/
if (nat->nat_dir == NAT_OUTBOUND) {
if (nat->nat_oport == tcp->th_dport) {
if (tcp->th_sport != nat->nat_inport) {
/*
* Fix ICMP checksum to compensate port
@ -1806,8 +1812,8 @@ int dir;
sum1 = ntohs(tcp->th_sport);
sum2 = ntohs(nat->nat_inport);
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
tcp->th_sport = nat->nat_inport;
fix_outcksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
@ -1830,11 +1836,10 @@ int dir;
* adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
sumd2 += sumd;
}
}
} else {
if (tcp->th_dport != nat->nat_outport) {
/*
* Fix ICMP checksum to compensate port
@ -1843,8 +1848,8 @@ int dir;
sum1 = ntohs(tcp->th_dport);
sum2 = ntohs(nat->nat_outport);
CALC_SUMD(sum1, sum2, sumd);
sumd2 += sumd;
tcp->th_dport = nat->nat_outport;
fix_incksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
@ -1866,10 +1871,19 @@ int dir;
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
sumd2 += sumd;
}
}
}
if (sumd2) {
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_outcksum(&icmp->icmp_cksum, sumd2);
} else {
fix_incksum(&icmp->icmp_cksum, sumd2);
}
}
}
nat->nat_age = fr_defnaticmpage;
return nat;
@ -1886,11 +1900,12 @@ int dir;
* we're looking for a table entry, based on the destination address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
nat_t *nat_inlookup(ifp, flags, p, src, mapdst, ports)
nat_t *nat_inlookup(ifp, flags, p, src, mapdst, ports, rw)
void *ifp;
register u_int flags, p;
struct in_addr src , mapdst;
u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
@ -1918,9 +1933,13 @@ u_32_t ports;
}
if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
hv = NAT_HASH_FN(dst, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
@ -1935,21 +1954,38 @@ u_32_t ports;
continue;
if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
nat_tabmove(nat);
nat_tabmove(nat, ports);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
if (!rw) {
MUTEX_DOWNGRADE(&ipf_nat);
}
return nat;
}
static void nat_tabmove(nat)
/*
* This function is only called for TCP/UDP NAT table entries where the
* original was placed in the table without hashing on the ports and we now
* want to include hashing on port numbers.
*/
static void nat_tabmove(nat, ports)
nat_t *nat;
u_32_t ports;
{
register u_short sport, dport;
nat_t **natp;
u_int hv;
dport = ports >> 16;
sport = ports & 0xffff;
if (nat->nat_oport == dport) {
nat->nat_inport = sport;
nat->nat_outport = sport;
}
/*
* Remove the NAT entry from the old location
*/
@ -1964,8 +2000,7 @@ nat_t *nat;
/*
* Add into the NAT table in the new position
*/
hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
ipf_nattable_sz);
hv = NAT_HASH_FN(nat->nat_inip.s_addr, sport, ipf_nattable_sz);
natp = &nat_table[0][hv];
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
@ -1973,8 +2008,7 @@ nat_t *nat;
nat->nat_hnext[0] = *natp;
*natp = nat;
hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
ipf_nattable_sz);
hv = NAT_HASH_FN(nat->nat_outip.s_addr, sport, ipf_nattable_sz);
natp = &nat_table[1][hv];
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
@ -1990,11 +2024,12 @@ nat_t *nat;
* we're looking for a table entry, based on the source address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
nat_t *nat_outlookup(ifp, flags, p, src, dst, ports)
nat_t *nat_outlookup(ifp, flags, p, src, dst, ports, rw)
void *ifp;
register u_int flags, p;
struct in_addr src , dst;
u_32_t ports;
int rw;
{
register u_short sport, dport;
register nat_t *nat;
@ -2015,7 +2050,7 @@ u_32_t ports;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
(((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
(((p == 0) && (flags == (nflags & IPN_TCPUDP)))
|| (p == nat->nat_p)) && (!flags ||
((nat->nat_inport == sport || nflags & FI_W_SPORT) &&
(nat->nat_oport == dport || nflags & FI_W_DPORT))))
@ -2023,9 +2058,13 @@ u_32_t ports;
}
if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
if (!rw) {
RWLOCK_EXIT(&ipf_nat);
}
hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
if (!rw) {
WRITE_ENTER(&ipf_nat);
}
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
@ -2038,13 +2077,15 @@ u_32_t ports;
if ((nat->nat_inip.s_addr != srcip) ||
(nat->nat_oip.s_addr != dst.s_addr))
continue;
if (((nat->nat_inport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_SPORT))) {
nat_tabmove(nat);
if (((nat->nat_inport == sport) || (nflags & FI_W_SPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_DPORT))) {
nat_tabmove(nat, ports);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
if (!rw) {
MUTEX_DOWNGRADE(&ipf_nat);
}
return nat;
}
@ -2064,7 +2105,7 @@ register natlookup_t *np;
* ip address. Else, we use the fake.
*/
if ((nat = nat_outlookup(NULL, np->nl_flags, 0, np->nl_inip,
np->nl_outip, ports))) {
np->nl_outip, ports, 0))) {
np->nl_realip = nat->nat_outip;
np->nl_realport = nat->nat_outport;
}
@ -2165,10 +2206,11 @@ fr_info_t *fin;
(nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
;
else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
(nat = ipfr_nat_knownfrag(ip, fin)))
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p, ip->ip_src,
ip->ip_dst, (dport << 16) | sport))) {
else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p,
ip->ip_src, ip->ip_dst,
(dport << 16) | sport, 0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nflags & FI_W_SPORT) &&
@ -2222,9 +2264,6 @@ fr_info_t *fin;
if ((nat = nat_new(np, ip, fin, (u_int)nflags,
NAT_OUTBOUND))) {
np->in_hits++;
#ifdef IPFILTER_LOG
nat_log(nat, (u_int)np->in_redir);
#endif
break;
}
}
@ -2240,6 +2279,9 @@ fr_info_t *fin;
MUTEX_DOWNGRADE(&ipf_nat);
}
/*
* NOTE: ipf_nat must now only be held as a read lock
*/
if (nat) {
np = nat->nat_ptr;
if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
@ -2384,7 +2426,8 @@ fr_info_t *fin;
(nat = ipfr_nat_knownfrag(ip, fin)))
natadd = 0;
else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p,
ip->ip_src, in, (dport << 16) | sport))) {
ip->ip_src, in, (dport << 16) | sport,
0))) {
nflags = nat->nat_flags;
if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT))
@ -2425,9 +2468,6 @@ fr_info_t *fin;
if ((nat = nat_new(np, ip, fin, nflags,
NAT_INBOUND))) {
np->in_hits++;
#ifdef IPFILTER_LOG
nat_log(nat, (u_int)np->in_redir);
#endif
break;
}
}
@ -2442,6 +2482,10 @@ fr_info_t *fin;
}
MUTEX_DOWNGRADE(&ipf_nat);
}
/*
* NOTE: ipf_nat must now only be held as a read lock
*/
if (nat) {
np = nat->nat_ptr;
fin->fin_fr = nat->nat_fr;

View File

@ -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.17.2.6 2000/07/15 14:50:06 darrenr Exp $
* $Id: ip_nat.h,v 2.17.2.14 2000/11/18 03:58:04 darrenr Exp $
* $FreeBSD$
*/
@ -86,7 +86,7 @@ typedef struct nat {
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
#if SOLARIS || defined(_sgi)
#if SOLARIS || defined(__sgi)
kmutex_t nat_lock;
#endif
} nat_t;
@ -248,6 +248,7 @@ typedef struct natlog {
#define NL_NEWRDR NAT_REDIRECT
#define NL_NEWBIMAP NAT_BIMAP
#define NL_NEWBLOCK NAT_MAPBLK
#define NL_FLUSH 0xfffe
#define NL_EXPIRE 0xffff
#define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m))
@ -286,9 +287,9 @@ extern int nat_ioctl __P((caddr_t, int, int));
extern int nat_init __P((void));
extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
struct in_addr, u_32_t));
struct in_addr, u_32_t, int));
extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
struct in_addr, u_32_t));
struct in_addr, u_32_t, int));
extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
struct in_addr));
extern nat_t *nat_lookupredir __P((natlookup_t *));

View File

@ -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.1.2.1 1999/09/19 12:18:20 darrenr Exp $
* $Id: ip_proxy.h,v 2.8.2.4 2000/12/02 00:15:03 darrenr Exp $
* $FreeBSD$
*/
@ -97,6 +97,7 @@ typedef struct ftpside {
char *ftps_rptr;
char *ftps_wptr;
u_32_t ftps_seq;
u_32_t ftps_len;
int ftps_junk;
char ftps_buf[FTP_BUFSZ];
} ftpside_t;

View File

@ -1,5 +1,5 @@
/*
* $Id: ip_rcmd_pxy.c,v 1.4.2.3 2000/10/27 22:54:04 darrenr Exp $
* $Id: ip_rcmd_pxy.c,v 1.4.2.4 2000/11/01 14:34:20 darrenr Exp $
*/
/*
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
@ -132,7 +132,7 @@ nat_t *nat;
sp = htons(sp);
dp = htons(fin->fin_data[1]);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
ip->ip_dst, (dp << 16) | sp);
ip->ip_dst, (dp << 16) | sp, 0);
if (ipn == NULL) {
int slen;

View File

@ -307,8 +307,8 @@ int mode;
break;
case FIONREAD :
#ifdef IPFILTER_LOG
error = IWCOPY((caddr_t)&iplused[IPL_LOGSTATE], (caddr_t)data,
sizeof(iplused[IPL_LOGSTATE]));
arg = (int)iplused[IPL_LOGSTATE];
error = IWCOPY((caddr_t)&arg, (caddr_t)data, sizeof(arg));
#endif
break;
case SIOCSTLCK :
@ -787,8 +787,6 @@ tcphdr_t *tcp;
}
ATOMIC_INCL(ips_stats.iss_hits);
is->is_pkts++;
is->is_bytes += fin->fin_dlen + fin->fin_hlen;
/*
* Nearing end of connection, start timeout.
*/
@ -1148,10 +1146,6 @@ fr_info_t *fin;
fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
fr = is->is_rule;
ips_stats.iss_hits++;
/*
* we must swap src and dst here because the icmp
* comes the other way around
*/
is->is_pkts++;
is->is_bytes += fin->fin_plen;
/*
@ -1379,6 +1373,9 @@ void *ifp;
}
/*
* Must always be called with fr_ipfstate held as a write lock.
*/
static void fr_delstate(is)
ipstate_t *is;
{
@ -1397,9 +1394,10 @@ ipstate_t *is;
fr = is->is_rule;
if (fr != NULL) {
ATOMIC_DEC32(fr->fr_ref);
if (fr->fr_ref == 0)
fr->fr_ref--;
if (fr->fr_ref == 0) {
KFREE(fr);
}
}
#ifdef _KERNEL
MUTEX_DESTROY(&is->is_lock);
@ -1452,12 +1450,12 @@ void fr_timeoutstate()
fr_delstate(is);
} else
isp = &is->is_next;
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
if (fr_state_doflush) {
(void) fr_state_flush(1);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
}

View File

@ -12,6 +12,6 @@
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.4.13"
#define IPL_VERSION "IP Filter: v3.4.16"
#endif

View File

@ -38,6 +38,12 @@
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#if (__FreeBSD_version >= 199511)
# include <net/route.h>
# include <netinet/ip_var.h>
# include <netinet/tcp.h>
# include <netinet/tcpip.h>
#endif
#include <netinet/ipl.h>
@ -47,6 +53,7 @@
#include <netinet/ip_nat.h>
#include <netinet/ip_auth.h>
#include <netinet/ip_frag.h>
#include <netinet/ip_proxy.h>
static dev_t ipf_devs[IPL_LOGMAX + 1];
@ -86,6 +93,11 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
&fr_defaultauthage, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW,
&ippr_ftp_pasvonly, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW,
&fr_minttllog, 0, "");
#define CDEV_MAJOR 79
static struct cdevsw ipl_cdevsw = {