summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordm <dm@cvs.openbsd.org>1996-07-18 05:01:10 +0000
committerdm <dm@cvs.openbsd.org>1996-07-18 05:01:10 +0000
commit746e8c40786f598f5da99fed9714ae7961393281 (patch)
tree7fa485ff1f4c0076948de7742853326232fa0cc1
parent6764f712dd3ffd42fd940f9e87d2a9109743c72d (diff)
ipfilter 3.1.0
-rw-r--r--sys/netinet/fil.c135
-rw-r--r--sys/netinet/in_proto.c7
-rw-r--r--sys/netinet/ip_fil.c339
-rw-r--r--sys/netinet/ip_fil.h271
-rw-r--r--sys/netinet/ip_fil_compat.h216
-rw-r--r--sys/netinet/ip_frag.c2
-rw-r--r--sys/netinet/ip_frag.h6
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet/ip_nat.c89
-rw-r--r--sys/netinet/ip_nat.h5
-rw-r--r--sys/netinet/ip_state.c27
-rw-r--r--sys/netinet/ip_state.h6
-rw-r--r--usr.sbin/ipftest/ipft_ef.c1
-rw-r--r--usr.sbin/ipftest/ipft_hx.c2
-rw-r--r--usr.sbin/ipftest/ipft_pc.c4
-rw-r--r--usr.sbin/ipftest/ipft_sn.c4
-rw-r--r--usr.sbin/ipftest/ipft_td.c1
-rw-r--r--usr.sbin/ipftest/ipft_tx.c128
-rw-r--r--usr.sbin/ipftest/ipftest.18
-rw-r--r--usr.sbin/ipftest/ipt.c42
-rw-r--r--usr.sbin/ipftest/ipt.h1
-rw-r--r--usr.sbin/ipftest/pcap.h1
-rw-r--r--usr.sbin/ipftest/snoop.h1
-rw-r--r--usr.sbin/ipmon/ipmon.c26
-rw-r--r--usr.sbin/ipsend/ipresend/Makefile8
-rw-r--r--usr.sbin/ipsend/ipresend/ipresend.c47
26 files changed, 950 insertions, 433 deletions
diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c
index f84114c3239..4cba4d8af2d 100644
--- a/sys/netinet/fil.c
+++ b/sys/netinet/fil.c
@@ -6,7 +6,8 @@
* to the original author and the contributors.
*/
#ifndef lint
-static char sccsid[] = "@(#)fil.c 1.32 4/10/96 (C) 1993-1996 Darren Reed";
+static char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
+static char rcsid[] = "$Id: fil.c,v 1.5 1996/07/18 05:00:55 dm Exp $";
#endif
#include <sys/errno.h>
@@ -45,6 +46,7 @@ static char sccsid[] = "@(#)fil.c 1.32 4/10/96 (C) 1993-1996 Darren Reed";
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "ip_fil.h"
+#include "ip_fil_compat.h"
#include "ip_nat.h"
#include "ip_frag.h"
#include "ip_state.h"
@@ -151,7 +153,7 @@ struct optlist secopt[8] = {
* compact the IP header into a structure which contains just the info.
* which is useful for comparing IP headers with.
*/
-fr_info_t *fr_makefrip(hlen, ip, fin)
+void fr_makefrip(hlen, ip, fin)
int hlen;
ip_t *ip;
fr_info_t *fin;
@@ -163,9 +165,7 @@ fr_info_t *fin;
int i, mv, ol, off;
u_char *s, opt;
- fin->fin_dp = ((char *)ip + hlen);
- tcp = (tcphdr_t *)fin->fin_dp;
- fi->fi_fl = 0;
+ fin->fin_fr = NULL;
fin->fin_tcpf = 0;
fin->fin_data[0] = 0;
fin->fin_data[1] = 0;
@@ -177,12 +177,13 @@ fr_info_t *fin;
fi->fi_tos = ip->ip_tos;
fin->fin_hlen = hlen;
fin->fin_dlen = ip->ip_len - hlen;
+ tcp = (tcphdr_t *)((char *)ip + hlen);
+ fin->fin_dp = (void *)tcp;
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
(*(((u_long *)fi) + 1)) = (*(((u_long *)ip) + 3));
(*(((u_long *)fi) + 2)) = (*(((u_long *)ip) + 4));
- if (hlen > sizeof(struct ip))
- fi->fi_fl |= FI_OPTIONS;
+ fi->fi_fl = (hlen > sizeof(struct ip)) ? FI_OPTIONS : 0;
off = (ip->ip_off & 0x1fff) << 3;
if (ip->ip_off & 0x3fff)
fi->fi_fl |= FI_FRAG;
@@ -202,21 +203,22 @@ fr_info_t *fin;
fi->fi_fl |= FI_SHORT;
if (!(fi->fi_fl & FI_SHORT) && !off)
fin->fin_tcpf = tcp->th_flags;
- break;
+ goto getports;
case IPPROTO_UDP :
fi->fi_fl |= FI_TCPUDP;
if ((!IPMINLEN(ip, udphdr) && !off) ||
(off && off < sizeof(struct udphdr)))
fi->fi_fl |= FI_SHORT;
+getports:
+ if (!off && (fin->fin_dlen > 3)) {
+ fin->fin_data[0] = ntohs(tcp->th_sport);
+ fin->fin_data[1] = ntohs(tcp->th_dport);
+ }
break;
default :
break;
}
- if ((fi->fi_fl & FI_TCPUDP) && !off && (fin->fin_dlen > 3)) {
- fin->fin_data[0] = ntohs(tcp->th_sport);
- fin->fin_data[1] = ntohs(tcp->th_dport);
- }
for (s = (u_char *)(ip + 1), hlen -= sizeof(*ip); hlen; ) {
if (!(opt = *s))
@@ -264,7 +266,6 @@ fr_info_t *fin;
fi->fi_optmsk = optmsk;
fi->fi_secmsk = secmsk;
fi->fi_auth = auth;
- return fin;
}
@@ -438,10 +439,10 @@ void *m;
continue;
} else if (fi->fi_p == IPPROTO_ICMP) {
if (!off && (fin->fin_dlen > 1)) {
- if ((*(u_short *)fin->fin_dp & fr->fr_icmpm) !=
+ if ((fin->fin_data[0] & fr->fr_icmpm) !=
fr->fr_icmp) {
FR_DEBUG(("i. %#x & %#x != %#x\n",
- *(u_short *)fin->fin_dp,
+ fin->fin_data[0],
fr->fr_icmpm, fr->fr_icmp));
continue;
}
@@ -453,8 +454,10 @@ void *m;
* Just log this packet...
*/
pass = fr->fr_flags;
+ if ((pass & FR_CALLNOW) && fr->fr_func)
+ pass = (*fr->fr_func)(ip, fin);
#ifdef IPFILTER_LOG
- if (pass & FR_LOG) {
+ if ((pass & FR_LOGMASK) == FR_LOG) {
if (!IPLLOG(fr->fr_flags, ip, fin, m))
frstats[fin->fin_out].fr_skip++;
frstats[fin->fin_out].fr_pkl++;
@@ -462,8 +465,6 @@ void *m;
#endif /* IPFILTER_LOG */
FR_DEBUG(("pass %#x\n", pass));
fr->fr_hits++;
- fin->fin_fr = fr;
- fin->fin_rule = rulen;
if (pass & FR_ACCOUNT)
fr->fr_bytes += ip->ip_len;
else
@@ -471,6 +472,8 @@ void *m;
if (pass & FR_QUICK)
break;
}
+ fin->fin_rule = rulen;
+ fin->fin_fr = fr;
return pass;
}
@@ -483,9 +486,10 @@ void *m;
int fr_check(ip, hlen, ifp, out
#ifdef _KERNEL
# if SOLARIS
-, qif, q)
+, qif, q, mb)
qif_t *qif;
queue_t *q;
+mblk_t *mb;
# else
, mp)
struct mbuf **mp;
@@ -501,12 +505,14 @@ int out;
/*
* The above really sucks, but short of writing a diff
*/
- register fr_info_t *fin;
fr_info_t frinfo, *fc;
+ register fr_info_t *fin = &frinfo;
+ frentry_t *fr;
int pass;
#if !defined(__SVR4) && !defined(__svr4__) && defined(_KERNEL)
register struct mbuf *m = *mp;
+ struct mbuf *mc = NULL;
if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
ip->ip_p == IPPROTO_ICMP)) {
@@ -522,7 +528,10 @@ int out;
}
}
#endif
- fin = fr_makefrip(hlen, ip, &frinfo);
+#if SOLARIS
+ mblk_t *mc = NULL;
+#endif
+ fr_makefrip(hlen, ip, fin);
fin->fin_ifp = ifp;
fin->fin_out = out;
@@ -552,9 +561,13 @@ int out;
frstats[out].fr_cfr++;
}
} else {
- fc = frcache+out;
+ fc = frcache + out;
if (fc->fin_fr && !bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
- fin = fc;
+ /*
+ * copy cached data so we can unlock the mutex
+ * earlier.
+ */
+ bcopy((char *)fc, (char *)fin, sizeof(*fin));
frstats[out].fr_chit++;
pass = fin->fin_fr->fr_flags;
} else {
@@ -580,13 +593,18 @@ int out;
frstats[out].fr_cfr++;
}
if (pass & FR_KEEPSTATE) {
- if (fr_addstate(ip, hlen, pass) == -1)
+ if (fr_addstate(ip, fin, pass) == -1)
frstats[out].fr_bads++;
else
frstats[out].fr_ads++;
}
}
+ fr = fin->fin_fr;
+
+ if (fr && fr->fr_func)
+ pass = (*fr->fr_func)(pass, ip, fin);
+
if (out) {
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT))
@@ -596,25 +614,26 @@ int out;
MUTEX_EXIT(&ipf_mutex);
#ifdef IPFILTER_LOG
- if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) {
- pass |= FF_LOGNOMATCH;
- if (!IPLLOG(pass, ip, fin, m))
- frstats[out].fr_skip++;
- frstats[out].fr_npkl++;
- } else if (((pass & FR_LOGP) == FR_LOGP) ||
- ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) {
- if ((pass & FR_LOGP) != FR_LOGP)
- pass |= FF_LOGPASS;
- if (!IPLLOG(pass, ip, fin, m))
- frstats[out].fr_skip++;
- frstats[out].fr_ppkl++;
- } else if (((pass & FR_LOGB) == FR_LOGB) ||
- ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) {
- if ((pass & FR_LOGB) != FR_LOGB)
- pass |= FF_LOGBLOCK;
- if (!IPLLOG(pass, ip, fin, m))
- frstats[out].fr_skip++;
- frstats[out].fr_bpkl++;
+ if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
+ if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) {
+ pass |= FF_LOGNOMATCH;
+ frstats[out].fr_npkl++;
+ goto logit;
+ } else if (((pass & FR_LOGMASK) == FR_LOGP) ||
+ ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) {
+ if ((pass & FR_LOGMASK) != FR_LOGP)
+ pass |= FF_LOGPASS;
+ frstats[out].fr_ppkl++;
+ goto logit;
+ } else if (((pass & FR_LOGMASK) == FR_LOGB) ||
+ ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) {
+ if ((pass & FR_LOGMASK) != FR_LOGB)
+ pass |= FF_LOGBLOCK;
+ frstats[out].fr_bpkl++;
+logit:
+ if (!IPLLOG(pass, ip, fin, m))
+ frstats[out].fr_skip++;
+ }
}
#endif /* IPFILTER_LOG */
@@ -638,7 +657,7 @@ int out;
# endif
frstats[0].fr_ret++;
- } else if (pass & FR_RETRST &&
+ } else if ((pass & FR_RETRST) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (SEND_RESET(ip, qif, q) == 0)
frstats[1].fr_ret++;
@@ -647,7 +666,8 @@ int out;
if (pass & FR_RETICMP) {
verbose("- ICMP unreachable sent\n");
frstats[0].fr_ret++;
- } else if (pass & FR_RETRST && IPMINLEN(ip, tcphdr)) {
+ } else if ((pass & FR_RETRST) &&
+ !(fin->fin_fi.fi_fl & FI_SHORT)) {
verbose("- TCP RST sent\n");
frstats[1].fr_ret++;
}
@@ -655,8 +675,33 @@ int out;
}
#ifdef _KERNEL
# if !SOLARIS
+ if (pass & FR_DUP)
+ mc = m_copy(m, 0, M_COPYALL);
+ if (fr) {
+ frdest_t *fdp = &fr->fr_tif;
+
+ if ((pass & FR_FASTROUTE) ||
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ ipfr_fastroute(m, fin, fdp);
+ if (mc)
+ ipfr_fastroute(mc, fin, &fr->fr_dif);
+ }
if (!(pass & FR_PASS) && m)
m_freem(m);
+# else
+ /*
+ if (pass & FR_DUP)
+ mc = dupmsg(mb);
+ if (fr) {
+ frdest_t *fdp = &fr->fr_tif;
+
+ if ((pass & FR_FASTROUTE) ||
+ (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
+ ipfr_fastroute(mb, fin, fdp);
+ if (mc)
+ ipfr_fastroute(mc, fin, &fr->fr_dif);
+ }
+ */
# endif
return (pass & FR_PASS) ? 0 : -1;
#else
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 28cca9a2fae..56387aaa7ca 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_proto.c,v 1.4 1996/04/24 06:00:43 mickey Exp $ */
+/* $OpenBSD: in_proto.c,v 1.5 1996/07/18 05:00:57 dm Exp $ */
/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
/*
@@ -89,6 +89,11 @@
#include <netinet/ip_mroute.h>
#endif /* MROUTING */
+#ifdef IPFILTER
+void iplinit();
+#define ip_init iplinit
+#endif
+
extern struct domain inetdomain;
struct protosw inetsw[] = {
diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c
index 9964e1ca030..14379a2c868 100644
--- a/sys/netinet/ip_fil.c
+++ b/sys/netinet/ip_fil.c
@@ -6,7 +6,8 @@
* to the original author and the contributors.
*/
#ifndef lint
-static char sccsid[] = "@(#)ip_fil.c 2.37 4/10/96 (C) 1993-1995 Darren Reed";
+static char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
+static char rcsid[] = "$Id: ip_fil.c,v 1.4 1996/07/18 05:00:58 dm Exp $";
#endif
#ifndef linux
@@ -28,6 +29,7 @@ static char sccsid[] = "@(#)ip_fil.c 2.37 4/10/96 (C) 1993-1995 Darren Reed";
#endif
#include <net/route.h>
#include <netinet/in.h>
+#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
@@ -38,6 +40,7 @@ static char sccsid[] = "@(#)ip_fil.c 2.37 4/10/96 (C) 1993-1995 Darren Reed";
#include <syslog.h>
#endif
#include "ip_fil.h"
+#include "ip_fil_compat.h"
#include "ip_frag.h"
#include "ip_nat.h"
#include "ip_state.h"
@@ -62,7 +65,7 @@ int ipl_unreach = ICMP_UNREACH_FILTER;
int send_reset();
#ifdef IPFILTER_LOG
-#define LOGSIZE 8192
+# define LOGSIZE 8192
int ipllog();
static char iplbuf[LOGSIZE];
static caddr_t iplh = iplbuf, iplt = iplbuf;
@@ -74,17 +77,17 @@ static int iplbusy = 0;
static int (*fr_savep)();
#if _BSDI_VERSION >= 199510
-#include <sys/device.h>
-#include <sys/conf.h>
+# include <sys/device.h>
+# include <sys/conf.h>
int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
int iplopen __P((dev_t, int, int, struct proc *));
int iplclose __P((dev_t, int, int, struct proc *));
-#ifdef IPFILTER_LOG
+# ifdef IPFILTER_LOG
int iplread __P((dev_t, struct uio *, int));
-#else
-#define iplread noread
-#endif
+# else
+# define iplread noread
+# endif
int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
struct cfdriver iplcd = {
@@ -97,7 +100,7 @@ struct devsw iplsw = {
nostrat, nodump, nopsize, 0,
nostop
};
-#endif
+#endif /* _BSDI_VERSION >= 199510 */
#ifdef IPFILTER_LKM
int iplidentify(s)
@@ -243,23 +246,32 @@ int mode;
SPLNET(s);
switch (cmd) {
case FIONREAD :
+#ifdef IPFILTER_LOG
*(int *)data = iplused;
+#endif
break;
#ifndef IPFILTER_LKM
case SIOCFRENB :
{
u_int enable;
- IRCOPY(data, (caddr_t)&enable, sizeof(enable));
- if (enable)
- error = iplattach();
- else
- error = ipldetach();
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ IRCOPY(data, (caddr_t)&enable, sizeof(enable));
+ if (enable)
+ error = iplattach();
+ else
+ error = ipldetach();
+ }
break;
}
#endif
case SIOCSETFF :
- IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags));
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags));
break;
case SIOCGETFF :
IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
@@ -267,17 +279,28 @@ int mode;
case SIOCINAFR :
case SIOCRMAFR :
case SIOCADAFR :
- error = frrequest(cmd, (struct frentry *)data, fr_active);
+ case SIOCZRLST :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ error = frrequest(cmd, data, fr_active);
break;
case SIOCINIFR :
case SIOCRMIFR :
case SIOCADIFR :
- error = frrequest(cmd, (struct frentry *)data, 1-fr_active);
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ error = frrequest(cmd, data, 1 - fr_active);
break;
case SIOCSWAPA :
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
- *(u_int *)data = fr_active;
- fr_active = 1 - fr_active;
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ bzero((char *)frcache, sizeof(frcache[0]) * 2);
+ *(u_int *)data = fr_active;
+ fr_active = 1 - fr_active;
+ }
break;
case SIOCGETFS :
{
@@ -298,23 +321,35 @@ int mode;
break;
}
case SIOCFRZST :
- frzerostats(data);
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ frzerostats(data);
break;
case SIOCIPFFL :
- frflush(data);
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ frflush(data);
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
- *(int *)data = iplused;
- iplh = iplt = iplbuf;
- iplused = 0;
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ *(int *)data = iplused;
+ iplh = iplt = iplbuf;
+ iplused = 0;
+ }
break;
#endif /* IPFILTER_LOG */
case SIOCADNAT :
case SIOCRMNAT :
case SIOCGNATS :
case SIOCGNATL :
- error = nat_ioctl(data, cmd);
+ case SIOCFLNAT :
+ case SIOCCNATL :
+ error = nat_ioctl(data, cmd, mode);
break;
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
@@ -323,7 +358,7 @@ int mode;
IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t));
break;
default :
- error = -EINVAL;
+ error = EINVAL;
break;
}
SPLX(s);
@@ -331,15 +366,20 @@ int mode;
}
-static int frrequest(req, fp, set)
+static int frrequest(req, data, set)
int req, set;
-register struct frentry *fp;
+caddr_t data;
{
- register struct frentry *f, **fprev;
- register struct frentry **ftail;
+ register frentry_t *fp, *f, **fprev;
+ register frentry_t **ftail;
+ frentry_t fr;
+ frdest_t *fdp;
struct frentry frd;
int error = 0, in;
+ fp = &fr;
+ IRCOPY(data, (caddr_t)fp, sizeof(*fp));
+
bzero((char *)frcache, sizeof(frcache[0]) * 2);
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
@@ -357,6 +397,24 @@ register struct frentry *fp;
if (!fp->fr_ifa)
fp->fr_ifa = (struct ifnet *)-1;
}
+
+ fdp = &fp->fr_dif;
+ fp->fr_flags &= ~FR_DUP;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ else
+ fp->fr_flags |= FR_DUP;
+ }
+
+ fdp = &fp->fr_tif;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ }
+
/*
* Look for a matching filter rule, but don't include the next or
* interface pointer in the comparison (fr_next, fr_ifa).
@@ -365,6 +423,19 @@ register struct frentry *fp;
if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip,
FR_CMPSIZ) == 0)
break;
+
+ /*
+ * If zero'ing statistics, copy current to caller and zero.
+ */
+ if (req == SIOCZRLST) {
+ if (!f)
+ return ESRCH;
+ IWCOPY((caddr_t)f, data, sizeof(*f));
+ f->fr_hits = 0;
+ f->fr_bytes = 0;
+ return 0;
+ }
+
if (!f) {
ftail = fprev;
if (req != SIOCINAFR && req != SIOCINIFR)
@@ -417,10 +488,8 @@ int flags;
{
u_int min = minor(dev);
- if ((flags & FWRITE) || min)
+ if (min)
min = ENXIO;
- else
- iplbusy++;
return min;
}
@@ -440,8 +509,6 @@ int flags;
if (min)
min = ENXIO;
- else if (iplbusy > 0)
- iplbusy--;
return min;
}
@@ -467,12 +534,14 @@ register struct uio *uio;
if (!uio->uio_resid)
return 0;
+ iplbusy++;
while (!iplused) {
error = SLEEP(iplbuf, "ipl sleep");
- if (error)
+ if (error) {
+ iplbusy--;
return error;
+ }
}
-
SPLNET(s);
sx = sz = MIN(uio->uio_resid, iplused);
@@ -499,6 +568,7 @@ register struct uio *uio;
iplh = iplt = iplbuf;
}
SPLX(s);
+ iplbusy--;
return ret;
}
# endif /* IPFILTER_LOG */
@@ -553,16 +623,15 @@ struct mbuf *m;
iplci.hlen = (u_char)hlen;
iplci.plen = (flags & FR_LOGBODY) ? (u_char)mlen : 0 ;
iplci.rule = fin->fin_rule;
-#if !defined (__OpenBSD__) && !defined (__NetBSD__)
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+ strcpy(iplci.ifname, ifp->if_xname);
+# else
iplci.unit = (u_char)ifp->if_unit;
- iplci.ifname[0] = ifp->if_name[0];
- iplci.ifname[1] = ifp->if_name[1];
- iplci.ifname[2] = ifp->if_name[2];
- iplci.ifname[3] = ifp->if_name[3];
-#else /* OpenBSD or NetBSD */
- bcopy (ifp->if_xname, iplci.ifname, IFNAMSIZ);
-#endif /* OpenBSD or NetBSD */
-
+ if ((iplci.ifname[0] = ifp->if_name[0]))
+ if ((iplci.ifname[1] = ifp->if_name[1]))
+ if ((iplci.ifname[2] = ifp->if_name[2]))
+ iplci.ifname[3] = ifp->if_name[3];
+# endif
if (iplh == iplbuf + LOGSIZE)
iplh = iplbuf;
tail = (iplh >= iplt) ? (iplbuf + LOGSIZE - iplh) : (iplt - iplh);
@@ -665,11 +734,7 @@ struct tcpiphdr *ti;
tp->ti_len = htons(sizeof(struct tcphdr));
tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr));
- ip->ip_hl = sizeof(struct ip) >> 2;
- ip->ip_v = IPVERSION;
ip->ip_tos = ((struct ip *)ti)->ip_tos;
- ip->ip_id = ((struct ip *)ti)->ip_id;
- ip->ip_off = ((struct ip *)ti)->ip_off;
ip->ip_p = ((struct ip *)ti)->ip_p;
ip->ip_len = sizeof (struct tcpiphdr);
#if BSD < 199306
@@ -681,7 +746,7 @@ struct tcpiphdr *ti;
/*
* extra 0 in case of multicast
*/
- (void) ip_output(m, (struct mbuf *)0, 0, IP_FORWARDING, 0);
+ (void) ip_output(m, (struct mbuf *)0, 0, 0, 0);
return 0;
}
@@ -689,7 +754,175 @@ struct tcpiphdr *ti;
#ifndef IPFILTER_LKM
iplinit()
{
- (void) iplattach();
+ /* (void) iplattach(); */
ip_init();
}
#endif
+
+
+void ipfr_fastroute(m0, fin, fdp)
+struct mbuf *m0;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+ register struct ip *ip, *mhip;
+ register struct mbuf *m = m0;
+ register struct route *ro;
+ struct ifnet *ifp = fdp->fd_ifp;
+ int len, off, error = 0, s;
+ int hlen = fin->fin_hlen;
+ struct route iproute;
+ struct sockaddr_in *dst;
+
+ ip = mtod(m0, struct ip *);
+ /*
+ * Route packet.
+ */
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof (*ro));
+ dst = (struct sockaddr_in *)&ro->ro_dst;
+ dst->sin_family = AF_INET;
+ dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
+#if BSD >= 199306 && !(defined(__NetBSD__))
+# ifdef RTF_CLONING
+ rtalloc_ign(ro, RTF_CLONING);
+# else
+ rtalloc_ign(ro, RTF_PRCLONING);
+# endif
+#else
+ rtalloc(ro);
+#endif
+ if (!ifp) {
+ if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) {
+ error = -2;
+ goto bad;
+ }
+ if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
+ if (in_localaddr(ip->ip_dst))
+ error = EHOSTUNREACH;
+ else
+ error = ENETUNREACH;
+ goto bad;
+ }
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
+ }
+ ro->ro_rt->rt_use++;
+
+ /*
+ * If small enough for interface, can just send directly.
+ */
+ if (ip->ip_len <= ifp->if_mtu) {
+#ifndef sparc
+ ip->ip_id = htons(ip->ip_id);
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+#endif
+ if (!ip->ip_sum)
+ ip->ip_sum = in_cksum(m, hlen);
+#if BSD >= 199306
+ error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
+ ro->ro_rt);
+
+#else
+ error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
+#endif
+ goto done;
+ }
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+ if (ip->ip_off & IP_DF) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ len = (ifp->if_mtu - hlen) &~ 7;
+ if (len < 8) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+
+ {
+ int mhlen, firstlen = len;
+ struct mbuf **mnext = &m->m_act;
+
+ /*
+ * Loop through length of segment after first fragment,
+ * make new header and copy data of each part and link onto chain.
+ */
+ m0 = m;
+ mhlen = sizeof (struct ip);
+ for (off = hlen + len; off < ip->ip_len; off += len) {
+ MGET(m, M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+#if BSD >= 199306
+ m->m_data += max_linkhdr;
+#else
+ m->m_off = MMAXOFF - hlen;
+#endif
+ mhip = mtod(m, struct ip *);
+ bcopy((char *)ip, (char *)mhip, sizeof(*ip));
+ if (hlen > sizeof (struct ip)) {
+ mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
+ mhip->ip_hl = mhlen >> 2;
+ }
+ m->m_len = mhlen;
+ mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
+ if (ip->ip_off & IP_MF)
+ mhip->ip_off |= IP_MF;
+ if (off + len >= ip->ip_len)
+ len = ip->ip_len - off;
+ else
+ mhip->ip_off |= IP_MF;
+ mhip->ip_len = htons((u_short)(len + mhlen));
+ m->m_next = m_copy(m0, off, len);
+ if (m->m_next == 0) {
+ error = ENOBUFS; /* ??? */
+ goto sendorfree;
+ }
+#ifndef sparc
+ mhip->ip_off = htons((u_short)mhip->ip_off);
+#endif
+ mhip->ip_sum = 0;
+ mhip->ip_sum = in_cksum(m, mhlen);
+ *mnext = m;
+ mnext = &m->m_act;
+ }
+ /*
+ * Update first fragment by trimming what's been copied out
+ * and updating header, then send each fragment (in order).
+ */
+ m_adj(m0, hlen + firstlen - ip->ip_len);
+ ip->ip_len = htons((u_short)(hlen + firstlen));
+ ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m0, hlen);
+sendorfree:
+ for (m = m0; m; m = m0) {
+ m0 = m->m_act;
+ m->m_act = 0;
+ if (error == 0)
+#if BSD >= 199306
+ error = (*ifp->if_output)(ifp, m,
+ (struct sockaddr *)dst, ro->ro_rt);
+#else
+ error = (*ifp->if_output)(ifp, m,
+ (struct sockaddr *)dst);
+#endif
+ else
+ m_freem(m);
+ }
+ }
+done:
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ }
+ return;
+bad:
+ m_freem(m);
+ goto done;
+}
diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h
index e80d977445e..29b5a1df2aa 100644
--- a/sys/netinet/ip_fil.h
+++ b/sys/netinet/ip_fil.h
@@ -5,7 +5,8 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * @(#)ip_fil.h 1.32 3/24/96
+ * @(#)ip_fil.h 1.35 6/5/96
+ * $Id: ip_fil.h,v 1.4 1996/07/18 05:00:59 dm Exp $
*/
#ifndef __IP_FIL_H__
@@ -18,207 +19,6 @@
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
-#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
-
-#ifndef IP_OFFMASK
-#define IP_OFFMASK 0x1fff
-#endif
-
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifdef _KERNEL
-# if SOLARIS
-# define MUTEX_ENTER(x) mutex_enter(x)
-# define MUTEX_EXIT(x) mutex_exit(x)
-# define MTOD(m,t) (t)((m)->b_rptr)
-# define IRCOPY(a,b,c) copyin((a), (b), (c))
-# define IWCOPY(a,b,c) copyout((a), (b), (c))
-# else
-# define MUTEX_ENTER(x) ;
-# define MUTEX_EXIT(x) ;
-# ifndef linux
-# define MTOD(m,t) mtod(m,t)
-# define IRCOPY(a,b,c) bcopy((a), (b), (c))
-# define IWCOPY(a,b,c) bcopy((a), (b), (c))
-# endif
-# endif /* SOLARIS */
-
-# ifdef sun
-# if defined(__svr4__) || defined(__SVR4)
-# define GETUNIT(n) get_unit((n))
-# else
-# include <sys/kmem_alloc.h>
-# define GETUNIT(n) ifunit((n), IFNAMSIZ)
-# endif
-# else
-# define GETUNIT(n) ifunit((n))
-# endif /* sun */
-
-# if defined(sun) && !defined(linux)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
-# define SLEEP(id, n) sleep((id), PZERO+1)
-# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
-# if SOLARIS
-typedef struct qif {
- struct qif *qf_next;
- ill_t *qf_ill;
- kmutex_t qf_lock;
- void *qf_iptr;
- void *qf_optr;
- queue_t *qf_in;
- queue_t *qf_out;
- void *qf_wqinfo;
- void *qf_rqinfo;
- char qf_name[8];
- int (*qf_inp)();
- int (*qf_outp)();
- /*
- * in case the ILL has disappeared...
- */
- int qf_hl; /* header length */
-} qif_t;
-# define SPLNET(x) ;
-# undef SPLX
-# define SPLX(x) ;
-# ifdef sparc
-# define ntohs(x) (x)
-# define ntohl(x) (x)
-# define htons(x) (x)
-# define htonl(x) (x)
-# endif
-# define KMALLOC(x) kmem_alloc((x), KM_SLEEP)
-# define GET_MINOR(x) getminor(x)
-# else
-# define KMALLOC(x) new_kmem_alloc((x), KMEM_SLEEP)
-# endif /* __svr4__ */
-# endif /* sun && !linux */
-# ifndef GET_MINOR
-# define GET_MINOR(x) minor(x)
-# endif
-# if BSD >= 199306 || defined(__FreeBSD__)
-# include <vm/vm.h>
-# if !defined(__FreeBSD__)
-# include <vm/vm_extern.h>
-# include <sys/proc.h>
-extern vm_map_t kmem_map;
-# else
-# include <vm/vm_kern.h>
-# endif /* __FreeBSD__ */
-# define KMALLOC(x) kmem_alloc(kmem_map, (x))
-# define KFREE(x) kmem_free(kmem_map, (vm_offset_t)(x), \
- sizeof(*(x)))
-# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
-# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
-# endif /* BSD */
-# if defined(NetBSD1_0) && (NetBSD1_0 > 1)
-# define SPLNET(x) x = splsoftnet()
-# else
-# if !SOLARIS
-# define SPLNET(x) x = splnet()
-# define SPLX(x) (void) splx(x)
-# endif
-# endif
-#else
-# define MUTEX_ENTER(x) ;
-# define MUTEX_EXIT(x) ;
-# define SPLNET(x) ;
-# define SPLX(x) ;
-# define KMALLOC(x) malloc(x)
-# define KFREE(x) free(x)
-# define GETUNIT(x) (x)
-# define IRCOPY(a,b,c) bcopy((a), (b), (c))
-# define IWCOPY(a,b,c) bcopy((a), (b), (c))
-#endif /* KERNEL */
-
-#ifdef linux
-# define ICMP_UNREACH ICMP_DEST_UNREACH
-# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
-# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
-# define ICMP_PARAMPROB ICMP_PARAMETERPROB
-# define icmp icmphdr
-# define icmp_type type
-# define icmp_code code
-
-# define TH_FIN 0x01
-# define TH_SYN 0x02
-# define TH_RST 0x04
-# define TH_PUSH 0x08
-# define TH_ACK 0x10
-# define TH_URG 0x20
-
-typedef struct {
- __u16 th_sport;
- __u16 th_dport;
- __u32 th_seq;
- __u32 th_ack;
- __u8 th_x;
- __u8 th_flags;
- __u16 th_win;
- __u16 th_sum;
- __u16 th_urp;
-} tcphdr_t;
-
-typedef struct {
- __u16 uh_sport;
- __u16 uh_dport;
- __u16 uh_ulen;
- __u16 uh_sun;
-} udphdr_t;
-
-typedef struct {
-# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
- defined(vax)
- __u8 ip_hl:4;
- __u8 ip_v:4;
-# else
- __u8 ip_hl:4;
- __u8 ip_v:4;
-# endif
- __u8 ip_tos;
- __u16 ip_len;
- __u16 ip_id;
- __u16 ip_off;
- __u8 ip_ttl;
- __u8 ip_p;
- __u16 ip_sum;
- __u32 ip_src;
- __u32 ip_dst;
-} ip_t;
-
-# define SPLX(x) (void)
-# define SPLNET(x) (void)
-
-# define bcopy(a,b,c) memmove(b,a,c)
-# define bcmp(a,b,c) memcmp(a,b,c)
-
-# define UNITNAME(n) dev_get((n))
-# define ifnet device
-
-# define KMALLOC(x) kmalloc((x), GFP_ATOMIC)
-# define KFREE(x) kfree_s((x), sizeof(*(x)))
-# define IRCOPY(a,b,c) { \
- error = verify_area(VERIFY_READ, \
- (b) ,sizeof((b))); \
- if (!error) \
- memcpy_fromfs((b), (a), (c)); \
- }
-# define IWCOPY(a,b,c) { \
- error = verify_area(VERIFY_WRITE, \
- (b) ,sizeof((b))); \
- if (!error) \
- memcpy_tofs((b), (a), (c)); \
- }
-#else
-typedef struct tcphdr tcphdr_t;
-typedef struct udphdr udphdr_t;
-typedef struct ip ip_t;
-#endif /* linux */
-
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
#if defined(KERNEL) && !defined(_KERNEL)
#define _KERNEL
@@ -256,6 +56,9 @@ typedef struct ip ip_t;
#define SIOCFRENB _IOW('r', 72, u_int)
#define SIOCFRSYN _IOW('r', 73, u_int)
#define SIOCFRZST _IOWR('r', 74, struct friostat)
+#define SIOCFLNAT _IOWR('r', 75, int)
+#define SIOCCNATL _IOWR('r', 76, int)
+#define SIOCZRLST _IOWR('r', 77, struct frentry)
#else
#define SIOCADAFR _IOW(r, 60, struct frentry)
#define SIOCRMAFR _IOW(r, 61, struct frentry)
@@ -272,6 +75,9 @@ typedef struct ip ip_t;
#define SIOCFRENB _IOW(r, 72, u_int)
#define SIOCFRSYN _IOW(r, 73, u_int)
#define SIOCFRZST _IOWR(r, 74, struct friostat)
+#define SIOCFLNAT _IOWR(r, 75, int)
+#define SIOCCNATL _IOWR(r, 76, int)
+#define SIOCZRLST _IOWR(r, 77, struct frentry)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
@@ -311,6 +117,12 @@ typedef struct fr_info {
#define FI_CSIZE (sizeof(struct fr_ip) + 11)
+typedef struct frdest {
+ void *fd_ifp;
+ struct in_addr fd_ip;
+ char fd_ifname[IFNAMSIZ];
+} frdest_t;
+
typedef struct frentry {
struct frentry *fr_next;
struct ifnet *fr_ifa;
@@ -336,8 +148,11 @@ typedef struct frentry {
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
u_long fr_flags; /* per-rule flags && options (see below) */
+ int (*fr_func)(); /* call this function */
char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
+ struct frdest fr_tif; /* "to" interface */
+ struct frdest fr_dif; /* duplicate packet interfaces */
} frentry_t;
#define fr_proto fr_ip.fi_p
@@ -356,29 +171,35 @@ typedef struct frentry {
/*
* fr_flags
*/
-#define FR_BLOCK 0x0001
-#define FR_PASS 0x0002
-#define FR_OUTQUE 0x0004
-#define FR_INQUE 0x0008
-#define FR_LOG 0x0010 /* Log */
-#define FR_LOGB 0x0021 /* Log-fail */
-#define FR_LOGP 0x0022 /* Log-pass */
-#define FR_LOGBODY 0x0040 /* Log the body */
-#define FR_LOGFIRST 0x0080
-#define FR_RETRST 0x0100
-#define FR_RETICMP 0x0200
-#define FR_NOMATCH 0x0400
-#define FR_ACCOUNT 0x0800 /* count packet bytes */
-#define FR_KEEPFRAG 0x1000
-#define FR_KEEPSTATE 0x2000
-#define FR_INACTIVE 0x4000
-#define FR_QUICK 0x8000
+#define FR_BLOCK 0x00001
+#define FR_PASS 0x00002
+#define FR_OUTQUE 0x00004
+#define FR_INQUE 0x00008
+#define FR_LOG 0x00010 /* Log */
+#define FR_LOGB 0x00011 /* Log-fail */
+#define FR_LOGP 0x00012 /* Log-pass */
+#define FR_LOGBODY 0x00020 /* Log the body */
+#define FR_LOGFIRST 0x00040
+#define FR_RETRST 0x00080
+#define FR_RETICMP 0x00100
+#define FR_NOMATCH 0x00200
+#define FR_ACCOUNT 0x00400 /* count packet bytes */
+#define FR_KEEPFRAG 0x00800
+#define FR_KEEPSTATE 0x01000
+#define FR_INACTIVE 0x02000
+#define FR_QUICK 0x04000
+#define FR_FASTROUTE 0x08000
+#define FR_CALLNOW 0x10000
+#define FR_DUP 0x20000
+
+#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
/*
* recognized flags for SIOCGETFF and SIOCSETFF
*/
#define FF_LOGPASS 0x100000
#define FF_LOGBLOCK 0x200000
#define FF_LOGNOMATCH 0x400000
+#define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH)
#define FR_NONE 0
#define FR_EQUAL 1
@@ -437,14 +258,14 @@ typedef struct ipl_ci {
u_char hlen;
u_char plen;
u_short rule;
- u_long flags:24;
-#if !defined (__OpenBSD__) && !defined (__NetBSD__)
+ u_long flags:24; /* XXX FIXME do we care about the extra bytes? */
+#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+ u_long filler:8; /* XXX FIXME do we care? */
+ u_char ifname[IFNAMSIZ];
+#else
u_long unit:8;
u_char ifname[4];
-#else /* OpenBSD or NetBSD */
- u_long : 0;
- u_char ifname[IFNAMSIZ];
-#endif /* OpenBSD or NetBSD */
+#endif
} ipl_ci_t;
diff --git a/sys/netinet/ip_fil_compat.h b/sys/netinet/ip_fil_compat.h
new file mode 100644
index 00000000000..70e30d11d8f
--- /dev/null
+++ b/sys/netinet/ip_fil_compat.h
@@ -0,0 +1,216 @@
+/*
+ * (C)opyright 1993, 1994, 1995 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_compat.h 1.8 1/14/96
+ * $Id: ip_fil_compat.h,v 1.1 1996/07/18 05:01:00 dm Exp $
+ */
+
+#ifndef __IP_COMPAT_H_
+#define __IP_COMPAT_H__
+
+#ifndef SOLARIS
+#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+#endif
+#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
+
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifdef _KERNEL
+# if SOLARIS
+# define MUTEX_ENTER(x) mutex_enter(x)
+# define MUTEX_EXIT(x) mutex_exit(x)
+# define MTOD(m,t) (t)((m)->b_rptr)
+# define IRCOPY(a,b,c) copyin((a), (b), (c))
+# define IWCOPY(a,b,c) copyout((a), (b), (c))
+# else
+# define MUTEX_ENTER(x) ;
+# define MUTEX_EXIT(x) ;
+# ifndef linux
+# define MTOD(m,t) mtod(m,t)
+# define IRCOPY(a,b,c) bcopy((a), (b), (c))
+# define IWCOPY(a,b,c) bcopy((a), (b), (c))
+# endif
+# endif /* SOLARIS */
+
+# ifdef sun
+# if defined(__svr4__) || defined(__SVR4)
+# define GETUNIT(n) get_unit((n))
+# else
+# include <sys/kmem_alloc.h>
+# define GETUNIT(n) ifunit((n), IFNAMSIZ)
+# endif
+# else
+# define GETUNIT(n) ifunit((n))
+# endif /* sun */
+
+# if defined(sun) && !defined(linux)
+# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
+# define SLEEP(id, n) sleep((id), PZERO+1)
+# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
+# if SOLARIS
+typedef struct qif {
+ struct qif *qf_next;
+ ill_t *qf_ill;
+ kmutex_t qf_lock;
+ void *qf_iptr;
+ void *qf_optr;
+ queue_t *qf_in;
+ queue_t *qf_out;
+ void *qf_wqinfo;
+ void *qf_rqinfo;
+ char qf_name[8];
+ int (*qf_inp)();
+ int (*qf_outp)();
+ /*
+ * in case the ILL has disappeared...
+ */
+ int qf_hl; /* header length */
+} qif_t;
+# define SPLNET(x) ;
+# undef SPLX
+# define SPLX(x) ;
+# ifdef sparc
+# define ntohs(x) (x)
+# define ntohl(x) (x)
+# define htons(x) (x)
+# define htonl(x) (x)
+# endif
+# define KMALLOC(x) kmem_alloc((x), KM_SLEEP)
+# define GET_MINOR(x) getminor(x)
+# else
+# define KMALLOC(x) new_kmem_alloc((x), KMEM_SLEEP)
+# endif /* __svr4__ */
+# endif /* sun && !linux */
+# ifndef GET_MINOR
+# define GET_MINOR(x) minor(x)
+# endif
+# if BSD >= 199306 || defined(__FreeBSD__)
+# include <vm/vm.h>
+# if !defined(__FreeBSD__)
+# include <vm/vm_extern.h>
+# include <sys/proc.h>
+extern vm_map_t kmem_map;
+# else
+# include <vm/vm_kern.h>
+# endif /* __FreeBSD__ */
+# define KMALLOC(x) kmem_alloc(kmem_map, (x))
+# define KFREE(x) kmem_free(kmem_map, (vm_offset_t)(x), \
+ sizeof(*(x)))
+# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
+# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
+# endif /* BSD */
+# if defined(NetBSD1_0) && (NetBSD1_0 > 1)
+# define SPLNET(x) x = splsoftnet()
+# else
+# if !SOLARIS
+# define SPLNET(x) x = splnet()
+# define SPLX(x) (void) splx(x)
+# endif
+# endif
+#else
+# define MUTEX_ENTER(x) ;
+# define MUTEX_EXIT(x) ;
+# define SPLNET(x) ;
+# define SPLX(x) ;
+# define KMALLOC(x) malloc(x)
+# define KFREE(x) free(x)
+# define GETUNIT(x) (x)
+# define IRCOPY(a,b,c) bcopy((a), (b), (c))
+# define IWCOPY(a,b,c) bcopy((a), (b), (c))
+#endif /* KERNEL */
+
+#ifdef linux
+# define ICMP_UNREACH ICMP_DEST_UNREACH
+# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+# define ICMP_PARAMPROB ICMP_PARAMETERPROB
+# define icmp icmphdr
+# define icmp_type type
+# define icmp_code code
+
+# define TH_FIN 0x01
+# define TH_SYN 0x02
+# define TH_RST 0x04
+# define TH_PUSH 0x08
+# define TH_ACK 0x10
+# define TH_URG 0x20
+
+typedef struct {
+ __u16 th_sport;
+ __u16 th_dport;
+ __u32 th_seq;
+ __u32 th_ack;
+ __u8 th_x;
+ __u8 th_flags;
+ __u16 th_win;
+ __u16 th_sum;
+ __u16 th_urp;
+} tcphdr_t;
+
+typedef struct {
+ __u16 uh_sport;
+ __u16 uh_dport;
+ __u16 uh_ulen;
+ __u16 uh_sun;
+} udphdr_t;
+
+typedef struct {
+# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
+ defined(vax)
+ __u8 ip_hl:4;
+ __u8 ip_v:4;
+# else
+ __u8 ip_hl:4;
+ __u8 ip_v:4;
+# endif
+ __u8 ip_tos;
+ __u16 ip_len;
+ __u16 ip_id;
+ __u16 ip_off;
+ __u8 ip_ttl;
+ __u8 ip_p;
+ __u16 ip_sum;
+ __u32 ip_src;
+ __u32 ip_dst;
+} ip_t;
+
+# define SPLX(x) (void)
+# define SPLNET(x) (void)
+
+# define bcopy(a,b,c) memmove(b,a,c)
+# define bcmp(a,b,c) memcmp(a,b,c)
+
+# define UNITNAME(n) dev_get((n))
+# define ifnet device
+
+# define KMALLOC(x) kmalloc((x), GFP_ATOMIC)
+# define KFREE(x) kfree_s((x), sizeof(*(x)))
+# define IRCOPY(a,b,c) { \
+ error = verify_area(VERIFY_READ, \
+ (b) ,sizeof((b))); \
+ if (!error) \
+ memcpy_fromfs((b), (a), (c)); \
+ }
+# define IWCOPY(a,b,c) { \
+ error = verify_area(VERIFY_WRITE, \
+ (b) ,sizeof((b))); \
+ if (!error) \
+ memcpy_tofs((b), (a), (c)); \
+ }
+#else
+typedef struct tcphdr tcphdr_t;
+typedef struct udphdr udphdr_t;
+typedef struct ip ip_t;
+#endif /* linux */
+
+#endif /* __IP_COMPAT_H__ */
diff --git a/sys/netinet/ip_frag.c b/sys/netinet/ip_frag.c
index 243448177f3..b193febd3e1 100644
--- a/sys/netinet/ip_frag.c
+++ b/sys/netinet/ip_frag.c
@@ -7,6 +7,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
+static char rcsid[] = "$Id: ip_frag.c,v 1.3 1996/07/18 05:01:02 dm Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@@ -46,6 +47,7 @@ static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
#include <netinet/ip_icmp.h>
#include <syslog.h>
#include "ip_fil.h"
+#include "ip_fil_compat.h"
#include "ip_frag.h"
#include "ip_nat.h"
#include "ip_state.h"
diff --git a/sys/netinet/ip_frag.h b/sys/netinet/ip_frag.h
index 61c79af3f72..6780071aa6c 100644
--- a/sys/netinet/ip_frag.h
+++ b/sys/netinet/ip_frag.h
@@ -6,6 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
+ * $Id: ip_frag.h,v 1.3 1996/07/18 05:01:03 dm Exp $
*/
#ifndef __IP_FRAG_H_
@@ -25,11 +26,6 @@ typedef struct ipfr {
u_char ipfr_pass;
} ipfr_t;
-#if defined(__STDC__) || defined(__GNUC__)
-#define SIOCGFRST _IOR('r', 76, struct ipfrstat)
-#else
-#define SIOCGFRST _IOR(r, 76, struct ipfrstat)
-#endif
typedef struct ipfrstat {
u_long ifs_exists; /* add & already exists */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 94e0050aa85..5b8b0ba031f 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.12 1996/05/07 15:20:25 mickey Exp $ */
+/* $OpenBSD: ip_input.c,v 1.13 1996/07/18 05:01:04 dm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -100,8 +100,8 @@ int ipqmaxlen = IFQ_MAXLEN;
struct in_ifaddrhead in_ifaddr;
struct ifqueue ipintrq;
#if defined(IPFILTER) || defined(IPFILTER_LKM)
-int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)
-);
+int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
+ struct mbuf **));
#endif
diff --git a/sys/netinet/ip_nat.c b/sys/netinet/ip_nat.c
index 34c91987124..b8b42874db4 100644
--- a/sys/netinet/ip_nat.c
+++ b/sys/netinet/ip_nat.c
@@ -17,9 +17,13 @@
* easy solution)
* 2) There needs to be a way to flush the NATs table completely. Either
* an ioctl, or an easy way of doing it from ipnat.c.
+ *
+ * Missing from RFC 1631: ICMP header checksum recalculations.
+ *
*/
#ifndef lint
-static char sccsid[] = "@(#)ip_nat.c 1.9 4/10/96 (C) 1995 Darren Reed";
+static char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
+static char rcsid[] = "$Id: ip_nat.c,v 1.4 1996/07/18 05:01:05 dm Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@@ -60,6 +64,7 @@ static char sccsid[] = "@(#)ip_nat.c 1.9 4/10/96 (C) 1995 Darren Reed";
#include <netinet/ip_icmp.h>
#include <syslog.h>
#include "ip_fil.h"
+#include "ip_fil_compat.h"
#include "ip_nat.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -103,19 +108,21 @@ extern kmutex_t ipf_nat;
/*
* Handle ioctls which manipulate the NAT.
*/
-int nat_ioctl(data, cmd)
+int nat_ioctl(data, cmd, mode)
caddr_t data;
-int cmd;
+int cmd, mode;
{
register ipnat_t *nat, *n, **np;
- int error = 0;
+ ipnat_t natd;
+ int error = 0, ret;
/*
* For add/delete, look to see if the NAT entry is already present
*/
MUTEX_ENTER(&ipf_nat);
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
- nat = (ipnat_t *)data;
+ IRCOPY(data, &natd, sizeof(natd));
+ nat = &natd;
for (np = &nat_list; (n = *np); np = &n->in_next)
if (!bcmp((char *)&nat->in_port, (char *)&n->in_port,
IPN_CMPSIZ))
@@ -125,6 +132,10 @@ int cmd;
switch (cmd)
{
case SIOCADNAT :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
if (n) {
error = EEXIST;
break;
@@ -148,6 +159,10 @@ int cmd;
*np = n;
break;
case SIOCRMNAT :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
if (!n) {
error = ESRCH;
break;
@@ -165,11 +180,7 @@ int cmd;
{
natlookup_t nl;
nat_t *na;
-#if !SOLARIS && defined(_KERNEL)
- int s;
-#endif
- SPLNET(s);
IRCOPY((char *)data, (char *)&nl, sizeof(nl));
if ((na = nat_lookupredir(&nl))) {
nl.nl_inip = na->nat_outip;
@@ -177,9 +188,24 @@ int cmd;
IWCOPY((char *)&nl, (char *)data, sizeof(nl));
} else
error = ESRCH;
- SPLX(s);
break;
}
+ case SIOCFLNAT :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
+ ret = flush_nattable();
+ IWCOPY((caddr_t)&ret, data, sizeof(ret));
+ break;
+ case SIOCCNATL :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
+ ret = clear_natlist();
+ IWCOPY((caddr_t)&ret, data, sizeof(ret));
+ break;
}
MUTEX_EXIT(&ipf_nat);
return error;
@@ -187,9 +213,49 @@ int cmd;
/*
- * Create a new NAT table entry.
+ * flush_nattable - clear the NAT table of all mapping entries.
+ */
+int flush_nattable()
+{
+ nat_t *nat, **natp;
+ int i, j = 0;
+
+ for (natp = &nat_table[0][0], i = NAT_SIZE - 1; i >= 0; i--, natp++)
+ while ((nat = *natp)) {
+ *natp = nat->nat_next;
+ KFREE((caddr_t)nat);
+ j++;
+ }
+
+ for (natp = &nat_table[1][0], i = NAT_SIZE - 1; i >= 0; i--, natp++)
+ while ((nat = *natp)) {
+ *natp = nat->nat_next;
+ KFREE((caddr_t)nat);
+ j++;
+ }
+ return j;
+}
+
+
+/*
+ * clear_natlist - delete all entries in the active NAT mapping list.
*/
+int clear_natlist()
+{
+ register ipnat_t *n, **np;
+ int i = 0;
+ for (np = &nat_list; (n = *np); i++) {
+ *np = n->in_next;
+ KFREE(n);
+ }
+ return i;
+}
+
+
+/*
+ * Create a new NAT table entry.
+ */
nat_t *nat_new(np, ip, hlen, flags, direction)
ipnat_t *np;
ip_t *ip;
@@ -213,7 +279,6 @@ int direction;
if (!(nat = (nat_t *)KMALLOC(sizeof(*nat))))
return NULL;
-
/*
* Search the current table for a match.
*/
diff --git a/sys/netinet/ip_nat.h b/sys/netinet/ip_nat.h
index e3785d421d7..19ce04caa5a 100644
--- a/sys/netinet/ip_nat.h
+++ b/sys/netinet/ip_nat.h
@@ -6,6 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
+ * $Id: ip_nat.h,v 1.3 1996/07/18 05:01:06 dm Exp $
*/
#ifndef __IP_NAT_H_
@@ -20,11 +21,15 @@
#define SIOCRMNAT _IOW('r', 81, struct ipnat)
#define SIOCGNATS _IOR('r', 82, struct natstat)
#define SIOCGNATL _IOWR('r', 83, struct natlookup)
+#define SIOCGFRST _IOR('r', 84, struct ipfrstat)
+#define SIOCGIPST _IOR('r', 85, struct ips_stat)
#else
#define SIOCADNAT _IOW(r, 80, struct ipnat)
#define SIOCRMNAT _IOW(r, 81, struct ipnat)
#define SIOCGNATS _IOR(r, 82, struct natstat)
#define SIOCGNATL _IOWR(r, 83, struct natlookup)
+#define SIOCGFRST _IOR(r, 84, struct ipfrstat)
+#define SIOCGIPST _IOR(r, 85, struct ips_stat)
#endif
#define NAT_SIZE 367
diff --git a/sys/netinet/ip_state.c b/sys/netinet/ip_state.c
index c6d1eff2d5f..946312cf4d7 100644
--- a/sys/netinet/ip_state.c
+++ b/sys/netinet/ip_state.c
@@ -6,7 +6,8 @@
* to the original author and the contributors.
*/
#ifndef lint
-static char sccsid[] = "@(#)ip_state.c 1.6 3/24/96 (C) 1993-1995 Darren Reed";
+static char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
+static char rcsid[] = "$Id: ip_state.c,v 1.3 1996/07/18 05:01:08 dm Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@@ -48,6 +49,7 @@ static char sccsid[] = "@(#)ip_state.c 1.6 3/24/96 (C) 1993-1995 Darren Reed";
#include <syslog.h>
#endif
#include "ip_fil.h"
+#include "ip_fil_compat.h"
#include "ip_state.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -82,9 +84,9 @@ ips_stat_t *fr_statetstats()
/*
* Create a new ipstate structure and hang it off the hash table.
*/
-int fr_addstate(ip, hlen, pass)
+int fr_addstate(ip, fin, pass)
ip_t *ip;
-int hlen;
+fr_info_t *fin;
u_int pass;
{
ipstate_t ips;
@@ -106,7 +108,7 @@ u_int pass;
{
case IPPROTO_ICMP :
{
- struct icmp *ic = (struct icmp *)((char *)ip + hlen);
+ struct icmp *ic = (struct icmp *)fin->fin_dp;
switch (ic->icmp_type)
{
@@ -129,7 +131,7 @@ u_int pass;
}
case IPPROTO_TCP :
{
- register tcphdr_t *tcp = (tcphdr_t *)((char *)ip + hlen);
+ register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
/*
* The endian of the ports doesn't matter, but the ack and
@@ -154,7 +156,7 @@ u_int pass;
}
case IPPROTO_UDP :
{
- register tcphdr_t *tcp = (tcphdr_t *)((char *)ip + hlen);
+ register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
hv += (is->is_dport = tcp->th_dport);
hv += (is->is_sport = tcp->th_sport);
@@ -175,7 +177,9 @@ u_int pass;
MUTEX_ENTER(&ipf_state);
is->is_next = ips_table[hv];
ips_table[hv] = is;
- is->is_pass = pass & ~(FR_LOGFIRST|FR_LOG);
+ is->is_pass = pass;
+ if (pass & FR_LOGFIRST)
+ is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
ips_num++;
MUTEX_EXIT(&ipf_state);
return 0;
@@ -303,9 +307,12 @@ fr_info_t *fin;
* timeout.
*/
#ifdef _KERNEL
- if ((tcp->th_flags & TCP_CLOSE) &&
- !is->is_age)
- is->is_age = 120;
+ if (!is->is_age) {
+ if (tcp->th_flags & TH_FIN)
+ is->is_age = 120;
+ if (tcp->th_flags & TH_RST)
+ is->is_age = 1;
+ }
MUTEX_EXIT(&ipf_state);
return is->is_pass;
#else
diff --git a/sys/netinet/ip_state.h b/sys/netinet/ip_state.h
index d22c930504d..b4aee7a4e14 100644
--- a/sys/netinet/ip_state.h
+++ b/sys/netinet/ip_state.h
@@ -6,6 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
+ * $Id: ip_state.h,v 1.2 1996/07/18 05:01:09 dm Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -55,11 +56,6 @@ typedef struct ipstate {
#define is_sport is_tcp.ts_sport
#define is_dport is_tcp.ts_dport
-#if defined(__STDC__) || defined(__GNUC__)
-#define SIOCGIPST _IOR('r', 75, struct ips_stat)
-#else
-#define SIOCGIPST _IOR(r, 75, struct ips_stat)
-#endif
typedef struct ips_stat {
u_long iss_hits;
diff --git a/usr.sbin/ipftest/ipft_ef.c b/usr.sbin/ipftest/ipft_ef.c
index 0febf3a6c3c..f2af0bc6a61 100644
--- a/usr.sbin/ipftest/ipft_ef.c
+++ b/usr.sbin/ipftest/ipft_ef.c
@@ -47,6 +47,7 @@ etherfind -n -t
#ifndef lint
static char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
+static char rcsid[] = "$Id: ipft_ef.c,v 1.4 1996/07/18 04:59:22 dm Exp $";
#endif
static int etherf_open(), etherf_close(), etherf_readip();
diff --git a/usr.sbin/ipftest/ipft_hx.c b/usr.sbin/ipftest/ipft_hx.c
index ceed1189dfb..46c795778cf 100644
--- a/usr.sbin/ipftest/ipft_hx.c
+++ b/usr.sbin/ipftest/ipft_hx.c
@@ -30,6 +30,7 @@
#include <netinet/ip_icmp.h>
#include <netinet/tcpip.h>
#include <net/if.h>
+#include "ip_fil_compat.h"
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
@@ -38,6 +39,7 @@
#ifndef lint
static char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
+static char rcsid[] = "$Id: ipft_hx.c,v 1.2 1996/07/18 04:59:23 dm Exp $";
#endif
extern int opts;
diff --git a/usr.sbin/ipftest/ipft_pc.c b/usr.sbin/ipftest/ipft_pc.c
index 72f94900fc0..e4020efb3fa 100644
--- a/usr.sbin/ipftest/ipft_pc.c
+++ b/usr.sbin/ipftest/ipft_pc.c
@@ -30,6 +30,10 @@
#include "ipt.h"
#include "pcap.h"
+#ifndef lint
+static char rcsid[] = "$Id: ipft_pc.c,v 1.4 1996/07/18 04:59:23 dm Exp $";
+#endif
+
struct llc {
int lc_sz; /* LLC header length */
int lc_to; /* LLC Type offset */
diff --git a/usr.sbin/ipftest/ipft_sn.c b/usr.sbin/ipftest/ipft_sn.c
index 68978d8dc37..2e2b3370591 100644
--- a/usr.sbin/ipftest/ipft_sn.c
+++ b/usr.sbin/ipftest/ipft_sn.c
@@ -33,6 +33,10 @@
#include "ipt.h"
#include "snoop.h"
+#ifndef lint
+static char rcsid[] = "$Id: ipft_sn.c,v 1.3 1996/07/18 04:59:24 dm Exp $";
+#endif
+
struct llc {
int lc_sz; /* LLC header length */
int lc_to; /* LLC Type offset */
diff --git a/usr.sbin/ipftest/ipft_td.c b/usr.sbin/ipftest/ipft_td.c
index 828ac4e4fe1..6ce649dea8a 100644
--- a/usr.sbin/ipftest/ipft_td.c
+++ b/usr.sbin/ipftest/ipft_td.c
@@ -56,6 +56,7 @@ tcpdump -nqte
#ifndef lint
static char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
+static char rcsid[] = "$Id: ipft_td.c,v 1.4 1996/07/18 04:59:24 dm Exp $";
#endif
static int tcpd_open(), tcpd_close(), tcpd_readip();
diff --git a/usr.sbin/ipftest/ipft_tx.c b/usr.sbin/ipftest/ipft_tx.c
index 277613ad356..af71291e8c8 100644
--- a/usr.sbin/ipftest/ipft_tx.c
+++ b/usr.sbin/ipftest/ipft_tx.c
@@ -30,27 +30,113 @@
#include <netinet/ip_icmp.h>
#include <netinet/tcpip.h>
#include <net/if.h>
+#include "ip_fil_compat.h"
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
-#include "ip_fil.h"
#include "ipf.h"
#include "ipt.h"
#ifndef lint
-static char sccsid[] = "@(#)ipft_tx.c 1.6 2/4/96 (C) 1993 Darren Reed";
+static char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
+static char rcsid[] = "$Id: ipft_tx.c,v 1.4 1996/07/18 04:59:24 dm Exp $";
#endif
extern int opts;
-extern u_short portnum();
extern u_long buildopts();
+static char *tx_proto = "";
+
static int text_open(), text_close(), text_readip(), parseline();
+static char tcp_flagset[] = "FSRPAU";
+static u_char tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
+ TH_ACK, TH_URG };
+
struct ipread iptext = { text_open, text_close, text_readip };
static FILE *tfp = NULL;
static int tfd = -1;
+static u_long tx_hostnum();
+static u_short tx_portnum();
+
+
+/*
+ * returns an ip address as a long var as a result of either a DNS lookup or
+ * straight inet_addr() call
+ */
+u_long tx_hostnum(host, resolved)
+char *host;
+int *resolved;
+{
+ struct hostent *hp;
+ struct netent *np;
+
+ *resolved = 0;
+ if (!strcasecmp("any",host))
+ return 0L;
+ if (isdigit(*host))
+ return inet_addr(host);
+
+ if (!(hp = gethostbyname(host))) {
+ if (!(np = getnetbyname(host))) {
+ *resolved = -1;
+ fprintf(stderr, "can't resolve hostname: %s\n", host);
+ return 0;
+ }
+ return np->n_net;
+ }
+ return *(u_long *)hp->h_addr;
+}
+
+
+/*
+ * find the port number given by the name, either from getservbyname() or
+ * straight atoi()
+ */
+u_short tx_portnum(name)
+char *name;
+{
+ struct servent *sp, *sp2;
+ u_short p1 = 0;
+
+ if (isdigit(*name))
+ return (u_short)atoi(name);
+ if (!tx_proto)
+ tx_proto = "tcp/udp";
+ if (strcasecmp(tx_proto, "tcp/udp")) {
+ sp = getservbyname(name, tx_proto);
+ if (sp)
+ return ntohs(sp->s_port);
+ (void) fprintf(stderr, "unknown service \"%s\".\n", name);
+ return 0;
+ }
+ sp = getservbyname(name, "tcp");
+ if (sp)
+ p1 = sp->s_port;
+ sp2 = getservbyname(name, "udp");
+ if (!sp || !sp2) {
+ (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n",
+ name);
+ return 0;
+ }
+ if (p1 != sp2->s_port) {
+ (void) fprintf(stderr, "%s %d/tcp is a different port to ",
+ name, p1);
+ (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port);
+ return 0;
+ }
+ return ntohs(p1);
+}
+
+
+char *tx_icmptypes[] = {
+ "echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
+ "redir", (char *)NULL, (char *)NULL, "echo", (char *)NULL,
+ (char *)NULL, "timex", "paramprob", "timest", "timestrep",
+ "inforeq", "inforep", "maskreq", "maskrep", "END"
+};
+
static int text_open(fname)
char *fname;
{
@@ -119,16 +205,15 @@ struct ip *ip;
char **ifn;
int *out;
{
- extern char *proto;
tcphdr_t th, *tcp = &th;
struct icmp icmp, *ic = &icmp;
- char *cps[20], **cpp, c, opts[68];
+ char *cps[20], **cpp, c, ipopts[68];
int i, r;
bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip));
bzero((char *)tcp, sizeof(*tcp));
bzero((char *)ic, sizeof(*ic));
- bzero(opts, sizeof(opts));
+ bzero(ipopts, sizeof(ipopts));
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; )
@@ -160,15 +245,15 @@ int *out;
if (c == 't') {
ip->ip_p = IPPROTO_TCP;
ip->ip_len += sizeof(struct tcphdr);
- proto = "tcp";
+ tx_proto = "tcp";
} else if (c == 'u') {
ip->ip_p = IPPROTO_UDP;
ip->ip_len += sizeof(struct udphdr);
- proto = "udp";
+ tx_proto = "udp";
} else {
ip->ip_p = IPPROTO_ICMP;
ip->ip_len += sizeof(struct icmp);
- proto = "icmp";
+ tx_proto = "icmp";
}
cpp++;
} else
@@ -185,9 +270,9 @@ int *out;
return 1;
}
*last++ = '\0';
- tcp->th_sport = htons(portnum(last));
+ tcp->th_sport = htons(tx_portnum(last));
}
- ip->ip_src.s_addr = hostnum(*cpp, &r);
+ ip->ip_src.s_addr = tx_hostnum(*cpp, &r);
cpp++;
if (!*cpp)
return 1;
@@ -201,27 +286,28 @@ int *out;
return 1;
}
*last++ = '\0';
- tcp->th_dport = htons(portnum(last));
+ tcp->th_dport = htons(tx_portnum(last));
}
- ip->ip_dst.s_addr = hostnum(*cpp, &r);
+ ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);
cpp++;
if (*cpp && ip->ip_p == IPPROTO_TCP) {
- extern char flagset[];
- extern u_char flags[];
+ extern char tcp_flagset[];
+ extern u_char tcp_flags[];
char *s, *t;
for (s = *cpp; *s; s++)
- if ((t = index(flagset, *s)))
- tcp->th_flags |= flags[t - flagset];
+ if ((t = index(tcp_flagset, *s)))
+ tcp->th_flags |= tcp_flags[t - tcp_flagset];
if (tcp->th_flags)
cpp++;
assert(tcp->th_flags != 0);
} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {
- extern char *icmptypes[];
+ extern char *tx_icmptypes[];
char **s, *t;
int i;
- for (s = icmptypes, i = 0; !*s || strcmp(*s, "END"); s++, i++)
+ for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END");
+ s++, i++)
if (*s && !strncasecmp(*cpp, *s, strlen(*s))) {
ic->icmp_type = i;
if ((t = index(*cpp, ',')))
@@ -235,9 +321,9 @@ int *out;
u_long olen;
cpp++;
- olen = buildopts(*cpp, opts);
+ olen = buildopts(*cpp, ipopts);
if (olen) {
- bcopy(opts, (char *)(ip + 1), olen);
+ bcopy(ipopts, (char *)(ip + 1), olen);
ip->ip_hl += olen >> 2;
}
}
diff --git a/usr.sbin/ipftest/ipftest.1 b/usr.sbin/ipftest/ipftest.1
index 2e6991a0d09..72591402fa2 100644
--- a/usr.sbin/ipftest/ipftest.1
+++ b/usr.sbin/ipftest/ipftest.1
@@ -3,7 +3,7 @@
.SH NAME
ipftest - test packet filter rules with arbitary input.
.SH SYNOPSIS
-ipftest [-vbdPSTE] [-I interface] -r <filename> [-i <filename>]
+ipftest [-vbdPSTEHX] [-I interface] -r <filename> [-i <filename>]
.SH DESCRIPTION
.LP
.PP
@@ -77,6 +77,12 @@ option combinations:
tcpdump -nqte
.fi
.LP
+.IP -H
+The input file is to be hex digits, representing the binary makeup of the
+packet. No length correction is made, if an incorrect length is put in
+the IP header.
+.IP -X
+The input file is composed of text descriptions of IP packets.
.IP -E
The input file is to be text output from etherfind. The text formats which
are currently supported are those which result from the following etherfind
diff --git a/usr.sbin/ipftest/ipt.c b/usr.sbin/ipftest/ipt.c
index 315ffd992c0..4ec9a8a5c39 100644
--- a/usr.sbin/ipftest/ipt.c
+++ b/usr.sbin/ipftest/ipt.c
@@ -39,7 +39,8 @@
#include <ctype.h>
#ifndef lint
-static char sccsid[] = "@(#)ipt.c 1.17 3/9/96 (C) 1993-1996 Darren Reed";
+static char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
+static char rcsid[] = "$Id: ipt.c,v 1.5 1996/07/18 04:59:25 dm Exp $";
#endif
extern int fr_check();
@@ -49,8 +50,6 @@ extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
extern void debug(), verbose();
struct frentry *ft_in = NULL, *ft_out = NULL;
-struct ipread *readers[] = { &iptext, &etherf, &tcpd, &snoop, &pcap, &iphex,
- NULL };
int opts = 0;
@@ -58,7 +57,7 @@ int main(argc,argv)
int argc;
char *argv[];
{
- struct ipread **r = readers;
+ struct ipread *r = &iptext;
struct frentry *f;
struct ip *ip;
u_long buf[64];
@@ -66,7 +65,7 @@ char *argv[];
char *rules = NULL, *datain = NULL, *iface = NULL;
int fd, i, dir = 0;
- while ((c = getopt(argc, argv, "bdEHi:I:Pr:STv")) != -1)
+ while ((c = getopt(argc, argv, "bdEHi:I:Pr:STvX")) != -1)
switch (c)
{
case 'b' :
@@ -88,29 +87,22 @@ char *argv[];
opts |= OPT_VERBOSE;
break;
case 'E' :
- for (i = 0, r = readers; *r; i++, r++)
- if (*r == &etherf)
- break;
+ r = &etherf;
break;
case 'H' :
- for (i = 0, r = readers; *r; i++, r++)
- if (*r == &iphex)
- break;
+ r = &iphex;
break;
case 'P' :
- for (i = 0, r = readers; *r; i++, r++)
- if (*r == &pcap)
- break;
+ r = &pcap;
break;
case 'S' :
- for (i = 0, r = readers; *r; i++, r++)
- if (*r == &snoop)
- break;
+ r = &snoop;
break;
case 'T' :
- for (i = 0, r = readers; *r; i++, r++)
- if (*r == &tcpd)
- break;
+ r = &tcpd;
+ break;
+ case 'X' :
+ r = &iptext;
break;
}
@@ -119,7 +111,7 @@ char *argv[];
exit(-1);
}
- initparse ();
+ initparse();
if (rules) {
struct frentry *fr;
@@ -171,15 +163,15 @@ char *argv[];
}
if (datain)
- fd = (*(*r)->r_open)(datain);
+ fd = (*r->r_open)(datain);
else
- fd = (*(*r)->r_open)("-");
+ fd = (*r->r_open)("-");
if (fd < 0)
exit(-1);
ip = (struct ip *)buf;
- while ((i = (*(*r)->r_readip)(buf, sizeof(buf), &iface, &dir)) > 0) {
+ while ((i = (*r->r_readip)(buf, sizeof(buf), &iface, &dir)) > 0) {
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
switch (fr_check(ip, ip->ip_hl << 2, iface, dir))
@@ -202,6 +194,6 @@ char *argv[];
putchar('\n');
dir = 0;
}
- (*(*r)->r_close)();
+ (*r->r_close)();
return 0;
}
diff --git a/usr.sbin/ipftest/ipt.h b/usr.sbin/ipftest/ipt.h
index fd0e5acf3e0..4545e1b39c4 100644
--- a/usr.sbin/ipftest/ipt.h
+++ b/usr.sbin/ipftest/ipt.h
@@ -4,6 +4,7 @@
* 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: ipt.h,v 1.2 1996/07/18 04:59:25 dm Exp $
*/
#include <fcntl.h>
diff --git a/usr.sbin/ipftest/pcap.h b/usr.sbin/ipftest/pcap.h
index 94373c9c52d..5ffb01c7484 100644
--- a/usr.sbin/ipftest/pcap.h
+++ b/usr.sbin/ipftest/pcap.h
@@ -4,6 +4,7 @@
* 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: pcap.h,v 1.3 1996/07/18 04:59:26 dm Exp $
*/
/*
* This header file is constructed to match the version described by
diff --git a/usr.sbin/ipftest/snoop.h b/usr.sbin/ipftest/snoop.h
index 37503ea29f8..e351a1f7c7d 100644
--- a/usr.sbin/ipftest/snoop.h
+++ b/usr.sbin/ipftest/snoop.h
@@ -8,6 +8,7 @@
/*
* written to comply with the RFC (1761) from Sun.
+ * $Id: snoop.h,v 1.2 1996/07/18 04:59:26 dm Exp $
*/
struct snoophdr {
char s_id[8];
diff --git a/usr.sbin/ipmon/ipmon.c b/usr.sbin/ipmon/ipmon.c
index 5f7d377ae71..188551b16bf 100644
--- a/usr.sbin/ipmon/ipmon.c
+++ b/usr.sbin/ipmon/ipmon.c
@@ -39,7 +39,8 @@
#include <arpa/inet.h>
#ifndef lint
-static char sccsid[] = "@(#)ipmon.c 1.20 3/24/96 (C)1993-1996 Darren Reed";
+static char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1996 Darren Reed";
+static char rcsid[] = "$Id: ipmon.c,v 1.4 1996/07/18 04:58:47 dm Exp $";
#endif
#include "ip_fil.h"
@@ -137,7 +138,7 @@ int opts;
struct tm *tm;
char c[3], pname[8], *t, *proto;
u_short hl, p;
- int i, lvl, res;
+ int i, lvl, res, len;
res = (opts & 2) ? 1 : 0;
t = line;
@@ -150,15 +151,20 @@ int opts;
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
-#if !defined (__OpenBSD__) && !defined (__NetBSD__)
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %c%c%ld @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- lp->ifname[0], lp->ifname[1], lp->unit, lp->rule);
-#else /* OpenBSD or NetBSD */
+#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
(void) sprintf(t, "%02d:%02d:%02d.%-.6ld %s @%hd ",
tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
lp->ifname, lp->rule);
-#endif /* OpenBSD or NetBSD */
+#else
+ for (len = 0; len < 3; len++)
+ if (!lp->ifname[len])
+ break;
+ if (lp->ifname[len])
+ len++;
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %*.*s%ld @%hd ",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
+ len, len, lp->ifname, lp->unit, lp->rule);
+#endif
pr = getprotobynumber((int)p);
if (!pr) {
proto = pname;
@@ -342,5 +348,7 @@ char *argv[];
(iplci.hlen + iplci.plen));
printpacket(log, buf, &iplci, opts);
}
- return 0;
+ /* NOTREACHED */
+ exit(0);
+ /* NOTREACHED */
}
diff --git a/usr.sbin/ipsend/ipresend/Makefile b/usr.sbin/ipsend/ipresend/Makefile
index da0f8a37855..99d65114bcb 100644
--- a/usr.sbin/ipsend/ipresend/Makefile
+++ b/usr.sbin/ipsend/ipresend/Makefile
@@ -1,12 +1,14 @@
-# $Id: Makefile,v 1.1 1996/05/10 21:40:57 dm Exp $
+# $Id: Makefile,v 1.2 1996/07/18 05:00:22 dm Exp $
PROG= ipresend
BINDIR= /usr/sbin
NOMAN=
-SRCS= ipresend.c resend.c ip.c sbpf.c sock.c 44arp.c ipft_sn.c ipft_pc.c
+SRCS= ipresend.c resend.c ip.c sbpf.c sock.c 44arp.c opt.c \
+ ipft_ef.c ipft_hx.c ipft_pc.c ipft_sn.c ipft_tx.c ipft_td.c
CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest \
-I${.CURDIR}/../../../sbin/ipf \
-I${.CURDIR}/../../../sys/netinet
-.PATH: ${.CURDIR}/../common ${.CURDIR}/../../ipftest
+.PATH: ${.CURDIR}/../common ${.CURDIR}/../../ipftest \
+ ${.CURDIR}/../../../sbin/ipf
.include <bsd.prog.mk>
diff --git a/usr.sbin/ipsend/ipresend/ipresend.c b/usr.sbin/ipsend/ipresend/ipresend.c
index 482811a4b53..863c8b754da 100644
--- a/usr.sbin/ipsend/ipresend/ipresend.c
+++ b/usr.sbin/ipsend/ipresend/ipresend.c
@@ -15,7 +15,7 @@
* This was written and tested (successfully) on SunOS 4.1.x.
*/
#ifndef lint
-static char sccsid[] = "@(#)ipresend.c 1.1 1/11/96 (C)1995 Darren Reed";
+static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
#endif
#include <stdio.h>
#include <netdb.h>
@@ -43,24 +43,29 @@ static char sccsid[] = "@(#)ipresend.c 1.1 1/11/96 (C)1995 Darren Reed";
extern char *optarg;
extern int optind;
-extern struct ipread snoop, pcap;
+extern struct ipread snoop, pcap, etherf, iphex, tcpd, iptext;
-#ifdef linux
+int opts = 0;
+#ifndef DEFAULT_DEVICE
+# ifdef linux
char default_device[] = "eth0";
-#else
-# ifdef sun
-char default_device[] = "le0";
# else
-# ifdef ultrix
-char default_device[] = "ln0";
+# ifdef sun
+char default_device[] = "le0";
# else
-# ifdef __bsdi__
-char default_device[] = "ef0";
+# ifdef ultrix
+char default_device[] = "ln0";
# else
+# ifdef __bsdi__
+char default_device[] = "ef0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
+#else
+char default_device[] = DEFAULT_DEVICE;
#endif
@@ -89,13 +94,9 @@ char **argv;
char c, *s, *resend = NULL;
int mtu = 1500;
- while ((c = getopt(argc, argv, "R:d:g:m:r:")) != -1)
+ while ((c = getopt(argc, argv, "EHPSTXd:g:m:r:")) != -1)
switch (c)
{
- case 'R' :
- resend = optarg;
- ipr = &pcap;
- break;
case 'd' :
dev = optarg;
break;
@@ -111,8 +112,24 @@ char **argv;
}
case 'r' :
resend = optarg;
+ break;
+ case 'E' :
+ ipr = &etherf;
+ break;
+ case 'H' :
+ ipr = &iphex;
+ break;
+ case 'P' :
+ ipr = &pcap;
+ break;
+ case 'S' :
ipr = &snoop;
break;
+ case 'T' :
+ ipr = &tcpd;
+ break;
+ case 'X' :
+ ipr = &iptext;
break;
default :
fprintf(stderr, "Unknown option \"%c\"\n", c);