diff options
author | dm <dm@cvs.openbsd.org> | 1996-07-18 05:01:10 +0000 |
---|---|---|
committer | dm <dm@cvs.openbsd.org> | 1996-07-18 05:01:10 +0000 |
commit | 746e8c40786f598f5da99fed9714ae7961393281 (patch) | |
tree | 7fa485ff1f4c0076948de7742853326232fa0cc1 | |
parent | 6764f712dd3ffd42fd940f9e87d2a9109743c72d (diff) |
ipfilter 3.1.0
-rw-r--r-- | sys/netinet/fil.c | 135 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 7 | ||||
-rw-r--r-- | sys/netinet/ip_fil.c | 339 | ||||
-rw-r--r-- | sys/netinet/ip_fil.h | 271 | ||||
-rw-r--r-- | sys/netinet/ip_fil_compat.h | 216 | ||||
-rw-r--r-- | sys/netinet/ip_frag.c | 2 | ||||
-rw-r--r-- | sys/netinet/ip_frag.h | 6 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_nat.c | 89 | ||||
-rw-r--r-- | sys/netinet/ip_nat.h | 5 | ||||
-rw-r--r-- | sys/netinet/ip_state.c | 27 | ||||
-rw-r--r-- | sys/netinet/ip_state.h | 6 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_ef.c | 1 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_hx.c | 2 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_pc.c | 4 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_sn.c | 4 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_td.c | 1 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipft_tx.c | 128 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipftest.1 | 8 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipt.c | 42 | ||||
-rw-r--r-- | usr.sbin/ipftest/ipt.h | 1 | ||||
-rw-r--r-- | usr.sbin/ipftest/pcap.h | 1 | ||||
-rw-r--r-- | usr.sbin/ipftest/snoop.h | 1 | ||||
-rw-r--r-- | usr.sbin/ipmon/ipmon.c | 26 | ||||
-rw-r--r-- | usr.sbin/ipsend/ipresend/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/ipsend/ipresend/ipresend.c | 47 |
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, ðerf, &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 == ðerf) - break; + r = ðerf; 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 = ðerf; + 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); |