summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/ipsend
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>1997-02-09 22:50:16 +0000
committerdarrenr <darrenr@FreeBSD.org>1997-02-09 22:50:16 +0000
commitcb8d46a179f2d30ac1cd0a01eb156e1a4c08d717 (patch)
tree93c7db298b1fd70f9e27663b3fd527da063d0008 /contrib/ipfilter/ipsend
downloadFreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.zip
FreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.tar.gz
Import IP Filter v3.1.7 into FreeBSD tree
Diffstat (limited to 'contrib/ipfilter/ipsend')
-rw-r--r--contrib/ipfilter/ipsend/44arp.c95
-rw-r--r--contrib/ipfilter/ipsend/Crashable20
-rw-r--r--contrib/ipfilter/ipsend/Makefile91
-rw-r--r--contrib/ipfilter/ipsend/arp.c119
-rw-r--r--contrib/ipfilter/ipsend/dlcommon.c1359
-rw-r--r--contrib/ipfilter/ipsend/dltest.h32
-rw-r--r--contrib/ipfilter/ipsend/in_var.h177
-rw-r--r--contrib/ipfilter/ipsend/ip.c346
-rw-r--r--contrib/ipfilter/ipsend/ip_compat.h242
-rw-r--r--contrib/ipfilter/ipsend/ip_var.h123
-rw-r--r--contrib/ipfilter/ipsend/ipresend.c165
-rw-r--r--contrib/ipfilter/ipsend/ipsend.c350
-rw-r--r--contrib/ipfilter/ipsend/ipsopt.c111
-rw-r--r--contrib/ipfilter/ipsend/iptest.c211
-rw-r--r--contrib/ipfilter/ipsend/iptests.c1296
-rw-r--r--contrib/ipfilter/ipsend/larp.c85
-rw-r--r--contrib/ipfilter/ipsend/linux.h17
-rw-r--r--contrib/ipfilter/ipsend/lsock.c261
-rw-r--r--contrib/ipfilter/ipsend/resend.c130
-rw-r--r--contrib/ipfilter/ipsend/sbpf.c136
-rw-r--r--contrib/ipfilter/ipsend/sdlpi.c130
-rw-r--r--contrib/ipfilter/ipsend/slinux.c94
-rw-r--r--contrib/ipfilter/ipsend/snit.c160
-rw-r--r--contrib/ipfilter/ipsend/sock.c370
-rw-r--r--contrib/ipfilter/ipsend/tcpip.h38
25 files changed, 6158 insertions, 0 deletions
diff --git a/contrib/ipfilter/ipsend/44arp.c b/contrib/ipfilter/ipsend/44arp.c
new file mode 100644
index 0000000..621d84c
--- /dev/null
+++ b/contrib/ipfilter/ipsend/44arp.c
@@ -0,0 +1,95 @@
+/*
+ * Based upon 4.4BSD's /usr/sbin/arp
+ */
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include <nlist.h>
+#include <stdio.h>
+
+/*
+ * lookup host and return
+ * its IP address in address
+ * (4 bytes)
+ */
+int resolve(host, address)
+char *host, *address;
+{
+ struct hostent *hp;
+ u_long add;
+
+ add = inet_addr(host);
+ if (add == -1)
+ {
+ if (!(hp = gethostbyname(host)))
+ {
+ fprintf(stderr, "unknown host: %s\n", host);
+ return -1;
+ }
+ bcopy((char *)hp->h_addr, (char *)address, 4);
+ return 0;
+ }
+ bcopy((char*)&add, address, 4);
+ return 0;
+}
+
+
+int arp(addr, eaddr)
+char *addr, *eaddr;
+{
+ int mib[6];
+ size_t needed;
+ char *malloc(), *lim, *buf, *next;
+ struct rt_msghdr *rtm;
+ struct sockaddr_inarp *sin;
+ struct sockaddr_dl *sdl;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = AF_INET;
+ mib[4] = NET_RT_FLAGS;
+ mib[5] = RTF_LLINFO;
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ {
+ perror("route-sysctl-estimate");
+ exit(-1);
+ }
+ if ((buf = malloc(needed)) == NULL)
+ {
+ perror("malloc");
+ exit(-1);
+ }
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
+ {
+ perror("actual retrieval of routing table");
+ exit(-1);
+ }
+ lim = buf + needed;
+ for (next = buf; next < lim; next += rtm->rtm_msglen)
+ {
+ rtm = (struct rt_msghdr *)next;
+ sin = (struct sockaddr_inarp *)(rtm + 1);
+ sdl = (struct sockaddr_dl *)(sin + 1);
+ if (addr && !bcmp(addr, (char *)&sin->sin_addr,
+ sizeof(struct in_addr)))
+ {
+ bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen);
+ return 0;
+ }
+ }
+ return -1;
+}
diff --git a/contrib/ipfilter/ipsend/Crashable b/contrib/ipfilter/ipsend/Crashable
new file mode 100644
index 0000000..dbe1b87
--- /dev/null
+++ b/contrib/ipfilter/ipsend/Crashable
@@ -0,0 +1,20 @@
+Test 1:
+ Solaris 2.4 - upto and including 101945-34, > 34 ?
+ Solaris 2.5 - 11/95
+ Linux 1.2.13, < 1.3.45(?)
+ 3com/sonix bridge
+ Instant Internet
+ KA9Q NOS
+ Netblazer 40i, Version 3.2 OS
+ Irix 6.x
+ HP-UX 9.0
+ HP-UX 10.1
+ LivingstonsComOS
+
+Test 6:
+ SunOS 4.1.x
+ ULtrix 4.3
+
+Test 7:
+ SunOS 4.1.x
+ Linux <= 1.3.84
diff --git a/contrib/ipfilter/ipsend/Makefile b/contrib/ipfilter/ipsend/Makefile
new file mode 100644
index 0000000..1f04912
--- /dev/null
+++ b/contrib/ipfilter/ipsend/Makefile
@@ -0,0 +1,91 @@
+#
+# (C)opyright 1993-1996 by Darren Reed.
+#
+# This code may be freely distributed as long as it retains this notice
+# and is not changed in any way. The author accepts no responsibility
+# for the use of this software. I hate legaleese, don't you ?
+#
+OBJS=ipsend.o ip.o ipsopt.o
+ROBJS=ipresend.o ip.o resend.o
+TOBJS=iptest.o iptests.o ip.o
+BPF=sbpf.o
+NIT=snit.o
+SUNOS4=sock.o arp.o
+BSD=sock.o 44arp.o
+LINUX=lsock.o slinux.o larp.o
+LINUXK=
+TOP=..
+SUNOS5=dlcommon.o sdlpi.o arp.o
+
+CC=gcc
+CFLAGS=-g -I.. -DNO_IPF
+
+all:
+ @echo "Use one of these targets:"
+ @echo " sunos4-nit (standard SunOS 4.1.x)"
+ @echo " sunos4-bpf (SunOS4.1.x with BPF in the kernel)"
+ @echo " bsd-bpf (4.4BSD variant with BPF in the kernel)"
+ @echo " linux10 (Linux 1.0 kernels)"
+ @echo " linux20 (Linux 2.0 kernels)"
+ @echo " sunos5 (Solaris 2.x)"
+
+.c.o:
+ $(CC) $(CFLAGS) $(LINUXK) -c $< -o $@
+
+bpf sunos4-bpf :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+
+nit sunos4 sunos4-nit :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+
+dlpi sunos5 :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
+
+bsd-bpf :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS) -DDOSOCKET"
+
+linuxrev :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+
+linux10:
+ make linuxrev 'LINUXK="LINUXK=-DLINUX=0100"'
+
+linux20:
+ make linuxrev 'LINUXK="LINUXK=-DLINUX=0200"'
+
+ipsend: $(OBJS) $(UNIXOBJS)
+ $(CC) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS)
+
+ipresend: $(ROBJS) $(UNIXOBJS)
+ $(CC) $(ROBJS) $(UNIXOBJS) -o $@ $(LIBS)
+
+iptest: $(TOBJS) $(UNIXOBJS)
+ $(CC) $(TOBJS) $(UNIXOBJS) -o $@ $(LIBS)
+
+clean:
+ rm -rf *.o *core a.out ipsend ipresend iptest
diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c
new file mode 100644
index 0000000..47f6fce
--- /dev/null
+++ b/contrib/ipfilter/ipsend/arp.c
@@ -0,0 +1,119 @@
+/*
+ * arp.c (C) 1995 Darren Reed
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+
+#if defined(__SVR4) || defined(__svr4__)
+#define bcopy(a,b,c) memmove(b,a,c)
+#define bzero(a,c) memset(a,0,c)
+#define bcmp(a,b,c) memcmp(a,b,c)
+#endif
+
+/*
+ * lookup host and return
+ * its IP address in address
+ * (4 bytes)
+ */
+int resolve(host, address)
+char *host, *address;
+{
+ struct hostent *hp;
+ u_long add;
+
+ add = inet_addr(host);
+ if (add == -1)
+ {
+ if (!(hp = gethostbyname(host)))
+ {
+ fprintf(stderr, "unknown host: %s\n", host);
+ return -1;
+ }
+ bcopy((char *)hp->h_addr, (char *)address, 4);
+ return 0;
+ }
+ bcopy((char*)&add, address, 4);
+ return 0;
+}
+
+/*
+ * ARP for the MAC address corresponding
+ * to the IP address. This taken from
+ * some BSD program, I cant remember which.
+ */
+int arp(ip, ether)
+char *ip;
+char *ether;
+{
+ static int sfd = -1;
+ static char ethersave[6], ipsave[4];
+ struct arpreq ar;
+ struct sockaddr_in *sin, san;
+ struct hostent *hp;
+ char *inet_ntoa();
+ int fd;
+
+ if (!bcmp(ipsave, ip, 4)) {
+ bcopy(ethersave, ether, 6);
+ return 0;
+ }
+ fd = -1;
+ bzero((char *)&ar, sizeof(ar));
+ sin = (struct sockaddr_in *)&ar.arp_pa;
+ sin->sin_family = AF_INET;
+ bcopy(ip, (char *)&sin->sin_addr.s_addr, 4);
+ if ((hp = gethostbyaddr(ip, 4, AF_INET)))
+ if (!(ether_hostton(hp->h_name, ether)))
+ goto savearp;
+
+ if (sfd == -1)
+ if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ perror("arp: socket");
+ return -1;
+ }
+tryagain:
+ if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1)
+ {
+ if (fd == -1)
+ {
+ bzero((char *)&san, sizeof(san));
+ san.sin_family = AF_INET;
+ san.sin_port = htons(1);
+ bcopy(ip, &san.sin_addr.s_addr, 4);
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ (void) sendto(fd, ip, 4, 0,
+ (struct sockaddr *)&san, sizeof(san));
+ sleep(1);
+ (void) close(fd);
+ goto tryagain;
+ }
+ fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr));
+ if (errno != ENXIO)
+ perror("SIOCGARP");
+ return -1;
+ }
+
+ bcopy(ar.arp_ha.sa_data, ether, 6);
+savearp:
+ bcopy(ether, ethersave, 6);
+ bcopy(ip, ipsave, 4);
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/dlcommon.c b/contrib/ipfilter/ipsend/dlcommon.c
new file mode 100644
index 0000000..59b283d
--- /dev/null
+++ b/contrib/ipfilter/ipsend/dlcommon.c
@@ -0,0 +1,1359 @@
+/*
+ * Common (shared) DLPI test routines.
+ * Mostly pretty boring boilerplate sorta stuff.
+ * These can be split into individual library routines later
+ * but it's just convenient to keep them in a single file
+ * while they're being developed.
+ *
+ * Not supported:
+ * Connection Oriented stuff
+ * QOS stuff
+ */
+
+/*
+typedef unsigned long ulong;
+*/
+
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#include <sys/dlpi.h>
+#include <sys/signal.h>
+#include <stdio.h>
+#include <string.h>
+#include "dltest.h"
+
+#define CASERET(s) case s: return ("s")
+
+char *dlprim();
+char *dlstate();
+char *dlerrno();
+char *dlpromisclevel();
+char *dlservicemode();
+char *dlstyle();
+char *dlmactype();
+
+
+dlinforeq(fd)
+int fd;
+{
+ dl_info_req_t info_req;
+ struct strbuf ctl;
+ int flags;
+
+ info_req.dl_primitive = DL_INFO_REQ;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (info_req);
+ ctl.buf = (char *) &info_req;
+
+ flags = RS_HIPRI;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlinforeq: putmsg");
+}
+
+dlinfoack(fd, bufp)
+int fd;
+char *bufp;
+{
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = MAXDLBUF;
+ ctl.len = 0;
+ ctl.buf = bufp;
+
+ strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlinfoack");
+
+ dlp = (union DL_primitives *) ctl.buf;
+
+ expecting(DL_INFO_ACK, dlp);
+
+ if (ctl.len < sizeof (dl_info_ack_t))
+ err("dlinfoack: response ctl.len too short: %d", ctl.len);
+
+ if (flags != RS_HIPRI)
+ err("dlinfoack: DL_INFO_ACK was not M_PCPROTO");
+
+ if (ctl.len < sizeof (dl_info_ack_t))
+ err("dlinfoack: short response ctl.len: %d", ctl.len);
+}
+
+dlattachreq(fd, ppa)
+int fd;
+u_long ppa;
+{
+ dl_attach_req_t attach_req;
+ struct strbuf ctl;
+ int flags;
+
+ attach_req.dl_primitive = DL_ATTACH_REQ;
+ attach_req.dl_ppa = ppa;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (attach_req);
+ ctl.buf = (char *) &attach_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlattachreq: putmsg");
+}
+
+dlenabmultireq(fd, addr, length)
+int fd;
+char *addr;
+int length;
+{
+ long buf[MAXDLBUF];
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ dlp = (union DL_primitives*) buf;
+
+ dlp->enabmulti_req.dl_primitive = DL_ENABMULTI_REQ;
+ dlp->enabmulti_req.dl_addr_length = length;
+ dlp->enabmulti_req.dl_addr_offset = sizeof (dl_enabmulti_req_t);
+
+ (void) memcpy((char*)OFFADDR(buf, sizeof (dl_enabmulti_req_t)), addr, length);
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (dl_enabmulti_req_t) + length;
+ ctl.buf = (char*) buf;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlenabmultireq: putmsg");
+}
+
+dldisabmultireq(fd, addr, length)
+int fd;
+char *addr;
+int length;
+{
+ long buf[MAXDLBUF];
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ dlp = (union DL_primitives*) buf;
+
+ dlp->disabmulti_req.dl_primitive = DL_ENABMULTI_REQ;
+ dlp->disabmulti_req.dl_addr_length = length;
+ dlp->disabmulti_req.dl_addr_offset = sizeof (dl_disabmulti_req_t);
+
+ (void) memcpy((char*)OFFADDR(buf, sizeof (dl_disabmulti_req_t)), addr, length);
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (dl_disabmulti_req_t) + length;
+ ctl.buf = (char*) buf;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dldisabmultireq: putmsg");
+}
+
+dlpromisconreq(fd, level)
+int fd;
+u_long level;
+{
+ dl_promiscon_req_t promiscon_req;
+ struct strbuf ctl;
+ int flags;
+
+ promiscon_req.dl_primitive = DL_PROMISCON_REQ;
+ promiscon_req.dl_level = level;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (promiscon_req);
+ ctl.buf = (char *) &promiscon_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlpromiscon: putmsg");
+
+}
+
+dlpromiscoff(fd, level)
+int fd;
+u_long level;
+{
+ dl_promiscoff_req_t promiscoff_req;
+ struct strbuf ctl;
+ int flags;
+
+ promiscoff_req.dl_primitive = DL_PROMISCOFF_REQ;
+ promiscoff_req.dl_level = level;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (promiscoff_req);
+ ctl.buf = (char *) &promiscoff_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlpromiscoff: putmsg");
+}
+
+dlphysaddrreq(fd, addrtype)
+int fd;
+u_long addrtype;
+{
+ dl_phys_addr_req_t phys_addr_req;
+ struct strbuf ctl;
+ int flags;
+
+ phys_addr_req.dl_primitive = DL_PHYS_ADDR_REQ;
+ phys_addr_req.dl_addr_type = addrtype;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (phys_addr_req);
+ ctl.buf = (char *) &phys_addr_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlphysaddrreq: putmsg");
+}
+
+dlsetphysaddrreq(fd, addr, length)
+int fd;
+char *addr;
+int length;
+{
+ long buf[MAXDLBUF];
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ dlp = (union DL_primitives*) buf;
+
+ dlp->set_physaddr_req.dl_primitive = DL_ENABMULTI_REQ;
+ dlp->set_physaddr_req.dl_addr_length = length;
+ dlp->set_physaddr_req.dl_addr_offset = sizeof (dl_set_phys_addr_req_t);
+
+ (void) memcpy((char*)OFFADDR(buf, sizeof (dl_set_phys_addr_req_t)), addr, length);
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (dl_set_phys_addr_req_t) + length;
+ ctl.buf = (char*) buf;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlsetphysaddrreq: putmsg");
+}
+
+dldetachreq(fd)
+int fd;
+{
+ dl_detach_req_t detach_req;
+ struct strbuf ctl;
+ int flags;
+
+ detach_req.dl_primitive = DL_DETACH_REQ;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (detach_req);
+ ctl.buf = (char *) &detach_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dldetachreq: putmsg");
+}
+
+dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest)
+int fd;
+u_long sap;
+u_long max_conind;
+u_long service_mode;
+u_long conn_mgmt;
+u_long xidtest;
+{
+ dl_bind_req_t bind_req;
+ struct strbuf ctl;
+ int flags;
+
+ bind_req.dl_primitive = DL_BIND_REQ;
+ bind_req.dl_sap = sap;
+ bind_req.dl_max_conind = max_conind;
+ bind_req.dl_service_mode = service_mode;
+ bind_req.dl_conn_mgmt = conn_mgmt;
+ bind_req.dl_xidtest_flg = xidtest;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (bind_req);
+ ctl.buf = (char *) &bind_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlbindreq: putmsg");
+}
+
+dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen)
+int fd;
+u_char *addrp;
+int addrlen;
+u_long minpri, maxpri;
+u_char *datap;
+int datalen;
+{
+ long buf[MAXDLBUF];
+ union DL_primitives *dlp;
+ struct strbuf data, ctl;
+
+ dlp = (union DL_primitives*) buf;
+
+ dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;
+ dlp->unitdata_req.dl_dest_addr_length = addrlen;
+ dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
+ dlp->unitdata_req.dl_priority.dl_min = minpri;
+ dlp->unitdata_req.dl_priority.dl_max = maxpri;
+
+ (void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen);
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (dl_unitdata_req_t) + addrlen;
+ ctl.buf = (char *) buf;
+
+ data.maxlen = 0;
+ data.len = datalen;
+ data.buf = (char *) datap;
+
+ if (putmsg(fd, &ctl, &data, 0) < 0)
+ syserr("dlunitdatareq: putmsg");
+}
+
+dlunbindreq(fd)
+int fd;
+{
+ dl_unbind_req_t unbind_req;
+ struct strbuf ctl;
+ int flags;
+
+ unbind_req.dl_primitive = DL_UNBIND_REQ;
+
+ ctl.maxlen = 0;
+ ctl.len = sizeof (unbind_req);
+ ctl.buf = (char *) &unbind_req;
+
+ flags = 0;
+
+ if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+ syserr("dlunbindreq: putmsg");
+}
+
+dlokack(fd, bufp)
+int fd;
+char *bufp;
+{
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = MAXDLBUF;
+ ctl.len = 0;
+ ctl.buf = bufp;
+
+ strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack");
+
+ dlp = (union DL_primitives *) ctl.buf;
+
+ expecting(DL_OK_ACK, dlp);
+
+ if (ctl.len < sizeof (dl_ok_ack_t))
+ err("dlokack: response ctl.len too short: %d", ctl.len);
+
+ if (flags != RS_HIPRI)
+ err("dlokack: DL_OK_ACK was not M_PCPROTO");
+
+ if (ctl.len < sizeof (dl_ok_ack_t))
+ err("dlokack: short response ctl.len: %d", ctl.len);
+}
+
+dlerrorack(fd, bufp)
+int fd;
+char *bufp;
+{
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = MAXDLBUF;
+ ctl.len = 0;
+ ctl.buf = bufp;
+
+ strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlerrorack");
+
+ dlp = (union DL_primitives *) ctl.buf;
+
+ expecting(DL_ERROR_ACK, dlp);
+
+ if (ctl.len < sizeof (dl_error_ack_t))
+ err("dlerrorack: response ctl.len too short: %d", ctl.len);
+
+ if (flags != RS_HIPRI)
+ err("dlerrorack: DL_OK_ACK was not M_PCPROTO");
+
+ if (ctl.len < sizeof (dl_error_ack_t))
+ err("dlerrorack: short response ctl.len: %d", ctl.len);
+}
+
+dlbindack(fd, bufp)
+int fd;
+char *bufp;
+{
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = MAXDLBUF;
+ ctl.len = 0;
+ ctl.buf = bufp;
+
+ strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack");
+
+ dlp = (union DL_primitives *) ctl.buf;
+
+ expecting(DL_BIND_ACK, dlp);
+
+ if (flags != RS_HIPRI)
+ err("dlbindack: DL_OK_ACK was not M_PCPROTO");
+
+ if (ctl.len < sizeof (dl_bind_ack_t))
+ err("dlbindack: short response ctl.len: %d", ctl.len);
+}
+
+dlphysaddrack(fd, bufp)
+int fd;
+char *bufp;
+{
+ union DL_primitives *dlp;
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = MAXDLBUF;
+ ctl.len = 0;
+ ctl.buf = bufp;
+
+ strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlphysaddrack");
+
+ dlp = (union DL_primitives *) ctl.buf;
+
+ expecting(DL_PHYS_ADDR_ACK, dlp);
+
+ if (flags != RS_HIPRI)
+ err("dlbindack: DL_OK_ACK was not M_PCPROTO");
+
+ if (ctl.len < sizeof (dl_phys_addr_ack_t))
+ err("dlphysaddrack: short response ctl.len: %d", ctl.len);
+}
+
+void
+sigalrm()
+{
+ (void) err("sigalrm: TIMEOUT");
+}
+
+strgetmsg(fd, ctlp, datap, flagsp, caller)
+int fd;
+struct strbuf *ctlp, *datap;
+int *flagsp;
+char *caller;
+{
+ int rc;
+ static char errmsg[80];
+
+ /*
+ * Start timer.
+ */
+ (void) signal(SIGALRM, sigalrm);
+ if (alarm(MAXWAIT) < 0) {
+ (void) sprintf(errmsg, "%s: alarm", caller);
+ syserr(errmsg);
+ }
+
+ /*
+ * Set flags argument and issue getmsg().
+ */
+ *flagsp = 0;
+ if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
+ (void) sprintf(errmsg, "%s: getmsg", caller);
+ syserr(errmsg);
+ }
+
+ /*
+ * Stop timer.
+ */
+ if (alarm(0) < 0) {
+ (void) sprintf(errmsg, "%s: alarm", caller);
+ syserr(errmsg);
+ }
+
+ /*
+ * Check for MOREDATA and/or MORECTL.
+ */
+ if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA))
+ err("%s: MORECTL|MOREDATA", caller);
+ if (rc & MORECTL)
+ err("%s: MORECTL", caller);
+ if (rc & MOREDATA)
+ err("%s: MOREDATA", caller);
+
+ /*
+ * Check for at least sizeof (long) control data portion.
+ */
+ if (ctlp->len < sizeof (long))
+ err("getmsg: control portion length < sizeof (long): %d", ctlp->len);
+}
+
+expecting(prim, dlp)
+int prim;
+union DL_primitives *dlp;
+{
+ if (dlp->dl_primitive != (u_long)prim) {
+ printdlprim(dlp);
+ err("expected %s got %s", dlprim(prim),
+ dlprim(dlp->dl_primitive));
+ exit(1);
+ }
+}
+
+/*
+ * Print any DLPI msg in human readable format.
+ */
+printdlprim(dlp)
+union DL_primitives *dlp;
+{
+ switch (dlp->dl_primitive) {
+ case DL_INFO_REQ:
+ printdlinforeq(dlp);
+ break;
+
+ case DL_INFO_ACK:
+ printdlinfoack(dlp);
+ break;
+
+ case DL_ATTACH_REQ:
+ printdlattachreq(dlp);
+ break;
+
+ case DL_OK_ACK:
+ printdlokack(dlp);
+ break;
+
+ case DL_ERROR_ACK:
+ printdlerrorack(dlp);
+ break;
+
+ case DL_DETACH_REQ:
+ printdldetachreq(dlp);
+ break;
+
+ case DL_BIND_REQ:
+ printdlbindreq(dlp);
+ break;
+
+ case DL_BIND_ACK:
+ printdlbindack(dlp);
+ break;
+
+ case DL_UNBIND_REQ:
+ printdlunbindreq(dlp);
+ break;
+
+ case DL_SUBS_BIND_REQ:
+ printdlsubsbindreq(dlp);
+ break;
+
+ case DL_SUBS_BIND_ACK:
+ printdlsubsbindack(dlp);
+ break;
+
+ case DL_SUBS_UNBIND_REQ:
+ printdlsubsunbindreq(dlp);
+ break;
+
+ case DL_ENABMULTI_REQ:
+ printdlenabmultireq(dlp);
+ break;
+
+ case DL_DISABMULTI_REQ:
+ printdldisabmultireq(dlp);
+ break;
+
+ case DL_PROMISCON_REQ:
+ printdlpromisconreq(dlp);
+ break;
+
+ case DL_PROMISCOFF_REQ:
+ printdlpromiscoffreq(dlp);
+ break;
+
+ case DL_UNITDATA_REQ:
+ printdlunitdatareq(dlp);
+ break;
+
+ case DL_UNITDATA_IND:
+ printdlunitdataind(dlp);
+ break;
+
+ case DL_UDERROR_IND:
+ printdluderrorind(dlp);
+ break;
+
+ case DL_UDQOS_REQ:
+ printdludqosreq(dlp);
+ break;
+
+ case DL_PHYS_ADDR_REQ:
+ printdlphysaddrreq(dlp);
+ break;
+
+ case DL_PHYS_ADDR_ACK:
+ printdlphysaddrack(dlp);
+ break;
+
+ case DL_SET_PHYS_ADDR_REQ:
+ printdlsetphysaddrreq(dlp);
+ break;
+
+ default:
+ err("printdlprim: unknown primitive type 0x%x",
+ dlp->dl_primitive);
+ break;
+ }
+}
+
+/* ARGSUSED */
+printdlinforeq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_INFO_REQ\n");
+}
+
+printdlinfoack(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+ u_char brdcst[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->info_ack.dl_addr_offset),
+ dlp->info_ack.dl_addr_length, addr);
+ addrtostring(OFFADDR(dlp, dlp->info_ack.dl_brdcst_addr_offset),
+ dlp->info_ack.dl_brdcst_addr_length, brdcst);
+
+ (void) printf("DL_INFO_ACK: max_sdu %d min_sdu %d\n",
+ dlp->info_ack.dl_max_sdu,
+ dlp->info_ack.dl_min_sdu);
+ (void) printf("addr_length %d mac_type %s current_state %s\n",
+ dlp->info_ack.dl_addr_length,
+ dlmactype(dlp->info_ack.dl_mac_type),
+ dlstate(dlp->info_ack.dl_current_state));
+ (void) printf("sap_length %d service_mode %s qos_length %d\n",
+ dlp->info_ack.dl_sap_length,
+ dlservicemode(dlp->info_ack.dl_service_mode),
+ dlp->info_ack.dl_qos_length);
+ (void) printf("qos_offset %d qos_range_length %d qos_range_offset %d\n",
+ dlp->info_ack.dl_qos_offset,
+ dlp->info_ack.dl_qos_range_length,
+ dlp->info_ack.dl_qos_range_offset);
+ (void) printf("provider_style %s addr_offset %d version %d\n",
+ dlstyle(dlp->info_ack.dl_provider_style),
+ dlp->info_ack.dl_addr_offset,
+ dlp->info_ack.dl_version);
+ (void) printf("brdcst_addr_length %d brdcst_addr_offset %d\n",
+ dlp->info_ack.dl_brdcst_addr_length,
+ dlp->info_ack.dl_brdcst_addr_offset);
+ (void) printf("addr %s\n", addr);
+ (void) printf("brdcst_addr %s\n", brdcst);
+}
+
+printdlattachreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_ATTACH_REQ: ppa %d\n",
+ dlp->attach_req.dl_ppa);
+}
+
+printdlokack(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_OK_ACK: correct_primitive %s\n",
+ dlprim(dlp->ok_ack.dl_correct_primitive));
+}
+
+printdlerrorack(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_ERROR_ACK: error_primitive %s errno %s unix_errno %d\n",
+ dlprim(dlp->error_ack.dl_error_primitive),
+ dlerrno(dlp->error_ack.dl_errno),
+ dlp->error_ack.dl_unix_errno);
+}
+
+printdlenabmultireq(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->enabmulti_req.dl_addr_offset),
+ dlp->enabmulti_req.dl_addr_length, addr);
+
+ (void) printf("DL_ENABMULTI_REQ: addr_length %d addr_offset %d\n",
+ dlp->enabmulti_req.dl_addr_length,
+ dlp->enabmulti_req.dl_addr_offset);
+ (void) printf("addr %s\n", addr);
+}
+
+printdldisabmultireq(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->disabmulti_req.dl_addr_offset),
+ dlp->disabmulti_req.dl_addr_length, addr);
+
+ (void) printf("DL_DISABMULTI_REQ: addr_length %d addr_offset %d\n",
+ dlp->disabmulti_req.dl_addr_length,
+ dlp->disabmulti_req.dl_addr_offset);
+ (void) printf("addr %s\n", addr);
+}
+
+printdlpromisconreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_PROMISCON_REQ: level %s\n",
+ dlpromisclevel(dlp->promiscon_req.dl_level));
+}
+
+printdlpromiscoffreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_PROMISCOFF_REQ: level %s\n",
+ dlpromisclevel(dlp->promiscoff_req.dl_level));
+}
+
+printdlphysaddrreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_PHYS_ADDR_REQ: addr_type 0x%x\n",
+ dlp->physaddr_req.dl_addr_type);
+}
+
+printdlphysaddrack(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->physaddr_ack.dl_addr_offset),
+ dlp->physaddr_ack.dl_addr_length, addr);
+
+ (void) printf("DL_PHYS_ADDR_ACK: addr_length %d addr_offset %d\n",
+ dlp->physaddr_ack.dl_addr_length,
+ dlp->physaddr_ack.dl_addr_offset);
+ (void) printf("addr %s\n", addr);
+}
+
+printdlsetphysaddrreq(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->set_physaddr_req.dl_addr_offset),
+ dlp->set_physaddr_req.dl_addr_length, addr);
+
+ (void) printf("DL_SET_PHYS_ADDR_REQ: addr_length %d addr_offset %d\n",
+ dlp->set_physaddr_req.dl_addr_length,
+ dlp->set_physaddr_req.dl_addr_offset);
+ (void) printf("addr %s\n", addr);
+}
+
+/* ARGSUSED */
+printdldetachreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_DETACH_REQ\n");
+}
+
+printdlbindreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_BIND_REQ: sap %d max_conind %d\n",
+ dlp->bind_req.dl_sap,
+ dlp->bind_req.dl_max_conind);
+ (void) printf("service_mode %s conn_mgmt %d xidtest_flg 0x%x\n",
+ dlservicemode(dlp->bind_req.dl_service_mode),
+ dlp->bind_req.dl_conn_mgmt,
+ dlp->bind_req.dl_xidtest_flg);
+}
+
+printdlbindack(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->bind_ack.dl_addr_offset),
+ dlp->bind_ack.dl_addr_length, addr);
+
+ (void) printf("DL_BIND_ACK: sap %d addr_length %d addr_offset %d\n",
+ dlp->bind_ack.dl_sap,
+ dlp->bind_ack.dl_addr_length,
+ dlp->bind_ack.dl_addr_offset);
+ (void) printf("max_conind %d xidtest_flg 0x%x\n",
+ dlp->bind_ack.dl_max_conind,
+ dlp->bind_ack.dl_xidtest_flg);
+ (void) printf("addr %s\n", addr);
+}
+
+/* ARGSUSED */
+printdlunbindreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_UNBIND_REQ\n");
+}
+
+printdlsubsbindreq(dlp)
+union DL_primitives *dlp;
+{
+ u_char sap[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->subs_bind_req.dl_subs_sap_offset),
+ dlp->subs_bind_req.dl_subs_sap_length, sap);
+
+ (void) printf("DL_SUBS_BIND_REQ: subs_sap_offset %d sub_sap_len %d\n",
+ dlp->subs_bind_req.dl_subs_sap_offset,
+ dlp->subs_bind_req.dl_subs_sap_length);
+ (void) printf("sap %s\n", sap);
+}
+
+printdlsubsbindack(dlp)
+union DL_primitives *dlp;
+{
+ u_char sap[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->subs_bind_ack.dl_subs_sap_offset),
+ dlp->subs_bind_ack.dl_subs_sap_length, sap);
+
+ (void) printf("DL_SUBS_BIND_ACK: subs_sap_offset %d sub_sap_length %d\n",
+ dlp->subs_bind_ack.dl_subs_sap_offset,
+ dlp->subs_bind_ack.dl_subs_sap_length);
+ (void) printf("sap %s\n", sap);
+}
+
+printdlsubsunbindreq(dlp)
+union DL_primitives *dlp;
+{
+ u_char sap[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->subs_unbind_req.dl_subs_sap_offset),
+ dlp->subs_unbind_req.dl_subs_sap_length, sap);
+
+ (void) printf("DL_SUBS_UNBIND_REQ: subs_sap_offset %d sub_sap_length %d\n",
+ dlp->subs_unbind_req.dl_subs_sap_offset,
+ dlp->subs_unbind_req.dl_subs_sap_length);
+ (void) printf("sap %s\n", sap);
+}
+
+printdlunitdatareq(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->unitdata_req.dl_dest_addr_offset),
+ dlp->unitdata_req.dl_dest_addr_length, addr);
+
+ (void) printf("DL_UNITDATA_REQ: dest_addr_length %d dest_addr_offset %d\n",
+ dlp->unitdata_req.dl_dest_addr_length,
+ dlp->unitdata_req.dl_dest_addr_offset);
+ (void) printf("dl_priority.min %d dl_priority.max %d\n",
+ dlp->unitdata_req.dl_priority.dl_min,
+ dlp->unitdata_req.dl_priority.dl_max);
+ (void) printf("addr %s\n", addr);
+}
+
+printdlunitdataind(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+ u_char src[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_dest_addr_offset),
+ dlp->unitdata_ind.dl_dest_addr_length, dest);
+ addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_src_addr_offset),
+ dlp->unitdata_ind.dl_src_addr_length, src);
+
+ (void) printf("DL_UNITDATA_IND: dest_addr_length %d dest_addr_offset %d\n",
+ dlp->unitdata_ind.dl_dest_addr_length,
+ dlp->unitdata_ind.dl_dest_addr_offset);
+ (void) printf("src_addr_length %d src_addr_offset %d\n",
+ dlp->unitdata_ind.dl_src_addr_length,
+ dlp->unitdata_ind.dl_src_addr_offset);
+ (void) printf("group_address 0x%x\n",
+ dlp->unitdata_ind.dl_group_address);
+ (void) printf("dest %s\n", dest);
+ (void) printf("src %s\n", src);
+}
+
+printdluderrorind(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->uderror_ind.dl_dest_addr_offset),
+ dlp->uderror_ind.dl_dest_addr_length, addr);
+
+ (void) printf("DL_UDERROR_IND: dest_addr_length %d dest_addr_offset %d\n",
+ dlp->uderror_ind.dl_dest_addr_length,
+ dlp->uderror_ind.dl_dest_addr_offset);
+ (void) printf("unix_errno %d errno %s\n",
+ dlp->uderror_ind.dl_unix_errno,
+ dlerrno(dlp->uderror_ind.dl_errno));
+ (void) printf("addr %s\n", addr);
+}
+
+printdltestreq(dlp)
+union DL_primitives *dlp;
+{
+ u_char addr[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->test_req.dl_dest_addr_offset),
+ dlp->test_req.dl_dest_addr_length, addr);
+
+ (void) printf("DL_TEST_REQ: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->test_req.dl_flag,
+ dlp->test_req.dl_dest_addr_length,
+ dlp->test_req.dl_dest_addr_offset);
+ (void) printf("dest_addr %s\n", addr);
+}
+
+printdltestind(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+ u_char src[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->test_ind.dl_dest_addr_offset),
+ dlp->test_ind.dl_dest_addr_length, dest);
+ addrtostring(OFFADDR(dlp, dlp->test_ind.dl_src_addr_offset),
+ dlp->test_ind.dl_src_addr_length, src);
+
+ (void) printf("DL_TEST_IND: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->test_ind.dl_flag,
+ dlp->test_ind.dl_dest_addr_length,
+ dlp->test_ind.dl_dest_addr_offset);
+ (void) printf("src_addr_length %d src_addr_offset %d\n",
+ dlp->test_ind.dl_src_addr_length,
+ dlp->test_ind.dl_src_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+ (void) printf("src_addr %s\n", src);
+}
+
+printdltestres(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->test_res.dl_dest_addr_offset),
+ dlp->test_res.dl_dest_addr_length, dest);
+
+ (void) printf("DL_TEST_RES: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->test_res.dl_flag,
+ dlp->test_res.dl_dest_addr_length,
+ dlp->test_res.dl_dest_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+}
+
+printdltestcon(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+ u_char src[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->test_con.dl_dest_addr_offset),
+ dlp->test_con.dl_dest_addr_length, dest);
+ addrtostring(OFFADDR(dlp, dlp->test_con.dl_src_addr_offset),
+ dlp->test_con.dl_src_addr_length, src);
+
+ (void) printf("DL_TEST_CON: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->test_con.dl_flag,
+ dlp->test_con.dl_dest_addr_length,
+ dlp->test_con.dl_dest_addr_offset);
+ (void) printf("src_addr_length %d src_addr_offset %d\n",
+ dlp->test_con.dl_src_addr_length,
+ dlp->test_con.dl_src_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+ (void) printf("src_addr %s\n", src);
+}
+
+printdlxidreq(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->xid_req.dl_dest_addr_offset),
+ dlp->xid_req.dl_dest_addr_length, dest);
+
+ (void) printf("DL_XID_REQ: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->xid_req.dl_flag,
+ dlp->xid_req.dl_dest_addr_length,
+ dlp->xid_req.dl_dest_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+}
+
+printdlxidind(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+ u_char src[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_dest_addr_offset),
+ dlp->xid_ind.dl_dest_addr_length, dest);
+ addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_src_addr_offset),
+ dlp->xid_ind.dl_src_addr_length, src);
+
+ (void) printf("DL_XID_IND: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->xid_ind.dl_flag,
+ dlp->xid_ind.dl_dest_addr_length,
+ dlp->xid_ind.dl_dest_addr_offset);
+ (void) printf("src_addr_length %d src_addr_offset %d\n",
+ dlp->xid_ind.dl_src_addr_length,
+ dlp->xid_ind.dl_src_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+ (void) printf("src_addr %s\n", src);
+}
+
+printdlxidres(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->xid_res.dl_dest_addr_offset),
+ dlp->xid_res.dl_dest_addr_length, dest);
+
+ (void) printf("DL_XID_RES: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->xid_res.dl_flag,
+ dlp->xid_res.dl_dest_addr_length,
+ dlp->xid_res.dl_dest_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+}
+
+printdlxidcon(dlp)
+union DL_primitives *dlp;
+{
+ u_char dest[MAXDLADDR];
+ u_char src[MAXDLADDR];
+
+ addrtostring(OFFADDR(dlp, dlp->xid_con.dl_dest_addr_offset),
+ dlp->xid_con.dl_dest_addr_length, dest);
+ addrtostring(OFFADDR(dlp, dlp->xid_con.dl_src_addr_offset),
+ dlp->xid_con.dl_src_addr_length, src);
+
+ (void) printf("DL_XID_CON: flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
+ dlp->xid_con.dl_flag,
+ dlp->xid_con.dl_dest_addr_length,
+ dlp->xid_con.dl_dest_addr_offset);
+ (void) printf("src_addr_length %d src_addr_offset %d\n",
+ dlp->xid_con.dl_src_addr_length,
+ dlp->xid_con.dl_src_addr_offset);
+ (void) printf("dest_addr %s\n", dest);
+ (void) printf("src_addr %s\n", src);
+}
+
+printdludqosreq(dlp)
+union DL_primitives *dlp;
+{
+ (void) printf("DL_UDQOS_REQ: qos_length %d qos_offset %d\n",
+ dlp->udqos_req.dl_qos_length,
+ dlp->udqos_req.dl_qos_offset);
+}
+
+/*
+ * Return string.
+ */
+addrtostring(addr, length, s)
+u_char *addr;
+u_long length;
+u_char *s;
+{
+ int i;
+
+ for (i = 0; i < length; i++) {
+ (void) sprintf((char*) s, "%x:", addr[i] & 0xff);
+ s = s + strlen((char*)s);
+ }
+ if (length)
+ *(--s) = '\0';
+}
+
+/*
+ * Return length
+ */
+stringtoaddr(sp, addr)
+char *sp;
+char *addr;
+{
+ int n = 0;
+ char *p;
+ int val;
+
+ p = sp;
+ while (p = strtok(p, ":")) {
+ if (sscanf(p, "%x", &val) != 1)
+ err("stringtoaddr: invalid input string: %s", sp);
+ if (val > 0xff)
+ err("stringtoaddr: invalid input string: %s", sp);
+ *addr++ = val;
+ n++;
+ p = NULL;
+ }
+
+ return (n);
+}
+
+
+static char
+hexnibble(c)
+char c;
+{
+ static char hextab[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+
+ return (hextab[c & 0x0f]);
+}
+
+char*
+dlprim(prim)
+u_long prim;
+{
+ static char primbuf[80];
+
+ switch ((int)prim) {
+ CASERET(DL_INFO_REQ);
+ CASERET(DL_INFO_ACK);
+ CASERET(DL_ATTACH_REQ);
+ CASERET(DL_DETACH_REQ);
+ CASERET(DL_BIND_REQ);
+ CASERET(DL_BIND_ACK);
+ CASERET(DL_UNBIND_REQ);
+ CASERET(DL_OK_ACK);
+ CASERET(DL_ERROR_ACK);
+ CASERET(DL_SUBS_BIND_REQ);
+ CASERET(DL_SUBS_BIND_ACK);
+ CASERET(DL_UNITDATA_REQ);
+ CASERET(DL_UNITDATA_IND);
+ CASERET(DL_UDERROR_IND);
+ CASERET(DL_UDQOS_REQ);
+ CASERET(DL_CONNECT_REQ);
+ CASERET(DL_CONNECT_IND);
+ CASERET(DL_CONNECT_RES);
+ CASERET(DL_CONNECT_CON);
+ CASERET(DL_TOKEN_REQ);
+ CASERET(DL_TOKEN_ACK);
+ CASERET(DL_DISCONNECT_REQ);
+ CASERET(DL_DISCONNECT_IND);
+ CASERET(DL_RESET_REQ);
+ CASERET(DL_RESET_IND);
+ CASERET(DL_RESET_RES);
+ CASERET(DL_RESET_CON);
+ default:
+ (void) sprintf(primbuf, "unknown primitive 0x%x", prim);
+ return (primbuf);
+ }
+}
+
+
+char*
+dlstate(state)
+u_long state;
+{
+ static char statebuf[80];
+
+ switch (state) {
+ CASERET(DL_UNATTACHED);
+ CASERET(DL_ATTACH_PENDING);
+ CASERET(DL_DETACH_PENDING);
+ CASERET(DL_UNBOUND);
+ CASERET(DL_BIND_PENDING);
+ CASERET(DL_UNBIND_PENDING);
+ CASERET(DL_IDLE);
+ CASERET(DL_UDQOS_PENDING);
+ CASERET(DL_OUTCON_PENDING);
+ CASERET(DL_INCON_PENDING);
+ CASERET(DL_CONN_RES_PENDING);
+ CASERET(DL_DATAXFER);
+ CASERET(DL_USER_RESET_PENDING);
+ CASERET(DL_PROV_RESET_PENDING);
+ CASERET(DL_RESET_RES_PENDING);
+ CASERET(DL_DISCON8_PENDING);
+ CASERET(DL_DISCON9_PENDING);
+ CASERET(DL_DISCON11_PENDING);
+ CASERET(DL_DISCON12_PENDING);
+ CASERET(DL_DISCON13_PENDING);
+ CASERET(DL_SUBS_BIND_PND);
+ default:
+ (void) sprintf(statebuf, "unknown state 0x%x", state);
+ return (statebuf);
+ }
+}
+
+char*
+dlerrno(errno)
+u_long errno;
+{
+ static char errnobuf[80];
+
+ switch (errno) {
+ CASERET(DL_ACCESS);
+ CASERET(DL_BADADDR);
+ CASERET(DL_BADCORR);
+ CASERET(DL_BADDATA);
+ CASERET(DL_BADPPA);
+ CASERET(DL_BADPRIM);
+ CASERET(DL_BADQOSPARAM);
+ CASERET(DL_BADQOSTYPE);
+ CASERET(DL_BADSAP);
+ CASERET(DL_BADTOKEN);
+ CASERET(DL_BOUND);
+ CASERET(DL_INITFAILED);
+ CASERET(DL_NOADDR);
+ CASERET(DL_NOTINIT);
+ CASERET(DL_OUTSTATE);
+ CASERET(DL_SYSERR);
+ CASERET(DL_UNSUPPORTED);
+ CASERET(DL_UNDELIVERABLE);
+ CASERET(DL_NOTSUPPORTED);
+ CASERET(DL_TOOMANY);
+ CASERET(DL_NOTENAB);
+ CASERET(DL_BUSY);
+ CASERET(DL_NOAUTO);
+ CASERET(DL_NOXIDAUTO);
+ CASERET(DL_NOTESTAUTO);
+ CASERET(DL_XIDAUTO);
+ CASERET(DL_TESTAUTO);
+ CASERET(DL_PENDING);
+
+ default:
+ (void) sprintf(errnobuf, "unknown dlpi errno 0x%x", errno);
+ return (errnobuf);
+ }
+}
+
+char*
+dlpromisclevel(level)
+u_long level;
+{
+ static char levelbuf[80];
+
+ switch (level) {
+ CASERET(DL_PROMISC_PHYS);
+ CASERET(DL_PROMISC_SAP);
+ CASERET(DL_PROMISC_MULTI);
+ default:
+ (void) sprintf(levelbuf, "unknown promisc level 0x%x", level);
+ return (levelbuf);
+ }
+}
+
+char*
+dlservicemode(servicemode)
+u_long servicemode;
+{
+ static char servicemodebuf[80];
+
+ switch (servicemode) {
+ CASERET(DL_CODLS);
+ CASERET(DL_CLDLS);
+ CASERET(DL_CODLS|DL_CLDLS);
+ default:
+ (void) sprintf(servicemodebuf,
+ "unknown provider service mode 0x%x", servicemode);
+ return (servicemodebuf);
+ }
+}
+
+char*
+dlstyle(style)
+long style;
+{
+ static char stylebuf[80];
+
+ switch (style) {
+ CASERET(DL_STYLE1);
+ CASERET(DL_STYLE2);
+ default:
+ (void) sprintf(stylebuf, "unknown provider style 0x%x", style);
+ return (stylebuf);
+ }
+}
+
+char*
+dlmactype(media)
+u_long media;
+{
+ static char mediabuf[80];
+
+ switch (media) {
+ CASERET(DL_CSMACD);
+ CASERET(DL_TPB);
+ CASERET(DL_TPR);
+ CASERET(DL_METRO);
+ CASERET(DL_ETHER);
+ CASERET(DL_HDLC);
+ CASERET(DL_CHAR);
+ CASERET(DL_CTCA);
+ default:
+ (void) sprintf(mediabuf, "unknown media type 0x%x", media);
+ return (mediabuf);
+ }
+}
+
+/*VARARGS1*/
+err(fmt, a1, a2, a3, a4)
+char *fmt;
+char *a1, *a2, *a3, *a4;
+{
+ (void) fprintf(stderr, fmt, a1, a2, a3, a4);
+ (void) fprintf(stderr, "\n");
+ (void) exit(1);
+}
+
+syserr(s)
+char *s;
+{
+ (void) perror(s);
+ exit(1);
+}
+
+strioctl(fd, cmd, timout, len, dp)
+int fd;
+int cmd;
+int timout;
+int len;
+char *dp;
+{
+ struct strioctl sioc;
+ int rc;
+
+ sioc.ic_cmd = cmd;
+ sioc.ic_timout = timout;
+ sioc.ic_len = len;
+ sioc.ic_dp = dp;
+ rc = ioctl(fd, I_STR, &sioc);
+
+ if (rc < 0)
+ return (rc);
+ else
+ return (sioc.ic_len);
+}
diff --git a/contrib/ipfilter/ipsend/dltest.h b/contrib/ipfilter/ipsend/dltest.h
new file mode 100644
index 0000000..4c32c30
--- /dev/null
+++ b/contrib/ipfilter/ipsend/dltest.h
@@ -0,0 +1,32 @@
+/*
+ * Common DLPI Test Suite header file
+ *
+ */
+
+/*
+ * Maximum control/data buffer size (in long's !!) for getmsg().
+ */
+#define MAXDLBUF 8192
+
+/*
+ * Maximum number of seconds we'll wait for any
+ * particular DLPI acknowledgment from the provider
+ * after issuing a request.
+ */
+#define MAXWAIT 15
+
+/*
+ * Maximum address buffer length.
+ */
+#define MAXDLADDR 1024
+
+
+/*
+ * Handy macro.
+ */
+#define OFFADDR(s, n) (u_char*)((char*)(s) + (int)(n))
+
+/*
+ * externs go here
+ */
+extern void sigalrm();
diff --git a/contrib/ipfilter/ipsend/in_var.h b/contrib/ipfilter/ipsend/in_var.h
new file mode 100644
index 0000000..63980ef
--- /dev/null
+++ b/contrib/ipfilter/ipsend/in_var.h
@@ -0,0 +1,177 @@
+/* @(#)in_var.h 1.3 88/08/19 SMI; from UCB 7.1 6/5/86 */
+
+/*
+ * Copyright (c) 1985, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * Interface address, Internet version. One of these structures
+ * is allocated for each interface with an Internet address.
+ * The ifaddr structure contains the protocol-independent part
+ * of the structure and is assumed to be first.
+ */
+
+#ifndef _netinet_in_var_h
+#define _netinet_in_var_h
+
+struct in_ifaddr {
+ struct ifaddr ia_ifa; /* protocol-independent info */
+#define ia_addr ia_ifa.ifa_addr
+#define ia_broadaddr ia_ifa.ifa_broadaddr
+#define ia_dstaddr ia_ifa.ifa_dstaddr
+#define ia_ifp ia_ifa.ifa_ifp
+ u_long ia_net; /* network number of interface */
+ u_long ia_netmask; /* mask of net part */
+ u_long ia_subnet; /* subnet number, including net */
+ u_long ia_subnetmask; /* mask of net + subnet */
+ struct in_addr ia_netbroadcast; /* broadcast addr for (logical) net */
+ int ia_flags;
+ struct in_ifaddr *ia_next; /* next in list of internet addresses */
+ struct in_multi *ia_multiaddrs;/* list of multicast addresses */
+};
+/*
+ * Given a pointer to an in_ifaddr (ifaddr),
+ * return a pointer to the addr as a sockadd_in.
+ */
+#define IA_SIN(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_addr))
+/*
+ * ia_flags
+ */
+#define IFA_ROUTE 0x01 /* routing entry installed */
+
+#ifdef KERNEL
+struct in_ifaddr *in_ifaddr;
+struct in_ifaddr *in_iaonnetof();
+struct ifqueue ipintrq; /* ip packet input queue */
+#endif
+
+#ifdef KERNEL
+/*
+ * Macro for finding the interface (ifnet structure) corresponding to one
+ * of our IP addresses.
+ */
+#define INADDR_TO_IFP(addr, ifp) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+{ \
+ register struct in_ifaddr *ia; \
+ \
+ for (ia = in_ifaddr; \
+ ia != NULL && IA_SIN(ia)->sin_addr.s_addr != (addr).s_addr; \
+ ia = ia->ia_next); \
+ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
+}
+
+/*
+ * Macro for finding the internet address structure (in_ifaddr) corresponding
+ * to a given interface (ifnet structure).
+ */
+#define IFP_TO_IA(ifp, ia) \
+ /* struct ifnet *ifp; */ \
+ /* struct in_ifaddr *ia; */ \
+{ \
+ for ((ia) = in_ifaddr; \
+ (ia) != NULL && (ia)->ia_ifp != (ifp); \
+ (ia) = (ia)->ia_next); \
+}
+#endif KERNEL
+
+/*
+ * Per-interface router version information is kept in this list.
+ * This information should be part of the ifnet structure but we don't wish
+ * to change that - as it might break a number of things
+ */
+
+struct router_info {
+ struct ifnet *ifp;
+ int type; /* type of router which is querier on this interface */
+ int time; /* # of slow timeouts since last old query */
+ struct router_info *next;
+};
+
+/*
+ * Internet multicast address structure. There is one of these for each IP
+ * multicast group to which this host belongs on a given network interface.
+ * They are kept in a linked list, rooted in the interface's in_ifaddr
+ * structure.
+ */
+
+struct in_multi {
+ struct in_addr inm_addr; /* IP multicast address */
+ struct ifnet *inm_ifp; /* back pointer to ifnet */
+ struct in_ifaddr *inm_ia; /* back pointer to in_ifaddr */
+ u_int inm_refcount;/* no. membership claims by sockets */
+ u_int inm_timer; /* IGMP membership report timer */
+ struct in_multi *inm_next; /* ptr to next multicast address */
+ u_int inm_state; /* state of the membership */
+ struct router_info *inm_rti; /* router info*/
+};
+
+#ifdef KERNEL
+/*
+ * Structure used by macros below to remember position when stepping through
+ * all of the in_multi records.
+ */
+struct in_multistep {
+ struct in_ifaddr *i_ia;
+ struct in_multi *i_inm;
+};
+
+/*
+ * Macro for looking up the in_multi record for a given IP multicast address
+ * on a given interface. If no matching record is found, "inm" returns NULL.
+ */
+#define IN_LOOKUP_MULTI(addr, ifp, inm) \
+ /* struct in_addr addr; */ \
+ /* struct ifnet *ifp; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ register struct in_ifaddr *ia; \
+ \
+ IFP_TO_IA((ifp), ia); \
+ if (ia == NULL) \
+ (inm) = NULL; \
+ else \
+ for ((inm) = ia->ia_multiaddrs; \
+ (inm) != NULL && (inm)->inm_addr.s_addr != (addr).s_addr; \
+ (inm) = inm->inm_next); \
+}
+
+/*
+ * Macro to step through all of the in_multi records, one at a time.
+ * The current position is remembered in "step", which the caller must
+ * provide. IN_FIRST_MULTI(), below, must be called to initialize "step"
+ * and get the first record. Both macros return a NULL "inm" when there
+ * are no remaining records.
+ */
+#define IN_NEXT_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ if (((inm) = (step).i_inm) != NULL) { \
+ (step).i_inm = (inm)->inm_next; \
+ } \
+ else while ((step).i_ia != NULL) { \
+ (inm) = (step).i_ia->ia_multiaddrs; \
+ (step).i_ia = (step).i_ia->ia_next; \
+ if ((inm) != NULL) { \
+ (step).i_inm = (inm)->inm_next; \
+ break; \
+ } \
+ } \
+}
+
+#define IN_FIRST_MULTI(step, inm) \
+ /* struct in_multistep step; */ \
+ /* struct in_multi *inm; */ \
+{ \
+ (step).i_ia = in_ifaddr; \
+ (step).i_inm = NULL; \
+ IN_NEXT_MULTI((step), (inm)); \
+}
+
+struct in_multi *in_addmulti();
+#endif KERNEL
+#endif /*!_netinet_in_var_h*/
diff --git a/contrib/ipfilter/ipsend/ip.c b/contrib/ipfilter/ipsend/ip.c
new file mode 100644
index 0000000..2c7f7ff
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ip.c
@@ -0,0 +1,346 @@
+/*
+ * ip.c (C) 1995 Darren Reed
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "%W% %G% (C)1995";
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcpip.h>
+#endif
+#include "ip_compat.h"
+#ifdef linux
+#include "tcpip.h"
+#endif
+
+
+static char *ipbuf = NULL, *ethbuf = NULL;
+
+extern int arp(), sendip();
+
+u_short chksum(buf,len)
+u_short *buf;
+int len;
+{
+ u_long sum = 0;
+ int nwords = len >> 1;
+
+ for(; nwords > 0; nwords--)
+ sum += *buf++;
+ sum = (sum>>16) + (sum & 0xffff);
+ sum += (sum >>16);
+ return (~sum);
+}
+
+
+int send_ether(nfd, buf, len, gwip)
+int nfd, len;
+char *buf;
+struct in_addr gwip;
+{
+ static struct in_addr last_gw;
+ static char last_arp[6] = { 0, 0, 0, 0, 0, 0};
+ ether_header_t *eh;
+ char *s;
+ int err;
+
+ if (!ethbuf)
+ ethbuf = (char *)calloc(1, 65536+1024);
+ s = ethbuf;
+ eh = (ether_header_t *)s;
+
+ bcopy((char *)buf, s + sizeof(*eh), len);
+ if (gwip.s_addr == last_gw.s_addr)
+ bcopy(last_arp, (char *)&eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, &eh->ether_dhost) == -1)
+ {
+ perror("arp");
+ return -2;
+ }
+ eh->ether_type = ETHERTYPE_IP;
+ last_gw.s_addr = gwip.s_addr;
+ err = sendip(nfd, s, sizeof(*eh) + len);
+ return err;
+}
+
+
+/*
+ */
+int send_ip(nfd, mtu, ip, gwip, frag)
+int nfd, mtu;
+ip_t *ip;
+struct in_addr gwip;
+int frag;
+{
+ static struct in_addr last_gw;
+ static char last_arp[6] = { 0, 0, 0, 0, 0, 0};
+ static u_short id = 0;
+ ether_header_t *eh;
+ ip_t ipsv;
+ int err;
+
+ if (!ipbuf)
+ ipbuf = (char *)malloc(65536);
+ eh = (ether_header_t *)ipbuf;
+
+ bzero((char *)&eh->ether_shost, sizeof(eh->ether_shost));
+ if (last_gw.s_addr && (gwip.s_addr == last_gw.s_addr))
+ bcopy(last_arp, (char *)&eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, &eh->ether_dhost) == -1)
+ {
+ perror("arp");
+ return -2;
+ }
+ bcopy((char *)&eh->ether_dhost, last_arp, sizeof(last_arp));
+ eh->ether_type = ETHERTYPE_IP;
+
+ bcopy((char *)ip, (char *)&ipsv, sizeof(*ip));
+ last_gw.s_addr = gwip.s_addr;
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+ if (!ip->ip_v)
+ ip->ip_v = IPVERSION;
+ if (!ip->ip_id)
+ ip->ip_id = htons(id++);
+ if (!ip->ip_ttl)
+ ip->ip_ttl = 60;
+
+ if (!frag || (sizeof(*eh) + ntohs(ip->ip_len) < mtu))
+ {
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+
+ bcopy((char *)ip, ipbuf + sizeof(*eh), ntohs(ip->ip_len));
+ err = sendip(nfd, ipbuf, sizeof(*eh) + ntohs(ip->ip_len));
+ }
+ else
+ {
+ /*
+ * Actually, this is bogus because we're putting all IP
+ * options in every packet, which isn't always what should be
+ * done. Will do for now.
+ */
+ ether_header_t eth;
+ char optcpy[48], ol;
+ char *s;
+ int i, iplen, sent = 0, ts, hlen, olen;
+
+ hlen = ip->ip_hl << 2;
+ if (mtu < (hlen + 8)) {
+ fprintf(stderr, "mtu (%d) < ip header size (%d) + 8\n",
+ mtu, hlen);
+ fprintf(stderr, "can't fragment data\n");
+ return -2;
+ }
+ ol = (ip->ip_hl << 2) - sizeof(*ip);
+ for (i = 0, s = (char*)(ip + 1); ol > 0; )
+ if (*s == IPOPT_EOL) {
+ optcpy[i++] = *s;
+ break;
+ } else if (*s == IPOPT_NOP) {
+ s++;
+ ol--;
+ } else
+ {
+ olen = (int)(*(u_char *)(s + 1));
+ ol -= olen;
+ if (IPOPT_COPIED(*s))
+ {
+ bcopy(s, optcpy + i, olen);
+ i += olen;
+ s += olen;
+ }
+ }
+ if (i)
+ {
+ /*
+ * pad out
+ */
+ while ((i & 3) && (i & 3) != 3)
+ optcpy[i++] = IPOPT_NOP;
+ if ((i & 3) == 3)
+ optcpy[i++] = IPOPT_EOL;
+ }
+
+ bcopy((char *)eh, (char *)&eth, sizeof(eth));
+ s = (char *)ip + hlen;
+ iplen = ntohs(ip->ip_len) - hlen;
+ ip->ip_off |= htons(IP_MF);
+
+ while (1)
+ {
+ if ((sent + (mtu - hlen)) >= iplen)
+ {
+ ip->ip_off ^= htons(IP_MF);
+ ts = iplen - sent;
+ }
+ else
+ ts = (mtu - hlen);
+ ip->ip_off &= htons(0xe000);
+ ip->ip_off |= htons(sent >> 3);
+ ts += hlen;
+ ip->ip_len = htons(ts);
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, hlen);
+ bcopy((char *)ip, ipbuf + sizeof(*eh), hlen);
+ bcopy(s + sent, ipbuf + sizeof(*eh) + hlen, ts - hlen);
+ err = sendip(nfd, ipbuf, sizeof(*eh) + ts);
+
+ bcopy((char *)&eth, ipbuf, sizeof(eth));
+ sent += (ts - hlen);
+ if (!(ntohs(ip->ip_off) & IP_MF))
+ break;
+ else if (!(ip->ip_off & htons(0x1fff)))
+ {
+ hlen = i + sizeof(*ip);
+ ip->ip_hl = (sizeof(*ip) + i) >> 2;
+ bcopy(optcpy, (char *)(ip + 1), i);
+ }
+ }
+ }
+
+ bcopy((char *)&ipsv, (char *)ip, sizeof(*ip));
+ return err;
+}
+
+
+/*
+ * send a tcp packet.
+ */
+int send_tcp(nfd, mtu, ip, gwip)
+int nfd, mtu;
+ip_t *ip;
+struct in_addr gwip;
+{
+ static tcp_seq iss = 2;
+ struct tcpiphdr *ti;
+ int thlen, i;
+ u_long lbuf[20];
+
+ ti = (struct tcpiphdr *)lbuf;
+ bzero((char *)ti, sizeof(*ti));
+ thlen = sizeof(tcphdr_t);
+ ip->ip_p = IPPROTO_TCP;
+ ti->ti_pr = ip->ip_p;
+ ti->ti_src = ip->ip_src;
+ ti->ti_dst = ip->ip_dst;
+ bcopy((char *)ip + (ip->ip_hl << 2),
+ (char *)&ti->ti_sport, sizeof(tcphdr_t));
+
+ if (!ti->ti_win)
+ ti->ti_win = htons(4096);
+ if (!ti->ti_seq)
+ ti->ti_seq = htonl(iss);
+ iss += 64;
+
+ if ((ti->ti_flags == TH_SYN) && !ip->ip_off)
+ {
+ ip = (ip_t *)realloc((char *)ip, ntohs(ip->ip_len) + 4);
+ i = sizeof(struct tcpiphdr) / sizeof(long);
+ lbuf[i] = htonl(0x020405b4);
+ bcopy((char *)(lbuf + i), (char*)ip + ntohs(ip->ip_len),
+ sizeof(u_long));
+ thlen += 4;
+ }
+ if (!ti->ti_off)
+ ti->ti_off = thlen >> 2;
+ ti->ti_len = htons(thlen);
+ ip->ip_len = (ip->ip_hl << 2) + thlen;
+ ti->ti_sum = 0;
+ ti->ti_sum = chksum(ti, thlen + sizeof(ip_t));
+
+ bcopy((char *)&ti->ti_sport,
+ (char *)ip + (ip->ip_hl << 2), thlen);
+ return send_ip(nfd, mtu, ip, gwip, 1);
+}
+
+
+/*
+ * send a udp packet.
+ */
+int send_udp(nfd, mtu, ip, gwip)
+int nfd, mtu;
+ip_t *ip;
+struct in_addr gwip;
+{
+ struct tcpiphdr *ti;
+ int thlen;
+ u_long lbuf[20];
+
+ ti = (struct tcpiphdr *)lbuf;
+ bzero((char *)ti, sizeof(*ti));
+ thlen = sizeof(udphdr_t);
+ ti->ti_pr = ip->ip_p;
+ ti->ti_src = ip->ip_src;
+ ti->ti_dst = ip->ip_dst;
+ bcopy((char *)ip + (ip->ip_hl << 2),
+ (char *)&ti->ti_sport, sizeof(udphdr_t));
+
+ ti->ti_len = htons(thlen);
+ ip->ip_len = (ip->ip_hl << 2) + thlen;
+ ti->ti_sum = 0;
+ ti->ti_sum = chksum(ti, thlen + sizeof(ip_t));
+
+ bcopy((char *)&ti->ti_sport,
+ (char *)ip + (ip->ip_hl << 2), sizeof(udphdr_t));
+ return send_ip(nfd, mtu, ip, gwip, 1);
+}
+
+
+/*
+ * send an icmp packet.
+ */
+int send_icmp(nfd, mtu, ip, gwip)
+int nfd, mtu;
+ip_t *ip;
+struct in_addr gwip;
+{
+ struct icmp *ic;
+
+ ic = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
+
+ ic->icmp_cksum = 0;
+ ic->icmp_cksum = chksum((char *)ic, sizeof(struct icmp));
+
+ return send_ip(nfd, mtu, ip, gwip, 1);
+}
+
+
+int send_packet(nfd, mtu, ip, gwip)
+int nfd, mtu;
+ip_t *ip;
+struct in_addr gwip;
+{
+ switch (ip->ip_p)
+ {
+ case IPPROTO_TCP :
+ return send_tcp(nfd, mtu, ip, gwip);
+ case IPPROTO_UDP :
+ return send_udp(nfd, mtu, ip, gwip);
+ case IPPROTO_ICMP :
+ return send_icmp(nfd, mtu, ip, gwip);
+ default :
+ return send_ip(nfd, mtu, ip, gwip, 1);
+ }
+}
diff --git a/contrib/ipfilter/ipsend/ip_compat.h b/contrib/ipfilter/ipsend/ip_compat.h
new file mode 100644
index 0000000..c38fa59
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ip_compat.h
@@ -0,0 +1,242 @@
+/*
+ * (C)opyright 1995 by Darren Reed.
+ *
+ * This code may be freely distributed as long as it retains this notice
+ * and is not changed in any way. The author accepts no responsibility
+ * for the use of this software. I hate legaleese, don't you ?
+ *
+ * @(#)ip_compat.h 1.2 12/7/95
+ */
+
+/*
+ * These #ifdef's are here mainly for linux, but who knows, they may
+ * not be in other places or maybe one day linux will grow up and some
+ * of these will turn up there too.
+ */
+#ifndef ICMP_UNREACH
+# define ICMP_UNREACH ICMP_DEST_UNREACH
+#endif
+#ifndef ICMP_SOURCEQUENCH
+# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+#endif
+#ifndef ICMP_TIMXCEED
+# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+#endif
+#ifndef ICMP_PARAMPROB
+# define ICMP_PARAMPROB ICMP_PARAMETERPROB
+#endif
+#ifndef IPVERSION
+# define IPVERSION 4
+#endif
+#ifndef IPOPT_MINOFF
+# define IPOPT_MINOFF 4
+#endif
+#ifndef IPOPT_COPIED
+# define IPOPT_COPIED(x) ((x)&0x80)
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IP_MF
+# define IP_MF ((u_short)0x2000)
+#endif
+#ifndef ETHERTYPE_IP
+# define ETHERTYPE_IP ((u_short)0x0800)
+#endif
+#ifndef TH_FIN
+# define TH_FIN 0x01
+#endif
+#ifndef TH_SYN
+# define TH_SYN 0x02
+#endif
+#ifndef TH_RST
+# define TH_RST 0x04
+#endif
+#ifndef TH_PUSH
+# define TH_PUSH 0x08
+#endif
+#ifndef TH_ACK
+# define TH_ACK 0x10
+#endif
+#ifndef TH_URG
+# define TH_URG 0x20
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IPOPT_RR
+# define IPOPT_RR 7
+#endif
+#ifndef IPOPT_TS
+# define IPOPT_TS 68
+#endif
+#ifndef IPOPT_SECURITY
+# define IPOPT_SECURITY 130
+#endif
+#ifndef IPOPT_LSRR
+# define IPOPT_LSRR 131
+#endif
+#ifndef IPOPT_SATID
+# define IPOPT_SATID 136
+#endif
+#ifndef IPOPT_SSRR
+# define IPOPT_SSRR 137
+#endif
+#ifndef IPOPT_SECUR_UNCLASS
+# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
+#endif
+#ifndef IPOPT_SECUR_CONFID
+# define IPOPT_SECUR_CONFID ((u_short)0xf135)
+#endif
+#ifndef IPOPT_SECUR_EFTO
+# define IPOPT_SECUR_EFTO ((u_short)0x789a)
+#endif
+#ifndef IPOPT_SECUR_MMMM
+# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
+#endif
+#ifndef IPOPT_SECUR_RESTR
+# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
+#endif
+#ifndef IPOPT_SECUR_SECRET
+# define IPOPT_SECUR_SECRET ((u_short)0xd788)
+#endif
+#ifndef IPOPT_SECUR_TOPSECRET
+# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
+#endif
+
+#ifdef linux
+# if LINUX < 0200
+# define icmp icmphdr
+# define icmp_type type
+# define icmp_code code
+# endif
+
+/*
+ * From /usr/include/netinet/ip_var.h
+ * !%@#!$@# linux...
+ */
+struct ipovly {
+ caddr_t ih_next, ih_prev; /* for protocol sequence q's */
+ u_char ih_x1; /* (unused) */
+ u_char ih_pr; /* protocol */
+ short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+
+typedef struct {
+ __u16 th_sport;
+ __u16 th_dport;
+ __u32 th_seq;
+ __u32 th_ack;
+# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
+ defined(vax)
+ __u8 th_res:4;
+ __u8 th_off:4;
+#else
+ __u8 th_off:4;
+ __u8 th_res:4;
+#endif
+ __u8 th_flags;
+ __u16 th_win;
+ __u16 th_sum;
+ __u16 th_urp;
+} tcphdr_t;
+
+typedef struct {
+ __u16 uh_sport;
+ __u16 uh_dport;
+ __s16 uh_ulen;
+ __u16 uh_sum;
+} 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;
+ struct in_addr ip_src;
+ struct in_addr ip_dst;
+} ip_t;
+
+typedef struct {
+ __u8 ether_dhost[6];
+ __u8 ether_shost[6];
+ __u16 ether_type;
+} ether_header_t;
+
+typedef struct icmp {
+ u_char icmp_type; /* type of message, see below */
+ u_char icmp_code; /* type sub code */
+ u_short icmp_cksum; /* ones complement cksum of struct */
+ union {
+ u_char ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ n_short icd_id;
+ n_short icd_seq;
+ } ih_idseq;
+ int ih_void;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+ union {
+ struct id_ts {
+ n_time its_otime;
+ n_time its_rtime;
+ n_time its_ttime;
+ } id_ts;
+ struct id_ip {
+ ip_t idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ u_long id_mask;
+ char id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+} icmphdr_t;
+
+# define bcopy(a,b,c) memmove(b,a,c)
+# define bcmp(a,b,c) memcmp(a,b,c)
+
+# define ifnet device
+
+#else
+
+typedef struct udphdr udphdr_t;
+typedef struct tcphdr tcphdr_t;
+typedef struct ip ip_t;
+typedef struct ether_header ether_header_t;
+
+#endif
+
+#if defined(__SVR4) || defined(__svr4__)
+# define bcopy(a,b,c) memmove(b,a,c)
+# define bcmp(a,b,c) memcmp(a,b,c)
+# define bzero(a,b) memset(a,0,b)
+#endif
diff --git a/contrib/ipfilter/ipsend/ip_var.h b/contrib/ipfilter/ipsend/ip_var.h
new file mode 100644
index 0000000..92eb38a
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ip_var.h
@@ -0,0 +1,123 @@
+/* @(#)ip_var.h 1.11 88/08/19 SMI; from UCB 7.1 6/5/86 */
+
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * Overlay for ip header used by other protocols (tcp, udp).
+ */
+
+#ifndef _netinet_ip_var_h
+#define _netinet_ip_var_h
+
+struct ipovly {
+ caddr_t ih_next, ih_prev; /* for protocol sequence q's */
+ u_char ih_x1; /* (unused) */
+ u_char ih_pr; /* protocol */
+ short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+
+/*
+ * Ip reassembly queue structure. Each fragment
+ * being reassembled is attached to one of these structures.
+ * They are timed out after ipq_ttl drops to 0, and may also
+ * be reclaimed if memory becomes tight.
+ */
+struct ipq {
+ struct ipq *next,*prev; /* to other reass headers */
+ u_char ipq_ttl; /* time for reass q to live */
+ u_char ipq_p; /* protocol of this fragment */
+ u_short ipq_id; /* sequence id for reassembly */
+ struct ipasfrag *ipq_next,*ipq_prev;
+ /* to ip headers of fragments */
+ struct in_addr ipq_src,ipq_dst;
+};
+
+/*
+ * Ip header, when holding a fragment.
+ *
+ * Note: ipf_next must be at same offset as ipq_next above
+ */
+struct ipasfrag {
+#if defined(vax) || defined(i386)
+ u_char ip_hl:4,
+ ip_v:4;
+#endif
+#if defined(mc68000) || defined(sparc)
+ u_char ip_v:4,
+ ip_hl:4;
+#endif
+ u_char ipf_mff; /* copied from (ip_off&IP_MF) */
+ short ip_len;
+ u_short ip_id;
+ short ip_off;
+ u_char ip_ttl;
+ u_char ip_p;
+ u_short ip_sum;
+ struct ipasfrag *ipf_next; /* next fragment */
+ struct ipasfrag *ipf_prev; /* previous fragment */
+};
+
+/*
+ * Structure stored in mbuf in inpcb.ip_options
+ * and passed to ip_output when ip options are in use.
+ * The actual length of the options (including ipopt_dst)
+ * is in m_len.
+ */
+#define MAX_IPOPTLEN 40
+
+struct ipoption {
+ struct in_addr ipopt_dst; /* first-hop dst if source routed */
+ char ipopt_list[MAX_IPOPTLEN]; /* options proper */
+};
+
+/*
+ * Structure stored in an mbuf attached to inpcb.ip_moptions and
+ * passed to ip_output when IP multicast options are in use.
+ */
+struct ip_moptions {
+ struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
+ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */
+ u_char imo_multicast_loop; /* 1 => hear sends if a member */
+ u_short imo_num_memberships;/* no. memberships this socket */
+ struct in_multi *imo_membership[IP_MAX_MEMBERSHIPS];
+#ifdef RSVP_ISI
+ long imo_multicast_vif; /* vif for outgoing multicasts */
+#endif /* RSVP_ISI */
+};
+
+struct ipstat {
+ long ips_total; /* total packets received */
+ long ips_badsum; /* checksum bad */
+ long ips_tooshort; /* packet too short */
+ long ips_toosmall; /* not enough data */
+ long ips_badhlen; /* ip header length < data size */
+ long ips_badlen; /* ip length < ip header length */
+ long ips_fragments; /* fragments received */
+ long ips_fragdropped; /* frags dropped (dups, out of space) */
+ long ips_fragtimeout; /* fragments timed out */
+ long ips_forward; /* packets forwarded */
+ long ips_cantforward; /* packets rcvd for unreachable dest */
+ long ips_redirectsent; /* packets forwarded on same net */
+};
+
+#ifdef KERNEL
+/* flags passed to ip_output as last parameter */
+#define IP_FORWARDING 0x1 /* most of ip header exists */
+#define IP_MULTICASTOPTS 0x2 /* multicast opts present */
+#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
+#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
+
+struct ipstat ipstat;
+struct ipq ipq; /* ip reass. queue */
+u_short ip_id; /* ip packet ctr, for ids */
+
+struct mbuf *ip_srcroute();
+#endif
+
+#endif /*!_netinet_ip_var_h*/
diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c
new file mode 100644
index 0000000..6fd91bf
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipresend.c
@@ -0,0 +1,165 @@
+/*
+ * ipsend.c (C) 1995 Darren Reed
+ *
+ * This was written to test what size TCP fragments would get through
+ * various TCP/IP packet filters, as used in IP firewalls. In certain
+ * conditions, enough of the TCP header is missing for unpredictable
+ * results unless the filter is aware that this can happen.
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ *
+ * This was written and tested (successfully) on SunOS 4.1.x.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#include <netinet/tcpip.h>
+#endif
+#include "ip_compat.h"
+#ifdef linux
+#include <linux/sockios.h>
+#include "tcpip.h"
+#endif
+#include "ipt.h"
+
+
+extern char *optarg;
+extern int optind;
+#ifndef NO_IPF
+extern struct ipread snoop, pcap, etherf, iphex, tcpd, iptext;
+#endif
+extern int resolve(), ip_resend();
+
+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";
+# else
+# ifdef __bsdi__
+char default_device[] = "ef0";
+# else
+char default_device[] = "lan0";
+# endif
+# endif
+# endif
+# endif
+#else
+char default_device[] = DEFAULT_DEVICE;
+#endif
+
+
+void usage(prog)
+char *prog;
+{
+ fprintf(stderr, "Usage: %s [options] <-r filename|-R filename>\n\
+\t\t-r filename\tsnoop data file to resend\n\
+\t\t-R filename\tlibpcap data file to resend\n\
+\toptions:\n\
+\t\t-d device\tSend out on this device\n\
+\t\t-g gateway\tIP gateway to use if non-local dest.\n\
+\t\t-m mtu\t\tfake MTU to use when sending out\n\
+", prog);
+ exit(1);
+}
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ struct in_addr gwip;
+ struct ipread *ipr = NULL;
+ char *name = argv[0], *gateway = NULL, *dev = NULL;
+ char c, *resend = NULL;
+ int mtu = 1500;
+
+ while ((c = getopt(argc, argv, "EHPSTXd:g:m:r:")) != -1)
+ switch (c)
+ {
+ case 'd' :
+ dev = optarg;
+ break;
+ case 'g' :
+ gateway = optarg;
+ break;
+ case 'm' :
+ mtu = atoi(optarg);
+ if (mtu < 28)
+ {
+ fprintf(stderr, "mtu must be > 28\n");
+ exit(1);
+ }
+ case 'r' :
+ resend = optarg;
+ break;
+#ifndef NO_IPF
+ 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;
+#endif
+ default :
+ fprintf(stderr, "Unknown option \"%c\"\n", c);
+ usage(name);
+ }
+
+ if (!ipr || !resend)
+ usage(name);
+
+ gwip.s_addr = 0;
+ if (gateway && resolve(gateway, (char *)&gwip) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", gateway);
+ exit(2);
+ }
+
+ if (!dev)
+ dev = default_device;
+
+ printf("Device: %s\n", dev);
+ printf("Gateway: %s\n", inet_ntoa(gwip));
+ printf("mtu: %d\n", mtu);
+
+ return ip_resend(dev, mtu, ipr, gwip, resend);
+}
diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c
new file mode 100644
index 0000000..e45d3ee
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipsend.c
@@ -0,0 +1,350 @@
+/*
+ * ipsend.c (C) 1995 Darren Reed
+ *
+ * This was written to test what size TCP fragments would get through
+ * various TCP/IP packet filters, as used in IP firewalls. In certain
+ * conditions, enough of the TCP header is missing for unpredictable
+ * results unless the filter is aware that this can happen.
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ *
+ * This was written and tested (successfully) on SunOS 4.1.x.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#include <netinet/tcpip.h>
+#endif
+#include "ip_compat.h"
+#ifdef linux
+#include <linux/sockios.h>
+#include "tcpip.h"
+#endif
+#include "ipt.h"
+
+
+extern char *optarg;
+extern int optind;
+
+extern int resolve(), optname(), initdevice(), send_packet();
+
+char options[68];
+#ifdef linux
+char default_device[] = "eth0";
+#else
+# ifdef sun
+char default_device[] = "le0";
+# else
+# ifdef ultrix
+char default_device[] = "ln0";
+# else
+# ifdef __bsdi__
+char default_device[] = "ef0";
+# else
+char default_device[] = "lan0";
+# endif
+# endif
+# endif
+#endif
+
+
+void usage(prog)
+char *prog;
+{
+ fprintf(stderr, "Usage: %s [options] dest [flags]\n\
+\toptions:\n\
+\t\t-d device\tSend out on this device\n\
+\t\t-f fragflags\tcan set IP_MF or IP_DF\n\
+\t\t-g gateway\tIP gateway to use if non-local dest.\n\
+\t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\
+\t\t-m mtu\t\tfake MTU to use when sending out\n\
+\t\t-P protocol\tSet protocol by name\n\
+\t\t-s src\t\tsource address for IP packet\n\
+\t\t-T\t\tSet TCP protocol\n\
+\t\t-t port\t\tdestination port\n\
+\t\t-U\t\tSet UDP protocol\n\
+", prog);
+ exit(1);
+}
+
+
+void do_icmp(ip, args)
+ip_t *ip;
+char *args;
+{
+ struct icmp *ic;
+ char *s;
+
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_len += sizeof(*ic);
+ ic = (struct icmp *)(ip + 1);
+ bzero((char *)ic, sizeof(*ic));
+ if (!(s = strchr(args, ',')))
+ {
+ fprintf(stderr, "ICMP args missing: ,\n");
+ return;
+ }
+ *s++ = '\0';
+ ic->icmp_type = atoi(args);
+ ic->icmp_code = atoi(s);
+ if (ic->icmp_type == ICMP_REDIRECT && strchr(s, ','))
+ {
+ char *t;
+
+ t = strtok(s, ",");
+ t = strtok(NULL, ",");
+ if (resolve(t, (char *)&ic->icmp_gwaddr) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", t);
+ exit(2);
+ }
+ if ((t = strtok(NULL, ",")))
+ {
+ if (resolve(t, (char *)&ic->icmp_ip.ip_dst) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", t);
+ exit(2);
+ }
+ if ((t = strtok(NULL, ",")))
+ {
+ if (resolve(t,
+ (char *)&ic->icmp_ip.ip_src) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", t);
+ exit(2);
+ }
+ }
+ }
+ }
+}
+
+
+int send_packets(dev, mtu, ip, gwip)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+{
+ u_short sport = 0;
+ int wfd;
+
+ if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
+ sport = ((struct tcpiphdr *)ip)->ti_sport;
+ wfd = initdevice(dev, sport, 5);
+
+ return send_packet(wfd, mtu, ip, gwip);
+}
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ struct tcpiphdr *ti;
+ struct in_addr gwip;
+ tcphdr_t *tcp;
+ ip_t *ip;
+ char *name = argv[0], host[64], *gateway = NULL, *dev = NULL;
+ char *src = NULL, *dst, c, *s;
+ int mtu = 1500, olen = 0;
+
+ /*
+ * 65535 is maximum packet size...you never know...
+ */
+ ip = (ip_t *)calloc(1, 65536);
+ ti = (struct tcpiphdr *)ip;
+ tcp = (tcphdr_t *)&ti->ti_sport;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_hl = sizeof(*ip) >> 2;
+
+ while ((c = getopt(argc, argv, "IP:TUd:f:g:m:o:s:t:")) != -1)
+ switch (c)
+ {
+ case 'I' :
+ if (ip->ip_p)
+ {
+ fprintf(stderr, "Protocol already set: %d\n",
+ ip->ip_p);
+ break;
+ }
+ do_icmp(ip, optarg);
+ break;
+ case 'P' :
+ {
+ struct protoent *p;
+
+ if (ip->ip_p)
+ {
+ fprintf(stderr, "Protocol already set: %d\n",
+ ip->ip_p);
+ break;
+ }
+ if ((p = getprotobyname(optarg)))
+ ip->ip_p = p->p_proto;
+ else
+ fprintf(stderr, "Unknown protocol: %s\n",
+ optarg);
+ break;
+ }
+ case 'T' :
+ if (ip->ip_p)
+ {
+ fprintf(stderr, "Protocol already set: %d\n",
+ ip->ip_p);
+ break;
+ }
+ ip->ip_p = IPPROTO_TCP;
+ ip->ip_len += sizeof(tcphdr_t);
+ break;
+ case 'U' :
+ if (ip->ip_p)
+ {
+ fprintf(stderr, "Protocol already set: %d\n",
+ ip->ip_p);
+ break;
+ }
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_len += sizeof(udphdr_t);
+ break;
+ case 'd' :
+ dev = optarg;
+ break;
+ case 'f' :
+ ip->ip_off = strtol(optarg, NULL, 0);
+ break;
+ case 'g' :
+ gateway = optarg;
+ break;
+ case 'm' :
+ mtu = atoi(optarg);
+ if (mtu < 28)
+ {
+ fprintf(stderr, "mtu must be > 28\n");
+ exit(1);
+ }
+ break;
+ case 'o' :
+ olen = optname(optarg, options);
+ break;
+ case 's' :
+ src = optarg;
+ break;
+ case 't' :
+ if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
+ tcp->th_dport = htons(atoi(optarg));
+ break;
+ case 'w' :
+ if (ip->ip_p == IPPROTO_TCP)
+ tcp->th_win = atoi(optarg);
+ else
+ fprintf(stderr, "set protocol to TCP first\n");
+ break;
+ default :
+ fprintf(stderr, "Unknown option \"%c\"\n", c);
+ usage(name);
+ }
+
+ if (argc - optind < 2)
+ usage(name);
+ dst = argv[optind++];
+
+ if (!src)
+ {
+ gethostname(host, sizeof(host));
+ src = host;
+ }
+
+ if (resolve(src, (char *)&ip->ip_src) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", src);
+ exit(2);
+ }
+
+ if (resolve(dst, (char *)&ip->ip_dst) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", dst);
+ exit(2);
+ }
+
+ if (!gateway)
+ gwip = ip->ip_dst;
+ else if (resolve(gateway, (char *)&gwip) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", gateway);
+ exit(2);
+ }
+
+ if (ip->ip_p == IPPROTO_TCP)
+ for (s = argv[optind]; (c = *s); s++)
+ switch(c)
+ {
+ case 'S' : case 's' :
+ tcp->th_flags |= TH_SYN;
+ break;
+ case 'A' : case 'a' :
+ tcp->th_flags |= TH_ACK;
+ break;
+ case 'F' : case 'f' :
+ tcp->th_flags |= TH_FIN;
+ break;
+ case 'R' : case 'r' :
+ tcp->th_flags |= TH_RST;
+ break;
+ case 'P' : case 'p' :
+ tcp->th_flags |= TH_PUSH;
+ break;
+ case 'U' : case 'u' :
+ tcp->th_flags |= TH_URG;
+ break;
+ }
+
+ if (!dev)
+ dev = default_device;
+ printf("Device: %s\n", dev);
+ printf("Source: %s\n", inet_ntoa(ip->ip_src));
+ printf("Dest: %s\n", inet_ntoa(ip->ip_dst));
+ printf("Gateway: %s\n", inet_ntoa(gwip));
+ if (ip->ip_p == IPPROTO_TCP && tcp->th_flags)
+ printf("Flags: %#x\n", tcp->th_flags);
+ printf("mtu: %d\n", mtu);
+
+ if (olen)
+ {
+ printf("Options: %d\n", olen);
+ ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
+ bcopy((char *)ip, (char *)ti, sizeof(*ip));
+ ip = (ip_t *)ti;
+ ip->ip_hl += (olen >> 2);
+ bcopy(options, (char *)(ip + 1), olen);
+ bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp));
+ tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
+ ip->ip_len += olen;
+ }
+
+#ifdef DOSOCKET
+ if (tcp->th_dport)
+ return do_socket(dev, mtu, ti, gwip);
+#endif
+ return send_packets(dev, mtu, ti, gwip);
+}
diff --git a/contrib/ipfilter/ipsend/ipsopt.c b/contrib/ipfilter/ipsend/ipsopt.c
new file mode 100644
index 0000000..75c4f16
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipsopt.c
@@ -0,0 +1,111 @@
+/*
+ * (C)opyright 1995 by Darren Reed.
+ *
+ * This code may be freely distributed as long as it retains this notice
+ * and is not changed in any way. The author accepts no responsibility
+ * for the use of this software. I hate legaleese, don't you ?
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include "ip_compat.h"
+
+struct ipopt_names {
+ int on_value;
+ int on_bit;
+ int on_siz;
+ char *on_name;
+};
+
+struct ipopt_names ionames[] = {
+ { IPOPT_EOL, 0x01, 1, "eol" },
+ { IPOPT_NOP, 0x02, 1, "nop" },
+ { IPOPT_RR, 0x04, 7, "rr" }, /* 1 route */
+ { IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */
+ { IPOPT_SECURITY, 0x08, 11, "sec-level" },
+ { IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */
+ { IPOPT_SATID, 0x20, 4, "satid" },
+ { IPOPT_SSRR, 0x40, 7, "ssrr" }, /* 1 route */
+ { 0, 0, 0, NULL } /* must be last */
+};
+
+struct ipopt_names secnames[] = {
+ { IPOPT_SECUR_UNCLASS, 0x0100, 0, "unclass" },
+ { IPOPT_SECUR_CONFID, 0x0200, 0, "confid" },
+ { IPOPT_SECUR_EFTO, 0x0400, 0, "efto" },
+ { IPOPT_SECUR_MMMM, 0x0800, 0, "mmmm" },
+ { IPOPT_SECUR_RESTR, 0x1000, 0, "restr" },
+ { IPOPT_SECUR_SECRET, 0x2000, 0, "secret" },
+ { IPOPT_SECUR_TOPSECRET, 0x4000,0, "topsecret" },
+ { 0, 0, 0, NULL } /* must be last */
+};
+
+
+u_short seclevel(slevel)
+char *slevel;
+{
+ struct ipopt_names *so;
+
+ for (so = secnames; so->on_name; so++)
+ if (!strcasecmp(slevel, so->on_name))
+ break;
+
+ if (!so->on_name) {
+ fprintf(stderr, "no such security level: %s\n", slevel);
+ return 0;
+ }
+ return so->on_value;
+}
+
+
+u_long optname(cp, op)
+char *cp, *op;
+{
+ struct ipopt_names *io;
+ u_short lvl;
+ u_long msk = 0;
+ char *s, *t;
+ int len = 0;
+
+ for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
+ if ((t = strchr(s, '=')))
+ *t++ = '\0';
+ for (io = ionames; io->on_name; io++) {
+ if (strcasecmp(s, io->on_name) || (msk & io->on_bit))
+ continue;
+ if ((len + io->on_siz) > 48) {
+ fprintf(stderr, "options too long\n");
+ return 0;
+ }
+ len += io->on_siz;
+ *op++ = io->on_value;
+ if (io->on_siz > 1) {
+ *op++ = io->on_siz;
+ *op++ = IPOPT_MINOFF;
+
+ if (t && !strcasecmp(s, "sec-level")) {
+ lvl = seclevel(t);
+ bcopy(&lvl, op, sizeof(lvl));
+ }
+ op += io->on_siz - 3;
+ }
+ msk |= io->on_bit;
+ break;
+ }
+ if (!io->on_name) {
+ fprintf(stderr, "unknown IP option name %s\n", s);
+ return 0;
+ }
+ }
+ *op++ = IPOPT_EOL;
+ len++;
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c
new file mode 100644
index 0000000..c5d48fa
--- /dev/null
+++ b/contrib/ipfilter/ipsend/iptest.c
@@ -0,0 +1,211 @@
+/*
+ * ipsend.c (C) 1995 Darren Reed
+ *
+ * This was written to test what size TCP fragments would get through
+ * various TCP/IP packet filters, as used in IP firewalls. In certain
+ * conditions, enough of the TCP header is missing for unpredictable
+ * results unless the filter is aware that this can happen.
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ *
+ * This was written and tested (successfully) on SunOS 4.1.x.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#include <netinet/tcpip.h>
+#endif
+#include "ip_compat.h"
+#ifdef linux
+#include <linux/sockios.h>
+#include "tcpip.h"
+#endif
+#include "ipt.h"
+
+
+extern char *optarg;
+extern int optind;
+
+extern int initdevice(), resolve();
+extern int ip_test1(), ip_test2(), ip_test3(), ip_test4(), ip_test5();
+extern int ip_test6(), ip_test7();
+
+char options[68];
+#ifdef linux
+char default_device[] = "eth0";
+#else
+# ifdef sun
+char default_device[] = "le0";
+# else
+# ifdef ultrix
+char default_device[] = "ln0";
+# else
+# ifdef __bsdi__
+char default_device[] = "ef0";
+# else
+char default_device[] = "lan0";
+# endif
+# endif
+# endif
+#endif
+
+
+void usage(prog)
+char *prog;
+{
+ fprintf(stderr, "Usage: %s [options] dest\n\
+\toptions:\n\
+\t\t-d device\tSend out on this device\n\
+\t\t-g gateway\tIP gateway to use if non-local dest.\n\
+\t\t-m mtu\t\tfake MTU to use when sending out\n\
+\t\t-p pointtest\t\n\
+\t\t-s src\t\tsource address for IP packet\n\
+\t\t-1 \t\tPerform test 1 (IP header)\n\
+\t\t-2 \t\tPerform test 2 (IP options)\n\
+\t\t-3 \t\tPerform test 3 (ICMP)\n\
+\t\t-4 \t\tPerform test 4 (UDP)\n\
+\t\t-5 \t\tPerform test 5 (TCP)\n\
+\t\t-6 \t\tPerform test 6 (overlapping fragments)\n\
+\t\t-7 \t\tPerform test 7 (random packets)\n\
+", prog);
+ exit(1);
+}
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ struct tcpiphdr *ti;
+ struct in_addr gwip;
+ ip_t *ip;
+ char *name = argv[0], host[64], *gateway = NULL, *dev = NULL;
+ char *src = NULL, *dst, c;
+ int mtu = 1500, tests = 0, pointtest = 0;
+
+ /*
+ * 65535 is maximum packet size...you never know...
+ */
+ ip = (ip_t *)calloc(1, 65536);
+ ti = (struct tcpiphdr *)ip;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_hl = sizeof(*ip) >> 2;
+
+ while ((c = getopt(argc, argv, "1234567IP:TUd:f:g:m:o:p:s:t:")) != -1)
+ switch (c)
+ {
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ tests = c - '0';
+ break;
+ case 'd' :
+ dev = optarg;
+ break;
+ case 'g' :
+ gateway = optarg;
+ break;
+ case 'm' :
+ mtu = atoi(optarg);
+ if (mtu < 28)
+ {
+ fprintf(stderr, "mtu must be > 28\n");
+ exit(1);
+ }
+ break;
+ case 'p' :
+ pointtest = atoi(optarg);
+ break;
+ case 's' :
+ src = optarg;
+ break;
+ default :
+ fprintf(stderr, "Unknown option \"%c\"\n", c);
+ usage(name);
+ }
+
+ if (argc - optind < 2 && !tests)
+ usage(name);
+ dst = argv[optind++];
+
+ if (!src)
+ {
+ gethostname(host, sizeof(host));
+ src = host;
+ }
+
+ if (resolve(dst, (char *)&ip->ip_dst) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", dst);
+ exit(2);
+ }
+
+ if (resolve(src, (char *)&ip->ip_src) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", src);
+ exit(2);
+ }
+
+ if (!gateway)
+ gwip = ip->ip_dst;
+ else if (resolve(gateway, (char *)&gwip) == -1)
+ {
+ fprintf(stderr,"Cant resolve %s\n", gateway);
+ exit(2);
+ }
+
+
+ if (!dev)
+ dev = default_device;
+ printf("Device: %s\n", dev);
+ printf("Source: %s\n", inet_ntoa(ip->ip_src));
+ printf("Dest: %s\n", inet_ntoa(ip->ip_dst));
+ printf("Gateway: %s\n", inet_ntoa(gwip));
+ printf("mtu: %d\n", mtu);
+
+ switch (tests)
+ {
+ case 1 :
+ return ip_test1(dev, mtu, ti, gwip, pointtest);
+ case 2 :
+ return ip_test2(dev, mtu, ti, gwip, pointtest);
+ case 3 :
+ return ip_test3(dev, mtu, ti, gwip, pointtest);
+ case 4 :
+ return ip_test4(dev, mtu, ti, gwip, pointtest);
+ case 5 :
+ return ip_test5(dev, mtu, ti, gwip, pointtest);
+ case 6 :
+ return ip_test6(dev, mtu, ti, gwip, pointtest);
+ case 7 :
+ return ip_test7(dev, mtu, ti, gwip, pointtest);
+ default :
+ break;
+ }
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c
new file mode 100644
index 0000000..b9da7b2
--- /dev/null
+++ b/contrib/ipfilter/ipsend/iptests.c
@@ -0,0 +1,1296 @@
+/*
+ * (C)opyright 1993, 1994, 1995 by Darren Reed.
+ *
+ * This code may be freely distributed as long as it retains this notice
+ * and is not changed in any way. The author accepts no responsibility
+ * for the use of this software. I hate legaleese, don't you ?
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#if !defined(solaris)
+# define _KERNEL
+# define KERNEL
+# include <sys/file.h>
+# undef _KERNEL
+# undef KERNEL
+# include <nlist.h>
+# include <sys/user.h>
+# include <sys/proc.h>
+#endif
+#include <kvm.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#ifdef sun
+#include <sys/systm.h>
+#include <sys/session.h>
+#endif
+#if BSD >= 199103
+#include <sys/sysctl.h>
+#include <sys/filedesc.h>
+#include <paths.h>
+#endif
+#include <netinet/in_systm.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include "ip_compat.h"
+#ifdef linux
+#include "tcpip.h"
+#else
+#include <netinet/tcpip.h>
+# if defined(__SVR4) || defined(__svr4__)
+#include <sys/sysmacros.h>
+# endif
+#endif
+
+#define PAUSE() tv.tv_sec = 0; tv.tv_usec = 10000; \
+ (void) select(0, NULL, NULL, NULL, &tv)
+
+extern int send_ip(), send_tcp(), send_udp(), send_icmp(), send_ether();
+extern int initdevice(), kmemcpy();
+extern u_short chksum();
+extern struct tcpcb *find_tcp();
+
+void ip_test1(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ struct timeval tv;
+ udphdr_t *u;
+ int nfd, i, len, id = getpid();
+
+ ip->ip_hl = sizeof(*ip) >> 2;
+ ip->ip_v = IPVERSION;
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_ttl = 60;
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_sum = 0;
+ u = (udphdr_t *)(ip + 1);
+ u->uh_sport = 1;
+ u->uh_dport = 9;
+ u->uh_sum = 0;
+ u->uh_ulen = sizeof(*u) + 4;
+ ip->ip_len = sizeof(*ip) + u->uh_ulen;
+ len = ip->ip_len;
+ nfd = initdevice(dev, u->uh_sport, 1);
+
+ u->uh_sport = htons(u->uh_sport);
+ u->uh_dport = htons(u->uh_dport);
+ u->uh_ulen = htons(u->uh_ulen);
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Part1: hl < len
+ */
+ ip->ip_id = 0;
+ printf("1.1. sending packets with ip_hl < ip_len\n");
+ for (i = 0; i < ((sizeof(*ip) + u->uh_ulen) >> 2); i++) {
+ ip->ip_hl = i >> 2;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 2)) {
+ /*
+ * Part2: hl > len
+ */
+ ip->ip_id = 0;
+ printf("1.2. sending packets with ip_hl > ip_len\n");
+ for (; i < ((sizeof(*ip) * 2 + u->uh_ulen) >> 2); i++) {
+ ip->ip_hl = i >> 2;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 3)) {
+ /*
+ * Part3: v < 4
+ */
+ ip->ip_id = 0;
+ printf("1.3. ip_v < 4\n");
+ ip->ip_hl = sizeof(*ip) >> 2;
+ for (i = 0; i < 4; i++) {
+ ip->ip_v = i;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 4)) {
+ /*
+ * Part4: v > 4
+ */
+ ip->ip_id = 0;
+ printf("1.4. ip_v > 4\n");
+ for (i = 5; i < 16; i++) {
+ ip->ip_v = i;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 5)) {
+ /*
+ * Part5: len < packet
+ */
+ ip->ip_id = 0;
+ ip->ip_v = IPVERSION;
+ i = ip->ip_len + 1;
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+ printf("1.5.0 ip_len < packet size (size++, long packets)\n");
+ for (; i < (ntohs(ip->ip_len) * 2); i++) {
+ ip->ip_id = htons(id++);
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, ip, i, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ printf("1.5.1 ip_len < packet size (ip_len-, short packets)\n");
+ for (i = len; i > 0; i--) {
+ ip->ip_id = htons(id++);
+ ip->ip_len = htons(i);
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, ip, len, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 6)) {
+ /*
+ * Part6: len > packet
+ */
+ ip->ip_id = 0;
+ printf("1.6.0 ip_len > packet size (increase ip_len)\n");
+ for (i = len + 1; i < (len * 2); i++) {
+ ip->ip_id = htons(id++);
+ ip->ip_len = htons(i);
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, ip, len, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ ip->ip_len = htons(len);
+ printf("1.6.1 ip_len > packet size (size--, short packets)\n");
+ for (i = len; i > 0; i--) {
+ ip->ip_id = htons(id++);
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, ip, i, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 7)) {
+ /*
+ * Part7: 0 length fragment
+ */
+ printf("1.7.0 Zero length fragments (ip_off = 0x2000)\n");
+ ip->ip_id = 0;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_off = htons(IP_MF);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("1.7.1 Zero length fragments (ip_off = 0x3000)\n");
+ ip->ip_id = 0;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_off = htons(IP_MF);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("1.7.2 Zero length fragments (ip_off = 0xa000)\n");
+ ip->ip_id = 0;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_off = htons(0xa000);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("1.7.3 Zero length fragments (ip_off = 0x0100)\n");
+ ip->ip_id = 0;
+ ip->ip_len = sizeof(*ip);
+ ip->ip_off = htons(0x0100);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 8)) {
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ srand(tv.tv_sec ^ getpid() ^ tv.tv_usec);
+ /*
+ * Part8.1: 63k packet + 1k fragment at offset 0x1ffe
+ * Mark it as being ICMP (so it doesn't get junked), but
+ * don't bother about the ICMP header, we're not worrying
+ * about that here.
+ */
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_off = IP_MF;
+ u->uh_dport = htons(9);
+ ip->ip_id = htons(id++);
+ printf("1.8.1 63k packet + 1k fragment at offset 0x1ffe\n");
+ ip->ip_len = 768 + 20 + 8;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+
+ ip->ip_len = MIN(768 + 20, mtu - 68);
+ i = 512;
+ for (; i < (63 * 1024 + 768); i += 768) {
+ ip->ip_off = IP_MF | (i >> 3);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ ip->ip_len = 896 + 20;
+ ip->ip_off = (i >> 3);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ putchar('\n');
+ fflush(stdout);
+
+ /*
+ * Part8.2: 63k packet + 1k fragment at offset 0x1ffe
+ * Mark it as being ICMP (so it doesn't get junked), but
+ * don't bother about the ICMP header, we're not worrying
+ * about that here. (Lossage here)
+ */
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_off = IP_MF;
+ u->uh_dport = htons(9);
+ ip->ip_id = htons(id++);
+ printf("1.8.2 63k packet + 1k fragment at offset 0x1ffe\n");
+ ip->ip_len = 768 + 20 + 8;
+ if ((rand() & 0x1f) != 0) {
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ } else
+ printf("skip 0\n");
+
+ ip->ip_len = MIN(768 + 20, mtu - 68);
+ i = 512;
+ for (; i < (63 * 1024 + 768); i += 768) {
+ ip->ip_off = IP_MF | (i >> 3);
+ if ((rand() & 0x1f) != 0) {
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ } else
+ printf("skip %d\n", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ ip->ip_len = 896 + 20;
+ ip->ip_off = (i >> 3);
+ if ((rand() & 0x1f) != 0) {
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ } else
+ printf("skip\n");
+ putchar('\n');
+ fflush(stdout);
+
+ /*
+ * Part8.3: 33k packet - test for not dealing with -ve length
+ * Mark it as being ICMP (so it doesn't get junked), but
+ * don't bother about the ICMP header, we're not worrying
+ * about that here.
+ */
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_off = IP_MF;
+ u->uh_dport = htons(9);
+ ip->ip_id = htons(id++);
+ printf("1.8.3 33k packet\n");
+ ip->ip_len = 768 + 20 + 8;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+
+ ip->ip_len = MIN(768 + 20, mtu - 68);
+ i = 512;
+ for (; i < (32 * 1024 + 768); i += 768) {
+ ip->ip_off = IP_MF | (i >> 3);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ ip->ip_len = 896 + 20;
+ ip->ip_off = (i >> 3);
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ printf("%d\r", i);
+ putchar('\n');
+ fflush(stdout);
+ }
+
+ ip->ip_len = len;
+ ip->ip_off = 0;
+ if (!ptest || (ptest == 9)) {
+ /*
+ * Part9: off & 0x8000 == 0x8000
+ */
+ ip->ip_id = 0;
+ ip->ip_off = 0x8000;
+ printf("1.9. ip_off & 0x8000 == 0x8000\n");
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ ip->ip_off = 0;
+
+ if (!ptest || (ptest == 10)) {
+ /*
+ * Part10: ttl = 255
+ */
+ ip->ip_id = 0;
+ ip->ip_ttl = 255;
+ printf("1.10.0 ip_ttl = 255\n");
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ ip->ip_ttl = 128;
+ printf("1.10.1 ip_ttl = 128\n");
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ ip->ip_ttl = 0;
+ printf("1.10.2 ip_ttl = 0\n");
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ (void) close(nfd);
+}
+
+
+void ip_test2(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ struct timeval tv;
+ int nfd;
+ u_char *s;
+
+ s = (u_char *)(ip + 1);
+ nfd = initdevice(dev, 1, 1);
+
+ ip->ip_hl = 6;
+ ip->ip_len = ip->ip_hl << 2;
+ s[IPOPT_OPTVAL] = IPOPT_NOP;
+ s++;
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Test 1: option length > packet length,
+ * header length == packet length
+ */
+ s[IPOPT_OPTVAL] = IPOPT_TS;
+ s[IPOPT_OLEN] = 4;
+ s[IPOPT_OFFSET] = IPOPT_MINOFF;
+ ip->ip_p = IPPROTO_IP;
+ printf("2.1 option length > packet length\n");
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ ip->ip_hl = 7;
+ ip->ip_len = ip->ip_hl << 2;
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Test 2: options have length = 0
+ */
+ printf("2.2.1 option length = 0, RR\n");
+ s[IPOPT_OPTVAL] = IPOPT_RR;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("2.2.2 option length = 0, TS\n");
+ s[IPOPT_OPTVAL] = IPOPT_TS;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("2.2.3 option length = 0, SECURITY\n");
+ s[IPOPT_OPTVAL] = IPOPT_SECURITY;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("2.2.4 option length = 0, LSRR\n");
+ s[IPOPT_OPTVAL] = IPOPT_LSRR;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("2.2.5 option length = 0, SATID\n");
+ s[IPOPT_OPTVAL] = IPOPT_SATID;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+
+ printf("2.2.6 option length = 0, SSRR\n");
+ s[IPOPT_OPTVAL] = IPOPT_SSRR;
+ s[IPOPT_OLEN] = 0;
+ (void) send_ip(nfd, mtu, ip, gwip, 1);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ (void) close(nfd);
+}
+
+
+/*
+ * test 3 (ICMP)
+ */
+void ip_test3(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ static int ict1[10] = { 8, 9, 10, 13, 14, 15, 16, 17, 18, 0 };
+ static int ict2[8] = { 3, 9, 10, 13, 14, 17, 18, 0 };
+ struct timeval tv;
+ struct icmp *icp;
+ int nfd, i;
+
+ ip->ip_hl = sizeof(*ip) >> 2;
+ ip->ip_v = IPVERSION;
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_ttl = 60;
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_sum = 0;
+ ip->ip_len = sizeof(*ip) + sizeof(*icp);
+ icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
+ nfd = initdevice(dev, 1, 1);
+
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Type 0 - 31, 255, code = 0
+ */
+ bzero((char *)icp, sizeof(*icp));
+ for (i = 0; i < 32; i++) {
+ icp->icmp_type = i;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, i);
+ }
+ icp->icmp_type = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, 255);
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 2)) {
+ /*
+ * Type 3, code = 0 - 31
+ */
+ icp->icmp_type = 3;
+ for (i = 0; i < 32; i++) {
+ icp->icmp_code = i;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.2.%d ICMP type 3 code %d (all 0's)\r", i, i);
+ }
+ }
+
+ if (!ptest || (ptest == 3)) {
+ /*
+ * Type 4, code = 0,127,128,255
+ */
+ icp->icmp_type = 4;
+ icp->icmp_code = 0;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.3.1 ICMP type 4 code 0 (all 0's)\r");
+ icp->icmp_code = 127;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.3.2 ICMP type 4 code 127 (all 0's)\r");
+ icp->icmp_code = 128;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.3.3 ICMP type 4 code 128 (all 0's)\r");
+ icp->icmp_code = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.3.4 ICMP type 4 code 255 (all 0's)\r");
+ }
+
+ if (!ptest || (ptest == 4)) {
+ /*
+ * Type 5, code = 0,127,128,255
+ */
+ icp->icmp_type = 5;
+ icp->icmp_code = 0;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.4.1 ICMP type 5 code 0 (all 0's)\r");
+ icp->icmp_code = 127;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.4.2 ICMP type 5 code 127 (all 0's)\r");
+ icp->icmp_code = 128;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.4.3 ICMP type 5 code 128 (all 0's)\r");
+ icp->icmp_code = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.4.4 ICMP type 5 code 255 (all 0's)\r");
+ }
+
+ if (!ptest || (ptest == 5)) {
+ /*
+ * Type 8-10;13-18, code - 0,127,128,255
+ */
+ for (i = 0; ict1[i]; i++) {
+ icp->icmp_type = ict1[i];
+ icp->icmp_code = 0;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type 5 code 0 (all 0's)\r",
+ i * 4);
+ icp->icmp_code = 127;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type 5 code 127 (all 0's)\r",
+ i * 4 + 1);
+ icp->icmp_code = 128;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type 5 code 128 (all 0's)\r",
+ i * 4 + 2);
+ icp->icmp_code = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type 5 code 255 (all 0's)\r",
+ i * 4 + 3);
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 6)) {
+ /*
+ * Type 12, code - 0,127,128,129,255
+ */
+ icp->icmp_type = 12;
+ icp->icmp_code = 0;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.6.1 ICMP type 12 code 0 (all 0's)\r");
+ icp->icmp_code = 127;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.6.2 ICMP type 12 code 127 (all 0's)\r");
+ icp->icmp_code = 128;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.6.3 ICMP type 12 code 128 (all 0's)\r");
+ icp->icmp_code = 129;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.6.4 ICMP type 12 code 129 (all 0's)\r");
+ icp->icmp_code = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.6.5 ICMP type 12 code 255 (all 0's)\r");
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 7)) {
+ /*
+ * Type 3;9-10;13-14;17-18 - shorter packets
+ */
+ ip->ip_len = sizeof(*ip) + sizeof(*icp) / 2;
+ for (i = 0; ict2[i]; i++) {
+ icp->icmp_type = ict1[i];
+ icp->icmp_code = 0;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type %d code 0 (all 0's)\r",
+ i * 4, icp->icmp_type);
+ icp->icmp_code = 127;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type %d code 127 (all 0's)\r",
+ i * 4 + 1, icp->icmp_type);
+ icp->icmp_code = 128;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type %d code 128 (all 0's)\r",
+ i * 4 + 2, icp->icmp_type);
+ icp->icmp_code = 255;
+ (void) send_icmp(nfd, mtu, ip, gwip);
+ PAUSE();
+ printf("3.5.%d ICMP type %d code 127 (all 0's)\r",
+ i * 4 + 3, icp->icmp_type);
+ }
+ putchar('\n');
+ }
+}
+
+
+/* Perform test 4 (UDP) */
+
+void ip_test4(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ struct timeval tv;
+ struct udphdr *u;
+ int nfd, i;
+
+
+ ip->ip_hl = sizeof(*ip) >> 2;
+ ip->ip_v = IPVERSION;
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_ttl = 60;
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_sum = 0;
+ u = (udphdr_t *)((char *)ip + (ip->ip_hl << 2));
+ u->uh_sport = 1;
+ u->uh_dport = 1;
+ u->uh_ulen = sizeof(*u) + 4;
+ nfd = initdevice(dev, u->uh_sport, 1);
+
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Test 1. ulen > packet
+ */
+ u->uh_ulen = sizeof(*u) + 4;
+ ip->ip_len = (ip->ip_hl << 2) + u->uh_ulen;
+ printf("4.1 UDP uh_ulen > packet size - short packets\n");
+ for (i = u->uh_ulen * 2; i > sizeof(*u) + 4; i--) {
+ u->uh_ulen = i;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 2)) {
+ /*
+ * Test 2. ulen < packet
+ */
+ u->uh_ulen = sizeof(*u) + 4;
+ ip->ip_len = (ip->ip_hl << 2) + u->uh_ulen;
+ printf("4.2 UDP uh_ulen < packet size - short packets\n");
+ for (i = u->uh_ulen * 2; i > sizeof(*u) + 4; i--) {
+ ip->ip_len = i;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 3)) {
+ /*
+ * Test 3: sport = 0, sport = 1, sport = 32767
+ * sport = 32768, sport = 65535
+ */
+ u->uh_ulen = sizeof(*u) + 4;
+ ip->ip_len = (ip->ip_hl << 2) + u->uh_ulen;
+ printf("4.3.1 UDP sport = 0\n");
+ u->uh_sport = 0;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("0\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.3.2 UDP sport = 1\n");
+ u->uh_sport = 1;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("1\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.3.3 UDP sport = 32767\n");
+ u->uh_sport = 32767;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("32767\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.3.4 UDP sport = 32768\n");
+ u->uh_sport = 32768;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("32768\n");
+ putchar('\n');
+ fflush(stdout);
+ PAUSE();
+ printf("4.3.5 UDP sport = 65535\n");
+ u->uh_sport = 65535;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("65535\n");
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 4)) {
+ /*
+ * Test 4: dport = 0, dport = 1, dport = 32767
+ * dport = 32768, dport = 65535
+ */
+ u->uh_ulen = sizeof(*u) + 4;
+ u->uh_sport = 1;
+ ip->ip_len = (ip->ip_hl << 2) + u->uh_ulen;
+ printf("4.4.1 UDP dport = 0\n");
+ u->uh_dport = 0;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("0\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.4.2 UDP dport = 1\n");
+ u->uh_dport = 1;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("1\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.4.3 UDP dport = 32767\n");
+ u->uh_dport = 32767;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("32767\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.4.4 UDP dport = 32768\n");
+ u->uh_dport = 32768;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("32768\n");
+ fflush(stdout);
+ PAUSE();
+ printf("4.4.5 UDP dport = 65535\n");
+ u->uh_dport = 65535;
+ (void) send_udp(nfd, 1500, ip, gwip);
+ printf("65535\n");
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 4)) {
+ /*
+ * Test 5: sizeof(struct ip) <= MTU <= sizeof(struct udphdr) +
+ * sizeof(struct ip)
+ */
+ printf("4.5 UDP 20 <= MTU <= 32\n");
+ for (i = sizeof(*ip); i <= u->uh_ulen; i++) {
+ (void) send_udp(nfd, i, ip, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+}
+
+
+/* Perform test 5 (TCP) */
+
+void ip_test5(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ struct timeval tv;
+ tcphdr_t *t;
+ int nfd, i;
+
+ t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2));
+ t->th_x2 = 0;
+ t->th_off = 0;
+ t->th_sport = 1;
+ t->th_dport = 1;
+ t->th_win = 4096;
+ t->th_urp = 0;
+ t->th_sum = 0;
+ t->th_seq = 1;
+ t->th_ack = 0;
+ nfd = initdevice(dev, t->th_sport, 1);
+
+ if (!ptest || (ptest == 1)) {
+ /*
+ * Test 1: flags variations, 0 - 3f
+ */
+ t->th_off = sizeof(*t) >> 2;
+ printf("5.1 Test TCP flag combinations\n");
+ for (i = 0; i <= (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN);
+ i++) {
+ t->th_flags = i;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ if (!ptest || (ptest == 2)) {
+ t->th_flags = TH_SYN;
+ /*
+ * Test 2: seq = 0, seq = 1, seq = 0x7fffffff, seq=0x80000000,
+ * seq = 0xa000000, seq = 0xffffffff
+ */
+ printf("5.2.1 TCP seq = 0\n");
+ t->th_seq = 0;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.2.2 TCP seq = 1\n");
+ t->th_seq = 1;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.2.3 TCP seq = 0x7fffffff\n");
+ t->th_seq = 0x7fffffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.2.4 TCP seq = 0x80000000\n");
+ t->th_seq = 0x80000000;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.2.5 TCP seq = 0xc0000000\n");
+ t->th_seq = 0xc0000000;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.2.6 TCP seq = 0xffffffff\n");
+ t->th_seq = 0xffffffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 3)) {
+ t->th_flags = TH_ACK;
+ /*
+ * Test 3: ack = 0, ack = 1, ack = 0x7fffffff, ack = 0x8000000
+ * ack = 0xa000000, ack = 0xffffffff
+ */
+ printf("5.3.1 TCP ack = 0\n");
+ t->th_ack = 0;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.3.2 TCP ack = 1\n");
+ t->th_ack = 1;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.3.3 TCP ack = 0x7fffffff\n");
+ t->th_ack = 0x7fffffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.3.4 TCP ack = 0x80000000\n");
+ t->th_ack = 0x80000000;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.3.5 TCP ack = 0xc0000000\n");
+ t->th_ack = 0xc0000000;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.3.6 TCP ack = 0xffffffff\n");
+ t->th_ack = 0xffffffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 4)) {
+ t->th_flags = TH_SYN;
+ /*
+ * Test 4: win = 0, win = 32768, win = 65535
+ */
+ printf("5.4.1 TCP win = 0\n");
+ t->th_seq = 0;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.4.2 TCP win = 32768\n");
+ t->th_seq = 0x7fff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.4.3 TCP win = 65535\n");
+ t->th_win = 0xffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+
+#if !defined(linux) && !defined(__SVR4) && !defined(__svr4__)
+ {
+ struct tcpcb *t, tcb;
+ struct tcpiphdr ti;
+ struct sockaddr_in sin;
+ int fd, slen;
+
+ bzero((char *)&sin, sizeof(sin));
+
+ for (i = 1; i < 63; i++) {
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_addr.s_addr = ip->ip_dst.s_addr;
+ sin.sin_port = htons(i);
+ if (!connect(fd, (struct sockaddr *)&sin, sizeof(sin)))
+ break;
+ }
+
+ if (i == 63) {
+ printf("Couldn't open a TCP socket between ports 1 and 63\n");
+ printf("to host %s for test 5 and 6 - skipping.\n",
+ inet_ntoa(ip->ip_dst));
+ goto skip_five_and_six;
+ }
+
+ bcopy((char *)ip, (char *)&ti, sizeof(*ip));
+ ti.ti_dport = i;
+ slen = sizeof(sin);
+ if (!getsockname(fd, (struct sockaddr *)&sin, &slen))
+ ti.ti_sport = sin.sin_port;
+ if (!(t = find_tcp(fd, &ti))) {
+ printf("Can't find PCB\n");
+ goto skip_five_and_six;
+ }
+ kmemcpy((char*)&tcb, (void *)t, sizeof(tcb));
+ ti.ti_win = tcb.rcv_adv;
+ ti.ti_seq = tcb.snd_nxt - 1;
+ ti.ti_ack = tcb.rcv_nxt;
+
+ if (!ptest || (ptest == 5)) {
+ /*
+ * Test 5: urp
+ */
+ printf("5.1 TCP Urgent pointer\n");
+ ti.ti_urp = 1;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ PAUSE();
+ ti.ti_urp = 0x7fff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ PAUSE();
+ ti.ti_urp = 0x8000;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ PAUSE();
+ ti.ti_urp = 0xffff;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 6)) {
+ /*
+ * Test 6: data offset, off = 0, off is inside, off is outside
+ */
+ printf("6.1 TCP off = 0-15, len = 40\n");
+ for (i = 0; i < 16; i++) {
+ ti.ti_off = ntohs(i);
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+ }
+
+ (void) close(fd);
+ }
+skip_five_and_six:
+#endif
+ t->th_seq = 1;
+ t->th_ack = 1;
+
+ if (!ptest || (ptest == 7)) {
+ t->th_off = 0;
+ t->th_flags = TH_SYN;
+ /*
+ * Test 7: sport = 0, sport = 1, sport = 32767
+ * sport = 32768, sport = 65535
+ */
+ printf("5.7.1 TCP sport = 0\n");
+ t->th_sport = 0;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.7.2 TCP sport = 1\n");
+ t->th_sport = 1;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.7.3 TCP sport = 32767\n");
+ t->th_sport = 32767;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.7.4 TCP sport = 32768\n");
+ t->th_sport = 32768;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.7.5 TCP sport = 65535\n");
+ t->th_sport = 65535;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ if (!ptest || (ptest == 8)) {
+ t->th_sport = 1;
+ /*
+ * Test 8: dport = 0, dport = 1, dport = 32767
+ * dport = 32768, dport = 65535
+ */
+ printf("5.8.1 TCP dport = 0\n");
+ t->th_dport = 0;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.8.2 TCP dport = 1\n");
+ t->th_dport = 1;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.8.3 TCP dport = 32767\n");
+ t->th_dport = 32767;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.8.4 TCP dport = 32768\n");
+ t->th_dport = 32768;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+
+ printf("5.8.5 TCP dport = 65535\n");
+ t->th_dport = 65535;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+ /* TCP options header checking */
+ /* 0 length options, etc */
+}
+
+
+/* Perform test 6 (exhaust mbuf test) */
+
+void ip_test6(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ struct timeval tv;
+ udphdr_t *u;
+ int nfd, i, j, k;
+
+ ip->ip_v = IPVERSION;
+ ip->ip_tos = 0;
+ ip->ip_off = 0;
+ ip->ip_ttl = 60;
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_sum = 0;
+ u = (udphdr_t *)(ip + 1);
+ u->uh_sport = 1;
+ u->uh_dport = 9;
+ u->uh_sum = 0;
+
+ nfd = initdevice(dev, u->uh_sport, 1);
+ u->uh_sport = htons(u->uh_sport);
+ u->uh_dport = htons(u->uh_dport);
+ u->uh_ulen = 7168;
+
+ for (i = 0; i < 128; i++) {
+ /*
+ * First send the entire packet in 768 byte chunks.
+ */
+ ip->ip_len = sizeof(*ip) + 768 + sizeof(*u);
+ ip->ip_hl = sizeof(*ip) >> 2;
+ ip->ip_off = IP_MF;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d %d\r", i, 0);
+ fflush(stdout);
+ PAUSE();
+ /*
+ * And again using 128 byte chunks.
+ */
+ ip->ip_len = sizeof(*ip) + 128 + sizeof(*u);
+ ip->ip_off = IP_MF;
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d %d\r", i, 0);
+ fflush(stdout);
+ PAUSE();
+
+ for (j = 768; j < 3584; j += 768) {
+ ip->ip_len = sizeof(*ip) + 768;
+ ip->ip_off = IP_MF|(j>>3);
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d %d\r", i, j);
+ fflush(stdout);
+ PAUSE();
+
+ ip->ip_len = sizeof(*ip) + 128;
+ for (k = j - 768; k < j; k += 128) {
+ ip->ip_off = IP_MF|(k>>3);
+ (void) send_ip(nfd, 1500, ip, gwip, 1);
+ printf("%d %d\r", i, k);
+ fflush(stdout);
+ PAUSE();
+ }
+ }
+ }
+ putchar('\n');
+}
+
+
+/* Perform test 7 (random packets) */
+
+static u_long tbuf[64];
+
+void ip_test7(dev, mtu, ip, gwip, ptest)
+char *dev;
+int mtu;
+ip_t *ip;
+struct in_addr gwip;
+int ptest;
+{
+ ip_t *pip;
+ struct timeval tv;
+ int nfd, i, j;
+ u_char *s;
+
+ nfd = initdevice(dev, 0, 1);
+ pip = (ip_t *)tbuf;
+
+ srand(time(NULL) ^ (getpid() * getppid()));
+
+ printf("7. send 1024 random IP packets.\n");
+
+ for (i = 0; i < 512; i++) {
+ for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++)
+ *s = (rand() >> 13) & 0xff;
+ pip->ip_v = IPVERSION;
+ bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst,
+ sizeof(struct in_addr));
+ pip->ip_sum = 0;
+ pip->ip_len &= 0xff;
+ (void) send_ip(nfd, mtu, pip, gwip, 0);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+
+ for (i = 0; i < 512; i++) {
+ for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++)
+ *s = (rand() >> 13) & 0xff;
+ pip->ip_v = IPVERSION;
+ pip->ip_off &= 0xc000;
+ bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst,
+ sizeof(struct in_addr));
+ pip->ip_sum = 0;
+ pip->ip_len &= 0xff;
+ (void) send_ip(nfd, mtu, pip, gwip, 0);
+ printf("%d\r", i);
+ fflush(stdout);
+ PAUSE();
+ }
+ putchar('\n');
+}
diff --git a/contrib/ipfilter/ipsend/larp.c b/contrib/ipfilter/ipsend/larp.c
new file mode 100644
index 0000000..1eb4b2f
--- /dev/null
+++ b/contrib/ipfilter/ipsend/larp.c
@@ -0,0 +1,85 @@
+/*
+ * larp.c (C) 1995 Darren Reed
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+
+/*
+ * lookup host and return
+ * its IP address in address
+ * (4 bytes)
+ */
+int resolve(host, address)
+char *host, *address;
+{
+ struct hostent *hp;
+ u_long add;
+
+ add = inet_addr(host);
+ if (add == -1)
+ {
+ if (!(hp = gethostbyname(host)))
+ {
+ fprintf(stderr, "unknown host: %s\n", host);
+ return -1;
+ }
+ bcopy((char *)hp->h_addr, (char *)address, 4);
+ return 0;
+ }
+ bcopy((char*)&add, address, 4);
+ return 0;
+}
+
+/*
+ * ARP for the MAC address corresponding
+ * to the IP address. This taken from
+ * some BSD program, I cant remember which.
+ */
+int arp(ip, ether)
+char *ip;
+char *ether;
+{
+ static int s = -1;
+ struct arpreq ar;
+ struct sockaddr_in *sin;
+ char *inet_ntoa();
+
+ bzero((char *)&ar, sizeof(ar));
+ sin = (struct sockaddr_in *)&ar.arp_pa;
+ sin->sin_family = AF_INET;
+ bcopy(ip, (char *)&sin->sin_addr.s_addr, 4);
+
+ if (s == -1)
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ {
+ perror("arp: socket");
+ return -1;
+ }
+
+ if (ioctl(s, SIOCGARP, (caddr_t)&ar) == -1)
+ {
+ fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr));
+ if (errno != ENXIO)
+ perror("SIOCGARP");
+ return -1;
+ }
+
+ bcopy(ar.arp_ha.sa_data, ether, 6);
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/linux.h b/contrib/ipfilter/ipsend/linux.h
new file mode 100644
index 0000000..7eb382b
--- /dev/null
+++ b/contrib/ipfilter/ipsend/linux.h
@@ -0,0 +1,17 @@
+/*
+ * (C)opyright 1995 by Darren Reed.
+ *
+ * This code may be freely distributed as long as it retains this notice
+ * and is not changed in any way. The author accepts no responsibility
+ * for the use of this software. I hate legaleese, don't you ?
+ *
+ * @(#)linux.h 1.1 8/19/95
+ */
+
+#include <linux/config.h>
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#endif /* MODULE */
+
+#include "ip_compat.h"
diff --git a/contrib/ipfilter/ipsend/lsock.c b/contrib/ipfilter/ipsend/lsock.c
new file mode 100644
index 0000000..89b6ab7
--- /dev/null
+++ b/contrib/ipfilter/ipsend/lsock.c
@@ -0,0 +1,261 @@
+/*
+ * lsock.c (C) 1995 Darren Reed
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/dir.h>
+#define __KERNEL__
+#if LINUX >= 0200
+# undef UINT_MAX
+# undef INT_MAX
+# undef ULONG_MAX
+# undef LONG_MAX
+# include <linux/notifier.h>
+#endif
+#include <linux/fs.h>
+#if LINUX >= 0200
+#include "linux/netdevice.h"
+#include "net/sock.h"
+#endif
+#undef __KERNEL__
+#include <linux/sched.h>
+#include <linux/netdevice.h>
+#include <nlist.h>
+#include <sys/user.h>
+#include <sys/socket.h>
+#include <math.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <net/if.h>
+#if LINUX < 0103
+#include <net/inet/sock.h>
+#endif
+#include "ip_compat.h"
+#include "tcpip.h"
+
+int nproc;
+struct task_struct *proc;
+
+#ifndef KMEM
+# ifdef _PATH_KMEM
+# define KMEM _PATH_KMEM
+# endif
+#endif
+#ifndef KMEM
+# define KMEM "/dev/kmem"
+#endif
+#ifndef KERNEL
+# define KERNEL "/System.map"
+#endif
+
+int kmemcpy(buf, pos, n)
+char *buf;
+void *pos;
+int n;
+{
+ static int kfd = -1;
+
+ if (kfd == -1)
+ kfd = open(KMEM, O_RDONLY);
+
+ if (lseek(kfd, (off_t)pos, SEEK_SET) == -1)
+ {
+ perror("lseek");
+ return -1;
+ }
+ if (read(kfd, buf, n) == -1)
+ {
+ perror("read");
+ return -1;
+ }
+ return n;
+}
+
+struct nlist names[3] = {
+ { "_task" },
+ { "_nr_tasks" },
+ { NULL }
+ };
+
+struct task_struct *getproc()
+{
+ struct task_struct *p, **pp;
+ void *v;
+ pid_t pid = getpid();
+ int siz, n;
+
+ n = nlist(KERNEL, names);
+ if (n != 0)
+ {
+ fprintf(stderr, "nlist(%#x) == %d\n", names, n);
+ return NULL;
+ }
+ if (kmemcpy((char *)&nproc, (void *)names[1].n_value,
+ sizeof(nproc)) == -1)
+ {
+ fprintf(stderr, "read nproc (%#x)\n", names[1].n_value);
+ return NULL;
+ }
+ siz = nproc * sizeof(struct task_struct *);
+ if (kmemcpy((char *)&v, (void *)names[0].n_value, sizeof(v)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) proc\n",
+ names[0].n_value, &v, sizeof(v));
+ return NULL;
+ }
+ pp = (struct task_struct **)malloc(siz);
+ if (kmemcpy((char *)pp, (void *)v, siz) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) proc\n",
+ v, pp, siz);
+ return NULL;
+ }
+ proc = (struct task_struct *)malloc(siz);
+ for (n = 0; n < NR_TASKS; n++)
+ {
+ if (kmemcpy((char *)(proc + n), (void *)pp[n],
+ sizeof(*proc)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) proc\n",
+ pp[n], proc + n, sizeof(*proc));
+ return NULL;
+ }
+ }
+
+ p = proc;
+
+ for (n = NR_TASKS; n; n--, p++)
+ if (p->pid == pid)
+ break;
+ if (!n)
+ return NULL;
+
+ return p;
+}
+
+
+struct sock *find_tcp(fd, ti)
+int fd;
+struct tcpiphdr *ti;
+{
+ struct sock *s;
+ struct inode *i;
+ struct files_struct *fs;
+ struct task_struct *p;
+ struct file *f, **o;
+
+ if (!(p = getproc()))
+ return NULL;
+
+ fs = p->files;
+ o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1));
+ if (kmemcpy((char *)o, (void *)fs->fd,
+ (fs->count + 1) * sizeof(*o)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n",
+ fs->fd, o, sizeof(*o));
+ return NULL;
+ }
+ f = (struct file *)calloc(1, sizeof(*f));
+ if (kmemcpy((char *)f, (void *)o[fd], sizeof(*f)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n",
+ o[fd], f, sizeof(*f));
+ return NULL;
+ }
+
+ i = (struct inode *)calloc(1, sizeof(*i));
+ if (kmemcpy((char *)i, (void *)f->f_inode, sizeof(*i)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n",
+ f->f_inode, i, sizeof(*i));
+ return NULL;
+ }
+ return i->u.socket_i.data;
+}
+
+int do_socket(dev, mtu, ti, gwip, flags)
+char *dev;
+int mtu;
+struct tcpiphdr *ti;
+struct in_addr gwip;
+int flags;
+{
+ struct sockaddr_in rsin, lsin;
+ struct sock *s, sk;
+ int fd, nfd, len;
+
+ printf("Dest. Port: %d\n", ti->ti_dport);
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ perror("socket");
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, FNDELAY) == -1)
+ {
+ perror("fcntl");
+ return -1;
+ }
+
+ bzero((char *)&lsin, sizeof(lsin));
+ lsin.sin_family = AF_INET;
+ bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
+ sizeof(struct in_addr));
+ if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
+ {
+ perror("bind");
+ return -1;
+ }
+ len = sizeof(lsin);
+ (void) getsockname(fd, (struct sockaddr *)&lsin, &len);
+ ti->ti_sport = lsin.sin_port;
+ printf("sport %d\n", ntohs(lsin.sin_port));
+ nfd = initdevice(dev, ntohs(lsin.sin_port));
+
+ if (!(s = find_tcp(fd, ti)))
+ return -1;
+
+ bzero((char *)&rsin, sizeof(rsin));
+ rsin.sin_family = AF_INET;
+ bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
+ sizeof(struct in_addr));
+ rsin.sin_port = ti->ti_dport;
+ if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
+ errno != EINPROGRESS)
+ {
+ perror("connect");
+ return -1;
+ }
+ kmemcpy((char*)&sk, (void *)s, sizeof(sk));
+ ti->ti_win = sk.window;
+ ti->ti_seq = sk.sent_seq - 1;
+ ti->ti_ack = sk.rcv_ack_seq;
+
+ if (send_tcp(nfd, mtu, ti, gwip, TH_SYN) == -1)
+ return -1;
+ (void)write(fd, "Hello World\n", 12);
+ sleep(2);
+ close(fd);
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/resend.c b/contrib/ipfilter/ipsend/resend.c
new file mode 100644
index 0000000..59ed75e
--- /dev/null
+++ b/contrib/ipfilter/ipsend/resend.c
@@ -0,0 +1,130 @@
+/*
+ * resend.c (C) 1995 Darren Reed
+ *
+ * This was written to test what size TCP fragments would get through
+ * various TCP/IP packet filters, as used in IP firewalls. In certain
+ * conditions, enough of the TCP header is missing for unpredictable
+ * results unless the filter is aware that this can happen.
+ *
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#include <netinet/tcpip.h>
+#include <netinet/if_ether.h>
+#endif
+#include "ip_compat.h"
+#ifdef linux
+#include <linux/sockios.h>
+#include "tcpip.h"
+#endif
+#include "ipt.h"
+
+
+static u_char buf[65536]; /* 1 big packet */
+
+extern int initdevice(), arp(), sendip();
+
+void printpacket(ip)
+ip_t *ip;
+{
+ tcphdr_t *t;
+ int i, j;
+
+ t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2));
+ if (ip->ip_tos)
+ printf("tos %#x ", ip->ip_tos);
+ if (ip->ip_off & 0x3fff)
+ printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
+ printf("len %d id %d ", ip->ip_len, ip->ip_id);
+ printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
+ inet_ntoa(ip->ip_src));
+ if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
+ printf(",%d", t->th_sport);
+ printf(" dst %s", inet_ntoa(ip->ip_dst));
+ if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
+ printf(",%d", t->th_dport);
+ if (ip->ip_p == IPPROTO_TCP) {
+ printf(" seq %lu:%lu flags ",
+ (u_long)t->th_seq, (u_long)t->th_ack);
+ for (j = 0, i = 1; i < 256; i *= 2, j++)
+ if (t->th_flags & i)
+ printf("%c", "FSRPAU--"[j]);
+ }
+ putchar('\n');
+}
+
+
+int ip_resend(dev, mtu, r, gwip, datain)
+char *dev;
+int mtu;
+struct in_addr gwip;
+struct ipread *r;
+char *datain;
+{
+ ether_header_t *eh;
+ char dhost[6];
+ ip_t *ip;
+ int fd, wfd = initdevice(dev, 0, 5), len, i;
+
+ if (datain)
+ fd = (*r->r_open)(datain);
+ else
+ fd = (*r->r_open)("-");
+
+ if (fd < 0)
+ exit(-1);
+
+ ip = (struct ip *)buf;
+ eh = (ether_header_t *)malloc(sizeof(*eh));
+
+ bzero(&eh->ether_shost, sizeof(eh->ether_shost));
+ if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
+ {
+ perror("arp");
+ return -2;
+ }
+
+ while ((i = (*r->r_readip)(buf, sizeof(buf), NULL, NULL)) > 0)
+ {
+ len = ntohs(ip->ip_len);
+ eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
+ eh->ether_type = htons((u_short)ETHERTYPE_IP);
+ if (!gwip.s_addr) {
+ if (arp((char *)&gwip,
+ (char *)&eh->ether_dhost) == -1) {
+ perror("arp");
+ continue;
+ }
+ } else
+ bcopy(dhost, (char *)&eh->ether_dhost, sizeof(dhost));
+ bcopy(ip, (char *)(eh + 1), len);
+ printpacket(ip);
+
+ if (sendip(wfd, eh, sizeof(*eh) + len) == -1)
+ {
+ perror("send_packet");
+ break;
+ }
+ }
+ (*r->r_close)();
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/sbpf.c b/contrib/ipfilter/ipsend/sbpf.c
new file mode 100644
index 0000000..5eb9d9b
--- /dev/null
+++ b/contrib/ipfilter/ipsend/sbpf.c
@@ -0,0 +1,136 @@
+/*
+ * (C)opyright October 1995 Darren Reed. (from tcplog)
+ *
+ * This software may be freely distributed as long as it is not altered
+ * in any way and that this messagge always accompanies it.
+ *
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#if BSD < 199103
+#include <sys/fcntlcom.h>
+#endif
+#include <sys/dir.h>
+#include <net/bpf.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sbpf[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
+#endif
+
+/*
+ * the code herein is dervied from libpcap.
+ */
+static u_char *buf = NULL;
+static int bufsize = 0, timeout = 1;
+
+
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ struct bpf_version bv;
+ struct timeval to;
+ struct ifreq ifr;
+ char bpfname[16];
+ int fd, i;
+
+ for (i = 0; i < 16; i++)
+ {
+ (void) sprintf(bpfname, "/dev/bpf%d", i);
+ if ((fd = open(bpfname, O_RDWR)) >= 0)
+ break;
+ }
+ if (i == 16)
+ {
+ fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
+ return -1;
+ }
+
+ if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
+ {
+ perror("BIOCVERSION");
+ return -1;
+ }
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION)
+ {
+ fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
+ bv.bv_major, bv.bv_minor);
+ fprintf(stderr, "current version: %d.%d\n",
+ BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
+ return -1;
+ }
+
+ (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, &ifr) == -1)
+ {
+ fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
+ perror("BIOCSETIF");
+ exit(1);
+ }
+ /*
+ * get kernel buffer size
+ */
+ if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
+ {
+ perror("BIOCSBLEN");
+ exit(-1);
+ }
+ buf = (u_char*)malloc(bufsize);
+ /*
+ * set the timeout
+ */
+ timeout = tout;
+ to.tv_sec = 1;
+ to.tv_usec = 0;
+ if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
+ {
+ perror("BIOCSRTIMEOUT");
+ exit(-1);
+ }
+
+ (void) ioctl(fd, BIOCFLUSH, 0);
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/bpf
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ if (write(fd, pkt, len) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/sdlpi.c b/contrib/ipfilter/ipsend/sdlpi.c
new file mode 100644
index 0000000..eabd61e
--- /dev/null
+++ b/contrib/ipfilter/ipsend/sdlpi.c
@@ -0,0 +1,130 @@
+/*
+ * (C)opyright October 1992 Darren Reed. (from tcplog)
+ *
+ * This software may be freely distributed as long as it is not altered
+ * in any way and that this messagge always accompanies it.
+ *
+ * The author of this software makes no garuntee about the
+ * performance of this package or its suitability to fulfill any purpose.
+ *
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/stropts.h>
+
+#include <sys/pfmod.h>
+#include <sys/bufmod.h>
+#include <sys/dlpi.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include "ip_compat.h"
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char snitid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed";
+#endif
+
+#define CHUNKSIZE 8192
+#define BUFSPACE (4*CHUNKSIZE)
+
+
+/*
+ * Be careful to only include those defined in the flags option for the
+ * interface are included in the header size.
+ */
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ char devname[16], *s, buf[256];
+ int i, fd;
+
+ (void) sprintf(devname, "/dev/%s", device);
+
+ s = devname + 5;
+ while (*s && !isdigit(*s))
+ s++;
+ if (!*s)
+ {
+ fprintf(stderr, "bad device name %s\n", devname);
+ exit(-1);
+ }
+ i = atoi(s);
+ *s = '\0';
+ /*
+ * For writing
+ */
+ if ((fd = open(devname, O_RDWR)) < 0)
+ {
+ fprintf(stderr, "O_RDWR(1) ");
+ perror(devname);
+ exit(-1);
+ }
+
+ if (dlattachreq(fd, i) == -1 || dlokack(fd, buf) == -1)
+ {
+ fprintf(stderr, "DLPI error\n");
+ exit(-1);
+ }
+ dlbindreq(fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0);
+ dlbindack(fd, buf);
+ /*
+ * write full headers
+ */
+ if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1)
+ {
+ fprintf(stderr, "DLIOCRAW error\n");
+ exit(-1);
+ }
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/nit
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ struct strbuf dbuf, *dp = &dbuf;
+
+ /*
+ * construct NIT STREAMS messages, first control then data.
+ */
+ dp->buf = pkt;
+ dp->len = len;
+ dp->maxlen = dp->len;
+
+ if (putmsg(fd, NULL, dp, 0) == -1)
+ {
+ perror("putmsg");
+ return -1;
+ }
+ if (ioctl(fd, I_FLUSH, FLUSHW) == -1)
+ {
+ perror("I_FLUSHW");
+ return -1;
+ }
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/slinux.c b/contrib/ipfilter/ipsend/slinux.c
new file mode 100644
index 0000000..1767dfe
--- /dev/null
+++ b/contrib/ipfilter/ipsend/slinux.c
@@ -0,0 +1,94 @@
+/*
+ * (C)opyright October 1992 Darren Reed. (from tcplog)
+ *
+ * This software may be freely distributed as long as it is not altered
+ * in any way and that this messagge always accompanies it.
+ *
+ * The author of this software makes no garuntee about the
+ * performance of this package or its suitability to fulfill any purpose.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/dir.h>
+#include <linux/netdevice.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include "ip_compat.h"
+#include "tcpip.h"
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)slinux.c 1.2 8/25/95";
+#endif
+
+#define CHUNKSIZE 8192
+#define BUFSPACE (4*CHUNKSIZE)
+
+/*
+ * Be careful to only include those defined in the flags option for the
+ * interface are included in the header size.
+ */
+
+static int timeout;
+static char *eth_dev = NULL;
+
+
+int initdevice(dev, sport, tout)
+char *dev;
+int sport, tout;
+{
+ int fd;
+
+ eth_dev = strdup(dev);
+ if ((fd = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_IP))) == -1)
+ {
+ perror("socket(SOCK_PACKET)");
+ exit(-1);
+ }
+
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/nit
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ struct sockaddr s;
+ struct ifreq ifr;
+
+ strncpy(ifr.ifr_name, eth_dev, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1)
+ {
+ perror("SIOCGIFHWADDR");
+ return -1;
+ }
+ bcopy(ifr.ifr_hwaddr.sa_data, pkt + 6, 6);
+ s.sa_family = ETHERTYPE_IP;
+ strncpy(s.sa_data, eth_dev, sizeof(s.sa_data));
+
+ if (sendto(fd, pkt, len, 0, &s, sizeof(s)) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/snit.c b/contrib/ipfilter/ipsend/snit.c
new file mode 100644
index 0000000..d022192
--- /dev/null
+++ b/contrib/ipfilter/ipsend/snit.c
@@ -0,0 +1,160 @@
+/*
+ * (C)opyright October 1992 Darren Reed. (from tcplog)
+ *
+ * This software may be freely distributed as long as it is not altered
+ * in any way and that this messagge always accompanies it.
+ *
+ * The author of this software makes no garuntee about the
+ * performance of this package or its suitability to fulfill any purpose.
+ *
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <net/nit.h>
+#include <sys/fcntlcom.h>
+#include <sys/dir.h>
+#include <net/nit_if.h>
+#include <net/nit_pf.h>
+#include <net/nit_buf.h>
+#include <net/packetfilt.h>
+#include <sys/stropts.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char snitid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed";
+#endif
+
+#define CHUNKSIZE 8192
+#define BUFSPACE (4*CHUNKSIZE)
+
+/*
+ * Be careful to only include those defined in the flags option for the
+ * interface are included in the header size.
+ */
+#define BUFHDR_SIZE (sizeof(struct nit_bufhdr))
+#define NIT_HDRSIZE (BUFHDR_SIZE)
+
+static int timeout;
+
+
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ struct strioctl si;
+ struct timeval to;
+ struct ifreq ifr;
+ int fd;
+
+ if ((fd = open("/dev/nit", O_RDWR)) < 0)
+ {
+ perror("/dev/nit");
+ exit(-1);
+ }
+
+ /*
+ * arrange to get messages from the NIT STREAM and use NIT_BUF option
+ */
+ ioctl(fd, I_SRDOPT, (char*)RMSGD);
+ ioctl(fd, I_PUSH, "nbuf");
+
+ /*
+ * set the timeout
+ */
+ timeout = tout;
+ si.ic_timout = 1;
+ to.tv_sec = 1;
+ to.tv_usec = 0;
+ si.ic_cmd = NIOCSTIME;
+ si.ic_len = sizeof(to);
+ si.ic_dp = (char*)&to;
+ if (ioctl(fd, I_STR, (char*)&si) == -1)
+ {
+ perror("ioctl: NIT timeout");
+ exit(-1);
+ }
+
+ /*
+ * request the interface
+ */
+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
+ si.ic_cmd = NIOCBIND;
+ si.ic_len = sizeof(ifr);
+ si.ic_dp = (char*)&ifr;
+ if (ioctl(fd, I_STR, (char*)&si) == -1)
+ {
+ perror(ifr.ifr_name);
+ exit(1);
+ }
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/nit
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ struct sockaddr sk, *sa = &sk;
+ struct strbuf cbuf, *cp = &cbuf, dbuf, *dp = &dbuf;
+
+ /*
+ * For ethernet, need at least 802.3 header and IP header.
+ */
+ if (len < (sizeof(sa->sa_data) + sizeof(struct ip)))
+ return -1;
+ /*
+ * to avoid any output processing for IP, say we're not.
+ */
+ sa->sa_family = AF_UNSPEC;
+ bcopy(pkt, sa->sa_data, sizeof(sa->sa_data));
+ pkt += sizeof(sa->sa_data);
+ len -= sizeof(sa->sa_data);
+
+ /*
+ * construct NIT STREAMS messages, first control then data.
+ */
+ cp->len = sizeof(*sa);
+ cp->maxlen = sizeof(*sa);
+ cp->buf = (char *)sa;
+
+ dp->buf = pkt;
+ dp->len = len;
+ dp->maxlen = dp->len;
+
+ if (putmsg(fd, cp, dp, 0) == -1)
+ {
+ perror("putmsg");
+ return -1;
+ }
+
+ if (ioctl(fd, I_FLUSH, FLUSHW) == -1)
+ {
+ perror("I_FLUSH");
+ return -1;
+ }
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c
new file mode 100644
index 0000000..58949c5
--- /dev/null
+++ b/contrib/ipfilter/ipsend/sock.c
@@ -0,0 +1,370 @@
+/*
+ * sock.c (C) 1995 Darren Reed
+ *
+ * The author provides this program as-is, with no gaurantee for its
+ * suitability for any specific purpose. The author takes no responsibility
+ * for the misuse/abuse of this program and provides it for the sole purpose
+ * of testing packet filter policies. This file maybe distributed freely
+ * providing it is not modified and that this notice remains in tact.
+ */
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/dir.h>
+#define _KERNEL
+#define KERNEL
+#include <sys/file.h>
+#undef _KERNEL
+#undef KERNEL
+#include <nlist.h>
+#include <sys/user.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/proc.h>
+#include <kvm.h>
+#ifdef sun
+#include <sys/systm.h>
+#include <sys/session.h>
+#endif
+#if BSD >= 199103
+#include <sys/sysctl.h>
+#include <sys/filedesc.h>
+#include <paths.h>
+#endif
+#include <math.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcpip.h>
+
+int nproc;
+struct proc *proc;
+
+extern int initdevice(), send_tcp();
+
+#ifndef KMEM
+# ifdef _PATH_KMEM
+# define KMEM _PATH_KMEM
+# endif
+#endif
+#ifndef KERNEL
+# ifdef _PATH_UNIX
+# define KERNEL _PATH_UNIX
+# endif
+#endif
+#ifndef KMEM
+# define KMEM "/dev/kmem"
+#endif
+#ifndef KERNEL
+# define KERNEL "/vmunix"
+#endif
+
+int kmemcpy(buf, pos, n)
+char *buf;
+off_t pos;
+int n;
+{
+ static int kfd = -1;
+
+ if (kfd == -1)
+ kfd = open(KMEM, O_RDONLY);
+
+ if (lseek(kfd, pos, SEEK_SET) == -1)
+ {
+ perror("lseek");
+ return -1;
+ }
+ if (read(kfd, buf, n) == -1)
+ {
+ perror("read");
+ return -1;
+ }
+ return n;
+}
+
+struct nlist names[3] = {
+ { "_proc" },
+ { "_nproc" },
+ { NULL }
+ };
+
+#if BSD < 199103
+struct proc *getproc()
+{
+ struct proc *p;
+ pid_t pid = getpid();
+ int siz, n;
+
+ n = nlist(KERNEL, names);
+ if (n != 0)
+ {
+ fprintf(stderr, "nlist(%#x) == %d\n", names, n);
+ return NULL;
+ }
+ if (kmemcpy((char *)&nproc, (off_t)names[1].n_value,
+ sizeof(nproc)) == -1)
+ {
+ fprintf(stderr, "read nproc (%#x)\n", names[1].n_value);
+ return NULL;
+ }
+ siz = nproc * sizeof(struct proc);
+ if (kmemcpy((char *)&p, (off_t)names[0].n_value, sizeof(p)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) proc\n",
+ names[0].n_value, &p, sizeof(p));
+ return NULL;
+ }
+ proc = (struct proc *)malloc(siz);
+ if (kmemcpy((char *)proc, (off_t)p, siz) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) proc\n",
+ p, proc, siz);
+ return NULL;
+ }
+
+ p = proc;
+
+ for (n = nproc; n; n--, p++)
+ if (p->p_pid == pid)
+ break;
+ if (!n)
+ return NULL;
+
+ return p;
+}
+
+
+struct tcpcb *find_tcp(fd, ti)
+int fd;
+struct tcpiphdr *ti;
+{
+ struct tcpcb *t;
+ struct inpcb *i;
+ struct socket *s;
+ struct user *up;
+ struct proc *p;
+ struct file *f, **o;
+
+ if (!(p = getproc()))
+ return NULL;
+
+ up = (struct user *)malloc(sizeof(*up));
+ if (kmemcpy((char *)up, (off_t)p->p_uarea, sizeof(*up)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea);
+ return NULL;
+ }
+
+ o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1));
+ if (kmemcpy((char *)o, (off_t)up->u_ofile,
+ (up->u_lastfile + 1) * sizeof(*o)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n",
+ up->u_ofile_arr, o, sizeof(*o));
+ return NULL;
+ }
+ f = (struct file *)calloc(1, sizeof(*f));
+ if (kmemcpy((char *)f, (off_t)o[fd], sizeof(*f)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n",
+ up->u_ofile_arr[fd], f, sizeof(*f));
+ return NULL;
+ }
+
+ s = (struct socket *)calloc(1, sizeof(*s));
+ if (kmemcpy((char *)s, (off_t)f->f_data, sizeof(*s)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n",
+ o[fd], s, sizeof(*s));
+ return NULL;
+ }
+
+ i = (struct inpcb *)calloc(1, sizeof(*i));
+ if (kmemcpy((char *)i, (off_t)s->so_pcb, sizeof(*i)) == -1)
+ {
+ fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n",
+ s->so_pcb, i, sizeof(*i));
+ return NULL;
+ }
+
+ t = (struct tcpcb *)calloc(1, sizeof(*t));
+ if (kmemcpy((char *)t, (off_t)i->inp_ppcb, sizeof(*t)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n",
+ i->inp_ppcb, t, sizeof(*t));
+ return NULL;
+ }
+ return (struct tcpcb *)i->inp_ppcb;
+}
+#else
+struct kinfo_proc *getproc()
+{
+ static struct kinfo_proc kp;
+ pid_t pid = getpid();
+ int n, mib[4];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+
+ n = 1;
+ if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1)
+ {
+ perror("sysctl");
+ return NULL;
+ }
+ return &kp;
+}
+
+
+struct tcpcb *find_tcp(tfd, ti)
+int tfd;
+struct tcpiphdr *ti;
+{
+ struct tcpcb *t;
+ struct inpcb *i;
+ struct socket *s;
+ struct filedesc *fd;
+ struct kinfo_proc *p;
+ struct file *f, **o;
+
+ if (!(p = getproc()))
+ return NULL;
+
+ fd = (struct filedesc *)malloc(sizeof(*fd));
+ if (kmemcpy((char *)fd, (void *)p->kp_proc.p_fd, sizeof(*fd)) == -1)
+ {
+ fprintf(stderr, "read(%#lx,%#lx) failed\n",
+ (u_long)p, (u_long)p->kp_proc.p_fd);
+ return NULL;
+ }
+
+ o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1));
+ if (kmemcpy((char *)o, (void *)fd->fd_ofiles,
+ (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
+ {
+ fprintf(stderr, "read(%#lx,%#lx,%d) - u_ofile - failed\n",
+ (u_long)fd->fd_ofiles, (u_long)o, sizeof(*o));
+ return NULL;
+ }
+ f = (struct file *)calloc(1, sizeof(*f));
+ if (kmemcpy((char *)f, (void *)o[tfd], sizeof(*f)) == -1)
+ {
+ fprintf(stderr, "read(%#lx,%#lx,%d) - o[tfd] - failed\n",
+ (u_long)o[tfd], (u_long)f, sizeof(*f));
+ return NULL;
+ }
+
+ s = (struct socket *)calloc(1, sizeof(*s));
+ if (kmemcpy((char *)s, (void *)f->f_data, sizeof(*s)) == -1)
+ {
+ fprintf(stderr, "read(%#lx,%#lx,%d) - f_data - failed\n",
+ (u_long)f->f_data, (u_long)s, sizeof(*s));
+ return NULL;
+ }
+
+ i = (struct inpcb *)calloc(1, sizeof(*i));
+ if (kmemcpy((char *)i, (void *)s->so_pcb, sizeof(*i)) == -1)
+ {
+ fprintf(stderr, "kvm_read(%#lx,%#lx,%d) - so_pcb - failed\n",
+ (u_long)s->so_pcb, (u_long)i, sizeof(*i));
+ return NULL;
+ }
+
+ t = (struct tcpcb *)calloc(1, sizeof(*t));
+ if (kmemcpy((char *)t, (void *)i->inp_ppcb, sizeof(*t)) == -1)
+ {
+ fprintf(stderr, "read(%#lx,%#lx,%d) - inp_ppcb - failed\n",
+ (u_long)i->inp_ppcb, (u_long)t, sizeof(*t));
+ return NULL;
+ }
+ return (struct tcpcb *)i->inp_ppcb;
+}
+#endif /* BSD < 199301 */
+
+int do_socket(dev, mtu, ti, gwip, flags)
+char *dev;
+int mtu;
+struct tcpiphdr *ti;
+struct in_addr gwip;
+int flags;
+{
+ struct sockaddr_in rsin, lsin;
+ struct tcpcb *t, tcb;
+ int fd, nfd, len;
+
+ printf("Dest. Port: %d\n", ti->ti_dport);
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ perror("socket");
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, FNDELAY) == -1)
+ {
+ perror("fcntl");
+ return -1;
+ }
+
+ bzero((char *)&lsin, sizeof(lsin));
+ lsin.sin_family = AF_INET;
+ bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
+ sizeof(struct in_addr));
+ if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
+ {
+ perror("bind");
+ return -1;
+ }
+ len = sizeof(lsin);
+ (void) getsockname(fd, (struct sockaddr *)&lsin, &len);
+ ti->ti_sport = lsin.sin_port;
+ printf("sport %d\n", ntohs(lsin.sin_port));
+ nfd = initdevice(dev, ntohs(lsin.sin_port));
+
+ if (!(t = find_tcp(fd, ti)))
+ return -1;
+
+ bzero((char *)&rsin, sizeof(rsin));
+ rsin.sin_family = AF_INET;
+ bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
+ sizeof(struct in_addr));
+ rsin.sin_port = ti->ti_dport;
+ if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
+ errno != EINPROGRESS)
+ {
+ perror("connect");
+ return -1;
+ }
+ kmemcpy((char*)&tcb, (void *)t, sizeof(tcb));
+ ti->ti_win = tcb.rcv_adv;
+ ti->ti_seq = tcb.snd_nxt - 1;
+ ti->ti_ack = tcb.rcv_nxt;
+
+ if (send_tcp(nfd, mtu, ti, gwip, TH_SYN) == -1)
+ return -1;
+ (void)write(fd, "Hello World\n", 12);
+ sleep(2);
+ close(fd);
+ return 0;
+}
diff --git a/contrib/ipfilter/ipsend/tcpip.h b/contrib/ipfilter/ipsend/tcpip.h
new file mode 100644
index 0000000..78f274f
--- /dev/null
+++ b/contrib/ipfilter/ipsend/tcpip.h
@@ -0,0 +1,38 @@
+/* @(#)tcpip.h 1.7 88/08/19 SMI; from UCB 7.1 6/5/85 */
+
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+/*
+ * Tcp+ip header, after ip options removed.
+ */
+
+#ifndef _netinet_tcpip_h
+#define _netinet_tcpip_h
+
+struct tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+ tcphdr_t ti_t; /* tcp header */
+};
+#define ti_next ti_i.ih_next
+#define ti_prev ti_i.ih_prev
+#define ti_x1 ti_i.ih_x1
+#define ti_pr ti_i.ih_pr
+#define ti_len ti_i.ih_len
+#define ti_src ti_i.ih_src
+#define ti_dst ti_i.ih_dst
+#define ti_sport ti_t.th_sport
+#define ti_dport ti_t.th_dport
+#define ti_seq ti_t.th_seq
+#define ti_ack ti_t.th_ack
+#define ti_x2 ti_t.th_x2
+#define ti_off ti_t.th_off
+#define ti_flags ti_t.th_flags
+#define ti_win ti_t.th_win
+#define ti_sum ti_t.th_sum
+#define ti_urp ti_t.th_urp
+
+#endif /*!_netinet_tcpip_h*/
OpenPOWER on IntegriCloud