diff options
author | darrenr <darrenr@FreeBSD.org> | 1997-02-09 22:50:16 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 1997-02-09 22:50:16 +0000 |
commit | cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717 (patch) | |
tree | 93c7db298b1fd70f9e27663b3fd527da063d0008 /contrib/ipfilter/ipsend | |
download | FreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.zip FreeBSD-src-cb8d46a179f2d30ac1cd0a01eb156e1a4c08d717.tar.gz |
Import IP Filter v3.1.7 into FreeBSD tree
Diffstat (limited to 'contrib/ipfilter/ipsend')
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 *)ð, 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 *)ð, 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 = ðerf; + break; + case 'H' : + ipr = &iphex; + break; + case 'P' : + ipr = &pcap; + break; + case 'S' : + ipr = &snoop; + break; + case 'T' : + ipr = &tcpd; + break; + case 'X' : + ipr = &iptext; + break; +#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*)𝔦 + 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*/ |