Update ipfilter from 3.4.31 -> 3.4.35. Some important changes:
* block packets that fail to create state table entries * only allow non-fragmented packets to influence whether or not a logged packet is the same as the one logged before. * correct the ICMP packet checksum fixing up when processing ICMP errors for NAT * implement a maximum for the number of entries in the NAT table (NAT_TABLE_MAX and ipf_nattable_max) * frsynclist() wasn't paying attention to all the places where interface names are, like it should. * fix comparing ICMP packets with established TCP state where only 8 bytes of header are returned in the ICMP error. MFC after: 1 week
This commit is contained in:
parent
c38dd4b6bd
commit
7b807523f4
@ -42,6 +42,7 @@
|
||||
# include <sys/mbuf.h>
|
||||
# endif
|
||||
#else
|
||||
# include <sys/cmn_err.h>
|
||||
# include <sys/byteorder.h>
|
||||
# if SOLARIS2 < 5
|
||||
# include <sys/dditypes.h>
|
||||
@ -146,6 +147,9 @@ fr_info_t frcache[2];
|
||||
static int frflushlist __P((int, minor_t, int *, frentry_t **));
|
||||
#ifdef _KERNEL
|
||||
static void frsynclist __P((frentry_t *));
|
||||
# ifndef __sgi
|
||||
static void *ipf_pullup __P((mb_t *, fr_info_t *, int, void *));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -194,19 +198,27 @@ struct optlist secopt[8] = {
|
||||
* compact the IP header into a structure which contains just the info.
|
||||
* which is useful for comparing IP headers with.
|
||||
*/
|
||||
void fr_makefrip(hlen, ip, fin)
|
||||
int fr_makefrip(hlen, ip, fin)
|
||||
int hlen;
|
||||
ip_t *ip;
|
||||
fr_info_t *fin;
|
||||
{
|
||||
u_short optmsk = 0, secmsk = 0, auth = 0;
|
||||
int i, mv, ol, off, p, plen, v;
|
||||
#if defined(_KERNEL)
|
||||
# if SOLARIS
|
||||
mb_t *m = fin->fin_qfm;
|
||||
# else
|
||||
mb_t *m = fin->fin_mp ? *fin->fin_mp : NULL;
|
||||
# endif
|
||||
#endif
|
||||
fr_ip_t *fi = &fin->fin_fi;
|
||||
struct optlist *op;
|
||||
u_char *s, opt;
|
||||
tcphdr_t *tcp;
|
||||
|
||||
fin->fin_rev = 0;
|
||||
fin->fin_dp = NULL;
|
||||
fin->fin_fr = NULL;
|
||||
fin->fin_tcpf = 0;
|
||||
fin->fin_data[0] = 0;
|
||||
@ -220,8 +232,10 @@ fr_info_t *fin;
|
||||
if (v == 4) {
|
||||
fin->fin_id = ip->ip_id;
|
||||
fi->fi_tos = ip->ip_tos;
|
||||
#if (OpenBSD >= 200311) && defined(_KERNEL)
|
||||
ip->ip_off = ntohs(ip->ip_off);
|
||||
#endif
|
||||
off = (ip->ip_off & IP_OFFMASK);
|
||||
tcp = (tcphdr_t *)((char *)ip + hlen);
|
||||
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
|
||||
fi->fi_src.i6[1] = 0;
|
||||
fi->fi_src.i6[2] = 0;
|
||||
@ -235,6 +249,9 @@ fr_info_t *fin;
|
||||
fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
|
||||
if (ip->ip_off & (IP_MF|IP_OFFMASK))
|
||||
fi->fi_fl |= FI_FRAG;
|
||||
#if (OpenBSD >= 200311) && defined(_KERNEL)
|
||||
ip->ip_len = ntohs(ip->ip_len);
|
||||
#endif
|
||||
plen = ip->ip_len;
|
||||
fin->fin_dlen = plen - hlen;
|
||||
}
|
||||
@ -246,7 +263,6 @@ fr_info_t *fin;
|
||||
p = ip6->ip6_nxt;
|
||||
fi->fi_p = p;
|
||||
fi->fi_ttl = ip6->ip6_hlim;
|
||||
tcp = (tcphdr_t *)(ip6 + 1);
|
||||
fi->fi_src.in6 = ip6->ip6_src;
|
||||
fi->fi_dst.in6 = ip6->ip6_dst;
|
||||
fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
|
||||
@ -258,14 +274,23 @@ fr_info_t *fin;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return;
|
||||
return -1;
|
||||
|
||||
fin->fin_off = off;
|
||||
fin->fin_plen = plen;
|
||||
fin->fin_dp = (char *)tcp;
|
||||
tcp = (tcphdr_t *)((char *)ip + hlen);
|
||||
fin->fin_misc = 0;
|
||||
off <<= 3;
|
||||
|
||||
/*
|
||||
* For both ICMPV6 & ICMP, we attempt to pullup the entire packet into
|
||||
* a single buffer for recognised error return packets. Why? Because
|
||||
* the entire data section of the ICMP payload is considered to be of
|
||||
* significance and maybe required in NAT/state processing, so rather
|
||||
* than be careful later, attempt to get it all in one buffeer first.
|
||||
* For TCP we just make sure the _entire_ TCP header is in the first
|
||||
* buffer for convienience.
|
||||
*/
|
||||
switch (p)
|
||||
{
|
||||
#ifdef USE_INET6
|
||||
@ -274,7 +299,7 @@ fr_info_t *fin;
|
||||
int minicmpsz = sizeof(struct icmp6_hdr);
|
||||
struct icmp6_hdr *icmp6;
|
||||
|
||||
if (fin->fin_dlen > 1) {
|
||||
if (!(fin->fin_fl & FI_SHORT) && (fin->fin_dlen > 1)) {
|
||||
fin->fin_data[0] = *(u_short *)tcp;
|
||||
|
||||
icmp6 = (struct icmp6_hdr *)tcp;
|
||||
@ -289,6 +314,14 @@ fr_info_t *fin;
|
||||
case ICMP6_PACKET_TOO_BIG :
|
||||
case ICMP6_TIME_EXCEEDED :
|
||||
case ICMP6_PARAM_PROB :
|
||||
# if defined(KERNEL) && !defined(__sgi)
|
||||
if ((m != NULL) && (M_BLEN(m) < plen)) {
|
||||
ip = ipf_pullup(m, fin, plen, ip);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
tcp = (tcphdr_t *)((char *)ip + hlen);
|
||||
}
|
||||
# endif /* KERNEL && !__sgi */
|
||||
minicmpsz = ICMP6ERR_IPICMPHLEN;
|
||||
break;
|
||||
default :
|
||||
@ -296,22 +329,27 @@ fr_info_t *fin;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(plen >= minicmpsz))
|
||||
if (!(fin->fin_dlen >= minicmpsz))
|
||||
fi->fi_fl |= FI_SHORT;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif /* USE_INET6 */
|
||||
|
||||
case IPPROTO_ICMP :
|
||||
{
|
||||
int minicmpsz = sizeof(struct icmp);
|
||||
icmphdr_t *icmp;
|
||||
|
||||
if (!off && (fin->fin_dlen > 1)) {
|
||||
if (!off && (fin->fin_dlen > 1) && !(fin->fin_fl & FI_SHORT)) {
|
||||
fin->fin_data[0] = *(u_short *)tcp;
|
||||
|
||||
icmp = (icmphdr_t *)tcp;
|
||||
|
||||
/*
|
||||
* Minimum ICMP packet is type(1) code(1) cksum(2)
|
||||
* plus 4 bytes following, totalling 8 bytes.
|
||||
*/
|
||||
switch (icmp->icmp_type)
|
||||
{
|
||||
case ICMP_ECHOREPLY :
|
||||
@ -327,7 +365,7 @@ fr_info_t *fin;
|
||||
*/
|
||||
case ICMP_TSTAMP :
|
||||
case ICMP_TSTAMPREPLY :
|
||||
minicmpsz = 20;
|
||||
minicmpsz = ICMP_MINLEN + 12;
|
||||
break;
|
||||
/*
|
||||
* type(1) + code(1) + cksum(2) + id(2) seq(2) +
|
||||
@ -335,9 +373,28 @@ fr_info_t *fin;
|
||||
*/
|
||||
case ICMP_MASKREQ :
|
||||
case ICMP_MASKREPLY :
|
||||
minicmpsz = 12;
|
||||
minicmpsz = ICMP_MINLEN + 4;
|
||||
break;
|
||||
/*
|
||||
* type(1) + code(1) + cksum(2) + arg(4) ip(20+)
|
||||
*/
|
||||
case ICMP_UNREACH :
|
||||
case ICMP_SOURCEQUENCH :
|
||||
case ICMP_REDIRECT :
|
||||
case ICMP_TIMXCEED :
|
||||
case ICMP_PARAMPROB :
|
||||
#if defined(KERNEL) && !defined(__sgi)
|
||||
if ((m != NULL) && (M_BLEN(m) < plen)) {
|
||||
ip = ipf_pullup(m, fin, plen, ip);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
tcp = (tcphdr_t *)((char *)ip + hlen);
|
||||
}
|
||||
#endif /* KERNEL && !__sgi */
|
||||
minicmpsz = ICMPERR_MINPKTLEN - sizeof(ip_t);
|
||||
break;
|
||||
default :
|
||||
minicmpsz = ICMP_MINLEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -345,9 +402,9 @@ fr_info_t *fin;
|
||||
if ((!(plen >= hlen + minicmpsz) && !off) ||
|
||||
(off && off < sizeof(struct icmp)))
|
||||
fi->fi_fl |= FI_SHORT;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IPPROTO_TCP :
|
||||
fi->fi_fl |= FI_TCPUDP;
|
||||
#ifdef USE_INET6
|
||||
@ -361,6 +418,20 @@ fr_info_t *fin;
|
||||
(off && off < sizeof(struct tcphdr)))
|
||||
fi->fi_fl |= FI_SHORT;
|
||||
}
|
||||
|
||||
#if defined(KERNEL) && !defined(__sgi)
|
||||
if (!off && !(fi->fi_fl & FI_SHORT)) {
|
||||
int tlen = hlen + (tcp->th_off << 2);
|
||||
|
||||
if ((m != NULL) && (M_BLEN(m) < tlen)) {
|
||||
ip = ipf_pullup(m, fin, tlen, ip);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
tcp = (tcphdr_t *)((char *)ip + hlen);
|
||||
}
|
||||
}
|
||||
#endif /* _KERNEL && !_sgi */
|
||||
|
||||
if (!(fi->fi_fl & FI_SHORT) && !off)
|
||||
fin->fin_tcpf = tcp->th_flags;
|
||||
goto getports;
|
||||
@ -400,12 +471,14 @@ getports:
|
||||
break;
|
||||
}
|
||||
|
||||
fin->fin_dp = (char *)tcp;
|
||||
|
||||
#ifdef USE_INET6
|
||||
if (v == 6) {
|
||||
fi->fi_optmsk = 0;
|
||||
fi->fi_secmsk = 0;
|
||||
fi->fi_auth = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -462,6 +535,7 @@ getports:
|
||||
fi->fi_optmsk = optmsk;
|
||||
fi->fi_secmsk = secmsk;
|
||||
fi->fi_auth = auth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -749,7 +823,7 @@ void *m;
|
||||
#endif /* IPFILTER_LOG */
|
||||
ATOMIC_INCL(fr->fr_hits);
|
||||
if (passt & FR_ACCOUNT)
|
||||
fr->fr_bytes += (U_QUAD_T)ip->ip_len;
|
||||
fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
|
||||
else
|
||||
fin->fin_icode = fr->fr_icode;
|
||||
fin->fin_rule = rulen;
|
||||
@ -812,12 +886,17 @@ int out;
|
||||
int p, len, drop = 0, logit = 0;
|
||||
mb_t *mc = NULL;
|
||||
# if !defined(__SVR4) && !defined(__svr4__)
|
||||
/*
|
||||
* We don't do this section for Solaris because fr_precheck() does a
|
||||
* pullupmsg() instead, effectively achieving the same result as here
|
||||
* so no need to duplicate it.
|
||||
*/
|
||||
# ifdef __sgi
|
||||
char hbuf[128];
|
||||
# endif
|
||||
int up;
|
||||
|
||||
# if !SOLARIS && !defined(NETBSD_PF) && \
|
||||
# if !defined(NETBSD_PF) && \
|
||||
((defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
|
||||
defined(__OpenBSD__) || defined(_BSDI_VERSION))
|
||||
if (fr_checkp != fr_check && fr_running > 0) {
|
||||
@ -855,7 +934,7 @@ int out;
|
||||
}
|
||||
# endif /* CSUM_DELAY_DATA */
|
||||
|
||||
# ifdef USE_INET6
|
||||
# ifdef USE_INET6
|
||||
if (v == 6) {
|
||||
len = ntohs(((ip6_t*)ip)->ip6_plen);
|
||||
if (!len)
|
||||
@ -863,17 +942,20 @@ int out;
|
||||
len += sizeof(ip6_t);
|
||||
p = ((ip6_t *)ip)->ip6_nxt;
|
||||
} else
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
p = ip->ip_p;
|
||||
len = ip->ip_len;
|
||||
}
|
||||
|
||||
fin->fin_mp = mp;
|
||||
fin->fin_out = out;
|
||||
|
||||
if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
|
||||
(v == 4 && p == IPPROTO_ICMP)
|
||||
# ifdef USE_INET6
|
||||
# ifdef USE_INET6
|
||||
|| (v == 6 && p == IPPROTO_ICMPV6)
|
||||
# endif
|
||||
# endif
|
||||
)) {
|
||||
int plen = 0;
|
||||
|
||||
@ -893,7 +975,7 @@ int out;
|
||||
case IPPROTO_ESP:
|
||||
plen = 8;
|
||||
break;
|
||||
# ifdef USE_INET6
|
||||
# ifdef USE_INET6
|
||||
case IPPROTO_ICMPV6 :
|
||||
/*
|
||||
* XXX does not take intermediate header
|
||||
@ -901,8 +983,10 @@ int out;
|
||||
*/
|
||||
plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
|
||||
break;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
if ((plen > 0) && (len < hlen + plen))
|
||||
fin->fin_fl |= FI_SHORT;
|
||||
up = MIN(hlen + plen, len);
|
||||
|
||||
if (up > m->m_len) {
|
||||
@ -917,14 +1001,34 @@ int out;
|
||||
ip = (ip_t *)hbuf;
|
||||
# else /* __ sgi */
|
||||
# ifndef linux
|
||||
if ((*mp = m_pullup(m, up)) == 0) {
|
||||
ATOMIC_INCL(frstats[out].fr_pull[1]);
|
||||
/*
|
||||
* Having determined that we need to pullup some data,
|
||||
* try to bring as much of the packet up into a single
|
||||
* buffer with the first pullup. This hopefully means
|
||||
* less need for doing futher pullups. Not needed for
|
||||
* Solaris because fr_precheck() does it anyway.
|
||||
*
|
||||
* The main potential for trouble here is if MLEN/MHLEN
|
||||
* become quite small, lets say < 64 bytes...but if
|
||||
* that did happen, BSD networking as a whole would be
|
||||
* slow/inefficient.
|
||||
*/
|
||||
# ifdef MHLEN
|
||||
/*
|
||||
* Assume that M_PKTHDR is set and just work with what
|
||||
* is left rather than check.. Should not make any
|
||||
* real difference, anyway.
|
||||
*/
|
||||
if ((MHLEN > up) && (len > up))
|
||||
up = MIN(len, MHLEN);
|
||||
# else
|
||||
if ((MLEN > up) && (len > up))
|
||||
up = MIN(len, MLEN);
|
||||
# endif
|
||||
ip = ipf_pullup(m, fin, up, ip);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
} else {
|
||||
ATOMIC_INCL(frstats[out].fr_pull[0]);
|
||||
m = *mp;
|
||||
ip = mtod(m, ip_t *);
|
||||
}
|
||||
m = *mp;
|
||||
# endif /* !linux */
|
||||
# endif /* __sgi */
|
||||
} else
|
||||
@ -937,9 +1041,14 @@ int out;
|
||||
|
||||
if ((u_int)ip & 0x3)
|
||||
return 2;
|
||||
fin->fin_mp = mp;
|
||||
fin->fin_out = out;
|
||||
fin->fin_qfm = m;
|
||||
fin->fin_qif = qif;
|
||||
# endif
|
||||
#else
|
||||
fin->fin_mp = mp;
|
||||
fin->fin_out = out;
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
@ -952,11 +1061,10 @@ int out;
|
||||
#endif
|
||||
|
||||
changed = 0;
|
||||
fin->fin_ifp = ifp;
|
||||
fin->fin_v = v;
|
||||
fin->fin_out = out;
|
||||
fin->fin_mp = mp;
|
||||
fr_makefrip(hlen, ip, fin);
|
||||
fin->fin_ifp = ifp;
|
||||
if (fr_makefrip(hlen, ip, fin) == -1)
|
||||
return -1;
|
||||
|
||||
#ifdef _KERNEL
|
||||
# ifdef USE_INET6
|
||||
@ -1120,6 +1228,10 @@ int out;
|
||||
if (pass & FR_KEEPSTATE) {
|
||||
if (fr_addstate(ip, fin, NULL, 0) == NULL) {
|
||||
ATOMIC_INCL(frstats[out].fr_bads);
|
||||
if (pass & FR_PASS) {
|
||||
pass &= ~FR_PASS;
|
||||
pass |= FR_BLOCK;
|
||||
}
|
||||
} else {
|
||||
ATOMIC_INCL(frstats[out].fr_ads);
|
||||
}
|
||||
@ -1306,6 +1418,12 @@ logit:
|
||||
(void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
|
||||
}
|
||||
# endif /* !SOLARIS */
|
||||
#if (OpenBSD >= 200311) && defined(_KERNEL)
|
||||
if (pass & FR_PASS) {
|
||||
ip->ip_len = htons(ip->ip_len);
|
||||
ip->ip_off = htons(ip->ip_off);
|
||||
}
|
||||
#endif
|
||||
return (pass & FR_PASS) ? 0 : error;
|
||||
#else /* _KERNEL */
|
||||
if (pass & FR_NOMATCH)
|
||||
@ -1403,10 +1521,10 @@ tcphdr_t *tcp;
|
||||
/*
|
||||
* Both sum and sum2 are partial sums, so combine them together.
|
||||
*/
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum = ~sum & 0xffff;
|
||||
sum2 += sum;
|
||||
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
|
||||
sum += ~sum2 & 0xffff;
|
||||
while (sum > 0xffff)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum2 = ~sum & 0xffff;
|
||||
# else /* defined(BSD) || defined(sun) */
|
||||
{
|
||||
union {
|
||||
@ -1543,7 +1661,7 @@ nodata:
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $
|
||||
* $Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $
|
||||
*/
|
||||
/*
|
||||
* Copy data from an mbuf chain starting "off" bytes from the beginning,
|
||||
@ -1975,12 +2093,40 @@ struct in_addr *inp;
|
||||
static void frsynclist(fr)
|
||||
register frentry_t *fr;
|
||||
{
|
||||
frdest_t *fdp;
|
||||
int i;
|
||||
|
||||
for (; fr; fr = fr->fr_next) {
|
||||
if (fr->fr_ifa != NULL) {
|
||||
fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_ip.fi_v);
|
||||
if (fr->fr_ifa == NULL)
|
||||
fr->fr_ifa = (void *)-1;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((fr->fr_ifnames[i][1] == '\0') &&
|
||||
((fr->fr_ifnames[i][0] == '-') ||
|
||||
(fr->fr_ifnames[i][0] == '*'))) {
|
||||
fr->fr_ifas[i] = NULL;
|
||||
} else if (*fr->fr_ifnames[i]) {
|
||||
fr->fr_ifas[i] = GETUNIT(fr->fr_ifnames[i],
|
||||
fr->fr_v);
|
||||
if (!fr->fr_ifas[i])
|
||||
fr->fr_ifas[i] = (void *)-1;
|
||||
}
|
||||
}
|
||||
|
||||
fdp = &fr->fr_dif;
|
||||
fr->fr_flags &= ~FR_DUP;
|
||||
if (*fdp->fd_ifname) {
|
||||
fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
|
||||
if (!fdp->fd_ifp)
|
||||
fdp->fd_ifp = (struct ifnet *)-1;
|
||||
else
|
||||
fr->fr_flags |= FR_DUP;
|
||||
}
|
||||
|
||||
fdp = &fr->fr_tif;
|
||||
if (*fdp->fd_ifname) {
|
||||
fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
|
||||
if (!fdp->fd_ifp)
|
||||
fdp->fd_ifp = (struct ifnet *)-1;
|
||||
}
|
||||
|
||||
if (fr->fr_grp)
|
||||
frsynclist(fr->fr_grp);
|
||||
}
|
||||
@ -2013,6 +2159,9 @@ void frsync()
|
||||
IFNET_RUNLOCK();
|
||||
# endif
|
||||
ip_natsync((struct ifnet *)-1);
|
||||
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
|
||||
IFNET_RUNLOCK();
|
||||
# endif
|
||||
# endif /* !SOLARIS */
|
||||
|
||||
WRITE_ENTER(&ipf_mutex);
|
||||
@ -2241,3 +2390,64 @@ mb_t *buf;
|
||||
return ip->ip_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_KERNEL) && !defined(__sgi)
|
||||
void *ipf_pullup(m, fin, len, ipin)
|
||||
mb_t *m;
|
||||
fr_info_t *fin;
|
||||
int len;
|
||||
void *ipin;
|
||||
{
|
||||
# if SOLARIS
|
||||
qif_t *qf = fin->fin_qif;
|
||||
# endif
|
||||
int out = fin->fin_out, dpoff, ipoff;
|
||||
char *ip;
|
||||
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
ipoff = (char *)ipin - MTOD(m, char *);
|
||||
if (fin->fin_dp != NULL)
|
||||
dpoff = (char *)fin->fin_dp - (char *)ipin;
|
||||
else
|
||||
dpoff = 0;
|
||||
|
||||
if (M_BLEN(m) < len) {
|
||||
# if SOLARIS
|
||||
qif_t *qf = fin->fin_qif;
|
||||
int inc = 0;
|
||||
|
||||
if (ipoff > 0) {
|
||||
if ((ipoff & 3) != 0) {
|
||||
inc = 4 - (ipoff & 3);
|
||||
if (m->b_rptr - inc >= m->b_datap->db_base)
|
||||
m->b_rptr -= inc;
|
||||
else
|
||||
inc = 0;
|
||||
}
|
||||
}
|
||||
if (!pullupmsg(m, len + ipoff + inc)) {
|
||||
ATOMIC_INCL(frstats[out].fr_pull[1]);
|
||||
return NULL;
|
||||
}
|
||||
m->b_rptr += inc;
|
||||
ATOMIC_INCL(frstats[out].fr_pull[0]);
|
||||
qf->qf_data = MTOD(m, char *) + ipoff;
|
||||
# else
|
||||
m = m_pullup(m, len);
|
||||
*fin->fin_mp = m;
|
||||
if (m == NULL) {
|
||||
ATOMIC_INCL(frstats[out].fr_pull[1]);
|
||||
return NULL;
|
||||
}
|
||||
ATOMIC_INCL(frstats[out].fr_pull[0]);
|
||||
# endif /* SOLARIS */
|
||||
}
|
||||
ip = MTOD(m, char *) + ipoff;
|
||||
if (fin->fin_dp != NULL)
|
||||
fin->fin_dp = (char *)ip + dpoff;
|
||||
return ip;
|
||||
}
|
||||
#endif /* _KERNEL */
|
||||
|
@ -320,7 +320,9 @@ int cmd;
|
||||
#endif
|
||||
{
|
||||
mb_t *m;
|
||||
#if defined(_KERNEL) && !SOLARIS
|
||||
#if defined(_KERNEL) && !SOLARIS && \
|
||||
(!defined(__FreeBSD_version) || (__FreeBSD_version < 501000))
|
||||
struct ifqueue *ifq;
|
||||
int s;
|
||||
#endif
|
||||
frauth_t auth, *au = &auth, *fra;
|
||||
@ -423,8 +425,8 @@ fr_authioctlloop:
|
||||
|
||||
bzero((char *)&ro, sizeof(ro));
|
||||
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
|
||||
defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
|
||||
(__FreeBSD_version >= 500042)
|
||||
defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
|
||||
(__FreeBSD_version >= 470102)
|
||||
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
|
||||
NULL);
|
||||
# else
|
||||
@ -442,8 +444,22 @@ fr_authioctlloop:
|
||||
# if SOLARIS
|
||||
error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
|
||||
# else /* SOLARIS */
|
||||
if (! netisr_queue(NETISR_IP, m))
|
||||
# if __FreeBSD_version >= 501104
|
||||
if (! netisr_dispatch(NETISR_IP, m))
|
||||
error = ENOBUFS;
|
||||
# else
|
||||
ifq = &ipintrq;
|
||||
if (IF_QFULL(ifq)) {
|
||||
IF_DROP(ifq);
|
||||
m_freem(m);
|
||||
error = ENOBUFS;
|
||||
} else {
|
||||
IF_ENQUEUE(ifq, m);
|
||||
# if IRIX < 605
|
||||
schednetisr(NETISR_IP);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
# endif /* SOLARIS */
|
||||
if (error)
|
||||
fr_authstats.fas_quefail++;
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
#if defined(__sgi) || defined(bsdi)
|
||||
struct ether_addr {
|
||||
u_char ether_addr_octet[6];
|
||||
u_char ether_addr_octet[6];
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -164,6 +164,7 @@ struct file;
|
||||
# define V4_PART_OF_V6(v6) v6.s6_addr32[3]
|
||||
# endif
|
||||
# endif
|
||||
# define M_BLEN(m) ((m)->b_wptr - (m)->b_rptr)
|
||||
|
||||
typedef struct qif {
|
||||
struct qif *qf_next;
|
||||
@ -173,6 +174,7 @@ typedef struct qif {
|
||||
void *qf_optr;
|
||||
queue_t *qf_in;
|
||||
queue_t *qf_out;
|
||||
void *qf_data; /* layer 3 header pointer */
|
||||
struct qinit *qf_wqinfo;
|
||||
struct qinit *qf_rqinfo;
|
||||
struct qinit qf_wqinit;
|
||||
@ -525,6 +527,7 @@ extern ill_t *get_unit __P((char *, int));
|
||||
# ifndef linux
|
||||
# define FREE_MB_T(m) m_freem(m)
|
||||
# define MTOD(m,t) mtod(m,t)
|
||||
# define M_BLEN(m) (m)->m_len
|
||||
# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
|
||||
# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
|
||||
# define IRCOPYPTR ircopyptr
|
||||
@ -963,7 +966,7 @@ typedef struct {
|
||||
__u32 th_seq;
|
||||
__u32 th_ack;
|
||||
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
|
||||
defined(vax)
|
||||
defined(__vax__)
|
||||
__u8 th_res:4;
|
||||
__u8 th_off:4;
|
||||
#else
|
||||
@ -985,7 +988,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
|
||||
defined(vax)
|
||||
defined(__vax__)
|
||||
__u8 ip_hl:4;
|
||||
__u8 ip_v:4;
|
||||
# else
|
||||
@ -1209,8 +1212,8 @@ struct ether_addr {
|
||||
#define ICMPERR_MINPKTLEN (20 + 8 + 20)
|
||||
#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
|
||||
#define ICMP6_MINLEN 8
|
||||
#define ICMP6ERR_MINPKTLEN (40 + 8)
|
||||
#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
|
||||
#define ICMP6ERR_IPICMPHLEN (40 + 8)
|
||||
#define ICMP6ERR_MINPKTLEN (40 + 8 + 40)
|
||||
|
||||
#ifndef ICMP6_DST_UNREACH
|
||||
# define ICMP6_DST_UNREACH 1
|
||||
|
@ -537,7 +537,7 @@ int ipldetach()
|
||||
# if (__NetBSD_Version__ >= 105150000) || (__FreeBSD_version >= 501108)
|
||||
struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
|
||||
# ifdef USE_INET6
|
||||
struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
|
||||
struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@ -1055,8 +1055,8 @@ caddr_t data;
|
||||
while ((f = *ftail))
|
||||
ftail = &f->fr_next;
|
||||
else {
|
||||
ftail = fprev;
|
||||
if (fp->fr_hits) {
|
||||
ftail = fprev;
|
||||
while (--fp->fr_hits && (f = *ftail))
|
||||
ftail = &f->fr_next;
|
||||
}
|
||||
@ -1310,7 +1310,7 @@ struct mbuf **mp;
|
||||
frn.fin_ifp = fin->fin_ifp;
|
||||
frn.fin_v = fin->fin_v;
|
||||
frn.fin_out = fin->fin_out;
|
||||
frn.fin_mp = fin->fin_mp;
|
||||
frn.fin_mp = mp;
|
||||
|
||||
ip = mtod(m, ip_t *);
|
||||
hlen = sizeof(*ip);
|
||||
@ -1354,9 +1354,10 @@ struct mbuf **mp;
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
# endif
|
||||
|
||||
fr_makefrip(hlen, ip, &frn);
|
||||
|
||||
error = ipfr_fastroute(m, mp, &frn, NULL);
|
||||
if (fr_makefrip(hlen, ip, &frn) == 0)
|
||||
error = ipfr_fastroute(m, mp, &frn, NULL);
|
||||
else
|
||||
error = EINVAL;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1489,7 +1490,13 @@ int dst;
|
||||
#endif
|
||||
|
||||
if (avail) {
|
||||
slen = oip->ip_len;
|
||||
oip->ip_len = htons(oip->ip_len);
|
||||
soff = oip->ip_off;
|
||||
oip->ip_off = htons(oip->ip_off);
|
||||
bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
|
||||
oip->ip_len = slen;
|
||||
oip->ip_off = soff;
|
||||
avail -= MIN(ohlen, avail);
|
||||
}
|
||||
|
||||
@ -1510,10 +1517,6 @@ int dst;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
slen = oip->ip_len;
|
||||
oip->ip_len = htons(oip->ip_len);
|
||||
soff = oip->ip_off;
|
||||
oip->ip_off = htons(ip->ip_off);
|
||||
|
||||
ip->ip_src.s_addr = dst4.s_addr;
|
||||
ip->ip_dst.s_addr = oip->ip_src.s_addr;
|
||||
@ -1533,13 +1536,7 @@ int dst;
|
||||
fin->fin_hlen = hlen;
|
||||
err = send_ip(oip, fin, &m);
|
||||
fin->fin_hlen = shlen;
|
||||
#ifdef USE_INET6
|
||||
if (fin->fin_v == 4)
|
||||
#endif
|
||||
{
|
||||
oip->ip_len = slen;
|
||||
oip->ip_off = soff;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1597,7 +1594,7 @@ frdest_t *fdp;
|
||||
register struct ip *ip, *mhip;
|
||||
register struct mbuf *m = m0;
|
||||
register struct route *ro;
|
||||
int len, off, error = 0, hlen, code;
|
||||
int len, off, error = 0, hlen, code, sout;
|
||||
struct ifnet *ifp, *sifp;
|
||||
struct sockaddr_in *dst;
|
||||
struct route iproute;
|
||||
@ -1663,7 +1660,7 @@ frdest_t *fdp;
|
||||
/*
|
||||
* Route packet.
|
||||
*/
|
||||
#if defined(__sgi) && (IRIX >= 605)
|
||||
#if (defined(IRIX) && (IRIX >= 605))
|
||||
ROUTE_RDLOCK();
|
||||
#endif
|
||||
bzero((caddr_t)ro, sizeof (*ro));
|
||||
@ -1682,8 +1679,12 @@ frdest_t *fdp;
|
||||
* check that we're going in the correct direction.
|
||||
*/
|
||||
if ((fr != NULL) && (fin->fin_rev != 0)) {
|
||||
if ((ifp != NULL) && (fdp == &fr->fr_tif))
|
||||
if ((ifp != NULL) && (fdp == &fr->fr_tif)) {
|
||||
# if (defined(IRIX) && (IRIX >= 605))
|
||||
ROUTE_UNLOCK();
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
} else if (fdp != NULL) {
|
||||
if (fdp->fd_ip.s_addr != 0)
|
||||
dst->sin_addr = fdp->fd_ip;
|
||||
@ -1703,13 +1704,12 @@ frdest_t *fdp;
|
||||
rtalloc(ro);
|
||||
# endif
|
||||
|
||||
#if defined(__sgi) && (IRIX > 602)
|
||||
ROUTE_UNLOCK();
|
||||
#endif
|
||||
|
||||
if (!ifp) {
|
||||
if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
|
||||
error = -2;
|
||||
# if (defined(IRIX) && (IRIX >= 605))
|
||||
ROUTE_UNLOCK();
|
||||
# endif
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@ -1722,11 +1722,14 @@ frdest_t *fdp;
|
||||
error = EHOSTUNREACH;
|
||||
else
|
||||
error = ENETUNREACH;
|
||||
# if (defined(IRIX) && (IRIX >= 605))
|
||||
ROUTE_UNLOCK();
|
||||
# endif
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
|
||||
#if BSD >= 199306
|
||||
#if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
|
||||
dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
|
||||
#else
|
||||
dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
|
||||
@ -1734,6 +1737,10 @@ frdest_t *fdp;
|
||||
}
|
||||
ro->ro_rt->rt_use++;
|
||||
|
||||
#if (defined(IRIX) && (IRIX > 602))
|
||||
ROUTE_UNLOCK();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For input packets which are being "fastrouted", they won't
|
||||
* go back through output filtering and miss their chance to get
|
||||
@ -1741,6 +1748,7 @@ frdest_t *fdp;
|
||||
*/
|
||||
if (fin->fin_out == 0) {
|
||||
sifp = fin->fin_ifp;
|
||||
sout = fin->fin_out;
|
||||
fin->fin_ifp = ifp;
|
||||
fin->fin_out = 1;
|
||||
if ((fin->fin_fr = ipacct[1][fr_active]) &&
|
||||
@ -1750,10 +1758,25 @@ frdest_t *fdp;
|
||||
fin->fin_fr = NULL;
|
||||
if (!fr || !(fr->fr_flags & FR_RETMASK))
|
||||
(void) fr_checkstate(ip, fin);
|
||||
(void) ip_natout(ip, fin);
|
||||
|
||||
switch (ip_natout(ip, fin))
|
||||
{
|
||||
case 0 :
|
||||
break;
|
||||
case 1 :
|
||||
ip->ip_sum = 0;
|
||||
break;
|
||||
case -1 :
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
|
||||
fin->fin_ifp = sifp;
|
||||
fin->fin_out = sout;
|
||||
} else
|
||||
ip->ip_sum = 0;
|
||||
|
||||
/*
|
||||
* If small enough for interface, can just send directly.
|
||||
*/
|
||||
@ -1783,8 +1806,14 @@ frdest_t *fdp;
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
# endif /* __NetBSD__ && M_CSUM_IPv4 */
|
||||
# if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
|
||||
# ifdef IRIX
|
||||
IFNET_UPPERLOCK(ifp);
|
||||
# endif
|
||||
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
|
||||
ro->ro_rt);
|
||||
# ifdef IRIX
|
||||
IFNET_UPPERUNLOCK(ifp);
|
||||
# endif
|
||||
# else
|
||||
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
|
||||
# endif
|
||||
@ -1930,7 +1959,7 @@ void *ifp;
|
||||
dst->sin_family = AF_INET;
|
||||
dst->sin_addr = ipa;
|
||||
# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
|
||||
!defined(__OpenBSD__)
|
||||
!defined(__OpenBSD__)
|
||||
# ifdef RTF_CLONING
|
||||
rtalloc_ign(&iproute, RTF_CLONING);
|
||||
# else
|
||||
@ -1982,17 +2011,18 @@ frdest_t *fdp;
|
||||
u_long mtu;
|
||||
int error;
|
||||
|
||||
ifp = NULL;
|
||||
ro = &ip6route;
|
||||
fr = fin->fin_fr;
|
||||
bzero((caddr_t)ro, sizeof(*ro));
|
||||
dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
|
||||
dst6->sin6_family = AF_INET6;
|
||||
dst6->sin6_len = sizeof(struct sockaddr_in6);
|
||||
dst6->sin6_addr = fin->fin_fi.fi_src.in6;
|
||||
dst6->sin6_addr = fin->fin_fi.fi_dst.in6;
|
||||
|
||||
if (fdp != NULL)
|
||||
ifp = fdp->fd_ifp;
|
||||
else
|
||||
ifp = fin->fin_ifp;
|
||||
|
||||
if ((fr != NULL) && (fin->fin_rev != 0)) {
|
||||
if ((ifp != NULL) && (fdp == &fr->fr_tif))
|
||||
@ -2001,9 +2031,14 @@ frdest_t *fdp;
|
||||
if (IP6_NOTZERO(&fdp->fd_ip6))
|
||||
dst6->sin6_addr = fdp->fd_ip6.in6;
|
||||
}
|
||||
if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
|
||||
if (ifp == NULL)
|
||||
return -2;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
/* KAME */
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr))
|
||||
dst6->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
|
||||
#endif
|
||||
rtalloc((struct route *)ro);
|
||||
|
||||
if ((ifp == NULL) && (ro->ro_rt != NULL))
|
||||
@ -2024,10 +2059,15 @@ frdest_t *fdp;
|
||||
error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu);
|
||||
if (error == 0) {
|
||||
#else
|
||||
#ifdef ND_IFINFO
|
||||
# ifdef IN6_LINKMTU
|
||||
mtu = IN6_LINKMTU(ifp);
|
||||
# else
|
||||
# ifdef ND_IFINFO
|
||||
mtu = ND_IFINFO(ifp)->linkmtu;
|
||||
#else
|
||||
# else
|
||||
mtu = nd_ifinfo[ifp->if_index].linkmtu;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
if (m0->m_pkthdr.len <= mtu)
|
||||
|
@ -152,7 +152,7 @@ typedef struct fr_info {
|
||||
u_short fin_dlen; /* length of data portion of packet */
|
||||
u_short fin_id; /* IP packet id field */
|
||||
u_int fin_misc;
|
||||
void *fin_mp; /* pointer to pointer to mbuf */
|
||||
mb_t **fin_mp; /* pointer to pointer to mbuf */
|
||||
#if SOLARIS
|
||||
void *fin_qfm; /* pointer to mblk where pkt starts */
|
||||
void *fin_qif;
|
||||
@ -630,7 +630,7 @@ extern void fr_forgetifp __P((void *));
|
||||
extern void fr_getstat __P((struct friostat *));
|
||||
extern int fr_ifpaddr __P((int, void *, struct in_addr *));
|
||||
extern int fr_lock __P((caddr_t, int *));
|
||||
extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
|
||||
extern int fr_makefrip __P((int, ip_t *, fr_info_t *));
|
||||
extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
|
||||
extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
|
||||
extern int fr_tcpudpchk __P((frtuc_t *, fr_info_t *));
|
||||
|
@ -195,7 +195,7 @@ ipfr_t *table[];
|
||||
|
||||
|
||||
/*
|
||||
* Instert the fragment into the fragment table, copy the struct used
|
||||
* Insert the fragment into the fragment table, copy the struct used
|
||||
* in the search using bcopy rather than reassign each field.
|
||||
* Set the ttl to the default.
|
||||
*/
|
||||
@ -423,7 +423,26 @@ fr_info_t *fin;
|
||||
/*
|
||||
* forget any references to this external object.
|
||||
*/
|
||||
void ipfr_forget(nat)
|
||||
void ipfr_forget(ptr)
|
||||
void *ptr;
|
||||
{
|
||||
ipfr_t *fr;
|
||||
int idx;
|
||||
|
||||
WRITE_ENTER(&ipf_frag);
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
|
||||
if (fr->ipfr_data == ptr)
|
||||
fr->ipfr_data = NULL;
|
||||
|
||||
RWLOCK_EXIT(&ipf_frag);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* forget any references to this external object.
|
||||
*/
|
||||
void ipfr_forgetnat(nat)
|
||||
void *nat;
|
||||
{
|
||||
ipfr_t *fr;
|
||||
@ -431,7 +450,7 @@ void *nat;
|
||||
|
||||
WRITE_ENTER(&ipf_natfrag);
|
||||
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
|
||||
for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
|
||||
for (fr = ipfr_nattab[idx]; fr; fr = fr->ipfr_next)
|
||||
if (fr->ipfr_data == nat)
|
||||
fr->ipfr_data = NULL;
|
||||
|
||||
|
@ -54,6 +54,7 @@ extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, struct nat *));
|
||||
extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
|
||||
extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
|
||||
extern void ipfr_forget __P((void *));
|
||||
extern void ipfr_forgetnat __P((void *));
|
||||
extern void ipfr_unload __P((void));
|
||||
extern void ipfr_fragexpire __P((void));
|
||||
|
||||
|
@ -121,7 +121,7 @@ int dlen;
|
||||
int inc, off;
|
||||
nat_t *ipn;
|
||||
mb_t *m;
|
||||
#if SOLARIS
|
||||
#if SOLARIS && defined(_KERNEL)
|
||||
mb_t *m1;
|
||||
#endif
|
||||
|
||||
@ -207,8 +207,13 @@ int dlen;
|
||||
a1 >>= 24;
|
||||
olen = s - f->ftps_rptr;
|
||||
/* DO NOT change this to snprintf! */
|
||||
#if defined(OpenBSD) && (200311 >= 200311)
|
||||
(void) snprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
|
||||
"PORT", a1, a2, a3, a4, a5, a6);
|
||||
#else
|
||||
(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
|
||||
"PORT", a1, a2, a3, a4, a5, a6);
|
||||
#endif
|
||||
|
||||
nlen = strlen(newbuf);
|
||||
inc = nlen - olen;
|
||||
@ -221,7 +226,7 @@ int dlen;
|
||||
}
|
||||
|
||||
#if !defined(_KERNEL)
|
||||
m = *((mb_t **)fin->fin_mp);
|
||||
m = *fin->fin_mp;
|
||||
bcopy(newbuf, (char *)m + off, nlen);
|
||||
#else
|
||||
# if SOLARIS
|
||||
@ -251,7 +256,7 @@ int dlen;
|
||||
}
|
||||
copyin_mblk(m, off, nlen, newbuf);
|
||||
# else
|
||||
m = *((mb_t **)fin->fin_mp);
|
||||
m = *fin->fin_mp;
|
||||
if (inc < 0)
|
||||
m_adj(m, inc);
|
||||
/* the mbuf chain will be extended if necessary by m_copyback() */
|
||||
@ -263,7 +268,7 @@ int dlen;
|
||||
# endif
|
||||
#endif
|
||||
if (inc != 0) {
|
||||
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
|
||||
#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
|
||||
register u_32_t sum1, sum2;
|
||||
|
||||
sum1 = ip->ip_len;
|
||||
@ -542,7 +547,7 @@ int dlen;
|
||||
return 0;
|
||||
|
||||
#if !defined(_KERNEL)
|
||||
m = *((mb_t **)fin->fin_mp);
|
||||
m = *fin->fin_mp;
|
||||
m_copyback(m, off, nlen, newbuf);
|
||||
#else
|
||||
# if SOLARIS
|
||||
@ -569,7 +574,7 @@ int dlen;
|
||||
}
|
||||
/*copyin_mblk(m, off, nlen, newbuf);*/
|
||||
# else /* SOLARIS */
|
||||
m = *((mb_t **)fin->fin_mp);
|
||||
m = *fin->fin_mp;
|
||||
if (inc < 0)
|
||||
m_adj(m, inc);
|
||||
/* the mbuf chain will be extended if necessary by m_copyback() */
|
||||
@ -577,7 +582,7 @@ int dlen;
|
||||
# endif /* SOLARIS */
|
||||
#endif /* _KERNEL */
|
||||
if (inc != 0) {
|
||||
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
|
||||
#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
|
||||
register u_32_t sum1, sum2;
|
||||
|
||||
sum1 = ip->ip_len;
|
||||
@ -714,7 +719,8 @@ size_t len;
|
||||
|
||||
if (i < 5) {
|
||||
#if !defined(_KERNEL) && !defined(KERNEL)
|
||||
fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
|
||||
fprintf(stdout, "ippr_ftp_client_valid:i(%lu) < 5\n",
|
||||
(u_long)i);
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
@ -750,8 +756,8 @@ size_t len;
|
||||
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);
|
||||
"ippr_ftp_client_valid:bad cmd:len %lu i %lu c 0x%x\n",
|
||||
(u_long)i, (u_long)len, c);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@ -812,8 +818,8 @@ size_t len;
|
||||
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);
|
||||
"ippr_ftp_server_valid:bad cmd:len %lu i %lu c 0x%x\n",
|
||||
(u_long)i, (u_long)len, c);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@ -875,7 +881,7 @@ int rv;
|
||||
#if SOLARIS && defined(_KERNEL)
|
||||
m = fin->fin_qfm;
|
||||
#else
|
||||
m = *((mb_t **)fin->fin_mp);
|
||||
m = *fin->fin_mp;
|
||||
#endif
|
||||
|
||||
#ifndef _KERNEL
|
||||
@ -1025,9 +1031,9 @@ int rv;
|
||||
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]);
|
||||
printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
|
||||
printf("ackmin %x ackoff %d\n", (u_int)aps->aps_ackmin[sel],
|
||||
aps->aps_ackoff[sel]);
|
||||
printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
|
||||
printf("seqmin %x seqoff %d\n", (u_int)aps->aps_seqmin[sel],
|
||||
aps->aps_seqoff[sel]);
|
||||
#endif
|
||||
|
||||
|
@ -247,17 +247,17 @@ mb_t *m;
|
||||
*/
|
||||
bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
|
||||
# if SOLARIS && defined(_KERNEL)
|
||||
ipfl.fl_unit = (u_char)ifp->ill_ppa;
|
||||
ipfl.fl_unit = (u_int)ifp->ill_ppa;
|
||||
bcopy(ifp->ill_name, ipfl.fl_ifname,
|
||||
MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
|
||||
mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
|
||||
# else
|
||||
# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
|
||||
(defined(OpenBSD) && (OpenBSD >= 199603)) || \
|
||||
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
|
||||
(defined(OpenBSD) && (OpenBSD >= 199603)) || \
|
||||
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
|
||||
strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
|
||||
# else
|
||||
ipfl.fl_unit = (u_char)ifp->if_unit;
|
||||
ipfl.fl_unit = (u_int)ifp->if_unit;
|
||||
strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
|
||||
sizeof(ifp->if_name)));
|
||||
# endif
|
||||
@ -319,7 +319,7 @@ int *types, cnt;
|
||||
* rather than create a new one.
|
||||
*/
|
||||
MUTEX_ENTER(&ipl_mutex);
|
||||
if (fin != NULL) {
|
||||
if ((fin != NULL) && (fin->fin_off == 0)) {
|
||||
if ((ipll[dev] != NULL) &&
|
||||
bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
|
||||
ipll[dev]->ipl_count++;
|
||||
@ -435,7 +435,7 @@ struct uio *uio;
|
||||
SPL_NET(s);
|
||||
MUTEX_ENTER(&ipl_mutex);
|
||||
|
||||
while (!iplused[unit] || !iplt[unit]) {
|
||||
while (iplt[unit] == NULL) {
|
||||
# if SOLARIS && defined(_KERNEL)
|
||||
if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
|
||||
MUTEX_EXIT(&ipl_mutex);
|
||||
|
@ -117,6 +117,7 @@ static const char rcsid[] = "@(#)$FreeBSD$";
|
||||
nat_t **nat_table[2] = { NULL, NULL },
|
||||
*nat_instances = NULL;
|
||||
ipnat_t *nat_list = NULL;
|
||||
u_int ipf_nattable_max = NAT_TABLE_MAX;
|
||||
u_int ipf_nattable_sz = NAT_TABLE_SZ;
|
||||
u_int ipf_natrules_sz = NAT_SIZE;
|
||||
u_int ipf_rdrrules_sz = RDR_SIZE;
|
||||
@ -780,6 +781,8 @@ caddr_t data;
|
||||
if ((aps != NULL) && (aps->aps_data != 0)) {
|
||||
ng.ng_sz += sizeof(ap_session_t);
|
||||
ng.ng_sz += aps->aps_psiz;
|
||||
if (aps->aps_psiz > 4) /* XXX - sizeof(ipn_data) */
|
||||
ng.ng_sz -= 4;
|
||||
}
|
||||
|
||||
error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
|
||||
@ -795,6 +798,7 @@ caddr_t data;
|
||||
nat_save_t ipn, *ipnp, *ipnn = NULL;
|
||||
register nat_t *n, *nat;
|
||||
ap_session_t *aps;
|
||||
size_t dsz;
|
||||
int error;
|
||||
|
||||
error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
|
||||
@ -826,7 +830,6 @@ caddr_t data;
|
||||
}
|
||||
|
||||
ipn.ipn_next = nat->nat_next;
|
||||
ipn.ipn_dsize = 0;
|
||||
bcopy((char *)nat, (char *)&ipn.ipn_nat, sizeof(ipn.ipn_nat));
|
||||
ipn.ipn_nat.nat_data = NULL;
|
||||
|
||||
@ -840,10 +843,13 @@ caddr_t data;
|
||||
sizeof(ipn.ipn_rule));
|
||||
|
||||
if ((aps = nat->nat_aps)) {
|
||||
ipn.ipn_dsize = sizeof(*aps);
|
||||
dsz = sizeof(*aps);
|
||||
if (aps->aps_data)
|
||||
ipn.ipn_dsize += aps->aps_psiz;
|
||||
KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
|
||||
dsz += aps->aps_psiz;
|
||||
ipn.ipn_dsize = dsz;
|
||||
if (dsz > sizeof(ipn.ipn_data))
|
||||
dsz -= sizeof(ipn.ipn_data);
|
||||
KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + dsz);
|
||||
if (ipnn == NULL)
|
||||
return ENOMEM;
|
||||
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
|
||||
@ -852,14 +858,14 @@ caddr_t data;
|
||||
if (aps->aps_data) {
|
||||
bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
|
||||
aps->aps_psiz);
|
||||
ipnn->ipn_dsize += aps->aps_psiz;
|
||||
}
|
||||
error = IWCOPY((caddr_t)ipnn, ipnp,
|
||||
sizeof(ipn) + ipn.ipn_dsize);
|
||||
sizeof(ipn) + dsz);
|
||||
if (error)
|
||||
error = EFAULT;
|
||||
KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
|
||||
KFREES(ipnn, sizeof(*ipnn) + dsz);
|
||||
} else {
|
||||
ipn.ipn_dsize = 0;
|
||||
error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
|
||||
if (error)
|
||||
error = EFAULT;
|
||||
@ -887,12 +893,12 @@ caddr_t data;
|
||||
return EFAULT;
|
||||
nat = NULL;
|
||||
if (ipn.ipn_dsize) {
|
||||
KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
|
||||
KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
|
||||
if (ipnn == NULL)
|
||||
return ENOMEM;
|
||||
bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
|
||||
error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
|
||||
ipn.ipn_dsize);
|
||||
error = IRCOPY((caddr_t)ipnp + offsetof(nat_save_t, ipn_data),
|
||||
(caddr_t)ipnn->ipn_data, ipn.ipn_dsize);
|
||||
if (error) {
|
||||
error = EFAULT;
|
||||
goto junkput;
|
||||
@ -1067,7 +1073,7 @@ struct nat *natd;
|
||||
* If there's a fragment table entry too for this nat entry, then
|
||||
* dereference that as well.
|
||||
*/
|
||||
ipfr_forget((void *)natd);
|
||||
ipfr_forgetnat((void *)natd);
|
||||
aps_free(natd->nat_aps);
|
||||
nat_stats.ns_inuse--;
|
||||
KFREE(natd);
|
||||
@ -1165,6 +1171,11 @@ int direction;
|
||||
qif_t *qf = fin->fin_qif;
|
||||
#endif
|
||||
|
||||
if (nat_stats.ns_inuse >= ipf_nattable_max) {
|
||||
nat_stats.ns_memfail++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nflags = flags & np->in_flags;
|
||||
if (flags & IPN_TCPUDP) {
|
||||
tcp = (tcphdr_t *)fin->fin_dp;
|
||||
@ -1176,6 +1187,17 @@ int direction;
|
||||
KMALLOC(nat, nat_t *);
|
||||
if (nat == NULL) {
|
||||
nat_stats.ns_memfail++;
|
||||
/*
|
||||
* Try to automatically tune the max # of entries in the
|
||||
* table allowed to be less than what will cause kmem_alloc()
|
||||
* to fail and try to eliminate panics due to out of memory
|
||||
* conditions arising.
|
||||
*/
|
||||
if (ipf_nattable_max > ipf_nattable_sz) {
|
||||
ipf_nattable_max = nat_stats.ns_inuse - 100;
|
||||
printf("ipf_nattable_max reduced to %d\n",
|
||||
ipf_nattable_max);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1432,7 +1454,7 @@ int direction;
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
|
||||
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
|
||||
if ((flags & IPN_TCPUDP) && dohwcksum &&
|
||||
if ((flags & IPN_TCP) && dohwcksum &&
|
||||
(qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
|
||||
if (direction == NAT_OUTBOUND)
|
||||
sum1 = LONG_SUM(ntohl(in.s_addr));
|
||||
@ -1684,6 +1706,7 @@ int dir;
|
||||
return NULL;
|
||||
|
||||
flags = 0;
|
||||
sumd2 = 0;
|
||||
*nflags = IPN_ICMPERR;
|
||||
icmp = (icmphdr_t *)fin->fin_dp;
|
||||
oip = (ip_t *)&icmp->icmp_ip;
|
||||
@ -1737,137 +1760,75 @@ int dir;
|
||||
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
|
||||
if (nat->nat_dir == NAT_OUTBOUND) {
|
||||
/*
|
||||
* Fix IP checksum of the offending IP packet to adjust for
|
||||
* the change in the IP address.
|
||||
*
|
||||
* Normally, you would expect that the ICMP checksum of the
|
||||
* ICMP error message needs to be adjusted as well for the
|
||||
* IP address change in oip.
|
||||
* However, this is a NOP, because the ICMP checksum is
|
||||
* calculated over the complete ICMP packet, which includes the
|
||||
* changed oip IP addresses and oip->ip_sum. However, these
|
||||
* two changes cancel each other out (if the delta for
|
||||
* the IP address is x, then the delta for ip_sum is minus x),
|
||||
* so no change in the icmp_cksum is necessary.
|
||||
*
|
||||
* Be careful that nat_dir refers to the direction of the
|
||||
* offending IP packet (oip), not to its ICMP response (icmp)
|
||||
*/
|
||||
fix_datacksum(&oip->ip_sum, sumd);
|
||||
/* Fix icmp cksum : IP Addr + Cksum */
|
||||
|
||||
/*
|
||||
* Fix UDP pseudo header checksum to compensate for the
|
||||
* IP address change.
|
||||
*/
|
||||
if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && udp->uh_sum) {
|
||||
/*
|
||||
* Fix IP checksum of the offending IP packet to adjust for
|
||||
* the change in the IP address.
|
||||
*
|
||||
* Normally, you would expect that the ICMP checksum of the
|
||||
* ICMP error message needs to be adjusted as well for the
|
||||
* IP address change in oip.
|
||||
* However, this is a NOP, because the ICMP checksum is
|
||||
* calculated over the complete ICMP packet, which includes the
|
||||
* changed oip IP addresses and oip->ip_sum. However, these
|
||||
* two changes cancel each other out (if the delta for
|
||||
* the IP address is x, then the delta for ip_sum is minus x),
|
||||
* so no change in the icmp_cksum is necessary.
|
||||
*
|
||||
* Be careful that nat_dir refers to the direction of the
|
||||
* offending IP packet (oip), not to its ICMP response (icmp)
|
||||
* The UDP checksum is optional, only adjust it
|
||||
* if it has been set.
|
||||
*/
|
||||
fix_datacksum(&oip->ip_sum, sumd);
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix UDP pseudo header checksum to compensate for the
|
||||
* IP address change.
|
||||
* Fix ICMP checksum to compensate the UDP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
|
||||
/*
|
||||
* The UDP checksum is optional, only adjust it
|
||||
* if it has been set.
|
||||
*/
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the UDP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix TCP pseudo header checksum to compensate for the
|
||||
* IP address change. Before we can do the change, we
|
||||
* must make sure that oip is sufficient large to hold
|
||||
* the TCP checksum (normally it does not!).
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the TCP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Fix IP checksum of the offending IP packet to adjust for
|
||||
* the change in the IP address.
|
||||
*
|
||||
* Normally, you would expect that the ICMP checksum of the
|
||||
* ICMP error message needs to be adjusted as well for the
|
||||
* IP address change in oip.
|
||||
* However, this is a NOP, because the ICMP checksum is
|
||||
* calculated over the complete ICMP packet, which includes the
|
||||
* changed oip IP addresses and oip->ip_sum. However, these
|
||||
* two changes cancel each other out (if the delta for
|
||||
* the IP address is x, then the delta for ip_sum is minus x),
|
||||
* so no change in the icmp_cksum is necessary.
|
||||
*
|
||||
* Be careful that nat_dir refers to the direction of the
|
||||
* offending IP packet (oip), not to its ICMP response (icmp)
|
||||
*/
|
||||
fix_datacksum(&oip->ip_sum, sumd);
|
||||
|
||||
/* XXX FV : without having looked at Solaris source code, it seems unlikely
|
||||
* that SOLARIS would compensate this in the kernel (a body of an IP packet
|
||||
* in the data section of an ICMP packet). I have the feeling that this should
|
||||
* be unconditional, but I'm not in a position to check.
|
||||
*/
|
||||
#if !SOLARIS && !defined(__sgi)
|
||||
/*
|
||||
* Fix UDP pseudo header checksum to compensate for the
|
||||
* IP address change.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
|
||||
/*
|
||||
* The UDP checksum is optional, only adjust it
|
||||
* if it has been set
|
||||
*/
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the UDP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix TCP pseudo header checksum to compensate for the
|
||||
* IP address change. Before we can do the change, we
|
||||
* must make sure that oip is sufficient large to hold
|
||||
* the TCP checksum (normally it does not!).
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the TCP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 = sumd;
|
||||
}
|
||||
#endif
|
||||
sumd2 = sumd << 1;
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
}
|
||||
|
||||
if ((flags & IPN_TCPUDP) != 0) {
|
||||
/*
|
||||
* Fix TCP pseudo header checksum to compensate for the
|
||||
* IP address change. Before we can do the change, we
|
||||
* must make sure that oip is sufficient large to hold
|
||||
* the TCP checksum (normally it does not!).
|
||||
*/
|
||||
else if ((oip->ip_p == IPPROTO_TCP) && (dlen >= 18)) {
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate the TCP
|
||||
* checksum adjustment.
|
||||
*/
|
||||
sumd2 = sumd << 1;
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
} else {
|
||||
sumd2 = (sumd >> 16);
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
sumd2 = ~sumd2;
|
||||
else
|
||||
sumd2 = ~sumd2 + 1;
|
||||
}
|
||||
|
||||
if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) {
|
||||
/*
|
||||
* Step 2 :
|
||||
* For offending TCP/UDP IP packets, translate the ports as
|
||||
@ -1887,17 +1848,14 @@ int dir;
|
||||
* include the TCP checksum. So we have to check if the
|
||||
* ip->ip_len actually holds the TCP checksum of the oip!
|
||||
*/
|
||||
|
||||
if (nat->nat_oport == tcp->th_dport) {
|
||||
if (tcp->th_sport != nat->nat_inport) {
|
||||
/*
|
||||
* Fix ICMP checksum to compensate port
|
||||
* adjustment.
|
||||
*/
|
||||
sum1 = ntohs(tcp->th_sport);
|
||||
sum2 = ntohs(nat->nat_inport);
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
sum1 = ntohs(nat->nat_inport);
|
||||
sum2 = ntohs(tcp->th_sport);
|
||||
tcp->th_sport = nat->nat_inport;
|
||||
|
||||
/*
|
||||
@ -1909,16 +1867,18 @@ int dir;
|
||||
* The UDP checksum is optional, only adjust
|
||||
* it if it has been set.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
|
||||
if ((oip->ip_p == IPPROTO_UDP) &&
|
||||
(dlen >= 8) && udp->uh_sum) {
|
||||
sumd = sum1 - sum2;
|
||||
sumd2 += sumd;
|
||||
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to
|
||||
* compensate UDP checksum
|
||||
* adjustment.
|
||||
* Fix ICMP checksum to compensate
|
||||
* UDP checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
@ -1930,63 +1890,73 @@ int dir;
|
||||
* packet flows the other direction compared to
|
||||
* the ICMP message.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
if (oip->ip_p == IPPROTO_TCP) {
|
||||
if (dlen >= 18) {
|
||||
sumd = sum1 - sum2;
|
||||
sumd2 += sumd;
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum,
|
||||
sumd);
|
||||
sum2 = ntohs(tcp->th_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to
|
||||
* compensate TCP checksum
|
||||
* adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
/*
|
||||
* Fix ICMP checksum to
|
||||
* compensate TCP checksum
|
||||
* adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
} else {
|
||||
sumd = sum2 - sum1 + 1;
|
||||
sumd2 += sumd;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tcp->th_dport != nat->nat_outport) {
|
||||
/*
|
||||
* Fix ICMP checksum to compensate port
|
||||
* adjustment.
|
||||
*/
|
||||
sum1 = ntohs(tcp->th_dport);
|
||||
sum2 = ntohs(nat->nat_outport);
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
} else if (tcp->th_dport != nat->nat_outport) {
|
||||
/*
|
||||
* Fix ICMP checksum to compensate port
|
||||
* adjustment.
|
||||
*/
|
||||
sum1 = ntohs(nat->nat_outport);
|
||||
sum2 = ntohs(tcp->th_dport);
|
||||
tcp->th_dport = nat->nat_outport;
|
||||
|
||||
/*
|
||||
* Fix udp checksum to compensate port
|
||||
* adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared
|
||||
* to the ICMP message.
|
||||
*
|
||||
* The UDP checksum is optional, only adjust
|
||||
* it if it has been set.
|
||||
*/
|
||||
if ((oip->ip_p == IPPROTO_UDP) &&
|
||||
(dlen >= 8) && udp->uh_sum) {
|
||||
sumd = sum1 - sum2;
|
||||
sumd2 += sumd;
|
||||
tcp->th_dport = nat->nat_outport;
|
||||
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix udp checksum to compensate port
|
||||
* adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared
|
||||
* to the ICMP message.
|
||||
*
|
||||
* The UDP checksum is optional, only adjust
|
||||
* it if it has been set.
|
||||
* Fix ICMP checksum to compensate
|
||||
* UDP checksum adjustment.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
}
|
||||
|
||||
sum1 = ntohs(udp->uh_sum);
|
||||
fix_datacksum(&udp->uh_sum, sumd);
|
||||
sum2 = ntohs(udp->uh_sum);
|
||||
|
||||
/*
|
||||
* Fix ICMP checksum to compensate
|
||||
* UDP checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
/*
|
||||
* Fix tcp checksum (if present) to compensate
|
||||
* port adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared to
|
||||
* the ICMP message.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP) {
|
||||
if (dlen >= 18) {
|
||||
sumd = sum1 - sum2;
|
||||
sumd2 += sumd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix tcp checksum (if present) to compensate
|
||||
* port adjustment. NOTE : the offending IP
|
||||
* packet flows the other direction compared to
|
||||
* the ICMP message.
|
||||
*/
|
||||
if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
|
||||
|
||||
sum1 = ntohs(tcp->th_sum);
|
||||
fix_datacksum(&tcp->th_sum, sumd);
|
||||
@ -1997,18 +1967,18 @@ int dir;
|
||||
* UDP checksum adjustment.
|
||||
*/
|
||||
CALC_SUMD(sum1, sum2, sumd);
|
||||
sumd2 += sumd;
|
||||
} else {
|
||||
sumd = sum2 - sum1;
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
sumd++;
|
||||
}
|
||||
}
|
||||
sumd2 += sumd;
|
||||
}
|
||||
if (sumd2) {
|
||||
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
|
||||
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
|
||||
if (nat->nat_dir == NAT_OUTBOUND) {
|
||||
fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
|
||||
} else {
|
||||
fix_incksum(fin, &icmp->icmp_cksum, sumd2);
|
||||
}
|
||||
fix_incksum(fin, &icmp->icmp_cksum, sumd2);
|
||||
}
|
||||
}
|
||||
if (oip->ip_p == IPPROTO_ICMP)
|
||||
@ -2478,13 +2448,9 @@ maskloop:
|
||||
s1 = LONG_SUM(ntohl(fin->fin_saddr));
|
||||
s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
|
||||
CALC_SUMD(s1, s2, sumd);
|
||||
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_outcksum(fin, &ip->ip_sum, sumd);
|
||||
else
|
||||
fix_incksum(fin, &ip->ip_sum, sumd);
|
||||
fix_outcksum(fin, &ip->ip_sum, sumd);
|
||||
}
|
||||
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
|
||||
#if (SOLARIS || defined(__sgi)) || !defined(_KERNEL)
|
||||
else {
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
|
||||
@ -2512,7 +2478,8 @@ maskloop:
|
||||
if (nat->nat_age < fr_defnaticmpage)
|
||||
nat->nat_age = fr_defnaticmpage;
|
||||
#ifdef LARGE_NAT
|
||||
else if (nat->nat_age > fr_defnatage)
|
||||
else if ((!np || !np->in_age[1]) &&
|
||||
(nat->nat_age > fr_defnatage))
|
||||
nat->nat_age = fr_defnatage;
|
||||
#endif
|
||||
/*
|
||||
@ -2705,19 +2672,19 @@ maskloop:
|
||||
nat->nat_bytes += ip->ip_len;
|
||||
nat->nat_pkts++;
|
||||
MUTEX_EXIT(&nat->nat_lock);
|
||||
ip->ip_dst = nat->nat_inip;
|
||||
fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
|
||||
|
||||
/*
|
||||
* Fix up checksums, not by recalculating them, but
|
||||
* simply computing adjustments.
|
||||
*/
|
||||
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
|
||||
if (nat->nat_dir == NAT_OUTBOUND)
|
||||
fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
|
||||
else
|
||||
fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
|
||||
#endif
|
||||
|
||||
ip->ip_dst = nat->nat_inip;
|
||||
fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
|
||||
|
||||
if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
|
||||
|
||||
if ((nat->nat_inport != 0) && (tcp != NULL)) {
|
||||
@ -2733,7 +2700,8 @@ maskloop:
|
||||
if (nat->nat_age < fr_defnaticmpage)
|
||||
nat->nat_age = fr_defnaticmpage;
|
||||
#ifdef LARGE_NAT
|
||||
else if (nat->nat_age > fr_defnatage)
|
||||
else if ((!np || !np->in_age[0]) &&
|
||||
(nat->nat_age > fr_defnatage))
|
||||
nat->nat_age = fr_defnatage;
|
||||
#endif
|
||||
/*
|
||||
@ -2985,7 +2953,7 @@ u_short *csump;
|
||||
if (&cp[1] >= ep)
|
||||
break;
|
||||
advance = cp[1];
|
||||
if (&cp[advance] >= ep)
|
||||
if (&cp[advance] > ep)
|
||||
break;
|
||||
switch (opt) {
|
||||
case TCPOPT_MAXSEG:
|
||||
|
@ -35,26 +35,39 @@
|
||||
* a setup with 1000-2000 networks to NAT.
|
||||
*/
|
||||
#ifndef NAT_SIZE
|
||||
# define NAT_SIZE 127
|
||||
# ifdef LARGE_NAT
|
||||
# define NAT_SIZE 2047
|
||||
# else
|
||||
# define NAT_SIZE 127
|
||||
# endif
|
||||
#endif
|
||||
#ifndef RDR_SIZE
|
||||
# define RDR_SIZE 127
|
||||
# ifdef LARGE_NAT
|
||||
# define RDR_SIZE 2047
|
||||
# else
|
||||
# define RDR_SIZE 127
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HOSTMAP_SIZE
|
||||
# define HOSTMAP_SIZE 127
|
||||
# ifdef LARGE_NAT
|
||||
# define HOSTMAP_SIZE 8191
|
||||
# else
|
||||
# define HOSTMAP_SIZE 2047
|
||||
# endif
|
||||
#endif
|
||||
#ifndef NAT_TABLE_MAX
|
||||
# ifdef LARGE_NAT
|
||||
# define NAT_TABLE_MAX 180000
|
||||
# else
|
||||
# define NAT_TABLE_MAX 30000
|
||||
# endif
|
||||
#endif
|
||||
#ifndef NAT_TABLE_SZ
|
||||
# define NAT_TABLE_SZ 127
|
||||
#endif
|
||||
#ifdef LARGE_NAT
|
||||
#undef NAT_SIZE
|
||||
#undef RDR_SIZE
|
||||
#undef NAT_TABLE_SZ
|
||||
#undef HOSTMAP_SIZE 127
|
||||
#define NAT_SIZE 2047
|
||||
#define RDR_SIZE 2047
|
||||
#define NAT_TABLE_SZ 16383
|
||||
#define HOSTMAP_SIZE 8191
|
||||
# ifdef LARGE_NAT
|
||||
# define NAT_TABLE_SZ 16383
|
||||
# else
|
||||
# define NAT_TABLE_SZ 2047
|
||||
# endif
|
||||
#endif
|
||||
#ifndef APR_LABELLEN
|
||||
#define APR_LABELLEN 16
|
||||
|
@ -66,9 +66,6 @@ nat_t *nat;
|
||||
tcphdr_t *tcp;
|
||||
int len = 0;
|
||||
mb_t *m;
|
||||
#if SOLARIS
|
||||
mb_t *m1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we've already processed the start messages, then nothing left
|
||||
@ -181,9 +178,6 @@ nat_t *nat;
|
||||
nat_t *ipn;
|
||||
u_char swp;
|
||||
mb_t *m;
|
||||
#if SOLARIS
|
||||
mb_t *m1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait until we've seen the end of the start messages and even then
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ip_rcmd_pxy.c,v 1.4.2.6 2002/10/01 15:24:59 darrenr Exp $
|
||||
* $Id: ip_rcmd_pxy.c,v 1.4.2.7 2003/04/26 05:59:39 darrenr Exp $
|
||||
*/
|
||||
/*
|
||||
* Simple RCMD transparent proxy for in-kernel use. For use with the NAT
|
||||
@ -89,9 +89,6 @@ nat_t *nat;
|
||||
u_short sp;
|
||||
nat_t *ipn;
|
||||
mb_t *m;
|
||||
#if SOLARIS
|
||||
mb_t *m1;
|
||||
#endif
|
||||
|
||||
tcp = (tcphdr_t *)fin->fin_dp;
|
||||
|
||||
|
@ -923,7 +923,8 @@ tcphdr_t *tcp;
|
||||
fdata->td_wscale = wscale;
|
||||
else if (wscale == -2)
|
||||
fdata->td_wscale = tdata->td_wscale = 0;
|
||||
win <<= fdata->td_wscale;
|
||||
if (!(tcp->th_flags & TH_SYN))
|
||||
win <<= fdata->td_wscale;
|
||||
|
||||
if ((fdata->td_end == 0) &&
|
||||
(!is->is_fsm || ((tcp->th_flags & TH_OPENING) == TH_OPENING))) {
|
||||
@ -957,14 +958,15 @@ tcphdr_t *tcp;
|
||||
(SEQ_GE(seq, fdata->td_end - maxwin)) &&
|
||||
/* XXX what about big packets */
|
||||
#define MAXACKWINDOW 66000
|
||||
(ackskew >= -MAXACKWINDOW) &&
|
||||
(ackskew <= MAXACKWINDOW)) {
|
||||
/* if ackskew < 0 then this should be due to fragented
|
||||
(-ackskew <= (MAXACKWINDOW << tdata->td_wscale)) &&
|
||||
( ackskew <= (MAXACKWINDOW << tdata->td_wscale))) {
|
||||
|
||||
/* if ackskew < 0 then this should be due to fragmented
|
||||
* packets. There is no way to know the length of the
|
||||
* total packet in advance.
|
||||
* We do know the total length from the fragment cache though.
|
||||
* Note however that there might be more sessions with
|
||||
* exactly the same source and destination paramters in the
|
||||
* exactly the same source and destination parameters in the
|
||||
* state cache (and source and destination is the only stuff
|
||||
* that is saved in the fragment cache). Note further that
|
||||
* some TCP connections in the state cache are hashed with
|
||||
@ -1211,6 +1213,10 @@ fr_info_t *fin;
|
||||
|
||||
oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
|
||||
ohlen = oip->ip_hl << 2;
|
||||
/*
|
||||
* Check if the at least the old IP header (with options) and
|
||||
* 8 bytes of payload is present.
|
||||
*/
|
||||
if (fin->fin_plen < ICMPERR_MAXPKTLEN + ohlen - sizeof(*oip))
|
||||
return NULL;
|
||||
|
||||
@ -1227,7 +1233,7 @@ fr_info_t *fin;
|
||||
* may be too big to be in this buffer but not so big that it's
|
||||
* outside the ICMP packet, leading to TCP deref's causing problems.
|
||||
* This is possible because we don't know how big oip_hl is when we
|
||||
* do the pullup early in fr_check() and thus can't gaurantee it is
|
||||
* do the pullup early in fr_check() and thus can't guarantee it is
|
||||
* all here now.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
@ -1254,9 +1260,43 @@ fr_info_t *fin;
|
||||
bzero((char *)&src, sizeof(src));
|
||||
bzero((char *)&dst, sizeof(dst));
|
||||
bzero((char *)&ofin, sizeof(ofin));
|
||||
/*
|
||||
* We make an fin entry to be able to feed it to
|
||||
* matchsrcdst. Note that not all fields are encessary
|
||||
* but this is the cleanest way. Note further that we
|
||||
* fill in fin_mp such that if someone uses it we'll get
|
||||
* a kernel panic. fr_matchsrcdst does not use this.
|
||||
*/
|
||||
ofin.fin_ifp = fin->fin_ifp;
|
||||
ofin.fin_out = !fin->fin_out;
|
||||
ofin.fin_mp = NULL;
|
||||
ofin.fin_v = 4;
|
||||
/*
|
||||
* watch out here, as ip is in host order and oip in network
|
||||
* order. Any change we make must be undone afterwards, like
|
||||
* oip->ip_off - it is still in network byte order so fix it.
|
||||
*/
|
||||
savelen = oip->ip_len;
|
||||
oip->ip_len = len;
|
||||
oip->ip_off = ntohs(oip->ip_off);
|
||||
(void) fr_makefrip(ohlen, oip, &ofin);
|
||||
/*
|
||||
* Reset the short flag here because in fr_matchsrcdst() the flags
|
||||
* for the current packet (fin_fl) are compared against * those for
|
||||
* the existing session.
|
||||
*/
|
||||
ofin.fin_fl &= ~FI_SHORT;
|
||||
|
||||
/*
|
||||
* Put old values of ip_len and ip_off back as we don't know
|
||||
* if we have to forward the packet (or process it again.
|
||||
*/
|
||||
oip->ip_len = savelen;
|
||||
oip->ip_off = htons(oip->ip_off);
|
||||
|
||||
#if SOLARIS
|
||||
ofin.fin_qfm = NULL;
|
||||
#endif
|
||||
fr = NULL;
|
||||
|
||||
switch (oip->ip_p)
|
||||
@ -1265,7 +1305,7 @@ fr_info_t *fin;
|
||||
icmp = (icmphdr_t *)((char *)oip + ohlen);
|
||||
|
||||
/*
|
||||
* a ICMP error can only be generated as a result of an
|
||||
* an ICMP error can only be generated as a result of an
|
||||
* ICMP query, not as the response on an ICMP error
|
||||
*
|
||||
* XXX theoretically ICMP_ECHOREP and the other reply's are
|
||||
@ -1289,18 +1329,15 @@ fr_info_t *fin;
|
||||
hv += icmp->icmp_seq;
|
||||
hv %= fr_statesize;
|
||||
|
||||
savelen = oip->ip_len;
|
||||
oip->ip_len = len;
|
||||
fr_makefrip(ohlen, oip, &ofin);
|
||||
oip->ip_len = savelen;
|
||||
|
||||
READ_ENTER(&ipf_state);
|
||||
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
|
||||
if ((is->is_p == pr) && (is->is_v == 4) &&
|
||||
(is->is_icmppkts < is->is_pkts) &&
|
||||
fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
|
||||
fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
|
||||
fr_matchicmpqueryreply(is->is_v, is, icmp,
|
||||
fin->fin_rev)) {
|
||||
ips_stats.iss_hits++;
|
||||
is->is_pkts++;
|
||||
is->is_icmppkts++;
|
||||
is->is_bytes += ip->ip_len;
|
||||
fr = is->is_rule;
|
||||
break;
|
||||
@ -1329,20 +1366,7 @@ fr_info_t *fin;
|
||||
hv += dport;
|
||||
hv += sport;
|
||||
hv %= fr_statesize;
|
||||
/*
|
||||
* we make an fin entry to be able to feed it to
|
||||
* matchsrcdst note that not all fields are encessary
|
||||
* but this is the cleanest way. Note further we fill
|
||||
* in fin_mp such that if someone uses it we'll get
|
||||
* a kernel panic. fr_matchsrcdst does not use this.
|
||||
*
|
||||
* watch out here, as ip is in host order and oip in network
|
||||
* order. Any change we make must be undone afterwards.
|
||||
*/
|
||||
savelen = oip->ip_len;
|
||||
oip->ip_len = len;
|
||||
fr_makefrip(ohlen, oip, &ofin);
|
||||
oip->ip_len = savelen;
|
||||
|
||||
READ_ENTER(&ipf_state);
|
||||
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
|
||||
/*
|
||||
@ -1350,13 +1374,16 @@ fr_info_t *fin;
|
||||
* encapsulated packet was allowed through the
|
||||
* other way around. Note that the minimal amount
|
||||
* of info present does not allow for checking against
|
||||
* tcp internals such as seq and ack numbers.
|
||||
* tcp internals such as seq and ack numbers. Only the
|
||||
* ports are known to be present and can be even if the
|
||||
* short flag is set.
|
||||
*/
|
||||
if ((is->is_p == pr) && (is->is_v == 4) &&
|
||||
(is->is_icmppkts < is->is_pkts) &&
|
||||
fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
|
||||
fr = is->is_rule;
|
||||
ips_stats.iss_hits++;
|
||||
is->is_pkts++;
|
||||
is->is_icmppkts++;
|
||||
is->is_bytes += fin->fin_plen;
|
||||
/*
|
||||
* we deliberately do not touch the timeouts
|
||||
@ -2083,7 +2110,7 @@ u_int type;
|
||||
int types[1];
|
||||
|
||||
ipsl.isl_type = type;
|
||||
ipsl.isl_pkts = is->is_pkts;
|
||||
ipsl.isl_pkts = is->is_pkts + is->is_icmppkts;
|
||||
ipsl.isl_bytes = is->is_bytes;
|
||||
ipsl.isl_src = is->is_src;
|
||||
ipsl.isl_dst = is->is_dst;
|
||||
@ -2111,7 +2138,11 @@ u_int type;
|
||||
sizes[0] = sizeof(ipsl);
|
||||
types[0] = 0;
|
||||
|
||||
(void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
|
||||
if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) {
|
||||
ATOMIC_INCL(ips_stats.iss_logged);
|
||||
} else {
|
||||
ATOMIC_INCL(ips_stats.iss_logfail);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2161,12 +2192,30 @@ fr_info_t *fin;
|
||||
bzero((char *)&ofin, sizeof(ofin));
|
||||
ofin.fin_out = !fin->fin_out;
|
||||
ofin.fin_ifp = fin->fin_ifp;
|
||||
ofin.fin_mp = NULL;
|
||||
ofin.fin_v = 6;
|
||||
#if SOLARIS
|
||||
ofin.fin_qfm = NULL;
|
||||
#endif
|
||||
/*
|
||||
* We make a fin entry to be able to feed it to
|
||||
* matchsrcdst. Note that not all fields are necessary
|
||||
* but this is the cleanest way. Note further we fill
|
||||
* in fin_mp such that if someone uses it we'll get
|
||||
* a kernel panic. fr_matchsrcdst does not use this.
|
||||
*
|
||||
* watch out here, as ip is in host order and oip in network
|
||||
* order. Any change we make must be undone afterwards.
|
||||
*/
|
||||
savelen = oip->ip6_plen;
|
||||
oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
|
||||
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
|
||||
oip->ip6_plen = savelen;
|
||||
|
||||
if (oip->ip6_nxt == IPPROTO_ICMPV6) {
|
||||
oic = (struct icmp6_hdr *)(oip + 1);
|
||||
/*
|
||||
* a ICMP error can only be generated as a result of an
|
||||
* an ICMP error can only be generated as a result of an
|
||||
* ICMP query, not as the response on an ICMP error
|
||||
*
|
||||
* XXX theoretically ICMP_ECHOREP and the other reply's are
|
||||
@ -2187,10 +2236,6 @@ fr_info_t *fin;
|
||||
hv += oic->icmp6_seq;
|
||||
hv %= fr_statesize;
|
||||
|
||||
oip->ip6_plen = ntohs(oip->ip6_plen);
|
||||
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
|
||||
oip->ip6_plen = htons(oip->ip6_plen);
|
||||
|
||||
READ_ENTER(&ipf_state);
|
||||
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
|
||||
if ((is->is_p == pr) &&
|
||||
@ -2234,20 +2279,7 @@ fr_info_t *fin;
|
||||
hv += dport;
|
||||
hv += sport;
|
||||
hv %= fr_statesize;
|
||||
/*
|
||||
* we make an fin entry to be able to feed it to
|
||||
* matchsrcdst note that not all fields are encessary
|
||||
* but this is the cleanest way. Note further we fill
|
||||
* in fin_mp such that if someone uses it we'll get
|
||||
* a kernel panic. fr_matchsrcdst does not use this.
|
||||
*
|
||||
* watch out here, as ip is in host order and oip in network
|
||||
* order. Any change we make must be undone afterwards.
|
||||
*/
|
||||
savelen = oip->ip6_plen;
|
||||
oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
|
||||
fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
|
||||
oip->ip6_plen = savelen;
|
||||
|
||||
READ_ENTER(&ipf_state);
|
||||
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
|
||||
/*
|
||||
|
@ -63,6 +63,7 @@ typedef struct ipstate {
|
||||
frentry_t *is_rule;
|
||||
U_QUAD_T is_pkts;
|
||||
U_QUAD_T is_bytes;
|
||||
U_QUAD_T is_icmppkts;
|
||||
union i6addr is_src;
|
||||
union i6addr is_dst;
|
||||
void *is_ifp[4];
|
||||
|
@ -10,6 +10,6 @@
|
||||
#ifndef __IPL_H__
|
||||
#define __IPL_H__
|
||||
|
||||
#define IPL_VERSION "IP Filter: v3.4.31"
|
||||
#define IPL_VERSION "IP Filter: v3.4.35"
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user