merge ipf 3.2.10

This commit is contained in:
mrg 1998-11-22 15:17:18 +00:00
parent c48ea35c91
commit 78db9d7d95
37 changed files with 1170 additions and 688 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: fil.c,v 1.23 1998/07/12 15:23:59 veego Exp $ */
/* $NetBSD: fil.c,v 1.24 1998/11/22 15:17:18 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 darrenr Exp ";
static const char rcsid[] = "@(#)Id: fil.c,v 2.0.2.41.2.27 1998/11/22 01:50:15 darrenr Exp ";
#endif
#include <sys/errno.h>
@ -32,7 +32,9 @@ static const char rcsid[] = "@(#)Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 d
# endif
#else
# include <sys/byteorder.h>
# if SOLARIS2 < 5
# include <sys/dditypes.h>
# endif
# include <sys/stream.h>
#endif
#ifndef linux
@ -90,13 +92,8 @@ extern int opts;
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
# if SOLARIS
extern krwlock_t ipf_mutex, ipf_auth;
# endif
# if defined(__sgi)
extern kmutex_t ipf_mutex, ipf_auth;
# endif
# if SOLARIS || defined(__sgi)
extern KRWLOCK_T ipf_mutex, ipf_auth;
extern kmutex_t ipf_rw;
# endif
# if SOLARIS
@ -203,7 +200,6 @@ fr_info_t *fin;
{
struct optlist *op;
tcphdr_t *tcp;
icmphdr_t *icmp;
fr_ip_t *fi = &fin->fin_fi;
u_short optmsk = 0, secmsk = 0, auth = 0;
int i, mv, ol, off;
@ -224,14 +220,13 @@ fr_info_t *fin;
fin->fin_hlen = hlen;
fin->fin_dlen = ip->ip_len - hlen;
tcp = (tcphdr_t *)((char *)ip + hlen);
icmp = (icmphdr_t *)tcp;
fin->fin_dp = (void *)tcp;
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
(*(((u_32_t *)fi) + 1)) = (*(((u_32_t *)ip) + 3));
(*(((u_32_t *)fi) + 2)) = (*(((u_32_t *)ip) + 4));
fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
off = (ip->ip_off & 0x1fff) << 3;
off = (ip->ip_off & IP_OFFMASK) << 3;
if (ip->ip_off & 0x3fff)
fi->fi_fl |= FI_FRAG;
switch (ip->ip_p)
@ -239,10 +234,12 @@ fr_info_t *fin;
case IPPROTO_ICMP :
{
int minicmpsz = sizeof(struct icmp);
icmphdr_t *icmp;
if (!off && ip->ip_len > ICMP_MINLEN + hlen &&
(icmp->icmp_type == ICMP_ECHOREPLY ||
icmp->icmp_type == ICMP_UNREACH))
icmp = (icmphdr_t *)tcp;
if (!off && (icmp->icmp_type == ICMP_ECHOREPLY ||
icmp->icmp_type == ICMP_ECHO))
minicmpsz = ICMP_MINLEN;
if ((!(ip->ip_len >= hlen + minicmpsz) && !off) ||
(off && off < sizeof(struct icmp)))
@ -434,7 +431,7 @@ void *m;
fin->fin_fr = NULL;
fin->fin_rule = 0;
fin->fin_group = 0;
off = ip->ip_off & 0x1fff;
off = ip->ip_off & IP_OFFMASK;
pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
@ -554,7 +551,7 @@ void *m;
/*
* frcheck - filter check
* check using source and destination addresses/pors in a packet whether
* check using source and destination addresses/ports in a packet whether
* or not to pass it on or not.
*/
int fr_check(ip, hlen, ifp, out
@ -602,19 +599,20 @@ int out;
ip->ip_p == IPPROTO_ICMP)) {
int plen = 0;
switch(ip->ip_p)
{
case IPPROTO_TCP:
plen = sizeof(tcphdr_t);
break;
case IPPROTO_UDP:
plen = sizeof(udphdr_t);
break;
case IPPROTO_ICMP:
if ((ip->ip_off & IP_OFFMASK) == 0)
switch(ip->ip_p)
{
case IPPROTO_TCP:
plen = sizeof(tcphdr_t);
break;
case IPPROTO_UDP:
plen = sizeof(udphdr_t);
break;
/* 96 - enough for complete ICMP error IP header */
plen = sizeof(struct icmp) + sizeof(ip_t) + 8;
break;
}
case IPPROTO_ICMP:
plen = 76 + sizeof(struct icmp);
break;
}
up = MIN(hlen + plen, ip->ip_len);
if (up > m->m_len) {
@ -959,7 +957,7 @@ int len;
u_short s;
} bytes;
u_32_t sum;
u_short *sp;
u_short *sp, slen;
# if SOLARIS || defined(__sgi)
int add, hlen;
# endif
@ -967,28 +965,27 @@ int len;
/*
* Add up IP Header portion
*/
bytes.c[0] = 0;
bytes.c[1] = IPPROTO_TCP;
len -= (ip->ip_hl << 2);
sum = bytes.s;
sum += htons((u_short)len);
sp = (u_short *)&ip->ip_src;
len -= (ip->ip_hl << 2);
slen = (u_short)len;
sum = ntohs(IPPROTO_TCP);
sum += htons(slen);
sum += *sp++; /* ip_src */
sum += *sp++;
sum += *sp++;
sum += *sp++;
sum += *sp++; /* ip_dst */
sum += *sp++;
if (sp != (u_short *)tcp)
sp = (u_short *)tcp;
sum += *sp++; /* sport */
sum += *sp++; /* dport */
sum += *sp++; /* seq */
sum += *sp++;
sum += *sp++; /* ack */
sum += *sp++;
sum += *sp++;
sum += *sp++;
sum += *sp++;
sum += *sp++;
sum += *sp++;
sum += *sp;
sum += *sp++; /* off */
sum += *sp; /* win */
sp += 2; /* Skip over checksum */
sum += *sp++;
sum += *sp++; /* urp */
#if SOLARIS
/*
@ -1003,9 +1000,12 @@ int len;
hlen -= add;
if ((caddr_t)sp >= (caddr_t)m->b_wptr) {
m = m->b_cont;
PANIC((!m),("fr_tcpsum: not enough data"));
if (!hlen)
if (!hlen) {
if (!m)
break;
sp = (u_short *)m->b_rptr;
}
PANIC((!m),("fr_tcpsum(1): not enough data"));
}
}
}
@ -1021,11 +1021,14 @@ int len;
add = MIN(hlen, m->m_len);
sp = (u_short *)(mtod(m, caddr_t) + add);
hlen -= add;
if (add >= m->m_len) {
if (add == m->m_len) {
m = m->m_next;
PANIC((!m),("fr_tcpsum: not enough data"));
if (!hlen)
if (!hlen) {
if (!m)
break;
sp = mtod(m, u_short *);
}
PANIC((!m),("fr_tcpsum(1): not enough data"));
}
}
}
@ -1033,39 +1036,51 @@ int len;
if (!(len -= sizeof(*tcp)))
goto nodata;
while (len > 0) {
while (len > 1) {
#if SOLARIS
while ((caddr_t)sp >= (caddr_t)m->b_wptr) {
if ((caddr_t)sp >= (caddr_t)m->b_wptr) {
m = m->b_cont;
PANIC((!m),("fr_tcpsum: not enough data"));
PANIC((!m),("fr_tcpsum(2): not enough data"));
sp = (u_short *)m->b_rptr;
}
if ((caddr_t)(sp + 1) > (caddr_t)m->b_wptr) {
bytes.c[0] = *(u_char *)sp;
m = m->b_cont;
PANIC((!m),("fr_tcpsum(3): not enough data"));
sp = (u_short *)m->b_rptr;
bytes.c[1] = *(u_char *)sp;
sum += bytes.s;
sp = (u_short *)((u_char *)sp + 1);
}
#else
while (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len)
{
if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) {
m = m->m_next;
PANIC((!m),("fr_tcpsum: not enough data"));
PANIC((!m),("fr_tcpsum(2): not enough data"));
sp = mtod(m, u_short *);
}
if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) {
bytes.c[0] = *(u_char *)sp;
m = m->m_next;
PANIC((!m),("fr_tcpsum(3): not enough data"));
sp = mtod(m, u_short *);
bytes.c[1] = *(u_char *)sp;
sum += bytes.s;
sp = (u_short *)((u_char *)sp + 1);
}
#endif /* SOLARIS */
if (len < 2)
break;
if((u_long)sp & 1) {
if ((u_long)sp & 1) {
bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s));
sum += bytes.s;
} else
sum += *sp++;
len -= 2;
}
if (len) {
bytes.c[1] = 0;
bytes.c[0] = *(u_char *)sp;
sum += bytes.s;
}
if (len)
sum += ntohs(*(u_char *)sp << 8);
nodata:
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
sum = (u_short)((~sum) & 0xffff);
while (sum > 0xffff)
sum = (sum & 0xffff) + (sum >> 16);
sum = (u_short)(~sum & 0xffff);
return sum;
}
@ -1104,7 +1119,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* Id: fil.c,v 2.0.2.41.2.17 1998/06/07 16:27:07 darrenr Exp
* Id: fil.c,v 2.0.2.41.2.27 1998/11/22 01:50:15 darrenr Exp
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,

View File

@ -1,25 +1,26 @@
/* $NetBSD: ip_auth.c,v 1.8 1998/07/12 15:23:59 veego Exp $ */
/* $NetBSD: ip_auth.c,v 1.9 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1997 by Darren Reed & Guido van Rooij.
* Copyright (C) 1998 by Darren Reed & Guido van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.0.2.21.2.5 1998/06/13 13:40:49 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.0.2.21.2.7 1998/11/22 01:50:19 darrenr Exp ";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdlib.h>
# include <string.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
@ -95,7 +96,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern krwlock_t ipf_auth;
extern KRWLOCK_T ipf_auth;
extern kmutex_t ipf_authmx;
# if SOLARIS
extern kcondvar_t ipfauthwait;

View File

@ -1,13 +1,13 @@
/* $NetBSD: ip_auth.h,v 1.3 1998/09/13 15:45:40 christos Exp $ */
/* $NetBSD: ip_auth.h,v 1.4 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1997 by Darren Reed & Guido van Rooij.
* Copyright (C) 1997-1998 by Darren Reed & Guido Van Rooij.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: ip_auth.h,v 2.0.2.10 1997/10/29 12:14:07 darrenr Exp
* Id: ip_auth.h,v 2.0.2.10.2.1 1998/11/22 01:50:20 darrenr Exp
*
*/

View File

@ -1,14 +1,14 @@
/* $NetBSD: ip_compat.h,v 1.15 1998/07/12 15:23:59 veego Exp $ */
/* $NetBSD: ip_compat.h,v 1.16 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* Id: ip_compat.h,v 2.0.2.31.2.12 1998/06/06 14:36:38 darrenr Exp
* Id: ip_compat.h,v 2.0.2.31.2.20 1998/11/22 01:50:20 darrenr Exp
*/
#ifndef _NETINET_IP_COMPAT_H_
@ -27,25 +27,28 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
#if defined(_KERNEL) && !defined(KERNEL)
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
# undef _KERNEL
# undef __KERNEL__
# define KERNEL
#endif
#if defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#if!defined(__KERNEL__) && defined(KERNEL)
# define __KERNEL__
#endif
#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
#define index strchr
# if !defined(_KERNEL)
# if !defined(KERNEL)
# define bzero(a,b) memset(a,0,b)
# define bcmp memcmp
# define bcopy(a,b,c) memmove(b,a,c)
# endif
#endif
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#if defined(__sgi) || defined(bsdi)
struct ether_addr {
u_char ether_addr_octet[6];
@ -82,7 +85,7 @@ struct ether_addr {
# undef IPOPT_LSRR
# undef IPOPT_RR
# undef IPOPT_SSRR
# ifndef _KERNEL
# ifndef KERNEL
# define _KERNEL
# undef RES_INIT
# include <inet/common.h>
@ -208,10 +211,23 @@ typedef unsigned long u_32_t;
# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
mutex_exit(&ipf_rw); }
# define MUTEX_ENTER(x) mutex_enter(x)
# define READ_ENTER(x) rw_enter(x, RW_READER)
# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
# define RWLOCK_EXIT(x) rw_exit(x)
# if 1
# define KRWLOCK_T krwlock_t
# define READ_ENTER(x) rw_enter(x, RW_READER)
# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
# define RWLOCK_INIT(x, y, z) rw_init((x), (y), RW_DRIVER, (z))
# define RWLOCK_EXIT(x) rw_exit(x)
# define RW_DESTROY(x) rw_destroy(x)
# else
# define KRWLOCK_T kmutex_t
# define READ_ENTER(x) mutex_enter(x)
# define WRITE_ENTER(x) mutex_enter(x)
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
# define RWLOCK_EXIT(x) mutex_exit(x)
# define RW_DESTROY(x) mutex_destroy(x)
# endif
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
@ -263,11 +279,12 @@ typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
(x)--; MUTEX_EXIT(&ipf_rw); }
# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
# define KRWLOCK_T kmutex_t
# define READ_ENTER(x) MUTEX_ENTER(x)
# define WRITE_ENTER(x) MUTEX_ENTER(x)
# define MUTEX_DOWNGRADE(x) ;
@ -387,7 +404,15 @@ extern vm_map_t kmem_map;
typedef mblk_t mb_t;
#else
# ifdef linux
# ifndef kernel
typedef struct mb {
struct mb *next;
u_int len;
u_char *data;
} mb_t;
# else
typedef struct sk_buff mb_t;
# endif
# else
typedef struct mbuf mb_t;
# endif
@ -522,6 +547,7 @@ typedef struct mbuf mb_t;
#endif /* linux || __sgi */
#ifdef linux
#include <linux/in_systm.h>
/*
* TCP States
*/
@ -543,8 +569,13 @@ typedef struct mbuf mb_t;
/*
* file flags.
*/
#ifdef WRITE
#define FWRITE WRITE
#define FREAD READ
#else
#define FWRITE _IOC_WRITE
#define FREAD _IOC_READ
#endif
/*
* mbuf related problems.
*/
@ -552,7 +583,10 @@ typedef struct mbuf mb_t;
#define m_len len
#define m_next next
#define IP_DF 0x8000
#ifdef IP_DF
#undef IP_DF
#endif
#define IP_DF 0x4000
typedef struct {
__u16 th_sport;
@ -604,15 +638,15 @@ typedef struct {
* Structure of an icmp header.
*/
typedef struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */
__u8 icmp_type; /* type of message, see below */
__u8 icmp_code; /* type sub code */
__u16 icmp_cksum; /* ones complement cksum of struct */
union {
u_char ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
n_short icd_id;
n_short icd_seq;
__u8 ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
__u16 icd_id;
__u16 icd_seq;
} ih_idseq;
int ih_void;
} icmp_hun;

View File

@ -1,7 +1,7 @@
/* $NetBSD: ip_fil.c,v 1.30 1998/11/15 17:36:19 drochner Exp $ */
/* $NetBSD: ip_fil.c,v 1.31 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:49 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.0.2.44.2.10 1998/11/22 01:50:22 darrenr Exp ";
#endif
#ifndef SOLARIS
@ -134,6 +134,9 @@ static int frrequest __P((int, int, caddr_t, int));
#endif
#ifdef _KERNEL
static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
# ifdef __sgi
extern kmutex_t ipf_rw;
# endif
#else
int ipllog __P((void));
void init_ifp __P((void));
@ -1004,9 +1007,16 @@ frdest_t *fdp;
/*
* For input packets which are being "fastrouted", they won't
* go back through output filtering and miss their chance to get
* NAT'd.
* NAT'd and counted.
*/
(void) ip_natout(ip, hlen, fin);
if (fin->fin_out == 0) {
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
ATOMIC_INC(frstats[1].fr_acct);
}
fin->fin_fr = NULL;
(void) ip_natout(ip, hlen, fin);
}
if (fin->fin_out)
ip->ip_sum = 0;
/*
@ -1128,9 +1138,8 @@ done:
else
ipl_frouteok[1]++;
if (ro->ro_rt) {
if (ro->ro_rt)
RTFREE(ro->ro_rt);
}
return;
bad:
m_freem(m);

View File

@ -1,19 +1,23 @@
/* $NetBSD: ip_fil.h,v 1.26 1998/07/12 15:23:59 veego Exp $ */
/* $NetBSD: ip_fil.h,v 1.27 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
* Id: ip_fil.h,v 2.0.2.39.2.12 1998/06/06 14:36:49 darrenr Exp
* Id: ip_fil.h,v 2.0.2.39.2.18 1998/11/22 01:50:24 darrenr Exp
*/
#ifndef _NETINET_IP_FIL_H_
#define _NETINET_IP_FIL_H_
#if defined(__NetBSD__) && defined(PFIL_HOOKS)
#include "opt_pfil_hooks.h"
#endif
/*
* Pathnames for various IP Filter control devices. Used by LKM
* and userland, so defined here.
@ -86,14 +90,14 @@
typedef struct fr_ip {
u_char fi_v:4; /* IP version */
u_char fi_fl:4; /* packet flags */
u_char fi_tos;
u_char fi_ttl;
u_char fi_p;
struct in_addr fi_src;
struct in_addr fi_dst;
u_char fi_tos; /* IP packet TOS */
u_char fi_ttl; /* IP packet TTL */
u_char fi_p; /* IP packet protocol */
struct in_addr fi_src; /* source address from packet */
struct in_addr fi_dst; /* destination address from packet */
u_32_t fi_optmsk; /* bitmask composed from IP options */
u_short fi_secmsk; /* bitmask composed from IP security options */
u_short fi_auth;
u_short fi_auth; /* authentication code from IP sec. options */
} fr_ip_t;
#define FI_OPTIONS (FF_OPTIONS >> 24)
@ -102,34 +106,35 @@ typedef struct fr_ip {
#define FI_SHORT (FF_SHORT >> 24)
typedef struct fr_info {
struct fr_ip fin_fi;
u_short fin_data[2];
u_short fin_out;
u_short fin_hlen;
u_char fin_tcpf;
u_char fin_icode; /* From here on is packet specific */
u_short fin_rule;
u_short fin_group;
u_short fin_dlen;
u_short fin_id;
void *fin_ifp;
struct frentry *fin_fr;
struct fr_ip fin_fi; /* IP Packet summary */
u_short fin_data[2]; /* TCP/UDP ports, ICMP code/type */
u_short fin_out; /* in or out ? 1 == out, 0 == in */
u_short fin_hlen; /* length of IP header in bytes */
u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
/* From here on is packet specific */
u_char fin_icode; /* ICMP error to return */
u_short fin_rule; /* rule # last matched */
u_short fin_group; /* group number, -1 for none */
u_short fin_dlen; /* length of data portion of packet */
u_short fin_id; /* IP packet id field */
void *fin_ifp; /* interface packet is `on' */
struct frentry *fin_fr; /* last matching rule */
char *fin_dp; /* start of data past IP header */
void *fin_mp;
void *fin_mp; /* pointer to pointer to mbuf */
#if SOLARIS && defined(_KERNEL)
void *fin_qfm;
void *fin_qfm; /* pointer to mblk where pkt starts */
#endif
} fr_info_t;
/*
* Size for compares on fr_info structures
*/
#define FI_CSIZE (sizeof(struct fr_ip) + sizeof(u_short) * 4 + \
sizeof(u_char))
#define FI_CSIZE offsetof(fr_info_t, fin_icode)
/*
* Size for copying cache fr_info structure
*/
#define FI_COPYSIZE (sizeof(fr_info_t) - sizeof(void *) * 2)
#define FI_COPYSIZE offsetof(fr_info_t, fin_dp)
typedef struct frdest {
void *fd_ifp;
@ -267,6 +272,8 @@ typedef struct filterstats {
u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
#if SOLARIS
u_long fr_notdata; /* PROTO/PCPROTO that have no data */
u_long fr_nodata; /* mblks that have no data */
u_long fr_bad; /* bad IP packets to the filter */
u_long fr_notip; /* packets passed through no on ip queue */
u_long fr_drop; /* packets dropped - no info for them! */

View File

@ -1,7 +1,7 @@
/* $NetBSD: ip_frag.c,v 1.12 1998/07/12 15:24:00 veego Exp $ */
/* $NetBSD: ip_frag.c,v 1.13 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,18 +9,19 @@
*/
#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.0.2.19.2.2 1998/06/06 14:37:02 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.0.2.19.2.6 1998/11/22 01:50:25 darrenr Exp ";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
#include <sys/filio.h>
#include <sys/fcntl.h>
@ -78,7 +79,7 @@ int ipfr_inuse = 0,
extern int ipfr_timer_id;
#endif
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern krwlock_t ipf_frag, ipf_natfrag, ipf_nat;
extern KRWLOCK_T ipf_frag, ipf_natfrag, ipf_nat;
extern kmutex_t ipf_rw;
#endif
@ -157,7 +158,7 @@ ipfr_t *table[];
/*
* Compute the offset of the expected start of the next packet.
*/
fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3);
fr->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
ATOMIC_INC(ipfr_stats.ifs_new);
ATOMIC_INC(ipfr_inuse);
return fr;
@ -187,7 +188,8 @@ nat_t *nat;
ipfr_t *ipf;
WRITE_ENTER(&ipf_natfrag);
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
ipf->ipfr_data = nat;
nat->nat_data = ipf;
}
@ -252,7 +254,7 @@ ipfr_t *table[];
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
if ((off & 0x1fff) == f->ipfr_off) {
if ((off & IP_OFFMASK) == f->ipfr_off) {
if (!(off & IP_MF))
f->ipfr_ttl = 1;
else
@ -277,12 +279,12 @@ fr_info_t *fin;
READ_ENTER(&ipf_natfrag);
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf) {
if (ipf != NULL) {
nat = ipf->ipfr_data;
/*
* This is the last fragment for this packet.
*/
if (ipf->ipfr_ttl == 1) {
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
@ -352,7 +354,8 @@ void ipfr_unload()
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
if ((nat = (nat_t *)fr->ipfr_data)) {
nat = (nat_t *)fr->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fr)
nat->nat_data = NULL;
}
@ -431,7 +434,8 @@ int ipfr_slowtimer()
*fp = fr->ipfr_next;
ATOMIC_INC(ipfr_stats.ifs_expire);
ATOMIC_DEC(ipfr_inuse);
if ((nat = (nat_t *)fr->ipfr_data)) {
nat = (nat_t *)fr->ipfr_data;
if (nat != NULL) {
if (nat->nat_data == fr)
nat->nat_data = NULL;
}

View File

@ -1,14 +1,14 @@
/* $NetBSD: ip_frag.h,v 1.11 1998/05/29 20:24:37 veego Exp $ */
/* $NetBSD: ip_frag.h,v 1.12 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
* Id: ip_frag.h,v 2.0.2.12.2.1 1998/05/23 14:29:39 darrenr Exp
* Id: ip_frag.h,v 2.0.2.12.2.2 1998/11/22 01:50:25 darrenr Exp
*/
#ifndef _NETINET_IP_FRAG_H_

View File

@ -1,9 +1,12 @@
/* $NetBSD: ip_ftp_pxy.c,v 1.9 1998/07/12 15:27:46 veego Exp $ */
/* $NetBSD: ip_ftp_pxy.c,v 1.10 1998/11/22 15:17:19 mrg Exp $ */
/*
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
#endif
#define isdigit(x) ((x) >= '0' && (x) <= '9')
@ -11,71 +14,33 @@
#define IPF_MINPORTLEN 18
#define IPF_MAXPORTLEN 30
#define IPF_MIN227LEN 39
#define IPF_MAX227LEN 51
int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *,
ap_session_t *, nat_t *));
int ippr_ftp_init __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
u_short ipf_ftp_atoi __P((char **));
int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
nat_t *));
u_short ipf_ftp_atoi __P((char **));
/*
* FTP application proxy initialization.
*/
int ippr_ftp_init(fin, ip, tcp, aps, nat)
int ippr_ftp_init(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
return 0;
}
int ippr_ftp_in(fin, ip, tcp, aps, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
u_32_t sum1, sum2;
short sel;
if (tcp->th_sport == aps->aps_dport) {
sum2 = (u_32_t)ntohl(tcp->th_ack);
sel = aps->aps_sel;
if ((aps->aps_after[!sel] > aps->aps_after[sel]) &&
(sum2 > aps->aps_after[!sel])) {
sel = aps->aps_sel = !sel; /* switch to other set */
}
if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) {
sum1 = (u_32_t)aps->aps_seqoff[sel];
tcp->th_ack = htonl(sum2 - sum1);
return 2;
}
}
return 0;
}
/*
* ipf_ftp_atoi - implement a version of atoi which processes numbers in
* pairs separated by commas (which are expected to be in the range 0 - 255),
@ -105,29 +70,29 @@ char **ptr;
}
int ippr_ftp_out(fin, ip, tcp, aps, nat)
int ippr_ftp_portmsg(fin, ip, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
register u_32_t sum1, sum2;
char newbuf[IPF_MAXPORTLEN+1];
char portbuf[IPF_MAXPORTLEN+1], *s;
int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2);
u_int a1, a2, a3, a4;
u_short a5, a6;
int olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
void *savep;
nat_t *ipn;
struct in_addr swip;
mb_t *m = *(mb_t **)fin->fin_mp;
char portbuf[IPF_MAXPORTLEN + 1], newbuf[IPF_MAXPORTLEN + 1], *s;
int off, olen, dlen, nlen = 0, inc = 0;
u_int a1, a2, a3, a4;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
struct in_addr swip;
u_short a5, a6, sp, dp;
fr_info_t fi;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
tcp = (tcphdr_t *)fin->fin_dp;
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
@ -138,10 +103,14 @@ nat_t *nat;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
portbuf[IPF_MAXPORTLEN] = '\0';
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
goto adjust_seqack;
if (!strncmp(portbuf, "PORT ", 5)) {
if (dlen < IPF_MINPORTLEN)
return 0;
} else
return 0;
/*
* Skip the PORT command + space
@ -150,21 +119,34 @@ nat_t *nat;
/*
* Pick out the address components, two at a time.
*/
(void) ipf_ftp_atoi(&s);
a1 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
(void) ipf_ftp_atoi(&s);
return 0;
a2 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
return 0;
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
if (a1 != ntohl(nat->nat_inip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
if (!s)
goto adjust_seqack;
return 0;
/*
* check for CR-LF at the end.
*/
if (*s != '\n' || *(s - 1) != '\r')
goto adjust_seqack;
a6 = a5 & 0xff;
if (((*s == '\r') && (*(s + 1) == '\n')) ||
((*(s - 1) == '\r') && (*s == '\n')))
a6 = a5 & 0xff;
else
return 0;
a5 >>= 8;
/*
* Calculate new address parts for PORT command
@ -175,25 +157,27 @@ nat_t *nat;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf + 1;
(void) sprintf(newbuf, "PORT %d,%d,%d,%d,%d,%d\r\n",
a1, a2, a3, a4, a5, a6);
(void) sprintf(newbuf, "%s %d,%d,%d,%d,%d,%d\r\n",
"PORT", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
#if SOLARIS
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if (inc > 0) {
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
mblk_t *nm;
/* alloc enough to keep same trailer space for lower driver */
nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, BPRI_MED);
nm = allocb(nlen, BPRI_MED);
PANIC((!nm),("ippr_ftp_out: allocb failed"));
nm->b_band = m1->b_band;
nm->b_wptr += nlen;
m1->b_wptr -= olen;
PANIC((m1->b_wptr < m1->b_rptr),("ippr_ftp_out: cannot handle fragmented data block"));
PANIC((m1->b_wptr < m1->b_rptr),
("ippr_ftp_out: cannot handle fragmented data block"));
linkb(m1, nm);
} else {
@ -208,6 +192,8 @@ nat_t *nat;
#endif
if (inc) {
#if SOLARIS || defined(__sgi)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
sum2 = ip->ip_len + inc;
@ -221,48 +207,216 @@ nat_t *nat;
#endif
ip->ip_len += inc;
}
ch = 1;
/*
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
savep = fin->fin_dp;
fin->fin_dp = (char *)tcp2;
sp = htons(a5 << 8 | a6);
dp = htons(fin->fin_data[1] - 1);
ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_inip, sp,
ip->ip_dst, dp);
if (ipn == NULL) {
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = sp;
tcp2->th_dport = dp;
fi.fin_dp = (char *)tcp2;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP, NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FR_INQUE|FR_PASS|
FR_QUICK|FR_KEEPSTATE);
}
ip->ip_src = swip;
}
return inc;
}
int ippr_ftp_out(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
return ippr_ftp_portmsg(fin, ip, nat);
}
int ippr_ftp_pasvmsg(fin, ip, tcp, nat)
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
nat_t *nat;
{
char portbuf[IPF_MAX227LEN + 1], newbuf[IPF_MAX227LEN + 1], *s;
int off, olen, dlen, nlen = 0, inc = 0;
u_int a1, a2, a3, a4;
tcphdr_t tcph, *tcp2 = &tcph;
struct in_addr swip;
u_short a5, a6;
fr_info_t fi;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
off = (ip->ip_hl << 2) + (tcp->th_off << 2);
m = *(mb_t **)fin->fin_mp;
#if SOLARIS
m = fin->fin_qfm;
dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));
copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
dlen = mbufchainlen(m) - off;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
portbuf[sizeof(portbuf) - 1] = '\0';
*newbuf = '\0';
if (!strncmp(portbuf, "227 ", 4)) {
if (dlen < IPF_MIN227LEN)
return 0;
else if (strncmp(portbuf, "227 Entering Passive Mode", 25))
return 0;
#ifndef notyet
return 0;
#endif
} else
return 0;
/*
* Skip the PORT command + space
*/
s = portbuf + 25;
while (*s && !isdigit(*s))
s++;
/*
* Pick out the address components, two at a time.
*/
a1 = ipf_ftp_atoi(&s);
if (!s)
return 0;
a2 = ipf_ftp_atoi(&s);
if (!s)
return 0;
/*
* check that IP address in the PORT/PASV reply is the same as the
* sender of the command - prevents using PORT for port scanning.
*/
a1 <<= 16;
a1 |= a2;
if (a1 != ntohl(nat->nat_oip.s_addr))
return 0;
a5 = ipf_ftp_atoi(&s);
if (!s)
return 0;
/*
* check for CR-LF at the end.
*/
if (((*s == '\r') && (*(s + 1) == '\n')) ||
((*(s - 1) == '\r') && (*s == '\n')))
a6 = a5 & 0xff;
else
return 0;
a5 >>= 8;
/*
* Calculate new address parts for 227 reply
*/
a1 = ntohl(nat->nat_inip.s_addr);
a2 = (a1 >> 16) & 0xff;
a3 = (a1 >> 8) & 0xff;
a4 = a1 & 0xff;
a1 >>= 24;
olen = s - portbuf + 1;
(void) sprintf(newbuf, "%s %d,%d,%d,%d,%d,%d\r\n",
"227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
#if SOLARIS
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
mblk_t *nm;
/* alloc enough to keep same trailer space for lower driver */
nm = allocb(nlen, BPRI_MED);
PANIC((!nm),("ippr_ftp_out: allocb failed"));
nm->b_band = m1->b_band;
nm->b_wptr += nlen;
m1->b_wptr -= olen;
PANIC((m1->b_wptr < m1->b_rptr),
("ippr_ftp_out: cannot handle fragmented data block"));
linkb(m1, nm);
} else {
m1->b_wptr += inc;
}
copyin_mblk(m, off, nlen, newbuf);
#else
if (inc < 0)
m_adj(m, inc);
/* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
#endif
if (inc) {
#if SOLARIS || defined(__sgi)
register u_32_t sum1, sum2;
sum1 = ip->ip_len;
sum2 = ip->ip_len + inc;
/* Because ~1 == -2, We really need ~1 == -1 */
if (sum1 > sum2)
sum2--;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2);
#endif
ip->ip_len += inc;
}
/*
* Add skeleton NAT entry for connection which will come back the
* other way.
*/
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(a5 << 8 | a6);
tcp2->th_dport = htons(20);
fi.fin_dp = (char *)tcp2;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND)))
ip->ip_src = nat->nat_oip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP, NAT_INBOUND);
if (ipn != NULL)
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE);
(void) fr_addstate(ip, &fi, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE);
ip->ip_src = swip;
fin->fin_dp = (char *)savep;
adjust_seqack:
if (tcp->th_dport == aps->aps_dport) {
sum2 = (u_32_t)ntohl(tcp->th_seq);
off = aps->aps_sel;
if ((aps->aps_after[!off] > aps->aps_after[off]) &&
(sum2 > aps->aps_after[!off])) {
off = aps->aps_sel = !off; /* switch to other set */
}
if (aps->aps_seqoff[off]) {
sum1 = (u_32_t)aps->aps_after[off] -
aps->aps_seqoff[off];
if (sum2 > sum1) {
sum1 = (u_32_t)aps->aps_seqoff[off];
sum2 += sum1;
tcp->th_seq = htonl(sum2);
ch = 1;
}
}
if (inc && (sum2 > aps->aps_after[!off])) {
aps->aps_after[!off] = sum2 + nlen - 1;
aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc;
}
}
return ch ? 2 : 0;
return inc;
}
int ippr_ftp_in(fin, ip, aps, nat)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
return ippr_ftp_pasvmsg(fin, ip, tcp, nat);
}

View File

@ -1,13 +1,13 @@
/* $NetBSD: ip_log.c,v 1.5 1998/07/12 15:24:00 veego Exp $ */
/* $NetBSD: ip_log.c,v 1.6 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: ip_log.c,v 2.0.2.13.2.4 1998/06/07 16:27:09 darrenr Exp
* Id: ip_log.c,v 2.0.2.13.2.7 1998/11/22 01:50:26 darrenr Exp
*/
#ifdef IPFILTER_LOG
# ifndef SOLARIS
@ -181,29 +181,36 @@ mb_t *m;
* calculate header size.
*/
hlen = fin->fin_hlen;
if (ip->ip_p == IPPROTO_TCP)
hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_UDP)
hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_ICMP) {
struct icmp *icmp = (struct icmp *)((char *)ip + hlen);
/*
* For ICMP, if the packet is an error packet, also include
* the information about the packet which caused the error.
*/
switch (icmp->icmp_type)
{
case ICMP_UNREACH :
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
hlen += MIN(sizeof(struct icmp) + 8, fin->fin_dlen);
break;
default :
hlen += MIN(sizeof(struct icmp), fin->fin_dlen);
break;
if ((ip->ip_off & IP_OFFMASK) == 0) {
if (ip->ip_p == IPPROTO_TCP)
hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_UDP)
hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
else if (ip->ip_p == IPPROTO_ICMP) {
struct icmp *icmp;
icmp = (struct icmp *)((char *)ip + hlen);
/*
* For ICMP, if the packet is an error packet, also
* include the information about the packet which
* caused the error.
*/
switch (icmp->icmp_type)
{
case ICMP_UNREACH :
case ICMP_SOURCEQUENCH :
case ICMP_REDIRECT :
case ICMP_TIMXCEED :
case ICMP_PARAMPROB :
hlen += MIN(sizeof(struct icmp) + 8,
fin->fin_dlen);
break;
default :
hlen += MIN(sizeof(struct icmp),
fin->fin_dlen);
break;
}
}
}
/*

View File

@ -1,7 +1,7 @@
/* $NetBSD: ip_nat.c,v 1.22 1998/11/15 17:36:20 drochner Exp $ */
/* $NetBSD: ip_nat.c,v 1.23 1998/11/22 15:17:19 mrg Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -11,23 +11,23 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.0.2.44.2.13 1998/06/13 13:42:47 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.0.2.44.2.30 1998/11/22 01:50:27 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
#define _KERNEL
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
@ -108,7 +108,7 @@ u_long fr_defnatage = 1200, /* 10 minutes (600 seconds) */
natstat_t nat_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_rw;
extern krwlock_t ipf_nat;
extern KRWLOCK_T ipf_nat;
#endif
static int nat_flushtable __P((void));
@ -120,11 +120,10 @@ static int nat_ifpaddr __P((nat_t *, void *, struct in_addr *));
#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
#define CALC_SUMD(s1, s2, sd) { \
/* Do it twice */ \
(s1) = ((s1) & 0xffff) + ((s1) >> 16); \
(s1) = ((s1) & 0xffff) + ((s1) >> 16); \
/* Do it twice */ \
(s2) = ((s2) & 0xffff) + ((s2) >> 16); \
/* Do it twice */ \
(s1) = ((s1) & 0xffff) + ((s1) >> 16); \
(s2) = ((s2) & 0xffff) + ((s2) >> 16); \
/* Because ~1 == -2, We really need ~1 == -1 */ \
if ((s1) > (s2)) (s2)--; \
@ -258,7 +257,13 @@ int mode;
n->in_ifp = (void *)GETUNIT(n->in_ifname);
if (!n->in_ifp)
n->in_ifp = (void *)-1;
n->in_apr = ap_match(n->in_p, n->in_plabel);
if (n->in_plabel[0] != '\0') {
n->in_apr = ap_match(n->in_p, n->in_plabel);
if (!n->in_apr) {
error = ENOENT;
break;
}
}
n->in_next = *np;
n->in_use = 0;
n->in_space = ~(0xffffffff & ntohl(n->in_outmsk));
@ -282,7 +287,7 @@ int mode;
/* Otherwise, these fields are preset */
*np = n;
n = NULL;
ATOMIC_INC(nat_stats.ns_rules);
nat_stats.ns_rules++;
break;
case SIOCRMNAT :
#if defined(__NetBSD__) && defined(_KERNEL)
@ -303,7 +308,7 @@ int mode;
if (n->in_apr)
ap_free(n->in_apr);
KFREE(n);
ATOMIC_DEC(nat_stats.ns_rules);
nat_stats.ns_rules--;
} else {
n->in_flags |= IPN_DELETE;
n->in_next = NULL;
@ -315,6 +320,7 @@ int mode;
nat_stats.ns_table[0] = nat_table[0];
nat_stats.ns_table[1] = nat_table[1];
nat_stats.ns_list = nat_list;
nat_stats.ns_apslist = ap_sess_list;
IWCOPY((char *)&nat_stats, (char *)data, sizeof(nat_stats));
break;
case SIOCGNATL :
@ -340,7 +346,6 @@ int mode;
break;
}
ret = nat_flushtable();
(void) ap_unload();
MUTEX_DOWNGRADE(&ipf_nat);
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
@ -365,7 +370,7 @@ int mode;
#endif
break;
}
RWLOCK_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
SPL_X(s);
if (nt)
KFREE(nt);
@ -402,7 +407,7 @@ struct nat *natd;
* longer being used.
*/
if ((ipn = natd->nat_ptr)) {
ATOMIC_INC(ipn->in_space);
ipn->in_space++;
ipn->in_use--;
if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) {
if (ipn->in_apr)
@ -417,6 +422,8 @@ struct nat *natd;
* dereference that as well.
*/
ipfr_forget((void *)natd);
aps_free(natd->nat_aps);
nat_stats.ns_inuse--;
KFREE(natd);
}
@ -430,7 +437,7 @@ static int nat_flushtable()
register int j = 0;
/*
* Everything will be deleted, so lets just make it the deletions
* ALL NAT mappings deleted, so lets just make it the deletions
* quicker.
*/
bzero((char *)nat_table[0], sizeof(nat_table[0]));
@ -441,13 +448,13 @@ static int nat_flushtable()
nat_delete(nat);
j++;
}
nat_stats.ns_inuse = 0;
return j;
}
/*
* nat_clearlist - delete all entries in the active NAT mapping list.
* nat_clearlist - delete all rules in the active NAT mapping list.
*/
static int nat_clearlist()
{
@ -460,14 +467,13 @@ static int nat_clearlist()
if (n->in_apr)
ap_free(n->in_apr);
KFREE(n);
ATOMIC_DEC(nat_stats.ns_rules);
i++;
nat_stats.ns_rules--;
} else {
n->in_flags |= IPN_DELETE;
n->in_next = NULL;
}
i++;
}
nat_stats.ns_inuse = 0;
return i;
}
@ -545,6 +551,7 @@ struct in_addr *inp;
/*
* Create a new NAT table entry.
* NOTE: assumes write lock on ipf_nat has been obtained already.
*/
nat_t *nat_new(np, ip, fin, flags, direction)
ipnat_t *np;
@ -579,15 +586,32 @@ int direction;
* Search the current table for a match.
*/
if (direction == NAT_OUTBOUND) {
/*
* Values at which the search for a free resouce starts.
*/
u_32_t st_ip;
u_short st_port;
/*
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
*/
l = 0;
st_ip = np->in_nip;
st_port = np->in_pnext;
do {
l++;
port = 0;
in.s_addr = np->in_nip;
if ((np->in_outmsk == 0xffffffff) &&
(np->in_pnext == 0)) {
if (l > 1) {
KFREE(nat);
return NULL;
}
}
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
if ((l > 1) ||
nat_ifpaddr(nat, fin->fin_ifp, &in) == -1) {
@ -600,19 +624,21 @@ int direction;
return NULL;
}
in.s_addr = ntohl(ip->ip_src.s_addr);
if (nflags & IPN_TCPUDP)
port = sport;
} else if (nflags & IPN_TCPUDP) {
} else if ((nflags & IPN_TCPUDP)) {
port = htons(np->in_pnext++);
if (np->in_pnext >= ntohs(np->in_pmax)) {
np->in_pnext = ntohs(np->in_pmin);
np->in_space--;
if (np->in_outmsk != 0xffffffff)
np->in_nip++;
}
} else if (np->in_outmsk != 0xffffffff) {
np->in_space--;
} else if (np->in_outmsk != 0xffffffff)
np->in_nip++;
if (!np->in_nip && (nflags & IPN_TCPUDP) &&
(np->in_pnext != 0)) {
port = htons(np->in_pnext++);
if (np->in_pnext >= ntohs(np->in_pmax))
np->in_pnext = ntohs(np->in_pmin);
}
if (!port && (flags & IPN_TCPUDP))
@ -620,9 +646,23 @@ int direction;
if ((np->in_nip & ntohl(np->in_outmsk)) >
ntohl(np->in_outip))
np->in_nip = ntohl(np->in_outip) + 1;
/*
* Has the search wrapped around and come back to the
* start ?
*/
if ((np->in_pnext != 0) && (st_port == np->in_pnext) &&
(np->in_nip != 0) && (st_ip == np->in_nip)) {
KFREE(nat);
return NULL;
}
} while (nat_inlookup(fin->fin_ifp, flags, ip->ip_dst,
dport, in, port));
if (np->in_space > 1)
np->in_space--;
/* Setup the NAT table */
nat->nat_inip = ip->ip_src;
nat->nat_outip.s_addr = htonl(in.s_addr);
@ -666,12 +706,11 @@ int direction;
}
}
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
if (sum1 > sum2)
@ -690,12 +729,10 @@ int direction;
sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16);
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
/* Do it twice */
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
if (sum1 > sum2)
@ -722,6 +759,7 @@ int direction;
nat->nat_pkts = 0;
nat->nat_ifp = fin->fin_ifp;
nat->nat_dir = direction;
nat->nat_age = fr_defnatage;
if (direction == NAT_OUTBOUND) {
if (flags & IPN_TCPUDP)
tcp->th_sport = port;
@ -729,9 +767,9 @@ int direction;
if (flags & IPN_TCPUDP)
tcp->th_dport = nport;
}
ATOMIC_INC(nat_stats.ns_added);
ATOMIC_INC(nat_stats.ns_inuse);
ATOMIC_INC(np->in_use);
nat_stats.ns_added++;
nat_stats.ns_inuse++;
np->in_use++;
return nat;
}
@ -772,7 +810,7 @@ fr_info_t *fin;
return nat_inlookup(fin->fin_ifp, flags, oip->ip_dst,
tcp->th_dport, oip->ip_src, tcp->th_sport);
}
return nat_inlookup(fin->fin_ifp, 0, oip->ip_src, 0, oip->ip_dst, 0);
return nat_inlookup(fin->fin_ifp, 0, oip->ip_dst, 0, oip->ip_src, 0);
}
@ -785,6 +823,8 @@ ip_t *ip;
fr_info_t *fin;
int *nflags;
{
u_32_t sum1, sum2, sumd;
struct in_addr in;
icmphdr_t *icmp;
nat_t *nat;
ip_t *oip;
@ -792,10 +832,9 @@ int *nflags;
if (!(nat = nat_icmpinlookup(ip, fin)))
return NULL;
*nflags = IPN_ICMPERR;
icmp = (icmphdr_t *)fin->fin_dp;
oip = (ip_t *)((char *)icmp + 8);
oip = (ip_t *)&icmp->icmp_ip;
if (oip->ip_p == IPPROTO_TCP)
flags = IPN_TCP;
else if (oip->ip_p == IPPROTO_UDP)
@ -809,54 +848,61 @@ int *nflags;
* to only modify the checksum once for the port # and twice
* for the IP#.
*/
if (flags & IPN_TCPUDP) {
tcphdr_t *tcp = (tcphdr_t *)(oip + 1);
u_32_t sum1, sum2, sumd;
struct in_addr in;
if (nat->nat_dir == NAT_OUTBOUND) {
sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
in = nat->nat_inip;
oip->ip_src = in;
} else {
sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr));
in = nat->nat_outip;
oip->ip_dst = in;
}
sum2 = LONG_SUM(ntohl(in.s_addr));
CALC_SUMD(sum1, sum2, sumd);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_incksum(&oip->ip_sum, sumd);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_outcksum(&icmp->icmp_cksum, sumd);
} else {
fix_outcksum(&oip->ip_sum, sumd);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_incksum(&icmp->icmp_cksum, sumd);
}
if ((flags & IPN_TCPUDP) != 0) {
tcphdr_t *tcp;
/* XXX - what if this is bogus hl and we go off the end ? */
tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
if (nat->nat_dir == NAT_OUTBOUND) {
sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
in = nat->nat_outip;
oip->ip_src = in;
tcp->th_sport = nat->nat_outport;
if (tcp->th_sport != nat->nat_inport) {
sum1 = ntohs(tcp->th_sport);
sum2 = ntohs(nat->nat_inport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_sport = nat->nat_inport;
fix_outcksum(&icmp->icmp_cksum, sumd);
}
} else {
sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr));
in = nat->nat_inip;
oip->ip_dst = in;
tcp->th_dport = nat->nat_inport;
}
sum2 = LONG_SUM(in.s_addr);
CALC_SUMD(sum1, sum2, sumd);
sumd = (sumd & 0xffff) + (sumd >> 16);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_incksum(&oip->ip_sum, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
} else {
fix_outcksum(&oip->ip_sum, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
}
/*
* TCP checksum doesn't make it into the 1st eight
* bytes but UDP does.
*/
if (ip->ip_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&udp->uh_sum,
nat->nat_sumd);
else
fix_outcksum(&udp->uh_sum,
nat->nat_sumd);
if (tcp->th_dport != nat->nat_outport) {
sum1 = ntohs(tcp->th_dport);
sum2 = ntohs(nat->nat_outport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_dport = nat->nat_outport;
fix_incksum(&icmp->icmp_cksum, sumd);
}
}
} else
ip->ip_dst = nat->nat_outip;
}
nat->nat_age = fr_defnaticmpage;
return nat;
}
@ -1010,12 +1056,12 @@ fr_info_t *fin;
else
ifp = fin->fin_ifp;
if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
nflags = IPN_UDP;
if (nflags) {
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
sport = tcp->th_sport;
dport = tcp->th_dport;
@ -1063,7 +1109,7 @@ fr_info_t *fin;
#endif
break;
}
MUTEX_DOWNGRADE(&ipf_nat);
MUTEX_DOWNGRADE(&ipf_nat);
}
if (nat) {
@ -1087,11 +1133,14 @@ fr_info_t *fin;
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if (nflags && !(ip->ip_off & 0x1fff) &&
if (!(ip->ip_off & IP_OFFMASK) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (nat->nat_outport)
if ((nat->nat_outport != 0) &&
(nflags & IPN_TCPUDP)) {
tcp->th_sport = nat->nat_outport;
fin->fin_data[0] = ntohs(tcp->th_sport);
}
if (ip->ip_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
@ -1107,15 +1156,11 @@ fr_info_t *fin;
if (nat->nat_age == fr_tcpclosed)
nat->nat_age = fr_tcplastack;
MUTEX_EXIT(&ipf_rw);
} else if (ip->ip_p == IPPROTO_UDP) {
} else if (ip->ip_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
icmphdr_t *ic = (icmphdr_t *)tcp;
csump = &ic->icmp_cksum;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
@ -1126,12 +1171,12 @@ fr_info_t *fin;
nat->nat_sumd);
}
}
(void) ap_check(ip, tcp, fin, nat);
(void) ap_check(ip, fin, nat);
ATOMIC_INC(nat_stats.ns_mapped[1]);
RWLOCK_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat); /* READ */
return -2;
}
RWLOCK_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
return 0;
}
@ -1153,13 +1198,13 @@ fr_info_t *fin;
nat_t *nat;
int nflags = 0, natadd = 1;
if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
nflags = IPN_UDP;
if (nflags) {
tcp = (tcphdr_t *)((char *)ip + hlen);
if ((nflags & IPN_TCPUDP)) {
tcp = (tcphdr_t *)fin->fin_dp;
dport = tcp->th_dport;
sport = tcp->th_sport;
}
@ -1199,14 +1244,14 @@ fr_info_t *fin;
#endif
break;
}
MUTEX_DOWNGRADE(&ipf_nat);
MUTEX_DOWNGRADE(&ipf_nat);
}
if (nat) {
if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
ipfr_nat_newfrag(ip, fin, 0, nat);
MUTEX_ENTER(&ipf_rw);
(void) ap_check(ip, tcp, fin, nat);
(void) ap_check(ip, fin, nat);
MUTEX_ENTER(&ipf_rw);
if (nflags != IPN_ICMPERR)
nat->nat_age = fr_defnatage;
@ -1225,11 +1270,14 @@ fr_info_t *fin;
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if ((nflags & IPN_TCPUDP) && !(ip->ip_off & 0x1fff) &&
if (!(ip->ip_off & IP_OFFMASK) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (nat->nat_inport)
if ((nat->nat_inport != 0) &&
(nflags & IPN_TCPUDP)) {
tcp->th_dport = nat->nat_inport;
fin->fin_data[1] = ntohs(tcp->th_dport);
}
if (ip->ip_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
@ -1250,10 +1298,6 @@ fr_info_t *fin;
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
icmphdr_t *ic = (icmphdr_t *)tcp;
csump = &ic->icmp_cksum;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
@ -1265,10 +1309,10 @@ fr_info_t *fin;
}
}
ATOMIC_INC(nat_stats.ns_mapped[0]);
RWLOCK_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat); /* READ */
return -2;
}
RWLOCK_EXIT(&ipf_nat);
RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
return 0;
}
@ -1281,7 +1325,6 @@ void ip_natunload()
WRITE_ENTER(&ipf_nat);
(void) nat_clearlist();
(void) nat_flushtable();
(void) ap_unload();
RWLOCK_EXIT(&ipf_nat);
}
@ -1300,7 +1343,7 @@ void ip_natexpire()
SPL_NET(s);
WRITE_ENTER(&ipf_nat);
for (natp = &nat_instances; (nat = *natp); ) {
ATOMIC_DEC(nat->nat_age);
nat->nat_age--;
if (nat->nat_age) {
natp = &nat->nat_next;
continue;
@ -1310,11 +1353,8 @@ void ip_natexpire()
nat_log(nat, NL_EXPIRE);
#endif
nat_delete(nat);
ATOMIC_INC(nat_stats.ns_expire);
nat_stats.ns_expire++;
}
ap_expire();
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}
@ -1348,7 +1388,7 @@ void *ifp;
*/
sum1 = nat->nat_outip.s_addr;
if (nat_ifpaddr(nat, ifp, &in) == -1)
nat->nat_outip.s_addr = htonl(in.s_addr);
nat->nat_outip.s_addr = htonl(in.s_addr);
sum2 = nat->nat_outip.s_addr;
/*
@ -1358,10 +1398,8 @@ void *ifp;
* Do it twice
*/
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
/* Do it twice */
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
/* Because ~1 == -2, We really need ~1 == -1 */

View File

@ -1,14 +1,14 @@
/* $NetBSD: ip_nat.h,v 1.14 1998/05/29 20:24:38 veego Exp $ */
/* $NetBSD: ip_nat.h,v 1.15 1998/11/22 15:17:20 mrg Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
* Id: ip_nat.h,v 2.0.2.23.2.3 1998/05/23 18:52:44 darrenr Exp
* Id: ip_nat.h,v 2.0.2.23.2.6 1998/11/22 01:50:29 darrenr Exp
*/
#ifndef _NETINET_IP_NAT_H_
@ -49,17 +49,18 @@ typedef struct nat {
u_32_t nat_sumd;
u_32_t nat_ipsumd;
void *nat_data;
void *nat_aps; /* proxy session */
struct in_addr nat_inip;
struct in_addr nat_outip;
struct in_addr nat_oip; /* other ip */
U_QUAD_T nat_pkts;
U_QUAD_T nat_bytes;
u_short nat_oport; /* other port */
u_short nat_oport; /* other port */
u_short nat_inport;
u_short nat_outport;
u_short nat_use;
u_char nat_state[2];
struct ipnat *nat_ptr;
struct ipnat *nat_ptr; /* pointer back to the rule */
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_hstart[2];
@ -69,8 +70,8 @@ typedef struct nat {
typedef struct ipnat {
struct ipnat *in_next;
void *in_ifp;
void *in_apr;
void *in_ifp; /* interface pointer */
void *in_apr; /* proxy structure ptr */
u_int in_space;
u_int in_use;
struct in_addr in_nextip;
@ -101,8 +102,7 @@ typedef struct ipnat {
#define NAT_REDIRECT 0x02
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \
sizeof(int) + IFNAMSIZ + APR_LABELLEN + sizeof(char))
#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
typedef struct natlookup {
struct in_addr nl_inip;
@ -124,6 +124,7 @@ typedef struct natstat {
u_long ns_logfail;
nat_t **ns_table[2];
ipnat_t *ns_list;
void *ns_apslist;
} natstat_t;
#define IPN_ANY 0x00

View File

@ -1,25 +1,20 @@
/* $NetBSD: ip_proxy.c,v 1.14 1998/07/12 15:24:00 veego Exp $ */
/* $NetBSD: ip_proxy.c,v 1.15 1998/11/22 15:17:20 mrg Exp $ */
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.9 1998/06/06 14:38:15 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.15 1998/11/22 01:50:29 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
# define _KERNEL
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
@ -28,6 +23,11 @@ static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.9 1998/06/06 14:38:
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#ifndef linux
# include <sys/protosw.h>
#endif
@ -77,11 +77,9 @@ static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.0.2.11.2.9 1998/06/06 14:38:
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
static ap_session_t *ap_find __P((ip_t *, tcphdr_t *));
static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *,
static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *,
fr_info_t *, nat_t *));
static int ap_matchsrcdst __P((ap_session_t *, struct in_addr,
struct in_addr, void *, u_short, u_short));
int ap_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int inc));
#define AP_SESS_SIZE 53
@ -91,6 +89,7 @@ static int ap_matchsrcdst __P((ap_session_t *, struct in_addr,
#endif
ap_session_t *ap_sess_tab[AP_SESS_SIZE];
ap_session_t *ap_sess_list = NULL;
aproxy_t ap_proxies[] = {
#ifdef IPF_FTP_PROXY
{ "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_in, ippr_ftp_out },
@ -116,79 +115,32 @@ ipnat_t *nat;
}
static int
ap_matchsrcdst(aps, src, dst, tcp, sport, dport)
ap_session_t *aps;
struct in_addr src, dst;
void *tcp;
u_short sport, dport;
{
if (aps->aps_dst.s_addr == dst.s_addr) {
if ((aps->aps_src.s_addr == src.s_addr) &&
(!tcp || ((sport == aps->aps_sport) &&
(dport == aps->aps_dport))))
return 1;
} else if (aps->aps_dst.s_addr == src.s_addr) {
if ((aps->aps_src.s_addr == dst.s_addr) &&
(!tcp || ((sport == aps->aps_dport) &&
(dport == aps->aps_sport))))
return 1;
}
return 0;
}
static ap_session_t *ap_find(ip, tcp)
ip_t *ip;
tcphdr_t *tcp;
{
register u_char p = ip->ip_p;
register ap_session_t *aps;
register u_short sp, dp;
register u_long hv;
struct in_addr src, dst;
src = ip->ip_src, dst = ip->ip_dst;
sp = dp = 0; /* XXX gcc -Wunitialized */
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
hv *= 651733;
if (tcp) {
sp = tcp->th_sport;
dp = tcp->th_dport;
hv ^= (sp + dp);
hv *= 5;
}
hv %= AP_SESS_SIZE;
for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next)
if ((aps->aps_p == p) &&
ap_matchsrcdst(aps, src, dst, tcp, sp, dp))
break;
return aps;
}
/*
* Allocate a new application proxy structure and fill it in with the
* relevant details. call the init function once complete, prior to
* returning.
*/
static ap_session_t *ap_new_session(apr, ip, tcp, fin, nat)
static ap_session_t *ap_new_session(apr, ip, fin, nat)
aproxy_t *apr;
ip_t *ip;
tcphdr_t *tcp;
fr_info_t *fin;
nat_t *nat;
{
register ap_session_t *aps;
tcphdr_t *tcp;
u_short dport;
u_long hv;
u_int hv;
if (!apr || (apr && (apr->apr_flags & APR_DELETE)) ||
(ip->ip_p != apr->apr_p))
return NULL;
if (!(fin->fin_fi.fi_fl & FI_TCPUDP))
tcp = NULL;
else
tcp = (tcphdr_t *)fin->fin_dp;
dport = nat->nat_ptr->in_dport;
if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
return NULL;
@ -208,16 +160,20 @@ nat_t *nat;
aps->aps_src = ip->ip_src;
aps->aps_dst = ip->ip_dst;
aps->aps_p = ip->ip_p;
aps->aps_tout = 1200; /* XXX */
if (tcp) {
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
}
aps->aps_data = NULL;
aps->aps_psiz = 0;
aps->aps_next = ap_sess_tab[hv];
aps->aps_hnext = ap_sess_tab[hv];
aps->aps_next = ap_sess_list;
ap_sess_list = aps;
aps->aps_nat = nat;
aps->aps_hv = hv;
nat->nat_aps = aps;
ap_sess_tab[hv] = aps;
(void) (*apr->apr_init)(fin, ip, tcp, aps, nat);
(void) (*apr->apr_init)(fin, ip, aps, nat);
return aps;
}
@ -226,23 +182,21 @@ nat_t *nat;
* check to see if a packet should be passed through an active proxy routine
* if one has been setup for it.
*/
int ap_check(ip, tcp, fin, nat)
int ap_check(ip, fin, nat)
ip_t *ip;
tcphdr_t *tcp;
fr_info_t *fin;
nat_t *nat;
{
ap_session_t *aps;
aproxy_t *apr;
tcphdr_t *tcp = NULL;
u_32_t sum;
int err;
if (!(fin->fin_fi.fi_fl & FI_TCPUDP))
tcp = NULL;
if ((aps = ap_find(ip, tcp)) ||
(aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) {
if ((aps = nat->nat_aps) ||
(aps = ap_new_session(nat->nat_ptr->in_apr, ip, fin, nat))) {
if (ip->ip_p == IPPROTO_TCP) {
tcp = (tcphdr_t *)fin->fin_dp;
/*
* verify that the checksum is correct. If not, then
* don't do anything with this packet.
@ -257,32 +211,31 @@ nat_t *nat;
frstats[fin->fin_out].fr_tcpbad++;
return -1;
}
fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin,
tcp->th_sport == aps->aps_sport);
}
apr = aps->aps_apr;
err = 0;
if (fin->fin_out) {
if (apr->apr_outpkt)
err = (*apr->apr_outpkt)(fin, ip, tcp,
aps, nat);
err = (*apr->apr_outpkt)(fin, ip, aps, nat);
} else {
if (apr->apr_inpkt)
err = (*apr->apr_inpkt)(fin, ip, tcp,
aps, nat);
err = (*apr->apr_inpkt)(fin, ip, aps, nat);
}
if (err == 2) {
if (tcp != NULL) {
err = ap_fixseqack(fin, ip, aps, err);
#if SOLARIS && defined(_KERNEL)
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip,
tcp, ip->ip_len);
tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp,
ip->ip_len);
#else
tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip,
tcp, ip->ip_len);
#endif
err = 0;
}
return err;
aps->aps_bytes += ip->ip_len;
aps->aps_pkts++;
return 2;
}
return -1;
}
@ -314,38 +267,128 @@ aproxy_t *ap;
void aps_free(aps)
ap_session_t *aps;
{
if (aps->aps_data && aps->aps_psiz)
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
ap_session_t *a, **ap;
u_int hv;
if (!aps)
return;
void ap_unload()
{
ap_session_t *aps;
int i;
hv = aps->aps_hv;
for (i = 0; i < AP_SESS_SIZE; i++)
while ((aps = ap_sess_tab[i])) {
ap_sess_tab[i] = aps->aps_next;
aps_free(aps);
for (ap = ap_sess_tab + hv; (a = *ap); ap = &a->aps_hnext)
if (a == aps) {
*ap = a->aps_hnext;
break;
}
}
void ap_expire()
{
ap_session_t *aps, **apsp;
int i;
for (i = 0; i < AP_SESS_SIZE; i++)
for (apsp = &ap_sess_tab[i]; (aps = *apsp); ) {
aps->aps_tout--;
if (!aps->aps_tout) {
ap_sess_tab[i] = aps->aps_next;
aps_free(aps);
*apsp = aps->aps_next;
} else
apsp = &aps->aps_next;
for (ap = &ap_sess_list; (a = *ap); ap = &a->aps_next)
if (a == aps) {
*ap = a->aps_next;
break;
}
if (a) {
if (aps->aps_data && aps->aps_psiz)
KFREES(aps->aps_data, aps->aps_psiz);
KFREE(aps);
}
}
int ap_fixseqack(fin, ip, aps, inc)
fr_info_t *fin;
ip_t *ip;
ap_session_t *aps;
int inc;
{
int sel, ch = 0, out, nlen;
u_32_t seq1, seq2;
tcphdr_t *tcp;
tcp = (tcphdr_t *)fin->fin_dp;
out = fin->fin_out;
nlen = ip->ip_len;
nlen -= (ip->ip_hl << 2) + (tcp->th_off << 2);
if (out != 0) {
seq1 = (u_32_t)ntohl(tcp->th_seq);
sel = aps->aps_sel[out];
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel]))
sel = aps->aps_sel[out] = !sel;
if (aps->aps_seqoff[sel]) {
seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
if (seq1 > seq2) {
seq2 = aps->aps_seqoff[sel];
seq1 += seq2;
tcp->th_seq = htonl(seq1);
ch = 1;
}
}
if (inc && (seq1 > aps->aps_seqmin[!sel])) {
aps->aps_seqmin[!sel] = seq1 + nlen - 1;
aps->aps_seqoff[!sel] = aps->aps_seqoff[sel] + inc;
}
/***/
seq1 = ntohl(tcp->th_ack);
sel = aps->aps_sel[1 - out];
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel]))
sel = aps->aps_sel[1 - out] = !sel;
if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
seq2 = aps->aps_ackoff[sel];
tcp->th_ack = htonl(seq1 - seq2);
ch = 1;
}
} else {
seq1 = ntohl(tcp->th_seq);
sel = aps->aps_sel[out];
/* switch to other set ? */
if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
(seq1 > aps->aps_ackmin[!sel]))
sel = aps->aps_sel[out] = !sel;
if (aps->aps_ackoff[sel]) {
seq2 = aps->aps_ackmin[sel] -
aps->aps_ackoff[sel];
if (seq1 > seq2) {
seq2 = aps->aps_ackoff[sel];
seq1 += seq2;
tcp->th_seq = htonl(seq1);
ch = 1;
}
}
if (inc && (seq1 > aps->aps_ackmin[!sel])) {
aps->aps_ackmin[!sel] = seq1 + nlen - 1;
aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc;
}
/***/
seq1 = ntohl(tcp->th_ack);
sel = aps->aps_sel[1 - out];
/* switch to other set ? */
if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
(seq1 > aps->aps_seqmin[!sel]))
sel = aps->aps_sel[1 - out] = !sel;
if (aps->aps_seqoff[sel] && (seq1 > aps->aps_seqmin[sel])) {
seq2 = aps->aps_seqoff[sel];
tcp->th_ack = htonl(seq1 - seq2);
ch = 1;
}
}
return ch ? 2 : 0;
}

View File

@ -1,13 +1,13 @@
/* $NetBSD: ip_proxy.h,v 1.11 1998/05/17 17:07:26 veego Exp $ */
/* $NetBSD: ip_proxy.h,v 1.12 1998/11/22 15:17:20 mrg Exp $ */
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: ip_proxy.h,v 2.0.2.10.2.1 1997/11/27 09:33:27 darrenr Exp
* Id: ip_proxy.h,v 2.0.2.10.2.4 1998/11/22 01:50:30 darrenr Exp
*/
#ifndef _NETINET_IP_PROXY_H_
@ -28,9 +28,11 @@ struct ipnat;
typedef struct ap_tcp {
u_short apt_sport; /* source port */
u_short apt_dport; /* destination port */
short apt_sel; /* seqoff/after set selector */
short apt_sel[2]; /* {seq,ack}{off,min} set selector */
short apt_seqoff[2]; /* sequence # difference */
tcp_seq apt_after[2]; /* don't change seq-off until after this */
tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
short apt_ackoff[2]; /* sequence # difference */
tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
u_char apt_state[2]; /* connection state */
} ap_tcp_t;
@ -48,12 +50,14 @@ typedef struct ap_session {
struct ap_tcp apu_tcp;
struct ap_udp apu_udp;
} aps_un;
u_int aps_hv;
u_int aps_flags;
QUAD_T aps_bytes; /* bytes sent */
QUAD_T aps_pkts; /* packets sent */
u_long aps_tout; /* time left before expiring */
U_QUAD_T aps_bytes; /* bytes sent */
U_QUAD_T aps_pkts; /* packets sent */
void *aps_nat; /* pointer back to nat struct */
void *aps_data; /* private data */
int aps_psiz; /* size of private data */
struct ap_session *aps_hnext;
struct ap_session *aps_next;
} ap_session_t ;
@ -61,8 +65,10 @@ typedef struct ap_session {
#define aps_dport aps_un.apu_tcp.apt_dport
#define aps_sel aps_un.apu_tcp.apt_sel
#define aps_seqoff aps_un.apu_tcp.apt_seqoff
#define aps_after aps_un.apu_tcp.apt_after
#define aps_seqmin aps_un.apu_tcp.apt_seqmin
#define aps_state aps_un.apu_tcp.apt_state
#define aps_ackoff aps_un.apu_tcp.apt_ackoff
#define aps_ackmin aps_un.apu_tcp.apt_ackmin
typedef struct aproxy {
@ -70,11 +76,11 @@ typedef struct aproxy {
u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((fr_info_t *, ip_t *, tcphdr_t *,
int (* apr_init) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_inpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
int (* apr_inpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
int (* apr_outpkt) __P((fr_info_t *, ip_t *, tcphdr_t *,
int (* apr_outpkt) __P((fr_info_t *, ip_t *,
ap_session_t *, struct nat *));
} aproxy_t;
@ -82,14 +88,13 @@ typedef struct aproxy {
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern ap_session_t *ap_sess_list;
extern aproxy_t ap_proxies[];
extern int ap_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
extern void ap_unload __P((void));
extern void ap_free __P((aproxy_t *));
extern void aps_free __P((ap_session_t *));
extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
extern int ap_check __P((ip_t *, fr_info_t *, struct nat *));
extern aproxy_t *ap_match __P((u_char, char *));
extern void ap_expire __P((void));
#endif /* _NETINET_IP_PROXY_H_ */

View File

@ -1,7 +1,7 @@
/* $NetBSD: ip_state.c,v 1.15 1998/07/12 15:24:00 veego Exp $ */
/* $NetBSD: ip_state.c,v 1.16 1998/11/22 15:17:20 mrg Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,10 +9,15 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_state.c,v 2.0.2.24.2.18 1998/06/12 16:31:29 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip_state.c,v 2.0.2.24.2.25 1998/11/22 01:50:31 darrenr Exp ";
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__)
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#else
@ -21,10 +26,6 @@ static const char rcsid[] = "@(#)Id: ip_state.c,v 2.0.2.24.2.18 1998/06/12 16:31
# include <linux/module.h>
# endif
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
@ -84,7 +85,7 @@ ipstate_t *ips_table[IPSTATE_SIZE];
int ips_num = 0;
ips_stat_t ips_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern krwlock_t ipf_state;
extern KRWLOCK_T ipf_state;
extern kmutex_t ipf_rw;
#endif
@ -220,7 +221,7 @@ u_int pass;
register ipstate_t *is = &ips;
register u_int hv;
if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT))
if ((ip->ip_off & IP_OFFMASK) || (fin->fin_fi.fi_fl & FI_SHORT))
return -1;
if (ips_num == IPSTATE_MAX) {
ips_stats.iss_max++;
@ -366,8 +367,8 @@ ip_t *ip;
tcphdr_t *tcp;
{
register int seqskew, ackskew;
register u_short swin, dwin;
register tcp_seq seq, ack;
u_short win;
int source;
/*
@ -387,7 +388,7 @@ tcphdr_t *tcp;
*/
is->is_seq = seq;
seqskew = seq - is->is_seq;
ackskew = ack - is->is_ack;
ackskew = (ack - 1) - is->is_ack;
} else {
if (!is->is_ack)
/*
@ -395,7 +396,7 @@ tcphdr_t *tcp;
*/
is->is_ack = seq;
ackskew = seq - is->is_ack;
seqskew = ack - is->is_seq;
seqskew = (ack - 1) - is->is_seq;
}
/*
@ -411,23 +412,18 @@ tcphdr_t *tcp;
* window size of the connection, store these values and match
* the packet.
*/
if (source) {
swin = is->is_swin;
dwin = is->is_dwin;
} else {
dwin = is->is_swin;
swin = is->is_dwin;
}
if ((seqskew <= dwin) && (ackskew <= swin)) {
win = ntohs(tcp->th_win);
if ((seqskew <= is->is_dwin) && (ackskew <= is->is_swin)) {
if (source) {
is->is_seq = seq;
is->is_ack = ack;
is->is_swin = ntohs(tcp->th_win);
if (win != 0)
is->is_swin = win;
} else {
is->is_seq = ack;
is->is_ack = seq;
is->is_dwin = ntohs(tcp->th_win);
if (win != 0)
is->is_dwin = win;
}
ATOMIC_INC(ips_stats.iss_hits);
is->is_pkts++;
@ -526,7 +522,7 @@ fr_info_t *fin;
tcphdr_t *tcp;
u_int hv, hlen, pass;
if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT))
if ((ip->ip_off & IP_OFFMASK) || (fin->fin_fi.fi_fl & FI_SHORT))
return 0;
hlen = fin->fin_hlen;
@ -654,6 +650,7 @@ void fr_stateunload()
*isp = is->is_next;
KFREE(is);
}
ips_num = 0;
RWLOCK_EXIT(&ipf_state);
}
@ -790,16 +787,20 @@ u_short type;
size_t sizes[1];
int types[1];
ipsl.isl_type = type;
ipsl.isl_pkts = is->is_pkts;
ipsl.isl_bytes = is->is_bytes;
ipsl.isl_src = is->is_src;
ipsl.isl_dst = is->is_dst;
ipsl.isl_p = is->is_p;
ipsl.isl_flags = is->is_flags;
ipsl.isl_type = type;
if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) {
ipsl.isl_sport = is->is_sport;
ipsl.isl_dport = is->is_dport;
if (ipsl.isl_p == IPPROTO_TCP) {
ipsl.isl_state[0] = is->is_state[0];
ipsl.isl_state[1] = is->is_state[1];
}
} else if (ipsl.isl_p == IPPROTO_ICMP)
ipsl.isl_itype = is->is_icmp.ics_type;
else {

View File

@ -1,14 +1,14 @@
/* $NetBSD: ip_state.h,v 1.12 1998/05/29 20:24:38 veego Exp $ */
/* $NetBSD: ip_state.h,v 1.13 1998/11/22 15:17:20 mrg Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* Id: ip_state.h,v 2.0.2.14.2.6 1998/05/24 05:18:04 darrenr Exp
* Id: ip_state.h,v 2.0.2.14.2.8 1998/11/22 01:50:32 darrenr Exp
*/
#ifndef _NETINET_IP_STATE_H_
@ -90,6 +90,7 @@ typedef struct ipslog {
struct in_addr isl_dst;
u_char isl_p;
u_char isl_flags;
u_char isl_state[2];
u_short isl_type;
union {
u_short isl_filler[2];

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ipf.5,v 1.5 1998/01/09 08:09:23 perry Exp $
.\" $NetBSD: ipf.5,v 1.6 1998/11/22 15:21:54 mrg Exp $
.\"
.TH IPF 5
.SH NAME
@ -421,7 +421,7 @@ The "fall-through" rule parsing allows for effects such as this:
.nf
block in from any to any port < 6000
pass in from any to any port >= 6000
block in from any to port > 6003
block in from any to any port > 6003
.fi
.PP
which sets up the range 6000-6003 as being permitted and all others being
@ -448,9 +448,9 @@ all inbound packets, we would do something like:
.LP
.nf
block in all
block in on le0 quick all head 100
block in on le1 quick all head 200
block in on lo0 quick all head 300
block in quick on le0 all head 100
block in quick on le1 all head 200
block in quick on lo0 all head 300
.fi
.PP

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipf.c,v 1.14 1998/05/29 20:46:45 veego Exp $ */
/* $NetBSD: ipf.c,v 1.15 1998/11/22 15:21:54 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -42,7 +42,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ipf.c,v 2.0.2.13.2.4 1998/05/23 14:29:44 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ipf.c,v 2.0.2.13.2.5 1998/11/22 01:50:32 darrenr Exp ";
#endif
static void frsync __P((void));

View File

@ -1,7 +1,7 @@
/* $NetBSD: fils.c,v 1.14 1998/07/12 15:01:49 veego Exp $ */
/* $NetBSD: fils.c,v 1.15 1998/11/22 15:21:54 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -48,7 +48,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)Id: fils.c,v 2.0.2.25.2.4 1998/06/08 06:58:12 darrenr Exp ";
static const char rcsid[] = "@(#)Id: fils.c,v 2.0.2.25.2.7 1998/11/22 01:50:17 darrenr Exp ";
#endif
#ifdef _PATH_UNIX
#define VMUNIX _PATH_UNIX
@ -221,6 +221,10 @@ struct friostat *fp;
#if SOLARIS
PRINTF("dropped packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_drop, fp->f_st[1].fr_drop);
PRINTF("non-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_notdata, fp->f_st[1].fr_notdata);
PRINTF("no-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_nodata, fp->f_st[1].fr_nodata);
PRINTF("non-ip packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_notip, fp->f_st[1].fr_notip);
PRINTF(" bad packets:\t\tin %lu\tout %lu\n",
@ -392,22 +396,21 @@ ips_stat_t *ipsp;
ips.is_pkts, ips.is_bytes);
#endif
if (ips.is_p == IPPROTO_TCP)
PRINTF("\t%hu -> %hu %lu:%lu %hu:%hu\n",
PRINTF("\t%hu -> %hu %lu:%lu %hu:%hu",
ntohs(ips.is_sport),
ntohs(ips.is_dport),
ips.is_seq, ips.is_ack,
ips.is_swin, ips.is_dwin);
else if (ips.is_p == IPPROTO_UDP)
PRINTF(" %hu -> %hu\n", ntohs(ips.is_sport),
PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
ntohs(ips.is_dport));
else if (ips.is_p == IPPROTO_ICMP)
PRINTF(" %hu %hu %d\n", ips.is_icmp.ics_id,
PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
ips.is_icmp.ics_seq,
ips.is_icmp.ics_type);
/* phil@ultimate.com ... */
PRINTF("\t");
/* from "printfr()" */
PRINTF("\n\t");
if (ips.is_pass & FR_PASS) {
PRINTF("pass");
} else if (ips.is_pass & FR_BLOCK) {
@ -447,7 +450,6 @@ ips_stat_t *ipsp;
if (ips.is_pass & FR_KEEPSTATE)
PRINTF(" keep state");
PRINTF("\n");
/* ... phil@ultimate.com */
PRINTF("\tpkt_flags & %x = %x,\t", ips.is_flags & 0xf,
ips.is_flags >> 4);

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipt.c,v 1.8 1997/11/14 12:58:06 mrg Exp $ */
/* $NetBSD: ipt.c,v 1.9 1998/11/22 15:21:55 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -55,7 +55,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)Id: ipt.c,v 2.0.2.12.2.1 1997/11/12 10:58:10 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ipt.c,v 2.0.2.12.2.2 1998/11/22 01:50:37 darrenr Exp ";
#endif
extern char *optarg;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ipmon.8,v 1.5 1998/05/17 16:51:41 veego Exp $
.\" $NetBSD: ipmon.8,v 1.6 1998/11/22 15:21:55 mrg Exp $
.\"
.TH ipmon 8
.SH NAME
@ -66,7 +66,8 @@ as for \fB-o\fP.
.TP
.B \-s
Packet information read in will be sent through syslogd rather than
saved to a file. The following levels are used:
saved to a file. The default facility when compiled and installed is
\fBlocal0\fP. The following levels are used:
.TP
.B "\-S <device>"
Set the logfile to be opened for reading state log records from to <device>.
@ -92,6 +93,9 @@ Treat the logfile as being composed of state log records.
.B \-t
read the input file/device in a manner akin to tail(1).
.TP
.B \-v
show tcp window, ack and sequence fields.
.TP
.B \-x
show the packet data in hex.
.TP

View File

@ -1,17 +1,29 @@
/* $NetBSD: ipmon.c,v 1.15 1998/05/29 20:50:55 veego Exp $ */
/* $NetBSD: ipmon.c,v 1.16 1998/11/22 15:21:55 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1997 Darren Reed";
static const char rcsid[] = "@(#)Id: ipmon.c,v 2.0.2.29.2.9 1998/05/23 14:29:45 darrenr Exp ";
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1998 Darren Reed";
static const char rcsid[] = "@(#)Id: ipmon.c,v 2.0.2.29.2.20 1998/11/22 01:50:35 darrenr Exp ";
#endif
#ifndef SOLARIS
#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun)
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@ -26,18 +38,13 @@ static const char rcsid[] = "@(#)Id: ipmon.c,v 2.0.2.29.2.9 1998/05/23 14:29:45
#include <sys/filio.h>
#include <sys/byteorder.h>
#endif
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/tcp_fsm.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@ -87,6 +94,15 @@ struct flags tcpfl[] = {
{ 0, '\0' }
};
#if SOLARIS
static char *pidfile = "/etc/opt/ipf/ipmon.pid";
#else
# if BSD >= 199306
static char *pidfile = "/var/run/ipmon.pid";
# else
static char *pidfile = "/etc/ipmon.pid";
# endif
#endif
static char line[2048];
static int opts = 0;
@ -101,6 +117,7 @@ static void print_ipflog __P((FILE *, char *, int));
static void print_natlog __P((FILE *, char *, int));
static void print_statelog __P((FILE *, char *, int));
static void dumphex __P((FILE *, u_char *, int));
static void write_pid __P((char *file));
static int read_log __P((int, int *, char *, int, FILE *));
char *hostname __P((int, struct in_addr));
char *portname __P((int, char *, u_short));
@ -126,8 +143,8 @@ static void logopts __P((int, char *));
#endif
static void handlehup(unused)
int unused;
void handlehup(sig)
int sig;
{
FILE *fp;
@ -274,7 +291,7 @@ int blen;
strcpy(t, "NAT:MAP ");
else if (nl->nl_type == NL_NEWRDR)
strcpy(t, "NAT:RDR ");
else if (nl->nl_type == ISL_EXPIRE)
else if (nl->nl_type == NL_EXPIRE)
strcpy(t, "NAT:EXPIRE ");
else
sprintf(t, "Type: %d ", nl->nl_type);
@ -339,8 +356,14 @@ int blen;
if (sl->isl_type == ISL_NEW)
strcpy(t, "STATE:NEW ");
else if (sl->isl_type == ISL_EXPIRE)
strcpy(t, "STATE:EXPIRE ");
else if (sl->isl_type == ISL_EXPIRE) {
if (sl->isl_state[0] > TCPS_ESTABLISHED ||
sl->isl_state[1] > TCPS_ESTABLISHED)
strcpy(t, "STATE:CLOSE ");
else
strcpy(t, "STATE:EXPIRE ");
} else if (sl->isl_type == ISL_FLUSH)
strcpy(t, "STATE:FLUSH ");
else
sprintf(t, "Type: %d ", sl->isl_type);
t += strlen(t);
@ -444,7 +467,7 @@ char *buf;
int blen;
{
struct protoent *pr;
struct tcphdr *tp;
tcphdr_t *tp;
struct icmp *ic;
struct tm *tm;
char c[3], pname[8], *t, *proto;
@ -531,8 +554,9 @@ int blen;
(void) strcat(line, c);
t = line + strlen(line);
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !(ip->ip_off & 0x1fff)) {
tp = (struct tcphdr *)((char *)ip + hl);
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) &&
!(ip->ip_off & IP_OFFMASK)) {
tp = (tcphdr_t *)((char *)ip + hl);
if (!(ipf->fl_flags & (FI_SHORT << 16))) {
(void) sprintf(t, "%s,%s -> ",
hostname(res, ip->ip_src),
@ -549,6 +573,13 @@ int blen;
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
*t++ = tcpfl[i].flag;
if (opts & OPT_VERBOSE) {
(void) sprintf(t, " %lu %lu %hu",
(u_long)tp->th_seq,
(u_long)tp->th_ack,
tp->th_win);
t += strlen(t);
}
}
if (opts & OPT_VERBOSE) {
(void) sprintf(t, " %lu %lu %hu",
@ -577,7 +608,7 @@ int blen;
ic->icmp_type == ICMP_REDIRECT ||
ic->icmp_type == ICMP_TIMXCEED) {
ipc = &ic->icmp_ip;
tp = (struct tcphdr *)((char *)ipc + hl);
tp = (tcphdr_t *)((char *)ipc + hl);
p = (u_short)ipc->ip_p;
pr = getprotobynumber((int)p);
@ -603,11 +634,12 @@ int blen;
(void) sprintf(t, "%s PR %s len %hu (%hu)",
hostname(res, ip->ip_dst), proto, hl, ip->ip_len);
t += strlen(t);
if (ip->ip_off & 0x1fff)
if (ip->ip_off & IP_OFFMASK)
(void) sprintf(t, " frag %s%s%hu@%hu",
ip->ip_off & IP_MF ? "+" : "",
ip->ip_off & IP_DF ? "-" : "",
ip->ip_len - hl, (ip->ip_off & 0x1fff) << 3);
ip->ip_len - hl,
(ip->ip_off & IP_OFFMASK) << 3);
}
t += strlen(t);
@ -642,6 +674,25 @@ char *prog;
}
static void write_pid(file)
char *file;
{
FILE *fp = NULL;
int fd;
if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0)
fp = fdopen(fd, "w");
if (!fp) {
close(fd);
fprintf(stderr, "unable to open/create pid file: %s\n", file);
return;
}
fprintf(fp, "%d", getpid());
fclose(fp);
close(fd);
}
static void flushlogs(file, log)
char *file;
FILE *log;
@ -713,7 +764,7 @@ char *argv[];
int fd[3], doread, n, i;
int tr, nr, regular[3], c;
int fdt[3], devices = 0, make_daemon = 0;
char buf[512], *iplfile[3];
char buf[512], *iplfile[3], *s;
extern int optind;
extern char *optarg;
@ -723,11 +774,14 @@ char *argv[];
iplfile[1] = IPNAT_NAME;
iplfile[2] = IPSTATE_NAME;
while ((c = getopt(argc, argv, "?aDf:FhI:nN:o:O:sS:tvxX")) != -1)
while ((c = getopt(argc, argv, "?aDf:FhnN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
case 'a' :
opts |= OPT_ALL;
fdt[0] = IPL_LOGIPF;
fdt[1] = IPL_LOGNAT;
fdt[2] = IPL_LOGSTATE;
break;
case 'D' :
make_daemon = 1;
@ -763,8 +817,14 @@ char *argv[];
case 'p' :
opts |= OPT_PORTNUM;
break;
case 'P' :
pidfile = optarg;
break;
case 's' :
openlog(argv[0], LOG_NDELAY|LOG_PID, LOGFAC);
s = strrchr(argv[0], '/');
if (s == NULL)
s = argv[0];
openlog(s, LOG_NDELAY|LOG_PID, LOGFAC);
opts |= OPT_SYSLOG;
break;
case 'S' :
@ -834,11 +894,13 @@ char *argv[];
if (make_daemon && (log != stdout)) {
if (fork() > 0)
exit(0);
write_pid(pidfile);
close(0);
close(1);
close(2);
setsid();
}
} else
write_pid(pidfile);
signal(SIGHUP, handlehup);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ipnat.8,v 1.4 1998/01/09 08:09:34 perry Exp $
.\" $NetBSD: ipnat.8,v 1.5 1998/11/22 15:21:55 mrg Exp $
.\"
.TH IPNAT 8
.SH NAME
@ -21,11 +21,11 @@ which they appear when given to \fBipnat\fP.
.SH OPTIONS
.TP
.B \-C
delete all entries in the current NAT listing (NAT rules)
delete all entries in the current NAT rule listing (NAT rules)
.TP
.B \-F
delete all active entries in the current NAT table (currently active
NAT mappings)
delete all active entries in the current NAT translation table (currently
active NAT mappings)
.TP
.B \-l
Show the list of current NAT table entry mappings.
@ -41,7 +41,8 @@ Retrieve and display NAT statistics
Remove matching NAT rules rather than add them to the internal lists
.TP
.B \-v
Turn verbose mode on. Displays information relating to rule processing.
Turn verbose mode on. Displays information relating to rule processing
and active rules/table entries.
.DT
.SH FILES
/dev/ipnat

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipnat.c,v 1.19 1998/07/12 15:02:44 veego Exp $ */
/* $NetBSD: ipnat.c,v 1.20 1998/11/22 15:21:55 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -64,7 +64,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)Id: ipnat.c,v 2.0.2.21.2.8 1998/06/06 14:39:56 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ipnat.c,v 2.0.2.21.2.16 1998/11/22 01:50:36 darrenr Exp ";
#endif
@ -74,6 +74,7 @@ static const char rcsid[] = "@(#)Id: ipnat.c,v 2.0.2.21.2.8 1998/06/06 14:39:56
extern char *optarg;
void printaps __P((ap_session_t *, int opts));
ipnat_t *parse __P((char *));
u_32_t hostnum __P((char *, int *));
u_32_t hostmask __P((char *));
@ -192,8 +193,9 @@ ipnat_t *np;
int verbose;
void *ptr;
{
int bits;
struct protoent *pr;
struct servent *sv;
int bits;
switch (np->in_redir)
{
@ -250,12 +252,22 @@ void *ptr;
else
printf("%s", inet_ntoa(np->in_out[1]));
if (*np->in_plabel) {
pr = getprotobynumber(np->in_p);
printf(" proxy port");
if (np->in_dport)
printf(" %hu", ntohs(np->in_dport));
if (np->in_dport != 0) {
if (pr != NULL)
sv = getservbyport(np->in_dport,
pr->p_name);
else
sv = getservbyport(np->in_dport, NULL);
if (sv != NULL)
printf(" %s", sv->s_name);
else
printf(" %hu", ntohs(np->in_dport));
}
printf(" %.*s/", (int)sizeof(np->in_plabel),
np->in_plabel);
if ((pr = getprotobynumber(np->in_p)))
if (pr != NULL)
fputs(pr->p_name, stdout);
else
printf("%d", np->in_p);
@ -271,10 +283,49 @@ void *ptr;
ntohs(np->in_pmax));
}
printf("\n");
if (verbose)
printf("\t%p %u %s %d %x\n", np->in_ifp,
np->in_space, inet_ntoa(np->in_nextip),
np->in_pnext, np->in_flags);
if (verbose) {
printf("\tifp %p space %u nextip %s pnext %d",
np->in_ifp, np->in_space,
inet_ntoa(np->in_nextip), np->in_pnext);
printf(" flags %x use %u\n",
np->in_flags, np->in_use);
}
}
}
void printaps(aps, opts)
ap_session_t *aps;
int opts;
{
ap_session_t ap;
aproxy_t apr;
if (kmemcpy((char *)&ap, (long)aps, sizeof(ap)))
return;
if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr)))
return;
printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label,
apr.apr_p, apr.apr_ref, apr.apr_flags);
printf("\t\t%d %s -> ", ap.aps_p, inet_ntoa(ap.aps_src));
printf("%s [%#x ", inet_ntoa(ap.aps_dst), ap.aps_flags);
#ifdef USE_QUAD_T
printf("%qu %qu", ap.aps_bytes, ap.aps_pkts);
#else
printf("%lu %lu", ap.aps_bytes, ap.aps_pkts);
#endif
printf(" %p[%d]]\n", ap.aps_data, ap.aps_psiz);
if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) {
printf("\t\t%hu -> %hu state[%d,%d], sel[%d,%d]\n",
ap.aps_sport, ap.aps_dport,
ap.aps_state[0], ap.aps_state[1],
ap.aps_sel[0], ap.aps_sel[1]);
printf("\t\tseq: off %hd/%hd min %x/%x\n",
ap.aps_seqoff[0], ap.aps_seqoff[1],
ap.aps_seqmin[0], ap.aps_seqmin[1]);
printf("\t\tack: off %hd/%hd min %x/%x\n",
ap.aps_ackoff[0], ap.aps_ackoff[1],
ap.aps_ackmin[0], ap.aps_ackmin[1]);
}
}
@ -371,13 +422,28 @@ int fd, opts;
ntohs(nat.nat_outport));
printf(" [%s %hu]", inet_ntoa(nat.nat_oip),
ntohs(nat.nat_oport));
printf(" %ld %hu %x", nat.nat_age,
nat.nat_use, nat.nat_sumd);
#if SOLARIS
printf(" %lx", nat.nat_ipsumd);
if (opts & OPT_VERBOSE) {
printf("\n\tage %lu use %hu sumd %x",
nat.nat_age, nat.nat_use,
nat.nat_sumd);
printf(" bkt %d flags %x ",
i, nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
nat.nat_bytes, nat.nat_pkts);
#else
printf("bytes %lu pkts %lu",
nat.nat_bytes, nat.nat_pkts);
#endif
#if SOLARIS
printf(" %lx", nat.nat_ipsumd);
#endif
}
putchar('\n');
if (nat.nat_aps)
printaps(nat.nat_aps, opts);
}
free(nt[0]);
}
}
@ -600,6 +666,11 @@ char *line;
if (*dnetm == '/')
*dnetm++ = '\0';
} else {
if (strrchr(dhost, '/') != NULL) {
fprintf(stderr, "No netmask supported in %s\n",
"destination host for redirect");
return NULL;
}
/* If it's a in_redir, expect target port */
if (!(s = strtok(NULL, " \t"))) {
fprintf(stderr, "missing fields (destination port)\n");

View File

@ -1,7 +1,7 @@
/* $NetBSD: resend.c,v 1.5 1997/10/30 16:10:24 mrg Exp $ */
/* $NetBSD: resend.c,v 1.6 1998/11/22 15:21:55 mrg Exp $ */
/*
* resend.c (C) 1995-1997 Darren Reed
* resend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -14,7 +14,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: resend.c,v 2.0.2.12 1997/10/23 11:42:46 darrenr Exp ";
static const char rcsid[] = "@(#)Id: resend.c,v 2.0.2.12.2.1 1998/11/22 01:51:19 darrenr Exp ";
#endif
#include <stdio.h>
#include <netdb.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: 44arp.c,v 1.5 1997/10/30 16:10:27 mrg Exp $ */
/* $NetBSD: 44arp.c,v 1.6 1998/11/22 15:21:55 mrg Exp $ */
/*
* Based upon 4.4BSD's /usr/sbin/arp
@ -28,6 +28,7 @@
# include <net/if_var.h>
#endif
#include "ipsend.h"
#include "iplang.h"
/*
@ -67,6 +68,11 @@ char *addr, *eaddr;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
#ifdef IPSEND
if (arp_getipv4(ip, ether) == 0)
return 0;
#endif
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;

View File

@ -1,7 +1,7 @@
/* $NetBSD: ip.c,v 1.7 1998/05/17 16:56:20 veego Exp $ */
/* $NetBSD: ip.c,v 1.8 1998/11/22 15:21:55 mrg Exp $ */
/*
* ip.c (C) 1995-1997 Darren Reed
* ip.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995";
static const char rcsid[] = "@(#)Id: ip.c,v 2.0.2.11.2.3 1997/12/21 12:17:37 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ip.c,v 2.0.2.11.2.4 1998/11/22 01:51:15 darrenr Exp ";
#endif
#include <errno.h>
#include <stdio.h>

View File

@ -1,14 +1,14 @@
/* $NetBSD: iplang_l.l,v 1.5 1998/05/17 16:53:24 veego Exp $ */
/* $NetBSD: iplang_l.l,v 1.6 1998/11/22 15:21:55 mrg Exp $ */
%{
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: iplang_l.l,v 2.0.2.15.2.5 1997/12/28 01:32:13 darrenr Exp
* Id: iplang_l.l,v 2.0.2.15.2.6 1998/11/22 01:51:03 darrenr Exp
*/
#include <stdio.h>
#include <string.h>

View File

@ -1,14 +1,14 @@
/* $NetBSD: iplang_y.y,v 1.7 1998/05/29 20:46:47 veego Exp $ */
/* $NetBSD: iplang_y.y,v 1.8 1998/11/22 15:21:55 mrg Exp $ */
%{
/*
* Copyright (C) 1997 by Darren Reed.
* Copyright (C) 1997-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Id: iplang_y.y,v 2.0.2.18.2.7 1998/05/23 14:29:53 darrenr Exp
* Id: iplang_y.y,v 2.0.2.18.2.10 1998/11/22 01:51:04 darrenr Exp
*/
#include <stdio.h>
@ -166,6 +166,7 @@ void end_tcp __P((void));
void end_data __P((void));
void yyerror __P((char *));
void iplang __P((FILE *));
int arp_getipv4 __P((char *ip, char *addr));
int yyparse __P((void));
%}
%union {
@ -1433,6 +1434,21 @@ char **arg;
}
int arp_getipv4(ip, addr)
char *ip;
char *addr;
{
arp_t *a;
for (a = arplist; a; a = a->arp_next)
if (!bcmp(ip, (char *)&a->arp_addr, 4)) {
bcopy((char *)&a->arp_eaddr, addr, 6);
return 0;
}
return -1;
}
void reset_send()
{
sending.snd_if = iflist;

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipsend.c,v 1.7 1998/07/06 07:02:57 mrg Exp $ */
/* $NetBSD: ipsend.c,v 1.8 1998/11/22 15:21:55 mrg Exp $ */
/*
* ipsend.c (C) 1995-1997 Darren Reed
* ipsend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -14,7 +14,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ipsend.c,v 2.0.2.19.2.1 1998/05/14 14:01:19 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ipsend.c,v 2.0.2.19.2.2 1998/11/22 01:51:16 darrenr Exp ";
#endif
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipsend.h,v 1.4 1997/10/30 16:10:35 mrg Exp $ */
/* $NetBSD: ipsend.h,v 1.5 1998/11/22 15:21:55 mrg Exp $ */
/*
* ipsend.h (C) 1997 Darren Reed
* ipsend.h (C) 1997-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain

View File

@ -1,7 +1,7 @@
/* $NetBSD: ipsopt.c,v 1.4 1997/11/01 09:12:23 enami Exp $ */
/* $NetBSD: ipsopt.c,v 1.5 1998/11/22 15:21:56 mrg Exp $ */
/*
* Copyright (C) 1995-1997 by Darren Reed.
* Copyright (C) 1995-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ipsopt.c,v 2.0.2.10 1997/09/28 07:13:28 darrenr Exp ";
static const char rcsid[] = "@(#)Id: ipsopt.c,v 2.0.2.10.2.1 1998/11/22 01:51:17 darrenr Exp ";
#endif
#include <stdio.h>
#include <string.h>

View File

@ -1,7 +1,7 @@
/* $NetBSD: sbpf.c,v 1.5 1997/10/30 16:10:38 mrg Exp $ */
/* $NetBSD: sbpf.c,v 1.6 1998/11/22 15:21:56 mrg Exp $ */
/*
* (C)opyright 1995-1997 Darren Reed. (from tcplog)
* (C)opyright 1995-1998 Darren Reed. (from tcplog)
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -41,7 +41,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: sbpf.c,v 2.0.2.7 1997/10/23 11:42:47 darrenr Exp ";
static const char rcsid[] = "@(#)Id: sbpf.c,v 2.0.2.7.2.1 1998/11/22 01:51:19 darrenr Exp ";
#endif
/*

View File

@ -1,7 +1,7 @@
/* $NetBSD: iptest.c,v 1.7 1998/07/06 07:02:40 mrg Exp $ */
/* $NetBSD: iptest.c,v 1.8 1998/11/22 15:21:56 mrg Exp $ */
/*
* ipsend.c (C) 1995-1997 Darren Reed
* ipsend.c (C) 1995-1998 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
@ -14,7 +14,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: iptest.c,v 2.0.2.8.2.1 1997/11/28 03:36:18 darrenr Exp ";
static const char rcsid[] = "@(#)Id: iptest.c,v 2.0.2.8.2.2 1998/11/22 01:51:17 darrenr Exp ";
#endif
#include <stdio.h>
#include <netdb.h>

View File

@ -1,7 +1,7 @@
/* $NetBSD: iptests.c,v 1.6 1998/05/17 16:54:28 veego Exp $ */
/* $NetBSD: iptests.c,v 1.7 1998/11/22 15:21:56 mrg Exp $ */
/*
* Copyright (C) 1993-1997 by Darren Reed.
* Copyright (C) 1993-1998 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)Id: iptests.c,v 2.0.2.13.2.2 1997/12/21 12:17:38 darrenr Exp ";
static const char rcsid[] = "@(#)Id: iptests.c,v 2.0.2.13.2.3 1998/11/22 01:51:17 darrenr Exp ";
#endif
#include <stdio.h>
#include <unistd.h>

View File

@ -1,7 +1,7 @@
/* $NetBSD: sock.c,v 1.8 1998/05/17 16:54:28 veego Exp $ */
/* $NetBSD: sock.c,v 1.9 1998/11/22 15:21:56 mrg Exp $ */
/*
* sock.c (C) 1995-1997 Darren Reed
* sock.c (C) 1995-1998 Darren Reed
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@ -9,7 +9,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.0.2.9.2.1 1997/11/28 03:36:01 darrenr Exp ";
static const char rcsid[] = "@(#)Id: sock.c,v 2.0.2.9.2.2 1998/11/22 01:51:21 darrenr Exp ";
#endif
#include <stdio.h>
#include <unistd.h>

View File

@ -56,7 +56,7 @@ pass out quick on lo0 all
#
# Allow all outgoing connections (SSH, TELNET, FTP, WWW, gopher, etc)
#
pass in log quick proto tcp all SA flags S/SA keep state group 200
pass in log quick proto tcp all flags S/SA keep state group 200
#
# Support all UDP `connections' initiated from inside.
#