summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ipftest/Makefile13
-rw-r--r--usr.sbin/ipftest/ipft_ef.c24
-rw-r--r--usr.sbin/ipftest/ipft_hx.c62
-rw-r--r--usr.sbin/ipftest/ipft_pc.c19
-rw-r--r--usr.sbin/ipftest/ipft_sn.c19
-rw-r--r--usr.sbin/ipftest/ipft_td.c25
-rw-r--r--usr.sbin/ipftest/ipft_tx.c50
-rw-r--r--usr.sbin/ipftest/ipftest.13
-rw-r--r--usr.sbin/ipftest/ipt.c99
-rw-r--r--usr.sbin/ipftest/ipt.h26
-rw-r--r--usr.sbin/ipftest/misc.c58
-rw-r--r--usr.sbin/ipftest/pcap.h5
-rw-r--r--usr.sbin/ipftest/snoop.h10
-rw-r--r--usr.sbin/ipmon/ipmon.869
-rw-r--r--usr.sbin/ipmon/ipmon.c768
-rw-r--r--usr.sbin/ipsend/common/44arp.c13
-rw-r--r--usr.sbin/ipsend/common/ip.c125
-rw-r--r--usr.sbin/ipsend/common/iplang.h51
-rw-r--r--usr.sbin/ipsend/common/ipsend.h67
-rw-r--r--usr.sbin/ipsend/common/sbpf.c21
-rw-r--r--usr.sbin/ipsend/common/sock.c131
-rw-r--r--usr.sbin/ipsend/common/tcpip.h91
-rw-r--r--usr.sbin/ipsend/ipresend/Makefile9
-rw-r--r--usr.sbin/ipsend/ipresend/ipresend.1107
-rw-r--r--usr.sbin/ipsend/ipresend/ipresend.c54
-rw-r--r--usr.sbin/ipsend/ipresend/resend.c80
-rw-r--r--usr.sbin/ipsend/ipsend/Makefile12
-rw-r--r--usr.sbin/ipsend/ipsend/iplang_l.l312
-rw-r--r--usr.sbin/ipsend/ipsend/iplang_y.y1840
-rw-r--r--usr.sbin/ipsend/ipsend/ipsend.1110
-rw-r--r--usr.sbin/ipsend/ipsend/ipsend.5399
-rw-r--r--usr.sbin/ipsend/ipsend/ipsend.c134
-rw-r--r--usr.sbin/ipsend/ipsend/ipsopt.c160
-rw-r--r--usr.sbin/ipsend/iptest/Makefile7
-rw-r--r--usr.sbin/ipsend/iptest/iptest.1102
-rw-r--r--usr.sbin/ipsend/iptest/iptest.c78
-rw-r--r--usr.sbin/ipsend/iptest/iptests.c250
37 files changed, 4636 insertions, 767 deletions
diff --git a/usr.sbin/ipftest/Makefile b/usr.sbin/ipftest/Makefile
index c1792e6122f..c25f5edad0e 100644
--- a/usr.sbin/ipftest/Makefile
+++ b/usr.sbin/ipftest/Makefile
@@ -1,11 +1,16 @@
-# $OpenBSD: Makefile,v 1.4 1997/09/21 11:43:45 deraadt Exp $
+# $OpenBSD: Makefile,v 1.5 1998/01/26 04:16:31 dgregor Exp $
PROG= ipftest
MAN= ipftest.1
SRCS= ipt.c fil.c ipft_hx.c ipft_sn.c ipft_ef.c ipft_td.c ipft_pc.c \
- ipft_tx.c misc.c parse.c opt.c ip_frag.c ip_nat.c ip_state.c
-.PATH: ${.CURDIR}/../../sbin/ipf ${.CURDIR}/../../sbin/ipfstat ${.CURDIR}/../../sys/netinet
-CFLAGS+=-DIPL_NAME=\"/dev/ipl\" -I${.CURDIR}/../../sbin/ipf -I${.CURDIR}/../../sys/netinet
+ ipft_tx.c misc.c parse.c opt.c ip_frag.c ip_nat.c ip_state.c \
+ ip_auth.c ip_fil.c ip_proxy.c
+
+.PATH: ${.CURDIR}/../../sbin/ipf ${.CURDIR}/../../sbin/ipfstat \
+ ${.CURDIR}/../../sys/netinet
+
+CFLAGS+=-DIPL_NAME=\"/dev/ipl\" -I${.CURDIR}/../../sbin/ipf \
+ -I${.CURDIR}/../../sys/netinet -I${.CURDIR}
.include <bsd.prog.mk>
diff --git a/usr.sbin/ipftest/ipft_ef.c b/usr.sbin/ipftest/ipft_ef.c
index 213cca7f4a5..8ba0f379027 100644
--- a/usr.sbin/ipftest/ipft_ef.c
+++ b/usr.sbin/ipftest/ipft_ef.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_ef.c,v 1.7 1997/06/23 16:44:48 kstailey Exp $ */
+/* $OpenBSD: ipft_ef.c,v 1.8 1998/01/26 04:16:32 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -32,26 +32,32 @@ etherfind -n -t
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
-static char rcsid[] = "$DRId: ipft_ef.c,v 2.0.1.1 1997/01/09 15:14:43 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 1.8 1998/01/26 04:16:32 dgregor Exp $";
#endif
-static int etherf_open(), etherf_close(), etherf_readip();
+static int etherf_open __P((char *));
+static int etherf_close __P((void));
+static int etherf_readip __P((char *, int, char **, int *));
struct ipread etherf = { etherf_open, etherf_close, etherf_readip };
@@ -87,7 +93,7 @@ char *buf, **ifn;
int cnt, *dir;
{
struct tcpiphdr pkt;
- struct ip *ip = (struct ip *)&pkt;
+ ip_t *ip = (ip_t *)&pkt;
struct protoent *p = NULL;
char src[16], dst[16], sprt[16], dprt[16];
char lbuf[128], len[8], prot[8], time[8], *s;
@@ -140,7 +146,7 @@ int cnt, *dir;
(void) inet_aton(src, &ip->ip_src);
(void) inet_aton(dst, &ip->ip_dst);
ip->ip_len = atoi(len);
- ip->ip_hl = sizeof(struct ip);
+ ip->ip_hl = sizeof(ip_t);
slen = ip->ip_hl + extra;
i = MIN(cnt, slen);
diff --git a/usr.sbin/ipftest/ipft_hx.c b/usr.sbin/ipftest/ipft_hx.c
index c828e429a01..94b5eb5c3ca 100644
--- a/usr.sbin/ipftest/ipft_hx.c
+++ b/usr.sbin/ipftest/ipft_hx.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_hx.c,v 1.5 1997/06/23 16:44:48 kstailey Exp $ */
+/* $OpenBSD: ipft_hx.c,v 1.6 1998/01/26 04:16:34 dgregor Exp $ */
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -10,13 +10,14 @@
#include <ctype.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -24,30 +25,33 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
-static char rcsid[] = "$DRId: ipft_hx.c,v 2.0.1.2 1997/02/04 13:57:56 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 1.6 1998/01/26 04:16:34 dgregor Exp $";
#endif
extern int opts;
-extern u_short portnum();
-extern u_long buildopts();
-static int hex_open(), hex_close(), hex_readip();
-static char *readhex();
+static int hex_open __P((char *));
+static int hex_close __P((void));
+static int hex_readip __P((char *, int, char **, int *));
+static char *readhex __P((char *, char *));
struct ipread iphex = { hex_open, hex_close, hex_readip };
static FILE *tfp = NULL;
@@ -86,11 +90,11 @@ static int hex_readip(buf, cnt, ifn, dir)
char *buf, **ifn;
int cnt, *dir;
{
- register char *s;
- struct ip *ip;
+ register char *s, *t, *u;
char line[513];
+ ip_t *ip;
- ip = (struct ip *)buf;
+ ip = (ip_t *)buf;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n'))) {
if (s == line)
@@ -105,7 +109,35 @@ int cnt, *dir;
printf("input: %s\n", line);
fflush(stdout);
}
- ip = (struct ip *)readhex(line, (char *)ip);
+
+ /*
+ * interpret start of line as possibly "[ifname]" or
+ * "[in/out,ifname]".
+ */
+ if (ifn)
+ *ifn = NULL;
+ if (dir)
+ *dir = 0;
+ if ((*buf == '[') && (s = index(line, ']'))) {
+ t = buf + 1;
+ if (t - s > 0) {
+ if ((u = index(t, ',')) && (u < s)) {
+ u++;
+ if (ifn)
+ *ifn = u;
+ if (dir) {
+ if (*t == 'i')
+ *dir = 0;
+ else if (*t == 'o')
+ *dir = 1;
+ }
+ } else if (ifn)
+ *ifn = t;
+ *s++ = '\0';
+ }
+ } else
+ s = line;
+ ip = (ip_t *)readhex(s, (char *)ip);
}
return -1;
}
diff --git a/usr.sbin/ipftest/ipft_pc.c b/usr.sbin/ipftest/ipft_pc.c
index c0a4f50b5a2..a9319e7b932 100644
--- a/usr.sbin/ipftest/ipft_pc.c
+++ b/usr.sbin/ipftest/ipft_pc.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_pc.c,v 1.7 1997/06/23 16:44:49 kstailey Exp $ */
+/* $OpenBSD: ipft_pc.c,v 1.8 1998/01/26 04:16:35 dgregor Exp $ */
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -21,17 +21,20 @@
#include <sys/param.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "pcap.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$DRId: ipft_pc.c,v 2.0.1.1 1997/01/09 15:14:44 darrenr Exp $";
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 1.8 1998/01/26 04:16:35 dgregor Exp $";
#endif
struct llc {
@@ -60,7 +63,11 @@ static struct llc llcs[DLT_MAX+1] = {
{ 0, 0, 0 } /* DLT_FDDI */
};
-static int pcap_open(), pcap_close(), pcap_readip();
+static int pcap_open __P((char *));
+static int pcap_close __P((void));
+static int pcap_readip __P((char *, int, char **, int *));
+static void swap_hdr __P((pcaphdr_t *));
+static int pcap_read_rec __P((struct pcap_pkthdr *));
static int pfd = -1, s_type = -1, swapped = 0;
diff --git a/usr.sbin/ipftest/ipft_sn.c b/usr.sbin/ipftest/ipft_sn.c
index c7d6003d03c..48d643511f2 100644
--- a/usr.sbin/ipftest/ipft_sn.c
+++ b/usr.sbin/ipftest/ipft_sn.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_sn.c,v 1.6 1997/06/23 16:44:49 kstailey Exp $ */
+/* $OpenBSD: ipft_sn.c,v 1.7 1998/01/26 04:16:36 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -22,19 +22,23 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "snoop.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$DRId: ipft_sn.c,v 2.0.1.1 1997/01/09 15:14:44 darrenr Exp $";
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 1.7 1998/01/26 04:16:36 dgregor Exp $";
#endif
struct llc {
@@ -60,9 +64,12 @@ static struct llc llcs[SDL_MAX+1] = {
{ 0, 0, 0 }, /* SDL_OTHER */
};
-static int snoop_open(), snoop_close(), snoop_readip();
+static int snoop_open __P((char *));
+static int snoop_close __P((void));
+static int snoop_readip __P((char *, int, char **, int *));
static int sfd = -1, s_type = -1;
+static int snoop_read_rec __P((struct snooppkt *));
struct ipread snoop = { snoop_open, snoop_close, snoop_readip };
diff --git a/usr.sbin/ipftest/ipft_td.c b/usr.sbin/ipftest/ipft_td.c
index d6ea941ae51..67385f78a41 100644
--- a/usr.sbin/ipftest/ipft_td.c
+++ b/usr.sbin/ipftest/ipft_td.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_td.c,v 1.7 1997/06/23 16:44:50 kstailey Exp $ */
+/* $OpenBSD: ipft_td.c,v 1.8 1998/01/26 04:16:37 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -36,6 +36,7 @@ tcpdump -nqte
#endif
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -44,23 +45,29 @@ tcpdump -nqte
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
-static char rcsid[] = "$DRId: ipft_td.c,v 2.0.1.1 1997/01/09 15:14:44 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.8 1998/01/26 04:16:37 dgregor Exp $";
#endif
-static int tcpd_open(), tcpd_close(), tcpd_readip();
+static int tcpd_open __P((char *));
+static int tcpd_close __P((void));
+static int tcpd_readip __P((char *, int, char **, int *));
+static int count_dots __P((char *));
struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip };
@@ -109,7 +116,7 @@ char *buf, **ifn;
int cnt, *dir;
{
struct tcpiphdr pkt;
- struct ip *ip = (struct ip *)&pkt;
+ ip_t *ip = (ip_t *)&pkt;
struct protoent *p;
char src[32], dst[32], misc[256], time[32], link1[32], link2[32];
char lbuf[160], *s;
@@ -152,7 +159,7 @@ int cnt, *dir;
(void) inet_aton(src, &ip->ip_src);
(void) inet_aton(src, &ip->ip_dst);
}
- ip->ip_len = ip->ip_hl = sizeof(struct ip);
+ ip->ip_len = ip->ip_hl = sizeof(ip_t);
s = strtok(misc, " :");
if ((p = getprotobyname(s))) {
diff --git a/usr.sbin/ipftest/ipft_tx.c b/usr.sbin/ipftest/ipft_tx.c
index 8cc50b1acba..74cb4ee3cf6 100644
--- a/usr.sbin/ipftest/ipft_tx.c
+++ b/usr.sbin/ipftest/ipft_tx.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: ipft_tx.c,v 1.9 1997/06/23 01:37:35 deraadt Exp $ */
+/* $OpenBSD: ipft_tx.c,v 1.10 1998/01/26 04:16:38 dgregor Exp $ */
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -10,13 +10,14 @@
#include <ctype.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -24,32 +25,35 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
-static char rcsid[] = "$DRId: ipft_tx.c,v 2.0.1.3 1997/02/20 09:47:47 darrenr Exp $"
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.10 1998/01/26 04:16:38 dgregor Exp $";
#endif
extern int opts;
-extern u_long buildopts();
static char *tx_proto = "";
-static int text_open(), text_close(), text_readip(), parseline();
+static int text_open __P((char *)), text_close __P((void));
+static int text_readip __P((char *, int, char **, int *));
+static int parseline __P((char *, ip_t *, char **, int *));
static char tcp_flagset[] = "FSRPAU";
static u_char tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
@@ -59,15 +63,15 @@ struct ipread iptext = { text_open, text_close, text_readip };
static FILE *tfp = NULL;
static int tfd = -1;
-static in_addr_t tx_hostnum();
-static in_port_t tx_portnum();
+static u_long tx_hostnum __P((char *, int *));
+static u_short tx_portnum __P((char *));
/*
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
-static in_addr_t tx_hostnum(host, resolved)
+static u_long tx_hostnum(host, resolved)
char *host;
int *resolved;
{
@@ -88,7 +92,7 @@ int *resolved;
}
return np->n_net;
}
- return *(in_addr_t *)hp->h_addr;
+ return *(u_32_t *)hp->h_addr;
}
@@ -96,7 +100,7 @@ int *resolved;
* find the port number given by the name, either from getservbyname() or
* straight atoi()
*/
-static in_port_t tx_portnum(name)
+static u_short tx_portnum(name)
char *name;
{
struct servent *sp, *sp2;
@@ -134,8 +138,8 @@ char *name;
char *tx_icmptypes[] = {
"echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
- "redir", (char *)NULL, (char *)NULL, "echo", (char *)NULL,
- (char *)NULL, "timex", "paramprob", "timest", "timestrep",
+ "redir", (char *)NULL, (char *)NULL, "echo", "routerad",
+ "routersol", "timex", "paramprob", "timest", "timestrep",
"inforeq", "inforep", "maskreq", "maskrep", "END"
};
@@ -173,10 +177,10 @@ char *buf, **ifn;
int cnt, *dir;
{
register char *s;
- struct ip *ip;
+ ip_t *ip;
char line[513];
- ip = (struct ip *)buf;
+ ip = (ip_t *)buf;
*ifn = NULL;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n')))
@@ -191,11 +195,11 @@ int cnt, *dir;
printf("input: %s\n", line);
*ifn = NULL;
*dir = 0;
- if (!parseline(line, buf, ifn, dir))
+ if (!parseline(line, (ip_t *)buf, ifn, dir))
#if 0
return sizeof(struct tcpiphdr);
#else
- return sizeof(struct ip);
+ return sizeof(ip_t);
#endif
}
return -1;
@@ -203,7 +207,7 @@ int cnt, *dir;
static int parseline(line, ip, ifn, out)
char *line;
-struct ip *ip;
+ip_t *ip;
char **ifn;
int *out;
{
@@ -243,7 +247,7 @@ int *out;
}
c = **cpp;
- ip->ip_len = sizeof(struct ip);
+ ip->ip_len = sizeof(ip_t);
if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") ||
!strcasecmp(*cpp, "icmp")) {
if (c == 't') {
@@ -325,7 +329,7 @@ int *out;
u_long olen;
cpp++;
- olen = buildopts(*cpp, ipopts);
+ olen = buildopts(*cpp, ipopts, (ip->ip_hl - 5) << 2);
if (olen) {
bcopy(ipopts, (char *)(ip + 1), olen);
ip->ip_hl += olen >> 2;
diff --git a/usr.sbin/ipftest/ipftest.1 b/usr.sbin/ipftest/ipftest.1
index f0e808957df..6e22ab15299 100644
--- a/usr.sbin/ipftest/ipftest.1
+++ b/usr.sbin/ipftest/ipftest.1
@@ -1,3 +1,4 @@
+.\" $OpenBSD: ipftest.1,v 1.5 1998/01/26 04:16:39 dgregor Exp $
.TH ipftest 8
.SH NAME
ipftest \- test packet filter rules with arbitrary input.
@@ -121,7 +122,7 @@ Specify the filename from which to take input. Default is stdin.
Specify the filename from which to read filter rules.
.SH FILES
.SH SEE ALSO
-ipf(1), ipf(5), snoop(1m), tcpdump(8), etherfind(8c)
+ipf(8), ipf(5), snoop(1m), tcpdump(8), etherfind(8c)
.SH BUGS
Not all of the input formats are sufficiently capable of introducing a
wide enough variety of packets for them to be all useful in testing.
diff --git a/usr.sbin/ipftest/ipt.c b/usr.sbin/ipftest/ipt.c
index eabf0795fb4..76d687c7bff 100644
--- a/usr.sbin/ipftest/ipt.c
+++ b/usr.sbin/ipftest/ipt.c
@@ -1,20 +1,28 @@
+/* $OpenBSD: ipt.c,v 1.11 1998/01/26 04:16:40 dgregor Exp $ */
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
+#ifdef __FreeBSD__
+# include <osreldate.h>
+#endif
#include <stdio.h>
#include <assert.h>
#include <string.h>
-#if !defined(__SVR4) && !defined(__svr4__)
+#include <sys/types.h>
+#if !defined(__SVR4) && !defined(__svr4__) && !defined(__sgi)
#include <strings.h>
#else
+#if !defined(__sgi)
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
+#include <sys/file.h>
+#endif
#include <sys/param.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -22,51 +30,54 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
-#include "ip_fil_compat.h"
-#include "ip_fil.h"
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
#include <netdb.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <resolv.h>
+#include <ctype.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
+#include "ip_fil.h"
#include "ipf.h"
#include "ipt.h"
-#include <ctype.h>
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: ipt.c,v 1.10 1997/09/22 05:17:47 millert Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipt.c,v 1.11 1998/01/26 04:16:40 dgregor Exp $";
#endif
-extern int fr_check();
extern char *optarg;
-extern struct frentry *ipfilter[2][2];
-extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
-extern void debug(), verbose();
-
-struct frentry *ft_in = NULL, *ft_out = NULL;
+extern struct frentry *ipfilter[2][2];
+extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
+extern struct ifnet *get_unit __P((char *));
+extern void init_ifp __P((void));
int opts = 0;
+int main __P((int, char *[]));
int main(argc,argv)
int argc;
char *argv[];
{
struct ipread *r = &iptext;
- struct frentry *f;
- struct ip *ip;
u_long buf[64];
- int c;
+ struct ifnet *ifp;
char *rules = NULL, *datain = NULL, *iface = NULL;
- int fd, i, dir = 0;
+ ip_t *ip;
+ int fd, i, dir = 0, c;
- while ((c = getopt(argc, argv, "bdEHi:I:Pr:STvX")) != -1)
+ while ((c = getopt(argc, argv, "bdEHi:I:oPr:STvX")) != -1)
switch (c)
{
case 'b' :
@@ -81,6 +92,9 @@ char *argv[];
case 'I' :
iface = optarg;
break;
+ case 'o' :
+ opts |= OPT_SAVEOUT;
+ break;
case 'r' :
rules = optarg;
break;
@@ -146,23 +160,19 @@ char *argv[];
if (!(fr = parse(line)))
continue;
- f = (struct frentry *)malloc(sizeof(*f));
- if (fr->fr_flags & FR_INQUE) {
- if (!ft_in)
- ft_in = ipfilter[0][0] = f;
- else
- ft_in->fr_next = f, ft_in = f;
- } else if (fr->fr_flags & FR_OUTQUE) {
- if (!ft_out)
- ft_out = ipfilter[1][0] = f;
- else
- ft_out->fr_next = f, ft_out = f;
- }
- bcopy((char *)fr, (char *)f, sizeof(*fr));
+ /* fake an `ioctl' call :) */
+ i = IPL_EXTERN(ioctl)(0, SIOCADDFR, (caddr_t)fr, FWRITE|FREAD);
+ if (opts & OPT_DEBUG)
+ fprintf(stderr,
+ "iplioctl(SIOCADDFR,%p,1) = %d\n",
+ fr, i);
}
(void)fclose(fp);
}
+ if (opts & OPT_SAVEOUT)
+ init_ifp();
+
if (datain)
fd = (*r->r_open)(datain);
else
@@ -171,12 +181,17 @@ char *argv[];
if (fd < 0)
exit(-1);
- ip = (struct ip *)buf;
- while ((i = (*r->r_readip)(buf, sizeof(buf), &iface, &dir)) > 0) {
+ ip = (ip_t *)buf;
+ while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
+ &iface, &dir)) > 0) {
+ ifp = iface ? get_unit(iface) : NULL;
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
- switch (fr_check(ip, ip->ip_hl << 2, (struct ifnet *)iface, dir)) /* XXX */
+ switch (fr_check(ip, ip->ip_hl << 2, ifp, dir, (mb_t **)&buf))
{
+ case -2 :
+ (void)printf("auth");
+ break;
case -1 :
(void)printf("block");
break;
@@ -189,9 +204,17 @@ char *argv[];
}
if (!(opts & OPT_BRIEF)) {
putchar(' ');
- printpacket(buf);
+ printpacket((ip_t *)buf);
printf("--------------");
}
+#ifndef linux
+ if (dir && ifp && ip->ip_v)
+# ifdef __sgi
+ (*ifp->if_output)(ifp, (void *)buf, NULL);
+# else
+ (*ifp->if_output)(ifp, (void *)buf, NULL, 0);
+# endif
+#endif
putchar('\n');
dir = 0;
}
diff --git a/usr.sbin/ipftest/ipt.h b/usr.sbin/ipftest/ipt.h
index 3756c7020c0..65ab3a2be49 100644
--- a/usr.sbin/ipftest/ipt.h
+++ b/usr.sbin/ipftest/ipt.h
@@ -1,17 +1,31 @@
-/* $OpenBSD: ipt.h,v 1.4 1997/06/23 17:08:04 kstailey Exp $ */
+/* $OpenBSD: ipt.h,v 1.5 1998/01/26 04:16:41 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
- * $DRId: ipt.h,v 2.0.1.1 1997/01/09 15:14:44 darrenr Exp $
+ * $Id: ipt.h,v 1.5 1998/01/26 04:16:41 dgregor Exp $
*/
+#ifndef __IPT_H__
+#define __IPT_H__
+
#include <fcntl.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
struct ipread {
- int (*r_open)();
- int (*r_close)();
- int (*r_readip)();
+ int (*r_open) __P((char *));
+ int (*r_close) __P((void));
+ int (*r_readip) __P((char *, int, char **, int *));
};
+
+extern void debug __P((char *, ...));
+extern void verbose __P((char *, ...));
+
+#endif /* __IPT_H__ */
diff --git a/usr.sbin/ipftest/misc.c b/usr.sbin/ipftest/misc.c
index 44f2bae9557..20f100c32cf 100644
--- a/usr.sbin/ipftest/misc.c
+++ b/usr.sbin/ipftest/misc.c
@@ -1,5 +1,6 @@
+/* $OpenBSD: misc.c,v 1.6 1998/01/26 04:16:42 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -8,13 +9,14 @@
#include <stdio.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -23,33 +25,36 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
+#ifdef __OpenBSD__
+#include <machine/stdarg.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
-#include "ip_fil_compat.h"
-#include "ip_fil.h"
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
+#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
+#include "ip_fil.h"
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
-static char rcsid[] = "$Id: misc.c,v 1.5 1997/02/11 22:24:01 kstailey Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: misc.c,v 1.6 1998/01/26 04:16:42 dgregor Exp $";
#endif
-void debug(), verbose();
-
extern int opts;
void printpacket(ip)
-struct ip *ip;
+ip_t *ip;
{
struct tcphdr *tcp;
@@ -69,18 +74,35 @@ struct ip *ip;
putchar('\n');
}
-
-void verbose(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9)
-char *fmt, *p1, *p2, *p3, *p4, *p5, *p6, *p7,*p8,*p9;
+#ifdef __STDC__
+void verbose(char *fmt, ...)
+#else
+void verbose(fmt, va_alist)
+char *fmt;
+va_dcl
+#endif
{
+ va_list pvar;
+
+ va_start(pvar, fmt);
if (opts & OPT_VERBOSE)
- printf(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ vprintf(fmt, pvar);
+ va_end(pvar);
}
-void debug(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9)
-char *fmt, *p1, *p2, *p3, *p4, *p5, *p6, *p7,*p8,*p9;
+#ifdef __STDC__
+void debug(char *fmt, ...)
+#else
+void debug(fmt, va_alist)
+char *fmt;
+va_dcl
+#endif
{
+ va_list pvar;
+
+ va_start(pvar, fmt);
if (opts & OPT_DEBUG)
- printf(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ vprintf(fmt, pvar);
+ va_end(pvar);
}
diff --git a/usr.sbin/ipftest/pcap.h b/usr.sbin/ipftest/pcap.h
index daf5efee6a4..a866093dfec 100644
--- a/usr.sbin/ipftest/pcap.h
+++ b/usr.sbin/ipftest/pcap.h
@@ -1,10 +1,11 @@
+/* $OpenBSD: pcap.h,v 1.5 1998/01/26 04:16:43 dgregor Exp $ */
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
- * $Id: pcap.h,v 1.4 1997/02/11 22:24:03 kstailey Exp $
+ * $Id: pcap.h,v 1.5 1998/01/26 04:16:43 dgregor Exp $
*/
/*
* This header file is constructed to match the version described by
diff --git a/usr.sbin/ipftest/snoop.h b/usr.sbin/ipftest/snoop.h
index ce92eb9c5df..60cc10da493 100644
--- a/usr.sbin/ipftest/snoop.h
+++ b/usr.sbin/ipftest/snoop.h
@@ -1,14 +1,18 @@
+/* $OpenBSD: snoop.h,v 1.4 1998/01/26 04:16:44 dgregor Exp $ */
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
+#ifndef __SNOOP_H__
+#define __SNOOP_H__
+
/*
* written to comply with the RFC (1761) from Sun.
- * $Id: snoop.h,v 1.3 1997/02/11 22:24:04 kstailey Exp $
+ * $Id: snoop.h,v 1.4 1998/01/26 04:16:44 dgregor Exp $
*/
struct snoophdr {
char s_id[8];
@@ -40,3 +44,5 @@ struct snooppkt {
int sp_sec;
int sp_usec;
};
+
+#endif /* __SNOOP_H__ */
diff --git a/usr.sbin/ipmon/ipmon.8 b/usr.sbin/ipmon/ipmon.8
index ff2f021e30b..7db99255734 100644
--- a/usr.sbin/ipmon/ipmon.8
+++ b/usr.sbin/ipmon/ipmon.8
@@ -1,12 +1,23 @@
+.\" $OpenBSD: ipmon.8,v 1.4 1998/01/26 04:16:46 dgregor Exp $
.TH ipmon 8
.SH NAME
ipmon \- monitors /dev/ipl for logged packets
.SH SYNOPSIS
.B ipmon
[
-.B \-sfN
+.B \-aFhnstvxX
] [
-<filename>
+.B "\-o [NSI]"
+] [
+.B "\-O [NSI]"
+] [
+.B "\-N <device>"
+] [
+.B "\-S <device>"
+] [
+.B "\-f <device>"
+] [
+.B <filename>
]
.SH DESCRIPTION
.LP
@@ -20,9 +31,45 @@ via syslog have the day, month and year removed from the message, but the
time (including microseconds), as recorded in the log, is still included.
.SH OPTIONS
.TP
+.B \-a
+Open all of the device logfiles for reading log entries from. All entries
+are displayed to the same output 'device' (stderr or syslog).
+.TP
+.B "\-f <device>"
+specify an alternative device/file from which to read the log information
+for normal IP Filter log records.
+.TP
+.B \-F
+Flush the current packet log buffer. The number of bytes flushed is displayed,
+even should the result be zero.
+.TP
+.B "\-N <device>"
+Set the logfile to be opened for reading NAT log records from to <device>.
+.TP
+.B \-n
+IP addresses and port numbers will be mapped, where possible, back into
+hostnames and service names.
+.TP
+.B "\-N <device>"
+Set the logfile to be opened for reading NAT log records from to <device>.
+.TP
+.B \-o
+Specify which log files to actually read data from. N - NAT logfile,
+S - State logfile, I - normal IP Filter logfile. The \fB-a\fP option is
+equivalent to using \fB-o NSI\fP.
+.TP
+.B \-O
+Specify which log files you do not wish to read from. This is most sensibly
+used with the \fB-a\fP. Letters available as paramters to this are the same
+as for \fB-o\fP.
+.TP
.B \-s
Packet information read in will be sent through syslogd rather than
saved to a file. The following levels are used:
+.TP
+.B "\-S <device>"
+Set the logfile to be opened for reading state log records from to <device>.
+.TP
.IP
.B LOG_INFO
\- packets logged using the "log" keyword as the action rather
@@ -38,13 +85,17 @@ than pass or block.
\- packets which have been logged and which can be considered
"short".
.TP
-.B \-f
-Flush the current packet log buffer. The number of bytes flushed is displayed,
-even should the result be zero.
+.B \-S
+Treat the logfile as being composed of state log records.
.TP
-.B \-N
-IP addresses and port numbers will be mapped, where possible, back into
-hostnames and service names.
+.B \-t
+read the input file/device in a manner akin to tail(1).
+.TP
+.B \-x
+show the packet data in hex.
+.TP
+.B \-X
+show the log header record data in hex.
.SH DIAGNOSTICS
\fBipmon\fP expects data that it reads to be consistent with how it should be
saved and will abort if it fails an assertion which detects an anomaly in the
@@ -52,5 +103,5 @@ recorded data.
.SH FILES
/dev/ipl
.SH SEE ALSO
-ipf(1), ipfstat(1)
+ipf(8), ipfstat(8)
.SH BUGS
diff --git a/usr.sbin/ipmon/ipmon.c b/usr.sbin/ipmon/ipmon.c
index e882089b9b8..b293bfbd35c 100644
--- a/usr.sbin/ipmon/ipmon.c
+++ b/usr.sbin/ipmon/ipmon.c
@@ -1,51 +1,73 @@
+/* $OpenBSD: ipmon.c,v 1.11 1998/01/26 04:16:47 dgregor Exp $ */
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1997 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.11 1998/01/26 04:16:47 dgregor Exp $";
+#endif
#include <stdio.h>
-#include <assert.h>
#include <unistd.h>
-#include <fcntl.h>
#include <string.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/uio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
+#include <strings.h>
#include <sys/dir.h>
-#include <sys/mbuf.h>
#else
+#include <sys/filio.h>
#include <sys/byteorder.h>
#endif
-#include <sys/protosw.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stddef.h>
#include <sys/socket.h>
-#include <sys/user.h>
-
-#include <net/if.h>
+#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#include <net/if.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
-#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/inet.h>
-#include <ctype.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$Id: ipmon.c,v 1.10 1997/07/22 17:00:05 kstailey Exp $";
+#include <sys/uio.h>
+#ifndef linux
+# include <sys/protosw.h>
+# include <sys/user.h>
+# include <netinet/ip_var.h>
#endif
+#include <netinet/tcp.h>
+#include <netinet/ip_icmp.h>
+
+#include <ctype.h>
+#include <syslog.h>
+
#include "ip_fil_compat.h"
+#include <netinet/tcpip.h>
#include "ip_fil.h"
+#include "ip_proxy.h"
+#include "ip_nat.h"
+#include "ip_state.h"
+
+
+#if defined(sun) && !defined(SOLARIS2)
+#define STRERROR(x) sys_errlist[x]
+extern char *sys_errlist[];
+#else
+#define STRERROR(x) strerror(x)
+#endif
struct flags {
@@ -65,158 +87,50 @@ struct flags tcpfl[] = {
static char line[2048];
-static void printpacket(), dumphex();
static int opts = 0;
-
-#define OPT_SYSLOG 0x01
-#define OPT_RESOLVE 0x02
-#define OPT_HEXBODY 0x04
-#define OPT_VERBOSE 0x08
-#define OPT_HEXHDR 0x10
+static void usage __P((char *));
+static void flushlogs __P((char *, FILE *));
+static void print_log __P((int, FILE *, char *, int));
+static void print_ipflog __P((FILE *, char *, int));
+static void print_natlog __P((FILE *, char *, int));
+static void print_statelog __P((FILE *, char *, int));
+static void dumphex __P((FILE *, u_char *, int));
+static int read_log __P((int, int *, char *, int, FILE *));
+char *hostname __P((int, struct in_addr));
+char *portname __P((int, char *, u_short));
+int main __P((int, char *[]));
+
+
+#define OPT_SYSLOG 0x001
+#define OPT_RESOLVE 0x002
+#define OPT_HEXBODY 0x004
+#define OPT_VERBOSE 0x008
+#define OPT_HEXHDR 0x010
+#define OPT_TAIL 0x020
+#define OPT_NAT 0x080
+#define OPT_STATE 0x100
+#define OPT_FILTER 0x200
+#define OPT_PORTNUM 0x400
+#define OPT_ALL (OPT_NAT|OPT_STATE|OPT_FILTER)
#ifndef LOGFAC
#define LOGFAC LOG_LOCAL0
#endif
-void printiplci(icp)
-struct ipl_ci *icp;
-{
- printf("sec %ld usec %ld hlen %d plen %d\n", icp->sec, icp->usec,
- icp->hlen, icp->plen);
-}
-
-
-void resynclog(fd, iplcp, log)
-int fd;
-struct ipl_ci *iplcp;
-FILE *log;
-{
- time_t now;
- char *s = NULL;
- int len, nr = 0;
-
- do {
- if (s) {
- s = (char *)&iplcp->sec;
- if (opts & OPT_SYSLOG) {
- syslog(LOG_INFO, "Sync bytes:");
- syslog(LOG_INFO, " %02x %02x %02x %02x",
- *s, *(s+1), *(s+2), *(s+3));
- syslog(LOG_INFO, " %02x %02x %02x %02x\n",
- *(s+4), *(s+5), *(s+6), *(s+7));
- } else {
- fprintf(log, "Sync bytes:");
- fprintf(log, " %02x %02x %02x %02x",
- *s, *(s+1), *(s+2), *(s+3));
- fprintf(log, " %02x %02x %02x %02x\n",
- *(s+4), *(s+5), *(s+6), *(s+7));
- }
- }
- do {
- s = (char *)&iplcp->sec;
- len = sizeof(iplcp->sec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- now = time(NULL);
- break;
- }
- }
- } while ((now < iplcp->sec) ||
- ((iplcp->sec - now) > (86400*5)));
-
- len = sizeof(iplcp->usec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- break;
- }
- }
- } while (iplcp->usec > 1000000);
- len = sizeof(*iplcp) - sizeof(iplcp->sec) - sizeof(iplcp->usec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- break;
- }
- }
-}
-
-
-int readlogentry(fd, lenp, buf, bufsize, log)
+static int read_log(fd, lenp, buf, bufsize, log)
int fd, bufsize, *lenp;
char *buf;
FILE *log;
{
- struct ipl_ci *icp = (struct ipl_ci *)buf;
- time_t now;
- char *s;
- int len, n = bufsize, tr = sizeof(struct ipl_ci), nr;
-
- if (bufsize < tr)
- return 1;
- for (s = buf; (n > 0) && (tr > 0); s += nr, n -= nr) {
- nr = read(fd, s, tr);
- if (nr > 0)
- tr -= nr;
- else
- return -1;
- }
-
- now = time(NULL);
- if ((icp->hlen > 92) || (now < icp->sec) ||
- ((now - icp->sec) > (86400*5))) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_INFO, "Out of sync! (1,%x)\n", now);
- else
- fprintf(log, "Out of sync! (1,%x)\n", now);
- dumphex(log, buf, sizeof(struct ipl_ci));
- resynclog(fd, icp, log);
- }
-
-
- len = (int)((u_int)icp->plen);
- if (len > 128 || len < 0) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_INFO, "Out of sync! (2,%d)\n", len);
- else
- fprintf(log, "Out of sync! (2,%d)\n", len);
- dumphex(log, buf, sizeof(struct ipl_ci));
- resynclog(fd, icp, log);
- }
-
-
- tr = icp->hlen + icp->plen;
- if (n < tr)
- return 1;
-
- for (; (n > 0) && (tr > 0); s += nr, n-= nr) {
- nr = read(fd, s, tr);
- if (nr > 0)
- tr -= nr;
- else
- return -1;
- }
- *lenp = s - buf;
+ int nr;
+
+ nr = read(fd, buf, bufsize);
+ if (!nr)
+ return 2;
+ if ((nr < 0) && (errno != EINTR))
+ return -1;
+ *lenp = nr;
return 0;
}
@@ -245,7 +159,7 @@ u_short port;
struct servent *serv;
(void) sprintf(pname, "%hu", htons(port));
- if (!res)
+ if (!res || (opts & OPT_PORTNUM))
return pname;
serv = getservbyport((int)port, proto);
if (!serv)
@@ -267,15 +181,18 @@ int len;
if (j && !(j & 0xf)) {
*t++ = '\n';
*t = '\0';
- fputs(line, log);
+ if (!(opts & OPT_SYSLOG))
+ fputs(line, stdout);
+ else
+ syslog(LOG_INFO, "%s", line);
t = (u_char *)line;
*t = '\0';
}
- sprintf(t, "%02x", *s & 0xff);
+ sprintf((char *)t, "%02x", *s & 0xff);
t += 2;
if (!((j + 1) & 0xf)) {
s -= 15;
- sprintf(t, " ");
+ sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
*t++ = (isprint(*s) ? *s : '.');
@@ -292,7 +209,7 @@ int len;
*t++ = ' ';
*t++ = ' ';
}
- sprintf(t, " ");
+ sprintf((char *)t, " ");
t += 7;
s -= j & 0xf;
for (k = j & 0xf; k; k--, s++)
@@ -300,12 +217,183 @@ int len;
*t++ = '\n';
*t = '\0';
}
- fputs(line, log);
- fflush(log);
+ if (!(opts & OPT_SYSLOG)) {
+ fputs(line, stdout);
+ fflush(stdout);
+ } else
+ syslog(LOG_INFO, "%s", line);
+}
+
+static void print_natlog(log, buf, blen)
+FILE *log;
+char *buf;
+int blen;
+{
+ struct natlog *nl;
+ iplog_t *ipl = (iplog_t *)buf;
+ char *t = line;
+ struct tm *tm;
+ int res;
+
+ nl = (struct natlog *)((char *)ipl + sizeof(*ipl));
+ res = (opts & OPT_RESOLVE) ? 1 : 0;
+ tm = localtime((time_t *)&ipl->ipl_sec);
+ if (!(opts & OPT_SYSLOG)) {
+ (void) sprintf(t, "%2d/%02d/%4d ",
+ tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
+ t += strlen(t);
+ }
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld @%hd ",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, ipl->ipl_usec,
+ nl->nl_rule+1);
+ t += strlen(t);
+
+ if (nl->nl_type == NL_NEWMAP)
+ strcpy(t, "NAT:MAP ");
+ else if (nl->nl_type == NL_NEWRDR)
+ strcpy(t, "NAT:RDR ");
+ else if (nl->nl_type == ISL_EXPIRE)
+ strcpy(t, "NAT:EXPIRE ");
+ else
+ sprintf(t, "Type: %d ", nl->nl_type);
+ t += strlen(t);
+
+ (void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nl_inip),
+ portname(res, NULL, nl->nl_inport));
+ t += strlen(t);
+ (void) sprintf(t, "%s,%s ", hostname(res, nl->nl_outip),
+ portname(res, NULL, nl->nl_outport));
+ t += strlen(t);
+ (void) sprintf(t, "[%s,%s]", hostname(res, nl->nl_origip),
+ portname(res, NULL, nl->nl_origport));
+ t += strlen(t);
+ if (nl->nl_type == NL_EXPIRE) {
+#ifdef USE_QUAD_T
+ (void) sprintf(t, " Pkts %qd Bytes %qd",
+#else
+ (void) sprintf(t, " Pkts %ld Bytes %ld",
+#endif
+ nl->nl_pkts, nl->nl_bytes);
+ t += strlen(t);
+ }
+
+ *t++ = '\n';
+ *t++ = '\0';
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "%s", line);
+ else
+ (void) fprintf(log, "%s", line);
+}
+
+
+static void print_statelog(log, buf, blen)
+FILE *log;
+char *buf;
+int blen;
+{
+ struct ipslog *sl;
+ iplog_t *ipl = (iplog_t *)buf;
+ struct protoent *pr;
+ char *t = line, *proto, pname[6];
+ struct tm *tm;
+ int res;
+
+ sl = (struct ipslog *)((char *)ipl + sizeof(*ipl));
+ res = (opts & OPT_RESOLVE) ? 1 : 0;
+ tm = localtime((time_t *)&ipl->ipl_sec);
+ if (!(opts & OPT_SYSLOG)) {
+ (void) sprintf(t, "%2d/%02d/%4d ",
+ tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
+ t += strlen(t);
+ }
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld ",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, ipl->ipl_usec);
+ t += strlen(t);
+
+ if (sl->isl_type == ISL_NEW)
+ strcpy(t, "STATE:NEW ");
+ else if (sl->isl_type == ISL_EXPIRE)
+ strcpy(t, "STATE:EXPIRE ");
+ else
+ sprintf(t, "Type: %d ", sl->isl_type);
+ t += strlen(t);
+
+ pr = getprotobynumber((int)sl->isl_p);
+ if (!pr) {
+ proto = pname;
+ sprintf(proto, "%d", (u_int)sl->isl_p);
+ } else
+ proto = pr->p_name;
+
+ if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) {
+ (void) sprintf(t, "%s,%s -> ",
+ hostname(res, sl->isl_src),
+ portname(res, proto, sl->isl_sport));
+ t += strlen(t);
+ (void) sprintf(t, "%s,%s PR %s",
+ hostname(res, sl->isl_dst),
+ portname(res, proto, sl->isl_dport), proto);
+ } else if (sl->isl_p == IPPROTO_ICMP) {
+ (void) sprintf(t, "%s -> ", hostname(res, sl->isl_src));
+ t += strlen(t);
+ (void) sprintf(t, "%s PR icmp %d",
+ hostname(res, sl->isl_dst), sl->isl_itype);
+ }
+ t += strlen(t);
+ if (sl->isl_type != ISL_NEW) {
+#ifdef USE_QUAD_T
+ (void) sprintf(t, " Pkts %qd Bytes %qd",
+#else
+ (void) sprintf(t, " Pkts %ld Bytes %ld",
+#endif
+ sl->isl_pkts, sl->isl_bytes);
+ t += strlen(t);
+ }
+
+ *t++ = '\n';
+ *t++ = '\0';
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "%s", line);
+ else
+ (void) fprintf(log, "%s", line);
}
-static void printpacket(log, buf, blen)
+static void print_log(logtype, log, buf, blen)
+FILE *log;
+char *buf;
+int logtype, blen;
+{
+ iplog_t *ipl;
+ int psize;
+
+ while (blen > 0) {
+ ipl = (iplog_t *)buf;
+ if (ipl->ipl_magic != IPL_MAGIC) {
+ /* invalid data or out of sync */
+ return;
+ }
+ psize = ipl->ipl_dsize;
+ switch (logtype)
+ {
+ case IPL_LOGIPF :
+ print_ipflog(log, buf, psize);
+ break;
+ case IPL_LOGNAT :
+ print_natlog(log, buf, psize);
+ break;
+ case IPL_LOGSTATE :
+ print_statelog(log, buf, psize);
+ break;
+ }
+
+ blen -= psize;
+ buf += psize;
+ }
+}
+
+
+static void print_ipflog(log, buf, blen)
FILE *log;
char *buf;
int blen;
@@ -313,46 +401,54 @@ int blen;
struct protoent *pr;
struct tcphdr *tp;
struct icmp *ic;
- struct ip *ipc;
struct tm *tm;
char c[3], pname[8], *t, *proto;
u_short hl, p;
- int i, lvl, res;
-#if !SOLARIS && !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))\
- && !(defined(OpenBSD) && (OpenBSD <= 1991011) && (OpenBSD >= 199603))
- int len;
-#endif
- struct ip *ip;
- struct ipl_ci *lp;
-
- lp = (struct ipl_ci *)buf;
- ip = (struct ip *)(buf + sizeof(*lp));
+ int i, lvl, res, len;
+ ip_t *ipc, *ip;
+ iplog_t *ipl;
+ ipflog_t *ipf;
+
+ ipl = (iplog_t *)buf;
+ ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
+ ip = (ip_t *)((char *)ipf + sizeof(*ipf));
res = (opts & OPT_RESOLVE) ? 1 : 0;
t = line;
*t = '\0';
hl = (ip->ip_hl << 2);
p = (u_short)ip->ip_p;
- tm = localtime((time_t *)&lp->sec);
+ tm = localtime((time_t *)&ipl->ipl_sec);
+#ifdef linux
+ ip->ip_len = ntohs(ip->ip_len);
+#endif
+
if (!(opts & OPT_SYSLOG)) {
(void) sprintf(t, "%2d/%02d/%4d ",
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
-#if SOLARIS || (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) \
- || (defined(OpenBSD) && (OpenBSD <= 1991011) && (OpenBSD >= 199603))
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %.*s @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- (int)sizeof(lp->ifname), lp->ifname, lp->rule);
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld ", tm->tm_hour, tm->tm_min,
+ tm->tm_sec, ipl->ipl_usec);
+ t += strlen(t);
+ if (ipl->ipl_count > 1) {
+ (void) sprintf(t, "%dx ", ipl->ipl_count);
+ t += strlen(t);
+ }
+#if (SOLARIS || \
+ (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
+ len = (int)sizeof(ipf->fl_ifname);
+ (void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
#else
for (len = 0; len < 3; len++)
- if (!lp->ifname[len])
+ if (!ipf->fl_ifname[len])
break;
- if (lp->ifname[len])
+ if (ipf->fl_ifname[len])
len++;
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %*.*s%ld @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- len, len, lp->ifname, lp->unit, lp->rule);
+ (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
#endif
+ t += strlen(t);
+ (void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
pr = getprotobynumber((int)p);
if (!pr) {
proto = pname;
@@ -360,22 +456,22 @@ int blen;
} else
proto = pr->p_name;
- if (lp->flags & (FI_SHORT << 20)) {
+ if (ipf->fl_flags & FF_SHORT) {
c[0] = 'S';
lvl = LOG_ERR;
- } else if (lp->flags & FR_PASS) {
- if (lp->flags & FR_LOGP)
+ } else if (ipf->fl_flags & FR_PASS) {
+ if (ipf->fl_flags & FR_LOGP)
c[0] = 'p';
else
c[0] = 'P';
lvl = LOG_NOTICE;
- } else if (lp->flags & FR_BLOCK) {
- if (lp->flags & FR_LOGB)
+ } else if (ipf->fl_flags & FR_BLOCK) {
+ if (ipf->fl_flags & FR_LOGB)
c[0] = 'b';
else
c[0] = 'B';
lvl = LOG_WARNING;
- } else if (lp->flags & FF_LOGNOMATCH) {
+ } else if (ipf->fl_flags & FF_LOGNOMATCH) {
c[0] = 'n';
lvl = LOG_NOTICE;
} else {
@@ -389,7 +485,7 @@ int blen;
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !(ip->ip_off & 0x1fff)) {
tp = (struct tcphdr *)((char *)ip + hl);
- if (!(lp->flags & (FI_SHORT << 16))) {
+ if (!(ipf->fl_flags & (FI_SHORT << 16))) {
(void) sprintf(t, "%s,%s -> ",
hostname(res, ip->ip_src),
portname(res, proto, tp->th_sport));
@@ -426,7 +522,7 @@ int blen;
t += strlen(t);
(void) sprintf(t, "%s PR icmp len %hu (%hu) icmp %d/%d",
hostname(res, ip->ip_dst), hl,
- ip->ip_len, ic->icmp_type, ic->icmp_code);
+ ntohs(ip->ip_len), ic->icmp_type, ic->icmp_code);
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
ic->icmp_type == ICMP_PARAMPROB ||
@@ -467,12 +563,12 @@ int blen;
}
t += strlen(t);
- if (lp->flags & FR_KEEPSTATE) {
+ if (ipf->fl_flags & FR_KEEPSTATE) {
(void) strcpy(t, " K-S");
t += strlen(t);
}
- if (lp->flags & FR_KEEPFRAG) {
+ if (ipf->fl_flags & FR_KEEPFRAG) {
(void) strcpy(t, " K-F");
t += strlen(t);
}
@@ -484,50 +580,150 @@ int blen;
else
(void) fprintf(log, "%s", line);
if (opts & OPT_HEXHDR)
- dumphex(log, buf, sizeof(struct ipl_ci));
+ dumphex(log, (u_char *)buf, sizeof(iplog_t));
if (opts & OPT_HEXBODY)
- dumphex(log, ip, lp->plen + lp->hlen);
- if (!(opts & OPT_SYSLOG))
- fflush(log);
+ dumphex(log, (u_char *)ip, ipf->fl_plen + ipf->fl_hlen);
+}
+
+
+static void usage(prog)
+char *prog;
+{
+ fprintf(stderr, "%s: [-NFhstvxX] [-f <logfile>]\n", prog);
+ exit(1);
}
+
+static void flushlogs(file, log)
+char *file;
+FILE *log;
+{
+ int fd, flushed = 0;
+
+ if ((fd = open(file, O_RDWR)) == -1) {
+ (void) fprintf(stderr, "%s: open: %s\n", file,STRERROR(errno));
+ exit(-1);
+ }
+
+ if (ioctl(fd, SIOCIPFFB, &flushed) == 0) {
+ printf("%d bytes flushed from log buffer\n",
+ flushed);
+ fflush(stdout);
+ } else
+ perror("SIOCIPFFB");
+ (void) close(fd);
+
+ if (flushed) {
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "%d bytes flushed from log\n",
+ flushed);
+ else if (log != stdout)
+ fprintf(log, "%d bytes flushed from log\n", flushed);
+ }
+}
+
+
+static void logopts(turnon, options)
+int turnon;
+char *options;
+{
+ int flags = 0;
+ char *s;
+
+ for (s = options; *s; s++)
+ {
+ switch (*s)
+ {
+ case 'N' :
+ flags |= OPT_NAT;
+ break;
+ case 'S' :
+ flags |= OPT_STATE;
+ break;
+ case 'I' :
+ flags |= OPT_FILTER;
+ break;
+ default :
+ fprintf(stderr, "Unknown log option %c\n", *s);
+ exit(1);
+ }
+ }
+
+ if (turnon)
+ opts |= flags;
+ else
+ opts &= ~(flags);
+}
+
+
int main(argc, argv)
int argc;
char *argv[];
{
- FILE *log = NULL;
- int fd = -1, flushed = 0, doread, n;
- char buf[512], c, *iplfile = IPL_NAME;
+ struct stat sb;
+ FILE *log = stdout;
+ int fd[3], doread, n, i;
+ int tr, nr, regular[3], c;
+ int fdt[3], devices = 0;
+ char buf[512], *iplfile[3];
extern int optind;
extern char *optarg;
- while ((c = getopt(argc, argv, "Nf:FsvxX")) != -1)
+ fd[0] = fd[1] = fd[2] = -1;
+ fdt[0] = fdt[1] = fdt[2] = -1;
+ iplfile[0] = IPL_NAME;
+ iplfile[1] = IPNAT_NAME;
+ iplfile[2] = IPSTATE_NAME;
+
+ while ((c = getopt(argc, argv, "?af:FhI:nN:o:O:sS:tvxX")) != -1)
switch (c)
{
- case 'f' :
- iplfile = optarg;
+ case 'a' :
+ opts |= OPT_ALL;
+ break;
+ case 'f' : case 'I' :
+ opts |= OPT_FILTER;
+ fdt[0] = IPL_LOGIPF;
+ iplfile[0] = optarg;
break;
case 'F' :
- if ((fd == -1) &&
- (fd = open(iplfile, O_RDWR)) == -1) {
- (void) fprintf(stderr, "%s: ", IPL_NAME);
- perror("open");
- exit(-1);
- }
- if (ioctl(fd, SIOCIPFFB, &flushed) == 0) {
- printf("%d bytes flushed from log buffer\n",
- flushed);
- fflush(stdout);
- } else
- perror("SIOCIPFFB");
+ flushlogs(iplfile[0], log);
+ flushlogs(iplfile[1], log);
+ flushlogs(iplfile[2], log);
break;
- case 'N' :
+ case 'n' :
opts |= OPT_RESOLVE;
break;
+ case 'N' :
+ opts |= OPT_NAT;
+ fdt[1] = IPL_LOGNAT;
+ iplfile[1] = optarg;
+ break;
+ case 'o' : case 'O' :
+ logopts(c == 'o', optarg);
+ fdt[0] = fdt[1] = fdt[2] = -1;
+ if (opts & OPT_FILTER)
+ fdt[0] = IPL_LOGIPF;
+ if (opts & OPT_NAT)
+ fdt[1] = IPL_LOGNAT;
+ if (opts & OPT_STATE)
+ fdt[2] = IPL_LOGSTATE;
+ break;
+ case 'p' :
+ opts |= OPT_PORTNUM;
+ break;
case 's' :
openlog(argv[0], LOG_NDELAY|LOG_PID, LOGFAC);
opts |= OPT_SYSLOG;
break;
+ case 'S' :
+ opts |= OPT_STATE;
+ fdt[2] = IPL_LOGSTATE;
+ iplfile[2] = optarg;
+ break;
+ case 't' :
+ opts |= OPT_TAIL;
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
@@ -537,52 +733,106 @@ char *argv[];
case 'X' :
opts |= OPT_HEXHDR;
break;
+ default :
+ case 'h' :
+ case '?' :
+ usage(argv[0]);
}
- if ((fd == -1) && (fd = open(iplfile, O_RDONLY)) == -1) {
- (void) fprintf(stderr, "%s: ", IPL_NAME);
- perror("open");
- exit(-1);
+ /*
+ * Default action is to only open the filter log file.
+ */
+ if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1))
+ fdt[0] = IPL_LOGIPF;
+
+ for (i = 0; i < 3; i++) {
+ if (fdt[i] == -1)
+ continue;
+ if (!strcmp(iplfile[i], "-"))
+ fd[i] = 0;
+ else {
+ if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) {
+ (void) fprintf(stderr,
+ "%s: open: %s\n", iplfile[i],
+ STRERROR(errno));
+ exit(-1);
+ }
+
+ if (fstat(fd[i], &sb) == -1) {
+ (void) fprintf(stderr, "%d: fstat: %s\n",fd[i],
+ STRERROR(errno));
+ exit(-1);
+ }
+ if (!(regular[i] = !S_ISCHR(sb.st_mode)))
+ devices++;
+ }
}
if (!(opts & OPT_SYSLOG)) {
log = argv[optind] ? fopen(argv[optind], "a") : stdout;
+ if (log == NULL) {
+
+ (void) fprintf(stderr, "%s: fopen: %s\n", argv[optind],
+ STRERROR(errno));
+ exit(-1);
+ }
setvbuf(log, NULL, _IONBF, 0);
} else {
daemon(0, 0);
}
- if (flushed) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_INFO, "%d bytes flushed from log\n",
- flushed);
- else
- fprintf(log, "%d bytes flushed from log\n", flushed);
- }
+ for (doread = 1; doread; ) {
+ nr = 0;
+
+ for (i = 0; i < 3; i++) {
+ tr = 0;
+ if (fdt[i] == -1)
+ continue;
+ if (!regular[i]) {
+ if (ioctl(fd[i], FIONREAD, &tr) == -1) {
+ perror("ioctl(FIONREAD)");
+ exit(-1);
+ }
+ } else {
+ tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size);
+ if (!tr && !(opts & OPT_TAIL))
+ doread = 0;
+ }
+ if (!tr)
+ continue;
+ nr += tr;
- for (doread = 1; doread; )
- switch (readlogentry(fd, &n, buf, sizeof(buf), log))
- {
- case -1 :
- if (opts & OPT_SYSLOG)
- syslog(LOG_ERR, "read: %m\n");
- else
- perror("read");
- doread = 0;
- break;
- case 1 :
- if (opts & OPT_SYSLOG)
- syslog(LOG_ERR, "aborting logging\n");
- else
- fprintf(log, "aborting logging\n");
- doread = 0;
- break;
- case 2 :
- break;
- case 0 :
- printpacket(log, buf, n, opts);
- break;
+ tr = read_log(fd[i], &n, buf, sizeof(buf), log);
+ switch (tr)
+ {
+ case -1 :
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_ERR, "read: %m\n");
+ else
+ perror("read");
+ doread = 0;
+ break;
+ case 1 :
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_ERR, "aborting logging\n");
+ else
+ fprintf(log, "aborting logging\n");
+ doread = 0;
+ break;
+ case 2 :
+ break;
+ case 0 :
+ if (n > 0) {
+ print_log(fdt[i], log, buf, n);
+ if (!(opts & OPT_SYSLOG))
+ fflush(log);
+ }
+ break;
+ }
}
+ if (!nr && ((opts & OPT_TAIL) || devices))
+ sleep(1);
+ }
exit(0);
/* NOTREACHED */
}
diff --git a/usr.sbin/ipsend/common/44arp.c b/usr.sbin/ipsend/common/44arp.c
index 04afb619f24..290e676d514 100644
--- a/usr.sbin/ipsend/common/44arp.c
+++ b/usr.sbin/ipsend/common/44arp.c
@@ -1,6 +1,9 @@
/*
* 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>
@@ -16,6 +19,14 @@
#include <errno.h>
#include <nlist.h>
#include <stdio.h>
+#include <netinet/in.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
+#include "ipsend.h"
+
/*
* lookup host and return
@@ -49,7 +60,7 @@ char *addr, *eaddr;
{
int mib[6];
size_t needed;
- char *host, *malloc(), *lim, *buf, *next;
+ char *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
diff --git a/usr.sbin/ipsend/common/ip.c b/usr.sbin/ipsend/common/ip.c
index 97ff1104851..ede14cf1cc9 100644
--- a/usr.sbin/ipsend/common/ip.c
+++ b/usr.sbin/ipsend/common/ip.c
@@ -1,18 +1,19 @@
/*
- * ip.c (C) 1995 Darren Reed
+ * ip.c (C) 1995-1997 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.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "%W% %G% (C)1995";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995";
+static const char rcsid[] = "@(#)$Id: ip.c,v 1.5 1998/01/26 04:16:50 dgregor Exp $";
#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>
@@ -22,15 +23,15 @@ static char sccsid[] = "%W% %G% (C)1995";
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
+#include <sys/param.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"
+# include <netinet/if_ether.h>
+# include <netinet/ip_var.h>
+# if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+# endif
#endif
+#include "ipsend.h"
static char *ipbuf = NULL, *ethbuf = NULL;
@@ -69,8 +70,8 @@ struct in_addr gwip;
bcopy((char *)buf, s + sizeof(*eh), len);
if (gwip.s_addr == last_gw.s_addr)
- bcopy(last_arp, eh->ether_dhost, 6);
- else if (arp((char *)&gwip, &eh->ether_dhost) == -1)
+ bcopy(last_arp, (char *)A_A eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1)
{
perror("arp");
return -2;
@@ -95,41 +96,44 @@ int frag;
static u_short id = 0;
ether_header_t *eh;
ip_t ipsv;
- int err;
+ int err, iplen;
if (!ipbuf)
ipbuf = (char *)malloc(65536);
eh = (ether_header_t *)ipbuf;
- bzero(&eh->ether_shost, sizeof(eh->ether_shost));
+ bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
if (last_gw.s_addr && (gwip.s_addr == last_gw.s_addr))
- bcopy(last_arp, eh->ether_dhost, 6);
- else if (arp((char *)&gwip, &eh->ether_dhost) == -1)
+ bcopy(last_arp, (char *)A_A eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1)
{
perror("arp");
return -2;
}
- bcopy(eh->ether_dhost, last_arp, sizeof(last_arp));
+ bcopy((char *)A_A eh->ether_dhost, last_arp, sizeof(last_arp));
eh->ether_type = htons(ETHERTYPE_IP);
bcopy((char *)ip, (char *)&ipsv, sizeof(*ip));
last_gw.s_addr = gwip.s_addr;
- ip->ip_len = htons(ip->ip_len);
+ iplen = ip->ip_len;
+ ip->ip_len = htons(iplen);
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))
+ if (!(frag & 2)) {
+ 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) + iplen < mtu))
{
ip->ip_sum = 0;
- ip->ip_sum = chksum(ip, ip->ip_hl << 2);
+ ip->ip_sum = chksum((u_short *)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));
+ bcopy((char *)ip, ipbuf + sizeof(*eh), iplen);
+ err = sendip(nfd, ipbuf, sizeof(*eh) + iplen);
}
else
{
@@ -141,7 +145,7 @@ int frag;
ether_header_t eth;
char optcpy[48], ol;
char *s;
- int i, iplen, sent = 0, ts, hlen, olen;
+ int i, sent = 0, ts, hlen, olen;
hlen = ip->ip_hl << 2;
if (mtu < (hlen + 8)) {
@@ -176,7 +180,7 @@ int frag;
*/
while ((i & 3) && (i & 3) != 3)
optcpy[i++] = IPOPT_NOP;
- if (i & 3 == 3)
+ if ((i & 3) == 3)
optcpy[i++] = IPOPT_EOL;
}
@@ -199,7 +203,7 @@ int frag;
ts += hlen;
ip->ip_len = htons(ts);
ip->ip_sum = 0;
- ip->ip_sum = chksum(ip, hlen);
+ ip->ip_sum = chksum((u_short *)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);
@@ -232,43 +236,44 @@ struct in_addr gwip;
{
static tcp_seq iss = 2;
struct tcpiphdr *ti;
- int thlen, i;
- u_long lbuf[20];
+ tcphdr_t *t;
+ int thlen, i, iplen, hlen;
+ u_32_t lbuf[20];
+ iplen = ip->ip_len;
+ hlen = ip->ip_hl << 2;
+ t = (tcphdr_t *)((char *)ip + hlen);
ti = (struct tcpiphdr *)lbuf;
+ thlen = t->th_off << 2;
+ if (!thlen)
+ thlen = sizeof(tcphdr_t);
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));
+ bcopy((char *)ip + hlen, (char *)&ti->ti_sport, thlen);
if (!ti->ti_win)
ti->ti_win = htons(4096);
- if (!ti->ti_seq)
- ti->ti_seq = htonl(iss);
- iss += 64;
+ iss += 63;
- 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);
+ i = sizeof(struct tcpiphdr) / sizeof(long);
+
+ if ((ti->ti_flags == TH_SYN) && !ip->ip_off &&
+ (lbuf[i] != htonl(0x020405b4))) {
lbuf[i] = htonl(0x020405b4);
- bcopy((char *)(lbuf + i), (char*)ip + ntohs(ip->ip_len),
- sizeof(u_long));
+ bcopy((char *)ip + hlen + thlen, (char *)ip + hlen + thlen + 4,
+ iplen - thlen - hlen);
thlen += 4;
}
- if (!ti->ti_off)
- ti->ti_off = thlen >> 2;
+ ti->ti_off = thlen >> 2;
ti->ti_len = htons(thlen);
- ip->ip_len = (ip->ip_hl << 2) + thlen;
+ ip->ip_len = hlen + thlen;
ti->ti_sum = 0;
- ti->ti_sum = chksum(ti, thlen + sizeof(ip_t));
+ ti->ti_sum = chksum((u_short *)ti, thlen + sizeof(ip_t));
- bcopy((char *)&ti->ti_sport,
- (char *)ip + (ip->ip_hl << 2), thlen);
+ bcopy((char *)&ti->ti_sport, (char *)ip + hlen, thlen);
return send_ip(nfd, mtu, ip, gwip, 1);
}
@@ -282,7 +287,7 @@ ip_t *ip;
struct in_addr gwip;
{
struct tcpiphdr *ti;
- int thlen, i;
+ int thlen;
u_long lbuf[20];
ti = (struct tcpiphdr *)lbuf;
@@ -297,7 +302,7 @@ struct in_addr gwip;
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));
+ ti->ti_sum = chksum((u_short *)ti, thlen + sizeof(ip_t));
bcopy((char *)&ti->ti_sport,
(char *)ip + (ip->ip_hl << 2), sizeof(udphdr_t));
@@ -318,7 +323,7 @@ struct in_addr gwip;
ic = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
ic->icmp_cksum = 0;
- ic->icmp_cksum = chksum((char *)ic, sizeof(struct icmp));
+ ic->icmp_cksum = chksum((u_short *)ic, sizeof(struct icmp));
return send_ip(nfd, mtu, ip, gwip, 1);
}
diff --git a/usr.sbin/ipsend/common/iplang.h b/usr.sbin/ipsend/common/iplang.h
new file mode 100644
index 00000000000..a7a13f91503
--- /dev/null
+++ b/usr.sbin/ipsend/common/iplang.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+typedef struct iface {
+ int if_MTU;
+ char *if_name;
+ struct in_addr if_addr;
+ struct ether_addr if_eaddr;
+ struct iface *if_next;
+ int if_fd;
+} iface_t;
+
+
+typedef struct send {
+ struct iface *snd_if;
+ struct in_addr snd_gw;
+} send_t;
+
+
+typedef struct arp {
+ struct in_addr arp_addr;
+ struct ether_addr arp_eaddr;
+ struct arp *arp_next;
+} arp_t;
+
+
+typedef struct aniphdr {
+ union {
+ ip_t *ahu_ip;
+ char *ahu_data;
+ tcphdr_t *ahu_tcp;
+ udphdr_t *ahu_udp;
+ icmphdr_t *ahu_icmp;
+ } ah_un;
+ int ah_optlen;
+ int ah_lastopt;
+ int ah_p;
+ size_t ah_len;
+ struct aniphdr *ah_next;
+ struct aniphdr *ah_prev;
+} aniphdr_t;
+
+#define ah_ip ah_un.ahu_ip
+#define ah_data ah_un.ahu_data
+#define ah_tcp ah_un.ahu_tcp
+#define ah_udp ah_un.ahu_udp
+#define ah_icmp ah_un.ahu_icmp
diff --git a/usr.sbin/ipsend/common/ipsend.h b/usr.sbin/ipsend/common/ipsend.h
new file mode 100644
index 00000000000..5d4aab9c300
--- /dev/null
+++ b/usr.sbin/ipsend/common/ipsend.h
@@ -0,0 +1,67 @@
+/*
+ * ipsend.h (C) 1997 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.
+ *
+ */
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+#include "ip_fil_compat.h"
+#ifdef linux
+#include <linux/sockios.h>
+#endif
+#include "tcpip.h"
+#include "ipt.h"
+#include "ipf.h"
+
+extern int resolve __P((char *, char *));
+extern int arp __P((char *, char *));
+extern u_short chksum __P((u_short *, int));
+extern int send_ether __P((int, char *, int, struct in_addr));
+extern int send_ip __P((int, int, ip_t *, struct in_addr, int));
+extern int send_tcp __P((int, int, ip_t *, struct in_addr));
+extern int send_udp __P((int, int, ip_t *, struct in_addr));
+extern int send_icmp __P((int, int, ip_t *, struct in_addr));
+extern int send_packet __P((int, int, ip_t *, struct in_addr));
+extern int send_packets __P((char *, int, ip_t *, struct in_addr));
+extern u_short seclevel __P((char *));
+extern u_32_t buildopts __P((char *, char *, int));
+extern int addipopt __P((char *, struct ipopt_names *, int, char *));
+extern int initdevice __P((char *, int, int));
+extern int sendip __P((int, char *, int));
+#ifdef linux
+extern struct sock *find_tcp __P((int, struct tcpiphdr *));
+#else
+extern struct tcpcb *find_tcp __P((int, struct tcpiphdr *));
+#endif
+extern int ip_resend __P((char *, int, struct ipread *, struct in_addr, char *));
+
+extern void ip_test1 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test2 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test3 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test4 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test5 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test6 __P((char *, int, ip_t *, struct in_addr, int));
+extern void ip_test7 __P((char *, int, ip_t *, struct in_addr, int));
+extern int do_socket __P((char *, int, struct tcpiphdr *, struct in_addr));
+extern int openkmem __P((void));
+extern int kmemcpy __P((char *, void *, int));
+
+#define KMCPY(a,b,c) kmemcpy((char *)(a), (void *)(b), (int)(c))
+
+#define OPT_RAW 0x80000
diff --git a/usr.sbin/ipsend/common/sbpf.c b/usr.sbin/ipsend/common/sbpf.c
index 9bc557a1a9e..e03d2040ee0 100644
--- a/usr.sbin/ipsend/common/sbpf.c
+++ b/usr.sbin/ipsend/common/sbpf.c
@@ -1,13 +1,15 @@
/*
- * (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.
+ * (C)opyright 1995-1997 Darren Reed. (from tcplog)
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
#include <stdio.h>
-#include <stdlib.h>
#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
@@ -29,15 +31,15 @@
#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 "ipsend.h"
-#ifndef lint
-static char sbpf[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: sbpf.c,v 1.3 1998/01/26 04:16:53 dgregor Exp $";
#endif
/*
@@ -51,7 +53,6 @@ int initdevice(device, sport, tout)
char *device;
int sport, tout;
{
- struct bpf_program prog;
struct bpf_version bv;
struct timeval to;
struct ifreq ifr;
diff --git a/usr.sbin/ipsend/common/sock.c b/usr.sbin/ipsend/common/sock.c
index 736f616f7a5..53e2db08a60 100644
--- a/usr.sbin/ipsend/common/sock.c
+++ b/usr.sbin/ipsend/common/sock.c
@@ -1,14 +1,13 @@
/*
- * sock.c (C) 1995 Darren Reed
+ * sock.c (C) 1995-1997 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.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: sock.c,v 1.3 1998/01/26 04:16:54 dgregor Exp $";
#endif
#include <stdio.h>
#include <unistd.h>
@@ -20,10 +19,16 @@ static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <sys/time.h>
#include <sys/param.h>
#include <sys/stat.h>
+#ifndef ultrix
#include <fcntl.h>
+#endif
#include <sys/dir.h>
#define _KERNEL
#define KERNEL
+#ifdef ultrix
+# undef LOCORE
+# include <sys/smp_lock.h>
+#endif
#include <sys/file.h>
#undef _KERNEL
#undef KERNEL
@@ -32,7 +37,9 @@ static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/proc.h>
-#include <kvm.h>
+#if !defined(ultrix) && !defined(hpux)
+# include <kvm.h>
+#endif
#ifdef sun
#include <sys/systm.h>
#include <sys/session.h>
@@ -53,7 +60,7 @@ static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <netinet/in_pcb.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
-#include <netinet/tcpip.h>
+#include "ipsend.h"
int nproc;
struct proc *proc;
@@ -75,17 +82,26 @@ struct proc *proc;
# define KERNEL "/vmunix"
#endif
+
+#if BSD < 199103
+static struct proc *getproc __P((void));
+#else
+static struct kinfo_proc *getproc __P((void));
+#endif
+
+
int kmemcpy(buf, pos, n)
char *buf;
void *pos;
int n;
{
static int kfd = -1;
+ off_t offset = (u_long)pos;
if (kfd == -1)
kfd = open(KMEM, O_RDONLY);
- if (lseek(kfd, (off_t)(u_long)pos, SEEK_SET) == -1)
+ if (lseek(kfd, offset, SEEK_SET) == -1)
{
perror("lseek");
return -1;
@@ -98,14 +114,19 @@ int n;
return n;
}
-struct nlist names[3] = {
+struct nlist names[4] = {
{ "_proc" },
{ "_nproc" },
+#ifdef ultrix
+ { "_u" },
+#else
+ { NULL },
+#endif
{ NULL }
};
#if BSD < 199103
-struct proc *getproc()
+static struct proc *getproc()
{
struct proc *p;
pid_t pid = getpid();
@@ -117,21 +138,20 @@ struct proc *getproc()
fprintf(stderr, "nlist(%#x) == %d\n", names, n);
return NULL;
}
- if (kmemcpy((char *)&nproc, (void *)names[1].n_value,
- sizeof(nproc)) == -1)
+ if (KMCPY(&nproc, 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, (void *)names[0].n_value, sizeof(p)) == -1)
+ if (KMCPY(&p, 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, (void *)p, siz) == -1)
+ if (KMCPY(proc, p, siz) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) proc\n",
p, proc, siz);
@@ -163,32 +183,40 @@ struct tcpiphdr *ti;
if (!(p = getproc()))
return NULL;
-
+printf("fl %x ty %x cn %d mc %d\n",
+f->f_flag, f->f_type, f->f_count, f->f_msgcount);
up = (struct user *)malloc(sizeof(*up));
- if (kmemcpy((char *)up, (void *)p->p_uarea, sizeof(*up)) == -1)
+#ifndef ultrix
+ if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1)
{
fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea);
return NULL;
}
+#else
+ if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value);
+ return NULL;
+ }
+#endif
o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1));
- if (kmemcpy((char *)o, (void *)up->u_ofile,
- (up->u_lastfile + 1) * sizeof(*o)) == -1)
+ if (KMCPY(o, 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));
+ up->u_ofile, o, sizeof(*o));
return NULL;
}
f = (struct file *)calloc(1, sizeof(*f));
- if (kmemcpy((char *)f, (void *)o[fd], sizeof(*f)) == -1)
+ if (KMCPY(f, o[fd], sizeof(*f)) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n",
- up->u_ofile_arr[fd], f, sizeof(*f));
+ up->u_ofile[fd], f, sizeof(*f));
return NULL;
}
s = (struct socket *)calloc(1, sizeof(*s));
- if (kmemcpy((char *)s, (void *)f->f_data, sizeof(*s)) == -1)
+ if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n",
o[fd], s, sizeof(*s));
@@ -196,7 +224,7 @@ struct tcpiphdr *ti;
}
i = (struct inpcb *)calloc(1, sizeof(*i));
- if (kmemcpy((char *)i, (void *)s->so_pcb, sizeof(*i)) == -1)
+ if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
{
fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n",
s->so_pcb, i, sizeof(*i));
@@ -204,7 +232,7 @@ struct tcpiphdr *ti;
}
t = (struct tcpcb *)calloc(1, sizeof(*t));
- if (kmemcpy((char *)t, (void *)i->inp_ppcb, sizeof(*t)) == -1)
+ if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n",
i->inp_ppcb, t, sizeof(*t));
@@ -213,7 +241,7 @@ struct tcpiphdr *ti;
return (struct tcpcb *)i->inp_ppcb;
}
#else
-struct kinfo_proc *getproc()
+static struct kinfo_proc *getproc()
{
static struct kinfo_proc kp;
pid_t pid = getpid();
@@ -225,7 +253,7 @@ struct kinfo_proc *getproc()
mib[2] = KERN_PROC_PID;
mib[3] = pid;
- n = 1;
+ n = sizeof(kp);
if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1)
{
perror("sysctl");
@@ -250,61 +278,60 @@ struct tcpiphdr *ti;
return NULL;
fd = (struct filedesc *)malloc(sizeof(*fd));
- if (kmemcpy((char *)fd, (void *)p->kp_proc.p_fd, sizeof(*fd)) == -1)
+ if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1)
{
- fprintf(stderr, "read(%#x,%#x) failed\n", p, p->kp_proc.p_fd);
+ 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)
+ if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
{
- fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n",
- fd->fd_ofiles, o, sizeof(*o));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
+ (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
return NULL;
}
f = (struct file *)calloc(1, sizeof(*f));
- if (kmemcpy((char *)f, (void *)o[tfd], sizeof(*f)) == -1)
+ if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
{
- fprintf(stderr, "read(%#x,%#x,%d) - o[tfd] - failed\n",
- o[tfd], f, sizeof(*f));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n",
+ (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f));
return NULL;
}
s = (struct socket *)calloc(1, sizeof(*s));
- if (kmemcpy((char *)s, (void *)f->f_data, sizeof(*s)) == -1)
+ if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
{
- fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n",
- f->f_data, s, sizeof(*s));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
+ (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
return NULL;
}
i = (struct inpcb *)calloc(1, sizeof(*i));
- if (kmemcpy((char *)i, (void *)s->so_pcb, sizeof(*i)) == -1)
+ if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
{
- fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n",
- s->so_pcb, i, sizeof(*i));
+ fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
+ (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
return NULL;
}
t = (struct tcpcb *)calloc(1, sizeof(*t));
- if (kmemcpy((char *)t, (void *)i->inp_ppcb, sizeof(*t)) == -1)
+ if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
{
- fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n",
- i->inp_ppcb, t, sizeof(*t));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
+ (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
return NULL;
}
return (struct tcpcb *)i->inp_ppcb;
}
#endif /* BSD < 199301 */
-int do_socket(dev, mtu, ti, gwip, flags)
+int do_socket(dev, mtu, ti, gwip)
char *dev;
int mtu;
struct tcpiphdr *ti;
struct in_addr gwip;
-int flags;
{
struct sockaddr_in rsin, lsin;
struct tcpcb *t, tcb;
@@ -338,7 +365,7 @@ int flags;
(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));
+ nfd = initdevice(dev, ntohs(lsin.sin_port), 1);
if (!(t = find_tcp(fd, ti)))
return -1;
@@ -354,12 +381,12 @@ int flags;
perror("connect");
return -1;
}
- kmemcpy((char*)&tcb, (void *)t, sizeof(tcb));
+ KMCPY(&tcb, 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)
+ if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
return -1;
(void)write(fd, "Hello World\n", 12);
sleep(2);
diff --git a/usr.sbin/ipsend/common/tcpip.h b/usr.sbin/ipsend/common/tcpip.h
new file mode 100644
index 00000000000..72c8737f443
--- /dev/null
+++ b/usr.sbin/ipsend/common/tcpip.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
+ * $Id: tcpip.h,v 1.3 1998/01/26 04:16:55 dgregor Exp $
+ */
+
+#ifndef _NETINET_TCPIP_H_
+#define _NETINET_TCPIP_H_
+
+# if defined(linux) && !defined(LINUX_IPOVLY)
+# define LINUX_IPOVLY
+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 */
+};
+# endif
+
+/*
+ * Tcp+ip header, after ip options removed.
+ */
+struct tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+#ifdef linux
+ tcphdr_t ti_t;
+#else
+ struct tcphdr ti_t; /* tcp header */
+#endif
+};
+#ifdef notyet
+/*
+ * Tcp+ip header, after ip options removed but including TCP options.
+ */
+struct full_tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+ struct tcphdr ti_t; /* tcp header */
+ char ti_o[TCP_MAXOLEN]; /* space for tcp options */
+};
+#endif /* notyet */
+#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
diff --git a/usr.sbin/ipsend/ipresend/Makefile b/usr.sbin/ipsend/ipresend/Makefile
index 99d65114bcb..f0d7c827559 100644
--- a/usr.sbin/ipsend/ipresend/Makefile
+++ b/usr.sbin/ipsend/ipresend/Makefile
@@ -1,10 +1,11 @@
-# $Id: Makefile,v 1.2 1996/07/18 05:00:22 dm Exp $
+# $OpenBSD: Makefile,v 1.3 1998/01/26 04:16:56 dgregor Exp $
PROG= ipresend
BINDIR= /usr/sbin
-NOMAN=
-SRCS= ipresend.c resend.c ip.c sbpf.c sock.c 44arp.c opt.c \
- ipft_ef.c ipft_hx.c ipft_pc.c ipft_sn.c ipft_tx.c ipft_td.c
+MAN= ipresend.1
+SRCS= ipresend.o resend.o \
+ ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o opt.o \
+ sock.o 44arp.o sbpf.o ip.o
CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest \
-I${.CURDIR}/../../../sbin/ipf \
-I${.CURDIR}/../../../sys/netinet
diff --git a/usr.sbin/ipsend/ipresend/ipresend.1 b/usr.sbin/ipsend/ipresend/ipresend.1
new file mode 100644
index 00000000000..40f98256209
--- /dev/null
+++ b/usr.sbin/ipsend/ipresend/ipresend.1
@@ -0,0 +1,107 @@
+.TH IPRESEND 1
+.SH NAME
+ipresend \- resend IP packets out to network
+.SH SYNOPSIS
+.B ipsend
+[
+.B \-EHPRSTX
+] [
+.B \-d
+<device>
+] [
+.B \-g
+<\fIgateway\fP>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-r
+<\fIfilename\fP>
+]
+.SH DESCRIPTION
+.PP
+\fBipresend\fP was designed to allow packets to be resent, once captured,
+back out onto the network for use in testing. \fIipresend\fP supports a
+number of different file formats as input, including saved snoop/tcpdump
+binary data.
+.SH OPTIONS
+.TP
+.BR \-d \0<interface>
+Set the interface name to be the name supplied. This is useful with the
+\fB\-P, \-S, \-T\fP and \fB\-E\fP options, where it is not otherwise possible
+to associate a packet with an interface. Normal "text packets" can override
+this setting.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.BR \-r \0<filename>
+Specify the filename from which to take input. Default is stdin.
+.B \-E
+The input file is to be text output from etherfind. The text formats which
+are currently supported are those which result from the following etherfind
+option combinations:
+.PP
+.nf
+ etherfind -n
+ etherfind -n -t
+.fi
+.LP
+.TP
+.B \-H
+The input file is to be hex digits, representing the binary makeup of the
+packet. No length correction is made, if an incorrect length is put in
+the IP header.
+.TP
+.B \-P
+The input file specified by \fB\-i\fP is a binary file produced using libpcap
+(i.e., tcpdump version 3). Packets are read from this file as being input
+(for rule purposes).
+.TP
+.B \-R
+When sending packets out, send them out "raw" (the way they came in). The
+only real significance here is that it will expect the link layer (i.e.
+ethernet) headers to be prepended to the IP packet being output.
+.TP
+.B \-S
+The input file is to be in "snoop" format (see RFC 1761). Packets are read
+from this file and used as input from any interface. This is perhaps the
+most useful input type, currently.
+.TP
+.B \-T
+The input file is to be text output from tcpdump. The text formats which
+are currently supported are those which result from the following tcpdump
+option combinations:
+.PP
+.nf
+ tcpdump -n
+ tcpdump -nq
+ tcpdump -nqt
+ tcpdump -nqtt
+ tcpdump -nqte
+.fi
+.LP
+.TP
+.B \-X
+The input file is composed of text descriptions of IP packets.
+.TP
+.SH FILES
+.DT
+.SH SEE ALSO
+snoop(1m), tcpdump(8), etherfind(8c), ipftest(1), ipresend(1), iptest(1), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+Not all of the input formats are sufficiently capable of introducing a
+wide enough variety of packets for them to be all useful in testing.
+If you find any, please send email to me at darrenr@cyber.com.au
+
diff --git a/usr.sbin/ipsend/ipresend/ipresend.c b/usr.sbin/ipsend/ipresend/ipresend.c
index 863c8b754da..52e2273574c 100644
--- a/usr.sbin/ipsend/ipresend/ipresend.c
+++ b/usr.sbin/ipsend/ipresend/ipresend.c
@@ -1,29 +1,30 @@
+/* $OpenBSD: ipresend.c,v 1.3 1998/01/26 04:16:58 dgregor Exp $ */
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipresend.c (C) 1995-1997 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.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipresend.c,v 1.3 1998/01/26 04:16:58 dgregor Exp $";
#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>
@@ -31,19 +32,15 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
#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"
+#include "ipsend.h"
extern char *optarg;
extern int optind;
+#ifndef NO_IPF
extern struct ipread snoop, pcap, etherf, iphex, tcpd, iptext;
+#endif
int opts = 0;
#ifndef DEFAULT_DEVICE
@@ -59,7 +56,11 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
@@ -69,7 +70,11 @@ char default_device[] = DEFAULT_DEVICE;
#endif
-void usage(prog)
+static void usage __P((char *));
+int main __P((int, char **));
+
+
+static void usage(prog)
char *prog;
{
fprintf(stderr, "Usage: %s [options] <-r filename|-R filename>\n\
@@ -84,17 +89,17 @@ char *prog;
}
-main(argc, argv)
+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, *s, *resend = NULL;
- int mtu = 1500;
+ char *resend = NULL;
+ int mtu = 1500, c;
- while ((c = getopt(argc, argv, "EHPSTXd:g:m:r:")) != -1)
+ while ((c = getopt(argc, argv, "EHPRSTXd:g:m:r:")) != -1)
switch (c)
{
case 'd' :
@@ -113,6 +118,10 @@ char **argv;
case 'r' :
resend = optarg;
break;
+ case 'R' :
+ opts |= OPT_RAW;
+ break;
+#ifndef NO_IPF
case 'E' :
ipr = &etherf;
break;
@@ -131,6 +140,7 @@ char **argv;
case 'X' :
ipr = &iptext;
break;
+#endif
default :
fprintf(stderr, "Unknown option \"%c\"\n", c);
usage(name);
diff --git a/usr.sbin/ipsend/ipresend/resend.c b/usr.sbin/ipsend/ipresend/resend.c
index 6762ae6048c..4beec1ac887 100644
--- a/usr.sbin/ipsend/ipresend/resend.c
+++ b/usr.sbin/ipsend/ipresend/resend.c
@@ -1,46 +1,52 @@
+/* $OpenBSD: resend.c,v 1.3 1998/01/26 04:16:59 dgregor Exp $ */
/*
- * resend.c (C) 1995 Darren Reed
+ * resend.c (C) 1995-1997 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.
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: resend.c,v 1.3 1998/01/26 04:16:59 dgregor Exp $";
#endif
#include <stdio.h>
-#include <stdlib.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>
+# include <netinet/ip_var.h>
+# include <netinet/if_ether.h>
+# if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+# endif
#endif
-#include "ip_compat.h"
-#ifdef linux
-#include <linux/sockios.h>
-#include "tcpip.h"
-#endif
-#include "ipt.h"
+#include "ipsend.h"
+extern int opts;
static u_char buf[65536]; /* 1 big packet */
+void printpacket __P((ip_t *));
-printpacket(ip)
+void printpacket(ip)
ip_t *ip;
{
tcphdr_t *t;
@@ -58,9 +64,10 @@ ip_t *ip;
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_sport);
+ printf(",%d", t->th_dport);
if (ip->ip_p == IPPROTO_TCP) {
- printf(" seq %u:%u flags ", t->th_seq, t->th_ack);
+ 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]);
@@ -71,6 +78,7 @@ ip_t *ip;
int ip_resend(dev, mtu, r, gwip, datain)
char *dev;
+int mtu;
struct in_addr gwip;
struct ipread *r;
char *datain;
@@ -91,7 +99,7 @@ char *datain;
ip = (struct ip *)buf;
eh = (ether_header_t *)malloc(sizeof(*eh));
- bzero(&eh->ether_shost, sizeof(eh->ether_shost));
+ bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
{
perror("arp");
@@ -100,21 +108,31 @@ char *datain;
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 (!(opts & OPT_RAW)) {
+ 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 *)A_A eh->ether_dhost) == -1) {
+ perror("arp");
+ continue;
+ }
+ } else
+ bcopy(dhost, (char *)A_A eh->ether_dhost,
+ sizeof(dhost));
+ if (!ip->ip_sum)
+ ip->ip_sum = chksum((u_short *)ip,
+ ip->ip_hl << 2);
+ bcopy(ip, (char *)(eh + 1), len);
+ len += sizeof(*eh);
+ printpacket(ip);
+ } else {
+ eh = (ether_header_t *)buf;
+ len = i;
+ }
- if (sendip(wfd, eh, sizeof(*eh) + len) == -1)
+ if (sendip(wfd, (char *)eh, len) == -1)
{
perror("send_packet");
break;
diff --git a/usr.sbin/ipsend/ipsend/Makefile b/usr.sbin/ipsend/ipsend/Makefile
index 4b2770b47ac..26e3192a88e 100644
--- a/usr.sbin/ipsend/ipsend/Makefile
+++ b/usr.sbin/ipsend/ipsend/Makefile
@@ -1,10 +1,14 @@
-# $Id: Makefile,v 1.1 1996/05/10 21:40:58 dm Exp $
+# $OpenBSD: Makefile,v 1.2 1998/01/26 04:17:01 dgregor Exp $
PROG= ipsend
BINDIR= /usr/sbin
-NOMAN=
-SRCS= ipsend.c ip.c ipsopt.c sbpf.c sock.c 44arp.c
-CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest
+MAN= ipsend.1 ipsend.5
+SRCS= ipsend.c ip.c ipsopt.c sbpf.c sock.c 44arp.c iplang_y.y iplang_l.l
+CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest \
+ -I${.CURDIR}/../../../sbin/ipf -I${.CURDIR}/../../../sys/netinet
+LDADD = -lfl
+CLEANFILES+=y.tab.h
+
.PATH: ${.CURDIR}/../common
.include <bsd.prog.mk>
diff --git a/usr.sbin/ipsend/ipsend/iplang_l.l b/usr.sbin/ipsend/ipsend/iplang_l.l
new file mode 100644
index 00000000000..c4dcad9fe3e
--- /dev/null
+++ b/usr.sbin/ipsend/ipsend/iplang_l.l
@@ -0,0 +1,312 @@
+%e 1500
+%p 4000
+%a 4000
+%o 6000
+%{
+/* $OpenBSD: iplang_l.l,v 1.1 1998/01/26 04:17:01 dgregor Exp $ */
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: iplang_l.l,v 1.1 1998/01/26 04:17:01 dgregor Exp $
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#if defined(__SVR4) || defined(__sysv__)
+#include <sys/stream.h>
+#endif
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include "y.tab.h"
+#include "ip_fil_compat.h"
+#include "ipf.h"
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+extern int opts;
+
+int lineNum = 0, proto = 0, oldproto = 0, next = -1, laststate = 0;
+int *prstack = NULL, numpr = 0, state = 0, token = 0;
+
+void yyerror __P((char *));
+void push_proto __P((void));
+void pop_proto __P((void));
+int next_state __P((int, int));
+int next_item __P((int));
+int save_token __P((void));
+void swallow __P((void));
+int yylex __P((void));
+%}
+
+%%
+[ \t\r] ;
+\n { lineNum++; swallow(); }
+interface |
+iface { return next_state(IL_INTERFACE, -1); }
+name |
+ifname { return next_state(IL_IFNAME, IL_TOKEN); }
+router { return next_state(IL_DEFROUTER, IL_TOKEN); }
+mtu { return next_state(IL_MTU, IL_NUMBER); }
+eaddr { return next_state(IL_EADDR, IL_TOKEN); }
+v4addr { return next_state(IL_V4ADDR, IL_TOKEN); }
+ipv4 { return next_state(IL_IPV4, -1); }
+v { return next_state(IL_V4V, IL_TOKEN); }
+proto { return next_state(IL_V4PROTO, IL_TOKEN); }
+hl { return next_state(IL_V4HL, IL_TOKEN); }
+id { return next_state(IL_V4ID, IL_TOKEN); }
+ttl { return next_state(IL_V4TTL, IL_TOKEN); }
+tos { return next_state(IL_V4TOS, IL_TOKEN); }
+src { return next_state(IL_V4SRC, IL_TOKEN); }
+dst { return next_state(IL_V4DST, IL_TOKEN); }
+opt { return next_state(IL_OPT, -1); }
+len { return next_state(IL_LEN, IL_TOKEN); }
+off { return next_state(IL_OFF, IL_TOKEN); }
+sum { return next_state(IL_SUM, IL_TOKEN); }
+tcp { return next_state(IL_TCP, -1); }
+sport { return next_state(IL_SPORT, IL_TOKEN); }
+dport { return next_state(IL_DPORT, IL_TOKEN); }
+seq { return next_state(IL_TCPSEQ, IL_TOKEN); }
+ack { return next_state(IL_TCPACK, IL_TOKEN); }
+flags { return next_state(IL_TCPFL, IL_TOKEN); }
+urp { return next_state(IL_TCPURP, IL_TOKEN); }
+win { return next_state(IL_TCPWIN, IL_TOKEN); }
+udp { return next_state(IL_UDP, -1); }
+send { return next_state(IL_SEND, -1); }
+via { return next_state(IL_VIA, IL_TOKEN); }
+arp { return next_state(IL_ARP, -1); }
+data { return next_state(IL_DATA, -1); }
+value { return next_state(IL_DVALUE, IL_TOKEN); }
+file { return next_state(IL_DFILE, IL_TOKEN); }
+nop { return next_state(IL_IPO_NOP, -1); }
+eol { return next_state(IL_IPO_EOL, -1); }
+rr { return next_state(IL_IPO_RR, -1); }
+zsu { return next_state(IL_IPO_ZSU, -1); }
+mtup { return next_state(IL_IPO_MTUP, -1); }
+mtur { return next_state(IL_IPO_MTUR, -1); }
+encode { return next_state(IL_IPO_ENCODE, -1); }
+ts { return next_state(IL_IPO_TS, -1); }
+tr { return next_state(IL_IPO_TR, -1); }
+sec { return next_state(IL_IPO_SEC, -1); }
+secclass { return next_state(IL_IPO_SECCLASS, IL_TOKEN); }
+lsrr { return next_state(IL_IPO_LSRR, -1); }
+esec { return next_state(IL_IPO_ESEC, -1); }
+cipso { return next_state(IL_IPO_CIPSO, -1); }
+satid { return next_state(IL_IPO_SATID, -1); }
+ssrr { return next_state(IL_IPO_SSRR, -1); }
+addext { return next_state(IL_IPO_ADDEXT, -1); }
+visa { return next_state(IL_IPO_VISA, -1); }
+imitd { return next_state(IL_IPO_IMITD, -1); }
+eip { return next_state(IL_IPO_EIP, -1); }
+finn { return next_state(IL_IPO_FINN, -1); }
+mss { return next_state(IL_TCPO_MSS, IL_TOKEN); }
+wscale { return next_state(IL_TCPO_MSS, IL_TOKEN); }
+reserv-4 { return next_state(IL_IPS_RESERV4, -1); }
+topsecret { return next_state(IL_IPS_TOPSECRET, -1); }
+secret { return next_state(IL_IPS_SECRET, -1); }
+reserv-3 { return next_state(IL_IPS_RESERV3, -1); }
+confid { return next_state(IL_IPS_CONFID, -1); }
+unclass { return next_state(IL_IPS_UNCLASS, -1); }
+reserv-2 { return next_state(IL_IPS_RESERV2, -1); }
+reserv-1 { return next_state(IL_IPS_RESERV1, -1); }
+icmp { return next_state(IL_ICMP, -1); }
+type { return next_state(IL_ICMPTYPE, -1); }
+code { return next_state(IL_ICMPCODE, -1); }
+echorep { return next_state(IL_ICMP_ECHOREPLY, -1); }
+unreach { return next_state(IL_ICMP_UNREACH, -1); }
+squench { return next_state(IL_ICMP_SOURCEQUENCH, -1); }
+redir { return next_state(IL_ICMP_REDIRECT, -1); }
+echo { return next_state(IL_ICMP_ECHO, -1); }
+routerad { return next_state(IL_ICMP_ROUTERADVERT, -1); }
+routersol { return next_state(IL_ICMP_ROUTERSOLICIT, -1); }
+timex { return next_state(IL_ICMP_TIMXCEED, -1); }
+paramprob { return next_state(IL_ICMP_PARAMPROB, -1); }
+timest { return next_state(IL_ICMP_TSTAMP, -1); }
+timestrep { return next_state(IL_ICMP_TSTAMPREPLY, -1); }
+inforeq { return next_state(IL_ICMP_IREQ, -1); }
+inforep { return next_state(IL_ICMP_IREQREPLY, -1); }
+maskreq { return next_state(IL_ICMP_MASKREQ, -1); }
+maskrep { return next_state(IL_ICMP_MASKREPLY, -1); }
+net-unr { return next_state(IL_ICMP_UNREACH_NET, -1); }
+host-unr { return next_state(IL_ICMP_UNREACH_HOST, -1); }
+proto-unr { return next_state(IL_ICMP_UNREACH_PROTOCOL, -1); }
+port-unr { return next_state(IL_ICMP_UNREACH_PORT, -1); }
+needfrag { return next_state(IL_ICMP_UNREACH_NEEDFRAG, -1); }
+srcfail { return next_state(IL_ICMP_UNREACH_SRCFAIL, -1); }
+net-unk { return next_state(IL_ICMP_UNREACH_NET_UNKNOWN, -1); }
+host-unk { return next_state(IL_ICMP_UNREACH_HOST_UNKNOWN, -1); }
+isolate { return next_state(IL_ICMP_UNREACH_ISOLATED, -1); }
+net-prohib { return next_state(IL_ICMP_UNREACH_NET_PROHIB, -1); }
+host-prohib { return next_state(IL_ICMP_UNREACH_HOST_PROHIB, -1); }
+net-tos { return next_state(IL_ICMP_UNREACH_TOSNET, -1); }
+host-tos { return next_state(IL_ICMP_UNREACH_TOSHOST, -1); }
+filter-prohib { return next_state(IL_ICMP_UNREACH_FILTER_PROHIB, -1); }
+host-preced { return next_state(IL_ICMP_UNREACH_HOST_PRECEDENCE, -1); }
+cutoff-preced { return next_state(IL_ICMP_UNREACH_PRECEDENCE_CUTOFF, -1); }
+net-redir { return next_state(IL_ICMP_REDIRECT_NET, -1); }
+host-redir { return next_state(IL_ICMP_REDIRECT_HOST, -1); }
+tos-net-redir { return next_state(IL_ICMP_REDIRECT_TOSNET, -1); }
+tos-host-redir { return next_state(IL_ICMP_REDIRECT_TOSHOST, -1); }
+intrans { return next_state(IL_ICMP_TIMXCEED_INTRANS, -1); }
+reass { return next_state(IL_ICMP_TIMXCEED_REASS, -1); }
+optabsent { return next_state(IL_ICMP_PARAMPROB_OPTABSENT, -1); }
+otime { return next_state(IL_ICMP_OTIME, -1); }
+rtime { return next_state(IL_ICMP_RTIME, -1); }
+ttime { return next_state(IL_ICMP_TTIME, -1); }
+icmpseq { return next_state(IL_ICMP_SEQ, -1); }
+icmpid { return next_state(IL_ICMP_SEQ, -1); }
+\377 { return 0; } /* EOF */
+\{ { push_proto(); return next_item('{'); }
+\} { pop_proto(); return next_item('}'); }
+\. { return next_item(IL_DOT); }
+; { return next_item(';'); }
+[0-9]+ { return next_item(IL_NUMBER); }
+[0-9a-fA-F] { return next_item(IL_HEXDIGIT); }
+: { return next_item(IL_COLON); }
+#[^\n]* { return next_item(IL_COMMENT); }
+[^ {}\n\t;]* { return next_item(IL_TOKEN); }
+\"[^\"]*\" { return next_item(IL_TOKEN); }
+%%
+void yyerror(msg)
+char *msg;
+{
+ fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
+ lineNum + 1);
+ exit(1);
+}
+
+
+void push_proto()
+{
+ numpr++;
+ if (!prstack)
+ prstack = (int *)malloc(sizeof(int));
+ else
+ prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
+ prstack[numpr - 1] = oldproto;
+}
+
+
+void pop_proto()
+{
+ numpr--;
+ proto = prstack[numpr];
+ if (!numpr) {
+ free(prstack);
+ prstack = NULL;
+ return;
+ }
+ prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
+}
+
+
+int save_token()
+{
+
+ yylval.str = strdup(yytext);
+ return IL_TOKEN;
+}
+
+
+int next_item(nstate)
+int nstate;
+{
+ if (next == IL_TOKEN) {
+ next = -1;
+ return save_token();
+ }
+ next = -1;
+ if (nstate == IL_NUMBER)
+ yylval.num = atoi(yytext);
+ token++;
+ return nstate;
+}
+
+
+int next_state(nstate, fornext)
+int nstate, fornext;
+{
+ token++;
+
+ if (next == IL_TOKEN) {
+ next = -1;
+ return save_token();
+ }
+
+ next = fornext;
+
+ switch (nstate)
+ {
+ case IL_IPV4 :
+ case IL_TCP :
+ case IL_UDP :
+ case IL_ICMP :
+ case IL_DATA :
+ case IL_INTERFACE :
+ case IL_ARP :
+ oldproto = proto;
+ proto = nstate;
+ break;
+ case IL_SUM :
+ if (proto == IL_IPV4)
+ nstate = IL_V4SUM;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPSUM;
+ else if (proto == IL_UDP)
+ nstate = IL_UDPSUM;
+ break;
+ case IL_OPT :
+ if (proto == IL_IPV4)
+ nstate = IL_V4OPT;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPOPT;
+ break;
+ case IL_IPO_NOP :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_NOP;
+ break;
+ case IL_IPO_EOL :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_EOL;
+ break;
+ case IL_IPO_TS :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_TS;
+ break;
+ case IL_OFF :
+ if (proto == IL_IPV4)
+ nstate = IL_V4OFF;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPOFF;
+ break;
+ case IL_LEN :
+ if (proto == IL_IPV4)
+ nstate = IL_V4LEN;
+ else if (proto == IL_UDP)
+ nstate = IL_UDPLEN;
+ break;
+ }
+ return nstate;
+}
+
+
+void swallow()
+{
+ int c = input();
+
+ if (c == '#') {
+ while ((c != '\n') && (c != EOF))
+ c = input();
+ }
+ unput(c);
+}
diff --git a/usr.sbin/ipsend/ipsend/iplang_y.y b/usr.sbin/ipsend/ipsend/iplang_y.y
new file mode 100644
index 00000000000..ace441a6366
--- /dev/null
+++ b/usr.sbin/ipsend/ipsend/iplang_y.y
@@ -0,0 +1,1840 @@
+%{
+/* $OpenBSD: iplang_y.y,v 1.1 1998/01/26 04:17:02 dgregor Exp $ */
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: iplang_y.y,v 1.1 1998/01/26 04:17:02 dgregor Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#if !defined(__SVR4) && !defined(__svr4__)
+#include <strings.h>
+#else
+#include <sys/byteorder.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#endif
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <net/if.h>
+#ifndef linux
+#include <netinet/if_ether.h>
+#endif
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <ctype.h>
+#include "ipsend.h"
+#include "ip_fil_compat.h"
+#include "ipf.h"
+#include "iplang.h"
+
+extern struct ether_addr *ether_aton __P((char *));
+
+extern int opts;
+extern struct ipopt_names ionames[];
+extern int state, state, lineNum, token;
+extern int yylineno;
+extern char yytext[];
+extern FILE *yyin;
+int yylex __P((void));
+#define YYDEBUG 1
+#if !defined(ultrix) && !defined(hpux)
+int yydebug = 1;
+#else
+extern int yydebug;
+#endif
+
+iface_t *iflist = NULL, **iftail = &iflist;
+iface_t *cifp = NULL;
+arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL;
+struct in_addr defrouter;
+send_t sending;
+char *sclass = NULL;
+u_short c_chksum __P((u_short *, u_int, u_long));
+u_long p_chksum __P((u_short *, u_int));
+
+u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */
+aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead;
+ip_t *ip = NULL;
+udphdr_t *udp = NULL;
+tcphdr_t *tcp = NULL;
+icmphdr_t *icmp = NULL;
+
+struct statetoopt {
+ int sto_st;
+ int sto_op;
+};
+
+struct in_addr getipv4addr __P((char *arg));
+u_short getportnum __P((char *, char *));
+struct ether_addr *geteaddr __P((char *, struct ether_addr *));
+void *new_header __P((int));
+void free_aniplist __P((void));
+void inc_anipheaders __P((int));
+void new_data __P((void));
+void set_datalen __P((char **));
+void set_datafile __P((char **));
+void set_data __P((char **));
+void new_packet __P((void));
+void set_ipv4proto __P((char **));
+void set_ipv4src __P((char **));
+void set_ipv4dst __P((char **));
+void set_ipv4off __P((char **));
+void set_ipv4v __P((char **));
+void set_ipv4hl __P((char **));
+void set_ipv4ttl __P((char **));
+void set_ipv4tos __P((char **));
+void set_ipv4id __P((char **));
+void set_ipv4sum __P((char **));
+void set_ipv4len __P((char **));
+void new_tcpheader __P((void));
+void set_tcpsport __P((char **));
+void set_tcpdport __P((char **));
+void set_tcpseq __P((char **));
+void set_tcpack __P((char **));
+void set_tcpoff __P((char **));
+void set_tcpurp __P((char **));
+void set_tcpwin __P((char **));
+void set_tcpsum __P((char **));
+void set_tcpflags __P((char **));
+void set_tcpopt __P((int, char **));
+void end_tcpopt __P((void));
+void new_udpheader __P((void));
+void set_udplen __P((char **));
+void set_udpsum __P((char **));
+void prep_packet __P((void));
+void packet_done __P((void));
+void new_interface __P((void));
+void check_interface __P((void));
+void set_ifname __P((char **));
+void set_ifmtu __P((int));
+void set_ifv4addr __P((char **));
+void set_ifeaddr __P((char **));
+void new_arp __P((void));
+void set_arpeaddr __P((char **));
+void set_arpv4addr __P((char **));
+void reset_send __P((void));
+void set_sendif __P((char **));
+void set_sendvia __P((char **));
+void set_defaultrouter __P((char **));
+void new_icmpheader __P((void));
+void set_icmpcode __P((int));
+void set_icmptype __P((int));
+void set_icmpcodetok __P((char **));
+void set_icmptypetok __P((char **));
+void set_icmpid __P((int));
+void set_icmpseq __P((int));
+void set_icmpotime __P((int));
+void set_icmprtime __P((int));
+void set_icmpttime __P((int));
+void set_icmpmtu __P((int));
+void set_redir __P((int, char **));
+void new_ipv4opt __P((void));
+void set_icmppprob __P((int));
+void add_ipopt __P((int, void *));
+void end_ipopt __P((void));
+void set_secclass __P((char **));
+void free_anipheader __P((void));
+void end_ipv4 __P((void));
+void end_icmp __P((void));
+void end_udp __P((void));
+void end_tcp __P((void));
+void end_data __P((void));
+void yyerror __P((char *));
+void iplang __P((FILE *));
+int yyparse __P((void));
+%}
+%union {
+ char *str;
+ int num;
+}
+%token <num> IL_NUMBER
+%type <num> number digits optnumber
+%token <str> IL_TOKEN
+%type <str> token optoken
+%token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT
+%token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR
+%token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL
+%token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID
+%token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF
+%token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL
+%token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS
+%token IL_UDP IL_UDPLEN IL_UDPSUM
+%token IL_ICMP IL_ICMPTYPE IL_ICMPCODE
+%token IL_SEND IL_VIA
+%token IL_ARP
+%token IL_DEFROUTER
+%token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT
+%token IL_DATA IL_DLEN IL_DVALUE IL_DFILE
+%token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL
+%token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC
+%token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD
+%token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE
+%token <str> IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3
+%token <str> IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1
+%token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET
+%token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT
+%token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL
+%token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN
+%token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB
+%token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET
+%token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB
+%token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF
+%token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET
+%token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET
+%token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT
+%token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS
+%token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT
+%token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY
+%token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID
+%token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME
+
+%%
+file: line
+ | line file
+ | IL_COMMENT
+ | IL_COMMENT file
+ ;
+
+line: iface
+ | arp
+ | send
+ | defrouter
+ | ipline
+ ;
+
+iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); }
+ ;
+
+ifhdr: IL_INTERFACE { new_interface(); }
+ ;
+
+ifaceopts:
+ ifaceopt
+ | ifaceopt ifaceopts
+ ;
+
+ifaceopt:
+ IL_IFNAME token { set_ifname(&$2); }
+ | IL_MTU number { set_ifmtu($2); }
+ | IL_V4ADDR token { set_ifv4addr(&$2); }
+ | IL_EADDR token { set_ifeaddr(&$2); }
+ ;
+
+send: sendhdr '{' sendbody '}' ';' { packet_done(); }
+ | sendhdr ';' { packet_done(); }
+ ;
+
+sendhdr:
+ IL_SEND { reset_send(); }
+ ;
+
+sendbody:
+ sendopt
+ | sendbody sendopt
+ ;
+
+sendopt:
+ IL_IFNAME token { set_sendif(&$2); }
+ | IL_VIA token { set_sendvia(&$2); }
+ ;
+
+arp: arphdr '{' arpbody '}' ';'
+ ;
+
+arphdr: IL_ARP { new_arp(); }
+ ;
+
+arpbody:
+ arpopt
+ | arpbody arpopt
+ ;
+
+arpopt: IL_V4ADDR token { set_arpv4addr(&$2); }
+ | IL_EADDR token { set_arpeaddr(&$2); }
+ ;
+
+defrouter:
+ IL_DEFROUTER token { set_defaultrouter(&$2); }
+ ;
+
+bodyline:
+ ipline
+ | tcp tcpline
+ | udp udpline
+ | icmp icmpline
+ | data dataline
+ ;
+
+ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); }
+ ;
+
+ipv4: IL_IPV4 { new_packet(); }
+
+ipv4body:
+ ipv4type
+ | ipv4type ipv4body
+ | bodyline
+ ;
+
+ipv4type:
+ IL_V4PROTO token { set_ipv4proto(&$2); }
+ | IL_V4SRC token { set_ipv4src(&$2); }
+ | IL_V4DST token { set_ipv4dst(&$2); }
+ | IL_V4OFF token { set_ipv4off(&$2); }
+ | IL_V4V token { set_ipv4v(&$2); }
+ | IL_V4HL token { set_ipv4hl(&$2); }
+ | IL_V4ID token { set_ipv4id(&$2); }
+ | IL_V4TTL token { set_ipv4ttl(&$2); }
+ | IL_V4TOS token { set_ipv4tos(&$2); }
+ | IL_V4SUM token { set_ipv4sum(&$2); }
+ | IL_V4LEN token { set_ipv4len(&$2); }
+ | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); }
+ ;
+
+tcp: IL_TCP { new_tcpheader(); }
+ ;
+
+tcpline:
+ '{' tcpheader '}' ';' { end_tcp(); }
+ ;
+
+tcpheader:
+ tcpbody
+ | tcpbody tcpheader
+ | bodyline
+ ;
+
+tcpbody:
+ IL_SPORT token { set_tcpsport(&$2); }
+ | IL_DPORT token { set_tcpdport(&$2); }
+ | IL_TCPSEQ token { set_tcpseq(&$2); }
+ | IL_TCPACK token { set_tcpack(&$2); }
+ | IL_TCPOFF token { set_tcpoff(&$2); }
+ | IL_TCPURP token { set_tcpurp(&$2); }
+ | IL_TCPWIN token { set_tcpwin(&$2); }
+ | IL_TCPSUM token { set_tcpsum(&$2); }
+ | IL_TCPFL token { set_tcpflags(&$2); }
+ | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); }
+ ;
+
+tcpopts:
+ | tcpopt tcpopts
+ ;
+
+tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); }
+ | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); }
+ | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);}
+ | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_MSS,&$2);}
+ | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);}
+ ;
+
+udp: IL_UDP { new_udpheader(); }
+ ;
+
+udpline:
+ '{' udpheader '}' ';' { end_udp(); }
+ ;
+
+
+udpheader:
+ udpbody
+ | udpbody udpheader
+ | bodyline
+ ;
+
+udpbody:
+ IL_SPORT token { set_tcpsport(&$2); }
+ | IL_DPORT token { set_tcpdport(&$2); }
+ | IL_UDPLEN token { set_udplen(&$2); }
+ | IL_UDPSUM token { set_udpsum(&$2); }
+ ;
+
+icmp: IL_ICMP { new_icmpheader(); }
+ ;
+
+icmpline:
+ '{' icmpbody '}' ';' { end_icmp(); }
+ ;
+
+icmpbody:
+ icmpheader
+ | icmpheader bodyline
+ ;
+
+icmpheader:
+ IL_ICMPTYPE icmptype
+ | IL_ICMPTYPE icmptype icmpcode
+ ;
+
+icmpcode:
+ IL_ICMPCODE token { set_icmpcodetok(&$2); }
+ ;
+
+icmptype:
+ IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); }
+ | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';'
+ | unreach
+ | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); }
+ | redirect
+ | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); }
+ | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); }
+ | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); }
+ | IL_ICMP_ECHO '{' icmpechoopts '}' ';'
+ | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); }
+ | IL_ICMP_TIMXCEED '{' exceed '}' ';'
+ | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); }
+ | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); }
+ | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';'
+ | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); }
+ | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); }
+ | IL_ICMP_IREQREPLY '{' data dataline '}' ';'
+ | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); }
+ | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); }
+ | IL_ICMP_MASKREPLY '{' token '}' ';'
+ | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); }
+ | IL_ICMP_PARAMPROB '{' paramprob '}' ';'
+ | IL_TOKEN ';' { set_icmptypetok(&$1); }
+ ;
+
+icmpechoopts:
+ | icmpechoopts icmpecho
+ ;
+
+icmpecho:
+ IL_ICMP_SEQ number { set_icmpseq($2); }
+ | IL_ICMP_ID number { set_icmpid($2); }
+ ;
+
+icmptsopts:
+ | icmptsopts icmpts ';'
+ ;
+
+icmpts: IL_ICMP_OTIME number { set_icmpotime($2); }
+ | IL_ICMP_RTIME number { set_icmprtime($2); }
+ | IL_ICMP_TTIME number { set_icmpttime($2); }
+ ;
+
+unreach:
+ IL_ICMP_UNREACH
+ | IL_ICMP_UNREACH '{' unreachopts '}' ';'
+ ;
+
+unreachopts:
+ IL_ICMP_UNREACH_NET line
+ | IL_ICMP_UNREACH_HOST line
+ | IL_ICMP_UNREACH_PROTOCOL line
+ | IL_ICMP_UNREACH_PORT line
+ | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); }
+ | IL_ICMP_UNREACH_SRCFAIL line
+ | IL_ICMP_UNREACH_NET_UNKNOWN line
+ | IL_ICMP_UNREACH_HOST_UNKNOWN line
+ | IL_ICMP_UNREACH_ISOLATED line
+ | IL_ICMP_UNREACH_NET_PROHIB line
+ | IL_ICMP_UNREACH_HOST_PROHIB line
+ | IL_ICMP_UNREACH_TOSNET line
+ | IL_ICMP_UNREACH_TOSHOST line
+ | IL_ICMP_UNREACH_FILTER_PROHIB line
+ | IL_ICMP_UNREACH_HOST_PRECEDENCE line
+ | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line
+ ;
+
+redirect:
+ IL_ICMP_REDIRECT
+ | IL_ICMP_REDIRECT '{' redirectopts '}' ';'
+ ;
+
+redirectopts:
+ | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); }
+ | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); }
+ | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); }
+ | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); }
+ ;
+
+exceed:
+ IL_ICMP_TIMXCEED_INTRANS line
+ | IL_ICMP_TIMXCEED_REASS line
+ ;
+
+paramprob:
+ IL_ICMP_PARAMPROB_OPTABSENT
+ | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg
+
+paraprobarg:
+ '{' number '}' ';' { set_icmppprob($2); }
+ ;
+
+ipv4opt: IL_V4OPT { new_ipv4opt(); }
+ ;
+
+ipv4optlist:
+ | ipv4opts ipv4optlist
+ ;
+
+ipv4opts:
+ IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); }
+ | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); }
+ | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); }
+ | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); }
+ | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); }
+ | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); }
+ | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); }
+ | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); }
+ | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); }
+ | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); }
+ | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); }
+ | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); }
+ | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); }
+ | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);}
+ | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); }
+ | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); }
+ | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); }
+ | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); }
+ | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); }
+ | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); }
+ ;
+
+secclass:
+ IL_IPS_RESERV4 ';' { set_secclass(&$1); }
+ | IL_IPS_TOPSECRET ';' { set_secclass(&$1); }
+ | IL_IPS_SECRET ';' { set_secclass(&$1); }
+ | IL_IPS_RESERV3 ';' { set_secclass(&$1); }
+ | IL_IPS_CONFID ';' { set_secclass(&$1); }
+ | IL_IPS_UNCLASS ';' { set_secclass(&$1); }
+ | IL_IPS_RESERV2 ';' { set_secclass(&$1); }
+ | IL_IPS_RESERV1 ';' { set_secclass(&$1); }
+ ;
+
+data: IL_DATA { new_data(); }
+ ;
+
+dataline:
+ '{' databody '}' ';' { end_data(); }
+ ;
+
+databody: dataopts
+ | dataopts databody
+ ;
+
+dataopts:
+ IL_DLEN token { set_datalen(&$2); }
+ | IL_DVALUE token { set_data(&$2); }
+ | IL_DFILE token { set_datafile(&$2); }
+ ;
+
+token: IL_TOKEN ';'
+ ;
+
+optoken: ';' { $$ = ""; }
+ | token
+ ;
+
+number: digits ';'
+ ;
+
+optnumber: ';' { $$ = 0; }
+ | number
+ ;
+
+digits: IL_NUMBER
+ | digits IL_NUMBER
+ ;
+%%
+
+struct statetoopt toipopts[] = {
+ { IL_IPO_NOP, IPOPT_NOP },
+ { IL_IPO_RR, IPOPT_RR },
+ { IL_IPO_ZSU, IPOPT_ZSU },
+ { IL_IPO_MTUP, IPOPT_MTUP },
+ { IL_IPO_MTUR, IPOPT_MTUR },
+ { IL_IPO_ENCODE, IPOPT_ENCODE },
+ { IL_IPO_TS, IPOPT_TS },
+ { IL_IPO_TR, IPOPT_TR },
+ { IL_IPO_SEC, IPOPT_SECURITY },
+ { IL_IPO_SECCLASS, IPOPT_SECURITY },
+ { IL_IPO_LSRR, IPOPT_LSRR },
+ { IL_IPO_ESEC, IPOPT_E_SEC },
+ { IL_IPO_CIPSO, IPOPT_CIPSO },
+ { IL_IPO_SATID, IPOPT_SATID },
+ { IL_IPO_SSRR, IPOPT_SSRR },
+ { IL_IPO_ADDEXT, IPOPT_ADDEXT },
+ { IL_IPO_VISA, IPOPT_VISA },
+ { IL_IPO_IMITD, IPOPT_IMITD },
+ { IL_IPO_EIP, IPOPT_EIP },
+ { IL_IPO_FINN, IPOPT_FINN },
+ { 0, 0 }
+};
+
+struct statetoopt tosecopts[] = {
+ { IL_IPS_RESERV4, IPSO_CLASS_RES4 },
+ { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS },
+ { IL_IPS_SECRET, IPSO_CLASS_SECR },
+ { IL_IPS_RESERV3, IPSO_CLASS_RES3 },
+ { IL_IPS_CONFID, IPSO_CLASS_CONF },
+ { IL_IPS_UNCLASS, IPSO_CLASS_UNCL },
+ { IL_IPS_RESERV2, IPSO_CLASS_RES2 },
+ { IL_IPS_RESERV1, IPSO_CLASS_RES1 },
+ { 0, 0 }
+};
+
+#ifdef bsdi
+struct ether_addr *
+ether_aton(s)
+ char *s;
+{
+ static struct ether_addr n;
+ u_int i[6];
+
+ if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
+ &i[2], &i[3], &i[4], &i[5]) == 6) {
+ n.ether_addr_octet[0] = (u_char)i[0];
+ n.ether_addr_octet[1] = (u_char)i[1];
+ n.ether_addr_octet[2] = (u_char)i[2];
+ n.ether_addr_octet[3] = (u_char)i[3];
+ n.ether_addr_octet[4] = (u_char)i[4];
+ n.ether_addr_octet[5] = (u_char)i[5];
+ return &n;
+ }
+ return NULL;
+}
+#endif
+
+
+struct in_addr getipv4addr(arg)
+char *arg;
+{
+ struct hostent *hp;
+ struct in_addr in;
+
+ in.s_addr = 0xffffffff;
+
+ if ((hp = gethostbyname(arg)))
+ bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr));
+ else
+ in.s_addr = inet_addr(arg);
+ return in;
+}
+
+
+u_short getportnum(pr, name)
+char *pr, *name;
+{
+ struct servent *sp;
+
+ if (!(sp = getservbyname(name, pr)))
+ return htons(atoi(name));
+ return sp->s_port;
+}
+
+
+struct ether_addr *geteaddr(arg, buf)
+char *arg;
+struct ether_addr *buf;
+{
+ struct ether_addr *e;
+
+#if !defined(hpux) && !defined(linux)
+ e = ether_aton(arg);
+ if (!e)
+ fprintf(stderr, "Invalid ethernet address: %s\n", arg);
+ else
+# ifdef __FreeBSD__
+ bcopy(e->octet, buf->octet, sizeof(e->octet));
+# else
+ bcopy(e->ether_addr_octet, buf->ether_addr_octet,
+ sizeof(e->ether_addr_octet));
+# endif
+ return e;
+#else
+ return NULL;
+#endif
+}
+
+
+void *new_header(type)
+int type;
+{
+ aniphdr_t *aip, *oip = canip;
+ int sz = 0;
+
+ aip = (aniphdr_t *)calloc(1, sizeof(*aip));
+ *aniptail = aip;
+ aniptail = &aip->ah_next;
+ aip->ah_p = type;
+ aip->ah_prev = oip;
+ canip = aip;
+
+ if (type == IPPROTO_UDP)
+ sz = sizeof(udphdr_t);
+ else if (type == IPPROTO_TCP)
+ sz = sizeof(tcphdr_t);
+ else if (type == IPPROTO_ICMP)
+ sz = sizeof(icmphdr_t);
+ else if (type == IPPROTO_IP)
+ sz = sizeof(ip_t);
+
+ if (oip)
+ canip->ah_data = oip->ah_data + oip->ah_len;
+ else
+ canip->ah_data = (char *)ipbuffer;
+
+ /*
+ * Increase the size fields in all wrapping headers.
+ */
+ for (aip = aniphead; aip; aip = aip->ah_next) {
+ aip->ah_len += sz;
+ if (aip->ah_p == IPPROTO_IP)
+ aip->ah_ip->ip_len += sz;
+ else if (aip->ah_p == IPPROTO_UDP)
+ aip->ah_udp->uh_ulen += sz;
+ }
+ return (void *)canip->ah_data;
+}
+
+
+void free_aniplist()
+{
+ aniphdr_t *aip, **aipp = &aniphead;
+
+ while ((aip = *aipp)) {
+ *aipp = aip->ah_next;
+ free(aip);
+ }
+ aniptail = &aniphead;
+}
+
+
+void inc_anipheaders(inc)
+int inc;
+{
+ aniphdr_t *aip;
+
+ for (aip = aniphead; aip; aip = aip->ah_next) {
+ aip->ah_len += inc;
+ if (aip->ah_p == IPPROTO_IP)
+ aip->ah_ip->ip_len += inc;
+ else if (aip->ah_p == IPPROTO_UDP)
+ aip->ah_udp->uh_ulen += inc;
+ }
+}
+
+
+void new_data()
+{
+ (void) new_header(-1);
+ canip->ah_len = 0;
+}
+
+
+void set_datalen(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_data(arg)
+char **arg;
+{
+ u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c;
+ int len = 0, todo = 0, quote = 0, val = 0;
+
+ while ((c = *s++)) {
+ if (todo) {
+ if (isdigit(c)) {
+ todo--;
+ if (c > '7') {
+ fprintf(stderr, "octal with %c!\n", c);
+ break;
+ }
+ val <<= 3;
+ val |= (c - '0');
+ }
+ if (!isdigit(c) || !todo) {
+ *t++ = (u_char)(val & 0xff);
+ todo = 0;
+ }
+ }
+ if (quote) {
+ if (isdigit(c)) {
+ todo = 2;
+ if (c > '7') {
+ fprintf(stderr, "octal with %c!\n", c);
+ break;
+ }
+ val = (c - '0');
+ } else {
+ switch (c)
+ {
+ case '\"' :
+ *t++ = '\"';
+ break;
+ case '\\' :
+ *t++ = '\\';
+ break;
+ case 'n' :
+ *t++ = '\n';
+ break;
+ case 'r' :
+ *t++ = '\r';
+ break;
+ case 't' :
+ *t++ = '\t';
+ break;
+ }
+ quote = 0;
+ }
+ continue;
+ }
+
+ if (c == '\\')
+ quote = 1;
+ else
+ *t++ = c;
+ }
+ if (quote)
+ *t++ = '\\';
+ len = t - (u_char *)canip->ah_data;
+ inc_anipheaders(len - canip->ah_len);
+ canip->ah_len = len;
+}
+
+
+void set_datafile(arg)
+char **arg;
+{
+ struct stat sb;
+ char *file = *arg;
+ int fd, len;
+
+ if ((fd = open(file, O_RDONLY)) == -1) {
+ perror("open");
+ exit(-1);
+ }
+
+ if (fstat(fd, &sb) == -1) {
+ perror("fstat");
+ exit(-1);
+ }
+
+ if ((sb.st_size + aniphead->ah_len ) > 65535) {
+ fprintf(stderr, "data file %s too big to include.\n", file);
+ close(fd);
+ return;
+ }
+ if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) {
+ perror("read");
+ close(fd);
+ return;
+ }
+ inc_anipheaders(len);
+ canip->ah_len += len;
+ close(fd);
+}
+
+
+void new_packet()
+{
+ static u_short id = 0;
+
+ if (!aniphead)
+ bzero((char *)ipbuffer, sizeof(ipbuffer));
+
+ ip = (ip_t *)new_header(IPPROTO_IP);
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = sizeof(ip_t) >> 2;
+ ip->ip_len = sizeof(ip_t);
+ ip->ip_ttl = 63;
+ ip->ip_id = htons(id++);
+}
+
+
+void set_ipv4proto(arg)
+char **arg;
+{
+ struct protoent *pr;
+
+ if ((pr = getprotobyname(*arg)))
+ ip->ip_p = pr->p_proto;
+ else
+ if (!(ip->ip_p = atoi(*arg)))
+ fprintf(stderr, "unknown protocol %s\n", *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4src(arg)
+char **arg;
+{
+ ip->ip_src = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4dst(arg)
+char **arg;
+{
+ ip->ip_dst = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4off(arg)
+char **arg;
+{
+ ip->ip_off = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4v(arg)
+char **arg;
+{
+ ip->ip_v = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4hl(arg)
+char **arg;
+{
+ int newhl, inc;
+
+ newhl = strtol(*arg, NULL, 0);
+ inc = (newhl - ip->ip_hl) << 2;
+ ip->ip_len += inc;
+ ip->ip_hl = newhl;
+ canip->ah_len += inc;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4ttl(arg)
+char **arg;
+{
+ ip->ip_ttl = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4tos(arg)
+char **arg;
+{
+ ip->ip_tos = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4id(arg)
+char **arg;
+{
+ ip->ip_id = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4sum(arg)
+char **arg;
+{
+ ip->ip_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4len(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len - ip->ip_len);
+ ip->ip_len = len;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_tcpheader()
+{
+
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) {
+ fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_TCP;
+
+ tcp = (tcphdr_t *)new_header(IPPROTO_TCP);
+ tcp->th_win = 4096;
+ tcp->th_off = sizeof(*tcp) >> 2;
+}
+
+
+void set_tcpsport(arg)
+char **arg;
+{
+ u_short *port;
+ char *pr;
+
+ if (ip->ip_p == IPPROTO_UDP) {
+ port = &udp->uh_sport;
+ pr = "udp";
+ } else {
+ port = &tcp->th_sport;
+ pr = "udp";
+ }
+
+ *port = getportnum(pr, *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpdport(arg)
+char **arg;
+{
+ u_short *port;
+ char *pr;
+
+ if (ip->ip_p == IPPROTO_UDP) {
+ port = &udp->uh_dport;
+ pr = "udp";
+ } else {
+ port = &tcp->th_dport;
+ pr = "udp";
+ }
+
+ *port = getportnum(pr, *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpseq(arg)
+char **arg;
+{
+ tcp->th_seq = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpack(arg)
+char **arg;
+{
+ tcp->th_ack = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpoff(arg)
+char **arg;
+{
+ int off;
+
+ off = strtol(*arg, NULL, 0);
+ inc_anipheaders((off - tcp->th_off) << 2);
+ tcp->th_off = off;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpurp(arg)
+char **arg;
+{
+ tcp->th_urp = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpwin(arg)
+char **arg;
+{
+ tcp->th_win = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpsum(arg)
+char **arg;
+{
+ tcp->th_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpflags(arg)
+char **arg;
+{
+ static char flags[] = "ASURPF";
+ static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH,
+ TH_FIN } ;
+ char *s, *t;
+
+ for (s = *arg; *s; s++)
+ if (!(t = strchr(flags, *s))) {
+ if (s - *arg) {
+ fprintf(stderr, "unknown TCP flag %c\n", *s);
+ break;
+ }
+ tcp->th_flags = strtol(*arg, NULL, 0);
+ break;
+ } else
+ tcp->th_flags |= flagv[t - flags];
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpopt(state, arg)
+int state;
+char **arg;
+{
+ u_char *s;
+ int val, len, val2, pad, optval;
+
+ if (arg && *arg)
+ val = atoi(*arg);
+ else
+ val = 0;
+
+ s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen;
+ switch (state)
+ {
+ case IL_TCPO_EOL :
+ optval = 0;
+ len = 1;
+ break;
+ case IL_TCPO_NOP :
+ optval = 1;
+ len = 1;
+ break;
+ case IL_TCPO_MSS :
+ optval = 2;
+ len = 4;
+ break;
+ case IL_TCPO_WSCALE :
+ optval = 3;
+ len = 3;
+ break;
+ case IL_TCPO_TS :
+ optval = 8;
+ len = 10;
+ break;
+ default :
+ optval = 0;
+ len = 0;
+ break;
+ }
+
+ if (len > 1) {
+ /*
+ * prepend padding - if required.
+ */
+ if (len & 3)
+ for (pad = 4 - (len & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ /*
+ * build tcp option
+ */
+ *s++ = (u_char)optval;
+ *s++ = (u_char)len;
+ if (len > 2) {
+ if (len == 3) { /* 1 byte - char */
+ *s++ = (u_char)val;
+ } else if (len == 4) { /* 2 bytes - short */
+ *s++ = (u_char)((val >> 8) & 0xff);
+ *s++ = (u_char)(val & 0xff);
+ } else if (len >= 6) { /* 4 bytes - long */
+ val2 = htonl(val);
+ bcopy((char *)&val2, s, 4);
+ }
+ s += (len - 2);
+ }
+ } else
+ *s++ = (u_char)optval;
+
+ canip->ah_lastopt = optval;
+ canip->ah_optlen += len;
+
+ if (arg && *arg) {
+ free(*arg);
+ *arg = NULL;
+ }
+}
+
+
+void end_tcpopt()
+{
+ int pad;
+ char *s = (char *)tcp;
+
+ s += sizeof(*tcp) + canip->ah_optlen;
+ /*
+ * pad out so that we have a multiple of 4 bytes in size fo the
+ * options. make sure last byte is EOL.
+ */
+ if (canip->ah_optlen & 3) {
+ if (canip->ah_lastopt != 1) {
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ canip->ah_optlen++;
+ } else {
+ s -= 1;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ }
+ *s++ = 0;
+ }
+ tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2;
+ inc_anipheaders(canip->ah_optlen);
+}
+
+
+void new_udpheader()
+{
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) {
+ fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_UDP;
+
+ udp = (udphdr_t *)new_header(IPPROTO_UDP);
+ udp->uh_ulen = sizeof(*udp);
+}
+
+
+void set_udplen(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len - udp->uh_ulen);
+ udp->uh_ulen = len;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_udpsum(arg)
+char **arg;
+{
+ udp->uh_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void prep_packet()
+{
+ iface_t *ifp;
+ struct in_addr gwip;
+
+ ifp = sending.snd_if;
+ if (!ifp) {
+ fprintf(stderr, "no interface defined for sending!\n");
+ return;
+ }
+ if (ifp->if_fd == -1)
+ ifp->if_fd = initdevice(ifp->if_name, 0, 5);
+ gwip = sending.snd_gw;
+ if (!gwip.s_addr)
+ gwip = aniphead->ah_ip->ip_dst;
+ (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2);
+}
+
+
+void packet_done()
+{
+ char outline[80];
+ int i, j, k;
+ u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline;
+
+ if (opts & OPT_VERBOSE) {
+ for (i = ip->ip_len, j = 0; i; i--, j++, s++) {
+ if (j && !(j & 0xf)) {
+ *t++ = '\n';
+ *t = '\0';
+ fputs(outline, stdout);
+ fflush(stdout);
+ t = (u_char *)outline;
+ *t = '\0';
+ }
+ sprintf((char *)t, "%02x", *s & 0xff);
+ t += 2;
+ if (!((j + 1) & 0xf)) {
+ s -= 15;
+ sprintf((char *)t, " ");
+ t += 8;
+ for (k = 16; k; k--, s++)
+ *t++ = (isprint(*s) ? *s : '.');
+ s--;
+ }
+
+ if ((j + 1) & 0xf)
+ *t++ = ' ';;
+ }
+
+ if (j & 0xf) {
+ for (k = 16 - (j & 0xf); k; k--) {
+ *t++ = ' ';
+ *t++ = ' ';
+ *t++ = ' ';
+ }
+ sprintf((char *)t, " ");
+ t += 7;
+ s -= j & 0xf;
+ for (k = j & 0xf; k; k--, s++)
+ *t++ = (isprint(*s) ? *s : '.');
+ *t++ = '\n';
+ *t = '\0';
+ }
+ fputs(outline, stdout);
+ fflush(stdout);
+ }
+
+ prep_packet();
+ free_aniplist();
+}
+
+
+void new_interface()
+{
+ cifp = (iface_t *)calloc(1, sizeof(iface_t));
+ *iftail = cifp;
+ iftail = &cifp->if_next;
+ cifp->if_fd = -1;
+}
+
+
+void check_interface()
+{
+ if (!cifp->if_name || !*cifp->if_name)
+ fprintf(stderr, "No interface name given!\n");
+ if (!cifp->if_MTU || !*cifp->if_name)
+ fprintf(stderr, "Interface %s has an MTU of 0!\n",
+ cifp->if_name);
+}
+
+
+void set_ifname(arg)
+char **arg;
+{
+ cifp->if_name = *arg;
+ *arg = NULL;
+}
+
+
+void set_ifmtu(arg)
+int arg;
+{
+ cifp->if_MTU = arg;
+}
+
+
+void set_ifv4addr(arg)
+char **arg;
+{
+ cifp->if_addr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ifeaddr(arg)
+char **arg;
+{
+ (void) geteaddr(*arg, &cifp->if_eaddr);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_arp()
+{
+ carp = (arp_t *)calloc(1, sizeof(arp_t));
+ *arptail = carp;
+ arptail = &carp->arp_next;
+}
+
+
+void set_arpeaddr(arg)
+char **arg;
+{
+ (void) geteaddr(*arg, &carp->arp_eaddr);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_arpv4addr(arg)
+char **arg;
+{
+ carp->arp_addr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void reset_send()
+{
+ sending.snd_if = iflist;
+ sending.snd_gw = defrouter;
+}
+
+
+void set_sendif(arg)
+char **arg;
+{
+ iface_t *ifp;
+
+ for (ifp = iflist; ifp; ifp = ifp->if_next)
+ if (ifp->if_name && !strcmp(ifp->if_name, *arg))
+ break;
+ sending.snd_if = ifp;
+ if (!ifp)
+ fprintf(stderr, "couldn't find interface %s\n", *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_sendvia(arg)
+char **arg;
+{
+ sending.snd_gw = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_defaultrouter(arg)
+char **arg;
+{
+ defrouter = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_icmpheader()
+{
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) {
+ fprintf(stderr, "protocol %d specified with ICMP!\n",
+ ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_ICMP;
+ icmp = (icmphdr_t *)new_header(IPPROTO_ICMP);
+}
+
+
+void set_icmpcode(code)
+int code;
+{
+ icmp->icmp_code = code;
+}
+
+
+void set_icmptype(type)
+int type;
+{
+ icmp->icmp_type = type;
+}
+
+
+static char *icmpcodes[] = {
+ "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail",
+ "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib",
+ "net-tos", "host-tos", NULL };
+
+void set_icmpcodetok(code)
+char **code;
+{
+ char *s;
+ int i;
+
+ for (i = 0; (s = icmpcodes[i]); i++)
+ if (!strcmp(s, *code)) {
+ icmp->icmp_code = i;
+ break;
+ }
+ if (!s)
+ fprintf(stderr, "unknown ICMP code %s\n", *code);
+ free(*code);
+ *code = NULL;
+}
+
+
+static char *icmptypes[] = {
+ "echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
+ "redir", (char *)NULL, (char *)NULL, "echo", (char *)NULL,
+ (char *)NULL, "timex", "paramprob", "timest", "timestrep",
+ "inforeq", "inforep", "maskreq", "maskrep", "END"
+};
+
+void set_icmptypetok(type)
+char **type;
+{
+ char *s;
+ int i, done = 0;
+
+ for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++)
+ if (s && !strcmp(s, *type)) {
+ icmp->icmp_type = i;
+ done = 1;
+ break;
+ }
+ if (!done)
+ fprintf(stderr, "unknown ICMP type %s\n", *type);
+ free(*type);
+ *type = NULL;
+}
+
+
+void set_icmpid(arg)
+int arg;
+{
+ icmp->icmp_id = arg;
+}
+
+
+void set_icmpseq(arg)
+int arg;
+{
+ icmp->icmp_seq = arg;
+}
+
+
+void set_icmpotime(arg)
+int arg;
+{
+ icmp->icmp_otime = arg;
+}
+
+
+void set_icmprtime(arg)
+int arg;
+{
+ icmp->icmp_rtime = arg;
+}
+
+
+void set_icmpttime(arg)
+int arg;
+{
+ icmp->icmp_ttime = arg;
+}
+
+
+void set_icmpmtu(arg)
+int arg;
+{
+#if BSD >= 199306
+ icmp->icmp_nextmtu = arg;
+#endif
+}
+
+
+void set_redir(redir, arg)
+int redir;
+char **arg;
+{
+ icmp->icmp_code = redir;
+ icmp->icmp_gwaddr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_icmppprob(num)
+int num;
+{
+ icmp->icmp_pptr = num;
+}
+
+
+void new_ipv4opt()
+{
+ new_header(-2);
+}
+
+
+void add_ipopt(state, ptr)
+int state;
+void *ptr;
+{
+ struct ipopt_names *io;
+ struct statetoopt *sto;
+ char numbuf[16], *arg, **param = ptr;
+ int inc, hlen;
+
+ if (state == IL_IPO_RR || state == IL_IPO_SATID) {
+ if (param)
+ sprintf(numbuf, "%d", *(int *)param);
+ else
+ strcpy(numbuf, "0");
+ arg = numbuf;
+ } else
+ arg = param ? *param : NULL;
+
+ if (canip->ah_next) {
+ fprintf(stderr, "cannot specify options after data body\n");
+ return;
+ }
+ for (sto = toipopts; sto->sto_st; sto++)
+ if (sto->sto_st == state)
+ break;
+ if (!sto || !sto->sto_st) {
+ fprintf(stderr, "No mapping for state %d to IP option\n",
+ state);
+ return;
+ }
+
+ hlen = sizeof(ip_t) + canip->ah_optlen;
+ for (io = ionames; io->on_name; io++)
+ if (io->on_value == sto->sto_op)
+ break;
+ canip->ah_lastopt = io->on_value;
+
+ if (io->on_name) {
+ inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg);
+ if (inc > 0) {
+ while (inc & 3) {
+ ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP;
+ canip->ah_lastopt = IPOPT_NOP;
+ inc++;
+ }
+ hlen += inc;
+ }
+ }
+
+ canip->ah_optlen = hlen - sizeof(ip_t);
+
+ if (state != IL_IPO_RR && state != IL_IPO_SATID)
+ if (param && *param) {
+ free(*param);
+ *param = NULL;
+ }
+ sclass = NULL;
+}
+
+
+void end_ipopt()
+{
+ int pad;
+ char *s, *buf = (char *)ip;
+
+ /*
+ * pad out so that we have a multiple of 4 bytes in size fo the
+ * options. make sure last byte is EOL.
+ */
+ if (canip->ah_lastopt == IPOPT_NOP) {
+ buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL;
+ } else if (canip->ah_lastopt != IPOPT_EOL) {
+ s = buf + sizeof(*ip) + canip->ah_optlen;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = IPOPT_NOP;
+ *s = IPOPT_EOL;
+ canip->ah_optlen++;
+ }
+ canip->ah_optlen++;
+ } else {
+ s = buf + sizeof(*ip) + canip->ah_optlen - 1;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = IPOPT_NOP;
+ *s = IPOPT_EOL;
+ canip->ah_optlen++;
+ }
+ }
+ ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2;
+ inc_anipheaders(canip->ah_optlen);
+ free_anipheader();
+}
+
+
+void set_secclass(arg)
+char **arg;
+{
+ sclass = *arg;
+ *arg = NULL;
+}
+
+
+void free_anipheader()
+{
+ aniphdr_t *aip;
+
+ aip = canip;
+ if ((canip = aip->ah_prev)) {
+ canip->ah_next = NULL;
+ aniptail = &canip->ah_next;
+ }
+
+ if (canip)
+ free(aip);
+}
+
+
+void end_ipv4()
+{
+ aniphdr_t *aip;
+
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ free_anipheader();
+ for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_IP)
+ ip = aip->ah_ip;
+}
+
+
+void end_icmp()
+{
+ aniphdr_t *aip;
+
+ icmp->icmp_cksum = 0;
+ icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len);
+ free_anipheader();
+ for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_ICMP)
+ icmp = aip->ah_icmp;
+}
+
+
+void end_udp()
+{
+ u_long sum;
+ aniphdr_t *aip;
+ ip_t iptmp;
+
+ bzero((char *)&iptmp, sizeof(iptmp));
+ iptmp.ip_p = ip->ip_p;
+ iptmp.ip_src = ip->ip_src;
+ iptmp.ip_dst = ip->ip_dst;
+ iptmp.ip_len = ip->ip_len - (ip->ip_hl << 2);
+ sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
+ udp->uh_sum = c_chksum((u_short *)udp, (u_int)iptmp.ip_len, sum);
+ free_anipheader();
+ for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_UDP)
+ udp = aip->ah_udp;
+}
+
+
+void end_tcp()
+{
+ u_long sum;
+ aniphdr_t *aip;
+ ip_t iptmp;
+
+ bzero((char *)&iptmp, sizeof(iptmp));
+ iptmp.ip_p = ip->ip_p;
+ iptmp.ip_src = ip->ip_src;
+ iptmp.ip_dst = ip->ip_dst;
+ iptmp.ip_len = ip->ip_len - (ip->ip_hl << 2);
+ sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
+ tcp->th_sum = 0;
+ tcp->th_sum = c_chksum((u_short *)tcp, (u_int)iptmp.ip_len, sum);
+ free_anipheader();
+ for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_TCP)
+ tcp = aip->ah_tcp;
+}
+
+
+void end_data()
+{
+ free_anipheader();
+}
+
+
+void iplang(fp)
+FILE *fp;
+{
+ yyin = fp;
+
+ yydebug = (opts & OPT_DEBUG) ? 1 : 0;
+
+ while (!feof(fp))
+ yyparse();
+}
+
+
+u_short c_chksum(buf, len, init)
+u_short *buf;
+u_int len;
+u_long init;
+{
+ u_long sum = init;
+ int nwords = len >> 1;
+
+ for(; nwords > 0; nwords--)
+ sum += *buf++;
+ sum = (sum>>16) + (sum & 0xffff);
+ sum += (sum >>16);
+ return (~sum);
+}
+
+
+u_long p_chksum(buf,len)
+u_short *buf;
+u_int len;
+{
+ u_long sum = 0;
+ int nwords = len >> 1;
+
+ for(; nwords > 0; nwords--)
+ sum += *buf++;
+ return sum;
+}
diff --git a/usr.sbin/ipsend/ipsend/ipsend.1 b/usr.sbin/ipsend/ipsend/ipsend.1
new file mode 100644
index 00000000000..8acb6821060
--- /dev/null
+++ b/usr.sbin/ipsend/ipsend/ipsend.1
@@ -0,0 +1,110 @@
+.\" $OpenBSD: ipsend.1,v 1.1 1998/01/26 04:17:03 dgregor Exp $
+.TH IPSEND 1
+.SH NAME
+ipsend \- sends IP packets
+.SH SYNOPSIS
+.B ipsend
+[
+.B \-dITUv
+] [
+.B \-i
+<interface>
+] [
+.B \-f
+<\fIoffset\fP>
+] [
+.B \-g
+<\fIgateway\fP>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-o
+<\fIoption\fP>
+] [
+.B \-P
+<protocol>
+] [
+.B \-s
+<\fIsource\fP>
+] [
+.B \-t
+<\fIdest. port\fP>
+] [
+.B \-w
+<\fIwindow\fP>
+] <destination> [TCP-flags]
+.SH DESCRIPTION
+.PP
+\fBipsend\fP can be compiled in two ways. The first is used to send one-off
+packets to a destination host, using command line options to specify various
+attributes present in the headers. The \fIdestination\fP must be given as
+the last command line option, except for when TCP flags are specified as
+a combination of A, S, F, U, P and R, last.
+.PP
+The other way it may be compiled, with DOSOCKET defined, is to allow an
+attempt at making a TCP connection using a with ipsend resending the SYN
+packet as per the command line options.
+.SH OPTIONS
+.TP
+.BR \-d
+enable debugging mode.
+.TP
+.BR \-f \0<offset>
+The \fI-f\fP allows the IP offset field in the IP header to be set to an
+arbitrary value, which can be specified in decimal or hexidecimal.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-i \0<interface>
+Set the interface name to be the name supplied.
+.TP
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.BR \-o \0<option>
+Specify options to be included at the end of the IP header. An EOL option
+is automatically appended and need not be given. If an option would also
+have data associated with it (source as an IP# for a lsrr option), then
+this will not be initialised.
+.TP
+.BR \-s \0<source>
+Set the source address in the packet to that provided - maybe either a
+hostname or IP#.
+.TP
+.BR \-t \0<dest. port>
+Set the destination port for TCP/UDP packets.
+.TP
+.BR \-w \0<window>
+Set the window size for TCP packets.
+.TP
+.B \-I
+Set the protocol to ICMP.
+.TP
+.B \-P <protocol>
+Set the protocol to the value given. If the parameter is a name, the name
+is looked up in the \fI/etc/protocols\fP file.
+.TP
+.B \-T
+Set the protocol to TCP.
+.TP
+.B \-U
+Set the protocol to UDP.
+.TP
+.BR \-d
+enable verbose mode.
+.DT
+.SH SEE ALSO
+ipsend(1), ipresend(1), iptest(1), protocols(4), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+If you find any, please send email to me at darrenr@cyber.com.au
diff --git a/usr.sbin/ipsend/ipsend/ipsend.5 b/usr.sbin/ipsend/ipsend/ipsend.5
new file mode 100644
index 00000000000..dae402b4f05
--- /dev/null
+++ b/usr.sbin/ipsend/ipsend/ipsend.5
@@ -0,0 +1,399 @@
+.\" $OpenBSD: ipsend.5,v 1.1 1998/01/26 04:17:03 dgregor Exp $
+.TH IPSEND 5
+.SH NAME
+ipsend \- IP packet description language
+.SH DESCRIPTION
+The \fBipsend\fP program expects, with the \fB-L\fP option, input to be a
+text file which fits the grammar described below. The purpose of this
+grammar is to allow IP packets to be described in an arbitary way which
+also allows encapsulation to be so done to an arbitary level.
+.SH GRAMMAR
+.LP
+.nf
+line ::= iface | arp | send | defrouter | ipv4line .
+
+iface ::= ifhdr "{" ifaceopts "}" ";" .
+ifhdr ::= "interface" | "iface" .
+ifaceopts ::= "ifname" name | "mtu" mtu | "v4addr" ipaddr |
+ "eaddr" eaddr .
+
+send ::= "send" ";" | "send" "{" sendbodyopts "}" ";" .
+sendbodyopts ::= sendbody [ sendbodyopts ] .
+sendbody ::= "ifname" name | "via" ipaddr .
+
+defrouter ::= "router" ipaddr .
+
+arp ::= "arp" "{" arpbodyopts "}" ";" .
+arpbodyopts ::= arpbody [ arpbodyopts ] .
+arpbody ::= "v4addr" ipaddr | "eaddr" eaddr .
+
+bodyline ::= ipv4line | tcpline | udpline | icmpline | dataline .
+
+ipv4line ::= "ipv4" "{" ipv4bodyopts "}" ";" .
+ipv4bodyopts ::= ipv4body [ ipv4bodyopts ] | bodyline .
+ipv4body ::= "proto" protocol | "src" ipaddr | "dst" ipaddr |
+ "off" number | "v" number | "hl" number| "id" number |
+ "ttl" number | "tos" number | "sum" number | "len" number |
+ "opt" "{" ipv4optlist "}" ";" .
+ipv4optlist ::= ipv4option [ ipv4optlist ] .
+ipv4optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
+ "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" |
+ "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" |
+ "secclass" ipv4secclass.
+ipv4secclass := "unclass" | "confid" | "reserv-1" | "reserv-2" |
+ "reserv-3" | "reserv-4" | "secret" | "topsecret" .
+
+tcpline ::= "tcp" "{" tcpbodyopts "}" ";" .
+tcpbodyopts ::= tcpbody [ tcpbodyopts ] | bodyline .
+tcpbody ::= "sport" port | "dport" port | "seq" number | "ack" number |
+ "off" number | "urp" number | "win" number | "sum" number |
+ "flags" tcpflags | data .
+
+udpline ::= "udp" "{" udpbodyopts "}" ";" .
+udpbodyopts ::= udpbody [ udpbodyopts ] | bodyline .
+udpbody ::= "sport" port | "dport" port | "len" number | "sum" number |
+ data .
+
+icmpline ::= "icmp" "{" icmpbodyopts "}" ";" .
+icmpbodyopts ::= icmpbody [ icmpbodyopts ] | bodyline .
+icmpbody ::= "type" icmptype [ "code" icmpcode ] .
+icmptype ::= "echorep" | "echorep" "{" echoopts "}" ";" | "unreach" |
+ "unreach" "{" unreachtype "}" ";" | "squench" | "redir" |
+ "redir" "{" redirtype "}" ";" | "echo" "{" echoopts "}" ";" |
+ "echo" | "routerad" | "routersol" | "timex" |
+ "timex" "{" timextype "}" ";" | "paramprob" |
+ "paramprob" "{" parapptype "}" ";" | "timest" | "timestrep" |
+ "inforeq" | "inforep" | "maskreq" | "maskrep" .
+
+echoopts ::= echoopts [ icmpechoopts ] .
+unreachtype ::= "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
+ "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
+ "net-prohib" | "host-prohib" | "net-tos" | "host-tos" |
+ "filter-prohib" | "host-preced" | "cutoff-preced" .
+redirtype ::= "net-redir" | "host-redir" | "tos-net-redir" |
+ "tos-host-redir" .
+timextype ::= "intrans" | "reass" .
+paramptype ::= "optabsent" .
+
+data ::= "data" "{" databodyopts "}" ";" .
+databodyopts ::= "len" number | "value" string | "file" filename .
+
+icmpechoopts ::= "icmpseq" number | "icmpid" number .
+.fi
+.SH COMMANDS
+.PP
+Before sending any packets or defining any packets, it is necessary to
+describe the interface(s) which will be used to send packets out.
+.TP
+.B interface
+is used to describe a network interface. The description included need
+not match the actual configuration currently employed by the operating
+system.
+.TP
+.B send
+is used to actually send out a packet across the network. If the
+destination is not specified, it will attempt to send the packet
+directly out on the network to the destination without routing it.
+.TP
+.B router
+configures the default router for ipsend, as distinct from the default
+route installed in the kernel.
+.TP
+.B ipv4
+is used to describe an IP (version 4) packet. IP header fields can be
+specified, including options, followed by a data section which may contain
+further protocol headers.
+.SH IPV4
+.TP
+.B hl <number>
+manually specifies the IP header length (automatically adjusts with the
+presence of IP options and defaults to 5);
+.TP
+.B v <number>
+set the IP version. Default is 4.
+.TP
+.B tos <number>
+set the type of service (TOS) field in the IP header. Default is 0.
+.TP
+.B len <number>
+manually specifies the length of the IP packet. The length will automatically
+be adjusted to accomodate data or further protocol headers.
+.TP
+.B off <number>
+sets the fragment offset field of the IP packet. Default is 0.
+.TP
+.B ttl <number>
+sets the time to live (TTL) field of the IP header. Default is 60.
+.TP
+.B proto <protocol>
+sets the protocol field of the IP header. The protocol can either be a
+number or a name found in \fB/etc/protocols\fP.
+.TP
+.B sum
+manually specifies the checksum for the IP header. If left unset (0), it
+will be calculated prior to being sent.
+.TP
+.B src
+manually specifies the source address of the IP header. If left unset, it
+will default to the host's IP address.
+.TP
+.B dst
+sets the destination of the IP packet. The default is 0.0.0.0.
+.TP
+.B opt
+is used to include IP options in the IP header.
+.TP
+.B tcp
+is used to indicate the a TCP protocol header is to follow. See the \fBTCP\fP
+section for TCP header options.
+.TP
+.B udp
+is used to indicate the a UDP protocol header is to follow. See the \fBUDP\fP
+section for UDP header options.
+.TP
+.B icmp
+is used to indicate the a ICMP protocol header is to follow. See the
+\fBICMP\fP section for ICMP header options.
+.TP
+.B data
+is used to indicate that raw data is to be included in the IP packet. See the
+\fBDATA\fP section for details on options available.
+.SH "IPv4 Options"
+these keywords indicate that the releveant IP option should be added to the
+IP header (the header length field will be adjusted appropriately).
+.TP
+.B nop
+No Operation [RFC 791] (space filler).
+.TP
+.B rr <number>
+Record Router [RFC 791]. The number given specifies the number of
+\fBbytes\fP to be used for storage. This should be a multiple of 4 for
+proper operation.
+.TP
+.B zsu
+Experimental Measurement.
+.TP
+.B mtup [RFC 1191].
+MTU Probe.
+.TP
+.B mtur [RFC 1191].
+MTU Ready.
+.TP
+.B encode
+.TP
+.B ts
+Timestamp [RFC 791].
+.TP
+.B tr
+Traceroute [RFC 1393].
+.TP
+.B "sec-class <security-level>, sec"
+Security [RFC 1108]. This option specifies the security label for the packet.
+Using \fBsec\fP sets up the framework of the security option but unless
+\fBsec-class\fP is given, the level may not be set.
+.TP
+.B "lsrr <ip-address>"
+Loose Source Route [RFC 791].
+.TP
+.B e-sec
+Extended Security [RFC 1108].
+.TP
+.B cipso
+Commercial Security.
+.TP
+.B satid
+Stream ID [RFC 791].
+.TP
+.B "ssrr <ip-address>"
+Strict Source Route [RFC 791].
+.TP
+.B addext
+Address Extension
+.TP
+.B visa
+Expermental Access Control.
+.TP
+.B imitd
+IMI Traffic Descriptor.
+.TP
+.B eip
+[RFC 1358].
+.TP
+.B finn
+Experimental Flow Control.
+.SH TCP
+.TP
+.B sport <port>
+sets the source port to the number/name given. Default is 0.
+.TP
+.B dport <port>
+sets the destination port to the number/name given. Default is 0.
+.TP
+.B seq <number>
+sets the sequence number to the number specified. Default is 0.
+.TP
+.B ack <number>
+sets the acknowledge number to the number specified. Default is 0.
+.TP
+.B off <number>
+sets the offset value for the start of data to the number specified. This
+implies the size of the TCP header. It is automatically adjusted if TCP
+options are included and defaults to 5.
+.TP
+.B urp <number>
+sets the value of the urgent data pointer to the number specified. Default
+is 0.
+.TP
+.B win <number>
+sets the size of the TCP window to the number specified. Default is 4096.
+.TP
+.B sum <number>
+manually specifies the checksum for the TCP pseudo-header and data. If left
+unset, it defaults to 0 and is automatically calculated.
+.TP
+.B flags <tcp-flags>
+sets the TCP flags field to match the flags specified. Valid flags are
+"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH).
+.TP
+.B opt
+indicates that TCP header options follow. As TCP options are added to the
+TCP header, the \fBoff\fP field is updated to match.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH "TCP options"
+With a TCP header, it is possible to append a number of header options.
+The TCP header offset will be updated automatically to reflect the change
+in size. The valid options are: \fBnop\fP No Operation,
+\fBeol\fP End Of (option) List, \fBmss [ size ]\fP Maximum Segment Size - this
+sets the maximum receivable size of a packet containing data,
+\fBwscale\fP Window Scale, \fBts\fP Timestamp.
+.SH UDP
+.TP
+.B sport <port>
+sets the source port to the number/name given. Default is 0.
+.TP
+.B dport <port>
+sets the destination port to the number/name given. Default is 0.
+.TP
+.B len <number>
+manually specifies the length of the UDP header and data. If left unset,
+it is automatically adjusted to match the header presence and any data if
+present.
+.TP
+.B sum <number>
+manually specifies the checksum for the UDP pseudo-header and data. If left
+unset, it defaults to 0 and is automatically calculated.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH ICMP
+.TP
+.B type <icmptype>
+sets the ICMP type according the to the icmptype tag. This may either be
+a number or one of the recognised tags (see the \fBICMP TYPES\fP section for a
+list of names recognised).
+.TP
+.B code <icmpcode>
+sets the ICMP code.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH DATA
+Each of the following extend the packet in a different way. \fBLen\fP just
+increases the length (without adding any content), \fBvalue\fP uses a string
+and \fBfile\fP a file.
+.TP
+.B len <number>
+extend the length of the packet by \fBnumber\fP bytes (without filling those
+bytes with any particular data).
+.TP
+.B value <string>
+indicates that the string provided should be added to the current packet as
+data. A string may be a consecutive list of characters and numbers (with
+no white spaces) or bounded by "'s (may not contain them, even if \\'d).
+The \\ charcater is recognised with the appropriate C escaped values, including
+octal numbers.
+.TP
+.B file <filename>
+reads data in from the specified file and appends it to the current packet.
+If the new total length would exceed 64k, an error will be reported.
+.SH "ICMP TYPES"
+.TP
+.B echorep
+Eecho Reply.
+.TP
+.B "unreach [ unreachable-code ]"
+Generic Unreachable error. This is used to indicate that an error has
+occurred whilst trying to send the packet across the network and that the
+destination cannot be reached. The unreachable code names are:
+\fBnet-unr\fP network unreachable, \fBhost-unr\fP host unreachable,
+\fBproto-unr\fP protocol unreachable, \fBport-unr\fP port unreachable,
+\fBneedfrag\fP, \fBsrcfail\fP source route failed,
+\fBnet-unk\fP network unknown, \fBhost-unk\fP host unknown,
+\fBisolate\fP, \fBnet-prohib\fP administratively prohibited contact with
+network,
+\fBhost-prohib\fP administratively prohibited contact with host,
+\fBnet-tos\fP network unreachable with given TOS,
+\fBhost-tos\fP host unreachable with given TOS,
+\fBfilter-prohib\fP packet prohibited by packet filter,
+\fBhost-preced\fP,
+\fBcutoff-preced\fP.
+.TP
+.B squench
+Source Quence.
+.TP
+.B "redir [ redirect-code ]"
+Redirect (routing). This is used to indicate that the route being chosen
+for forwarding the packet is suboptimal and that the sender of the packet
+should be routing packets via another route. The redirect code names are:
+\fBnet-redir\fP redirect packets for a network,
+\fBhost-redir\fP redirect packets for a host,
+\fBtos-net-redir\fP redirect packets for a network with a given TOS,
+\fBtos-host-redir\fP redirect packets for a host with a given TOS.
+.TP
+.B echo
+Echo.
+.TP
+.B routerad
+Router Advertisment.
+.TP
+.B routersol
+Router solicitation.
+.TP
+.B "timex [ timexceed-code ]"
+Time Exceeded. This is used to indicate that the packet failed to reach the
+destination because it was in transit too long (i.e. ttl reached 0). The
+valid code names are: \fBintrans\fP,
+\fBreass\fP could not reassemble packet from fragments within a given time.
+.TP
+.B "paramprob [ paramprob-code ]"
+Parameter problem. There is only one available parameter problem code name:
+\fBoptabsent\fP.
+.TP
+.B timest
+Time stamp request.
+.TP
+.B "timestrep [ { timestamp-code } ]"
+Time stamp reply. In a timestamp reply, it is possible to supply the
+following values: \fBrtime\fP, \fBotime\fP, \fBttime\fP.
+.TP
+.B inforeq
+Information request.
+.TP
+.B inforep
+Information reply.
+.TP
+.B maskreq
+Address mask request.
+.TP
+.B maskrep
+Address mask reply.
+.SH FILES
+/etc/protocols
+/etc/services
+/etc/hosts
+.SH SEE ALSO
diff --git a/usr.sbin/ipsend/ipsend/ipsend.c b/usr.sbin/ipsend/ipsend/ipsend.c
index afd41fa8a58..af87ff1410e 100644
--- a/usr.sbin/ipsend/ipsend/ipsend.c
+++ b/usr.sbin/ipsend/ipsend/ipsend.c
@@ -1,30 +1,30 @@
+/* $OpenBSD: ipsend.c,v 1.5 1998/01/26 04:17:04 dgregor Exp $ */
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipsend.c (C) 1995-1997 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.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsend.c,v 1.5 1998/01/26 04:17:04 dgregor Exp $";
#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>
@@ -32,20 +32,18 @@ static char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
#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"
+#include "ip_fil_compat.h"
+#include "ipsend.h"
+#include "ipf.h"
extern char *optarg;
extern int optind;
+extern void iplang __P((FILE *));
char options[68];
+int opts;
#ifdef linux
char default_device[] = "eth0";
#else
@@ -58,19 +56,29 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
#endif
-void usage(prog)
+static void usage __P((char *));
+static void do_icmp __P((ip_t *, char *));
+int main __P((int, char **));
+
+
+static 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-d\tdebug mode\n\
+\t\t-i 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\
@@ -80,12 +88,20 @@ char *prog;
\t\t-T\t\tSet TCP protocol\n\
\t\t-t port\t\tdestination port\n\
\t\t-U\t\tSet UDP protocol\n\
+\t\t-v\tverbose mode\n\
+\t\t-w <window>\tSet the TCP window size\n\
+", prog);
+ fprintf(stderr, "Usage: %s [-dv] -L <filename>\n\
+\toptions:\n\
+\t\t-d\tdebug mode\n\
+\t\t-L filename\tUse IP language for sending packets\n\
+\t\t-v\tverbose mode\n\
", prog);
exit(1);
}
-void do_icmp(ip, args)
+static void do_icmp(ip, args)
ip_t *ip;
char *args;
{
@@ -153,17 +169,18 @@ struct in_addr gwip;
}
-main(argc, argv)
+int main(argc, argv)
int argc;
char **argv;
{
+ FILE *langfile = NULL;
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, *s;
- int mtu = 1500, olen = 0, c;
+ int mtu = 1500, olen = 0, c, nonl = 0;
/*
* 65535 is maximum packet size...you never know...
@@ -174,10 +191,11 @@ char **argv;
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)
+ while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1)
switch (c)
{
case 'I' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -186,10 +204,26 @@ char **argv;
}
do_icmp(ip, optarg);
break;
+ case 'L' :
+ if (nonl) {
+ fprintf(stderr,
+ "Incorrect usage of -L option.\n");
+ usage(name);
+ }
+ if (!strcmp(optarg, "-"))
+ langfile = stdin;
+ else if (!(langfile = fopen(optarg, "r"))) {
+ fprintf(stderr, "can't open file %s\n",
+ optarg);
+ exit(1);
+ }
+ iplang(langfile);
+ return 0;
case 'P' :
{
struct protoent *p;
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -204,6 +238,7 @@ char **argv;
break;
}
case 'T' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -214,6 +249,7 @@ char **argv;
ip->ip_len += sizeof(tcphdr_t);
break;
case 'U' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -224,15 +260,22 @@ char **argv;
ip->ip_len += sizeof(udphdr_t);
break;
case 'd' :
- dev = optarg;
+ opts |= OPT_DEBUG;
break;
case 'f' :
+ nonl++;
ip->ip_off = strtol(optarg, NULL, 0);
break;
case 'g' :
+ nonl++;
gateway = optarg;
break;
+ case 'i' :
+ nonl++;
+ dev = optarg;
+ break;
case 'm' :
+ nonl++;
mtu = atoi(optarg);
if (mtu < 28)
{
@@ -241,16 +284,23 @@ char **argv;
}
break;
case 'o' :
- olen = optname(optarg, options);
+ nonl++;
+ olen = buildopts(optarg, options, (ip->ip_hl - 5) << 2);
break;
case 's' :
+ nonl++;
src = optarg;
break;
case 't' :
+ nonl++;
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
tcp->th_dport = htons(atoi(optarg));
break;
+ case 'v' :
+ opts |= OPT_VERBOSE;
+ break;
case 'w' :
+ nonl++;
if (ip->ip_p == IPPROTO_TCP)
tcp->th_win = atoi(optarg);
else
@@ -291,8 +341,25 @@ char **argv;
exit(2);
}
+ if (olen)
+ {
+ caddr_t ipo = (caddr_t)ip;
+
+ 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));
+ ip->ip_len += olen;
+ bcopy((char *)ip, (char *)ipo, ip->ip_len);
+ ip = (ip_t *)ipo;
+ tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
+ }
+
if (ip->ip_p == IPPROTO_TCP)
- for (s = argv[optind]; c = *s; s++)
+ for (s = argv[optind]; (c = *s); s++)
switch(c)
{
case 'S' : case 's' :
@@ -325,22 +392,9 @@ char **argv;
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);
+ return send_packets(dev, mtu, (ip_t *)ti, gwip);
}
diff --git a/usr.sbin/ipsend/ipsend/ipsopt.c b/usr.sbin/ipsend/ipsend/ipsopt.c
index 13d9e49d002..1d598f2757c 100644
--- a/usr.sbin/ipsend/ipsend/ipsopt.c
+++ b/usr.sbin/ipsend/ipsend/ipsopt.c
@@ -1,34 +1,45 @@
+/* $OpenBSD: ipsopt.c,v 1.2 1998/01/26 04:17:06 dgregor Exp $ */
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 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 ?
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsopt.c,v 1.2 1998/01/26 04:17:06 dgregor Exp $";
#endif
#include <stdio.h>
#include <string.h>
+#include <stdlib.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"
+#ifndef linux
+#include <netinet/ip_var.h>
+#endif
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include "ipsend.h"
+
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
-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_RR, 0x04, 3, "rr" }, /* 1 route */
{ IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */
{ IPOPT_SECURITY, 0x08, 11, "sec-level" },
{ IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */
@@ -53,7 +64,6 @@ u_short seclevel(slevel)
char *slevel;
{
struct ipopt_names *so;
- u_short level = 0;
for (so = secnames; so->on_name; so++)
if (!strcasecmp(slevel, so->on_name))
@@ -67,14 +77,82 @@ char *slevel;
}
-u_long optname(cp, op)
+int addipopt(op, io, len, class)
+char *op;
+struct ipopt_names *io;
+int len;
+char *class;
+{
+ struct in_addr ipadr;
+ int olen = len, srr = 0;
+ u_short val;
+ u_char lvl;
+ char *s = op, *t;
+
+ 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) {
+ /*
+ * Allow option to specify RR buffer length in bytes.
+ */
+ if (io->on_value == IPOPT_RR) {
+ val = (class && *class) ? atoi(class) : 4;
+ *op++ = val + io->on_siz;
+ len += val;
+ } else
+ *op++ = io->on_siz;
+ *op++ = IPOPT_MINOFF;
+
+ while (class && *class) {
+ t = NULL;
+ switch (io->on_value)
+ {
+ case IPOPT_SECURITY :
+ lvl = seclevel(class);
+ *(op - 1) = lvl;
+ break;
+ case IPOPT_LSRR :
+ case IPOPT_SSRR :
+ if ((t = strchr(class, ',')))
+ *t = '\0';
+ ipadr.s_addr = inet_addr(class);
+ srr++;
+ bcopy((char *)&ipadr, op, sizeof(ipadr));
+ op += sizeof(ipadr);
+ break;
+ case IPOPT_SATID :
+ val = atoi(class);
+ bcopy((char *)&val, op, 2);
+ break;
+ }
+
+ if (t)
+ *t++ = ',';
+ class = t;
+ }
+ if (srr)
+ s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4 * srr;
+ if (io->on_value == IPOPT_RR)
+ op += val;
+ else
+ op += io->on_siz - 3;
+ }
+ return len - olen;
+}
+
+
+u_32_t buildopts(cp, op, len)
char *cp, *op;
+int len;
{
- struct ipopt_names *io, *so;
- u_short lvl;
- u_long msk = 0;
- char *s, *sec, *t;
- int len = 0;
+ struct ipopt_names *io;
+ u_32_t msk = 0;
+ char *s, *t;
+ int inc, lastop = -1;
for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
if ((t = strchr(s, '=')))
@@ -82,21 +160,10 @@ char *cp, *op;
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;
+ lastop = io->on_value;
+ if ((inc = addipopt(op, io, len, t))) {
+ op += inc;
+ len += inc;
}
msk |= io->on_bit;
break;
@@ -106,7 +173,24 @@ char *cp, *op;
return 0;
}
}
- *op++ = IPOPT_EOL;
- len++;
+
+ if (len & 3) {
+ while (len & 3) {
+ *op++ = ((len & 3) == 3) ? IPOPT_EOL : IPOPT_NOP;
+ len++;
+ }
+ } else {
+ if (lastop != IPOPT_EOL) {
+ if (lastop == IPOPT_NOP)
+ *(op - 1) = IPOPT_EOL;
+ else {
+ *op++ = IPOPT_NOP;
+ *op++ = IPOPT_NOP;
+ *op++ = IPOPT_NOP;
+ *op = IPOPT_EOL;
+ len += 4;
+ }
+ }
+ }
return len;
}
diff --git a/usr.sbin/ipsend/iptest/Makefile b/usr.sbin/ipsend/iptest/Makefile
index 17cdef66a36..829a0ca4690 100644
--- a/usr.sbin/ipsend/iptest/Makefile
+++ b/usr.sbin/ipsend/iptest/Makefile
@@ -1,10 +1,11 @@
-# $Id: Makefile,v 1.1 1996/05/10 21:40:59 dm Exp $
+# $OpenBSD: Makefile,v 1.2 1998/01/26 04:17:08 dgregor Exp $
PROG= iptest
BINDIR= /usr/sbin
-NOMAN=
+MAN= iptest.1
SRCS= iptest.c iptests.c ip.c sbpf.c sock.c 44arp.c
-CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest
+CFLAGS+= -DDOSOCKET -I${.CURDIR}/../common -I${.CURDIR}/../../ipftest \
+ -I${.CURDIR}/../../../sys/netinet -I${.CURDIR}/../../../sbin/ipf
.PATH: ${.CURDIR}/../common
.include <bsd.prog.mk>
diff --git a/usr.sbin/ipsend/iptest/iptest.1 b/usr.sbin/ipsend/iptest/iptest.1
new file mode 100644
index 00000000000..5e6c6b5754a
--- /dev/null
+++ b/usr.sbin/ipsend/iptest/iptest.1
@@ -0,0 +1,102 @@
+.\" $OpenBSD: iptest.1,v 1.1 1998/01/26 04:17:09 dgregor Exp $
+.TH IPTEST 1
+.SH NAME
+iptest \- automatically generate a packets to test IP functionality
+.SH SYNOPSIS
+.B iptest
+[
+.B \-1234567
+] [
+.B \-d
+<device>
+] [
+.B \-g
+<gateway>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-p
+<\fIpointtest\fP>
+] [
+.B \-s
+<\fIsource\fP>
+] <destination>
+.SH DESCRIPTION
+.PP
+\fBiptest\fP ...
+.SH OPTIONS
+.TP
+.B \-1
+Run IP test group #1. This group of tests generates packets with the IP
+header fields set to invalid values given other packet characteristics.
+The point tests are: 1 (ip_hl < ip_len), 2 (ip_hl > ip_len),
+3 (ip_v < 4), 4 (ip_v > 4), 5 (ip_len < packetsize, long packets),
+6 (ip_len > packet size, short packets), 7 (Zero length fragments),
+8 (packet > 64k after reassembly), 9 (IP offset with MSB set), 10 (ttl
+variations).
+.TP
+.B \-2
+Run IP test group #2. This group of tests generates packets with the IP
+options constructed with invalud values given other packet characteristics.
+The point tests are: 1 (option length > packet length), 2 (option length = 0).
+.TP
+.B \-3
+Run IP test group #3. This group of tests generates packets with the ICMP
+header fields set to non-standard values. The point tests are: 1 (ICMP types
+0-31 & 255), 2 (type 3 & code 0 - 31), 3 (type 4 & code 0, 127, 128, 255),
+4 (type 5 & code 0, 127, 128, 255), 5 (types 8-10,13-18 with codes 0, 127,
+128 and 255), 6 (type 12 & code 0, 127, 128, 129, 255) and 7 (type 3 & codes
+9-10, 13-14 and 17-18 - shortened packets).
+.TP
+.B \-4
+Run IP test group #4. This group of tests generates packets with the UDP
+header fields set to non-standard values. The point tests are: 1 (UDP length
+> packet size), 2 (UDP length < packetsize), 3 (sport = 0, 1, 32767, 32768,
+65535), 4 (dport = 0, 1, 32767, 32768, 65535) and 5 (sizeof(struct ip) <= MTU
+<= sizeof(struct udphdr) + sizeof(struct ip)).
+.TP
+.B \-5
+Run IP test group #5. This group of tests generates packets with the TCP
+header fields set to non-standard values. The point tests are: 1 (TCP flags
+variations, all combinations), 2 (seq = 0, 0x7fffffff, 0x8000000, 0xa0000000,
+0xffffffff), 3 (ack = 0, 0x7fffffff, 0x8000000, 0xa0000000, 0xffffffff),
+4 (SYN packet with window of 0, 32768, 65535), 5 (set urgent pointer to 1,
+0x7fff, 0x8000, 0xffff), 6 (data offset), 7 (sport = 0, 1, 32767, 32768,
+65535) and 8 (dport = 0, 1, 32767, 32768, 65535).
+.TP
+.B \-6
+Run IP test group #6. This test generates a large number of fragments in
+an attempt to exhaust the network buffers used for holding packets for later
+reassembly. WARNING: this may crash or cause serious performance degradation
+to the target host.
+.TP
+.B \-7
+Run IP test group #7. This test generates 1024 random IP packets with only
+the IP version, checksum, length and IP offset field correct.
+.TP
+.BR \-d \0<interface>
+Set the interface name to be the name supplied.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.B \-p <test>
+Run a...
+.DT
+.SH SEE ALSO
+ipsend(1), ipresend(1), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+Only one of the numeric test options may be given when \fIiptest\fP is run.
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+If you find any, please send email to me at darrenr@cyber.com.au
diff --git a/usr.sbin/ipsend/iptest/iptest.c b/usr.sbin/ipsend/iptest/iptest.c
index 85f2d27d542..c5ff22a15b9 100644
--- a/usr.sbin/ipsend/iptest/iptest.c
+++ b/usr.sbin/ipsend/iptest/iptest.c
@@ -1,30 +1,30 @@
+/* $OpenBSD: iptest.c,v 1.4 1998/01/26 04:17:10 dgregor Exp $ */
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipsend.c (C) 1995-1997 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.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: iptest.c,v 1.4 1998/01/26 04:17:10 dgregor Exp $";
#endif
#include <stdio.h>
-#include <stdlib.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>
@@ -32,14 +32,11 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
#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"
+#include "ipsend.h"
extern char *optarg;
@@ -58,15 +55,22 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
#endif
+static void usage __P((char *));
+int main __P((int, char **));
-void usage(prog)
-char *prog;
+
+static void usage(prog)
+char *prog;
{
fprintf(stderr, "Usage: %s [options] dest\n\
\toptions:\n\
@@ -87,15 +91,15 @@ char *prog;
}
-main(argc, argv)
-int argc;
-char **argv;
+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, *s;
+ char *src = NULL, *dst;
int mtu = 1500, tests = 0, pointtest = 0, c;
/*
@@ -106,7 +110,7 @@ char **argv;
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)
+ while ((c = getopt(argc, argv, "1234567d:g:m:p:s:")) != -1)
switch (c)
{
case '1' :
@@ -143,7 +147,7 @@ char **argv;
usage(name);
}
- if (argc - optind < 2 && !tests)
+ if ((argc <= optind) || !argv[optind])
usage(name);
dst = argv[optind++];
@@ -185,20 +189,34 @@ char **argv;
switch (tests)
{
case 1 :
- return ip_test1(dev, mtu, ti, gwip, pointtest);
+ ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 2 :
- return ip_test2(dev, mtu, ti, gwip, pointtest);
+ ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 3 :
- return ip_test3(dev, mtu, ti, gwip, pointtest);
+ ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 4 :
- return ip_test4(dev, mtu, ti, gwip, pointtest);
+ ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 5 :
- return ip_test5(dev, mtu, ti, gwip, pointtest);
+ ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 6 :
- return ip_test6(dev, mtu, ti, gwip, pointtest);
+ ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
case 7 :
- return ip_test7(dev, mtu, ti, gwip, pointtest);
+ ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ break;
default :
+ ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest);
+ ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest);
break;
}
return 0;
diff --git a/usr.sbin/ipsend/iptest/iptests.c b/usr.sbin/ipsend/iptest/iptests.c
index 9c74804963a..f18e77b2e70 100644
--- a/usr.sbin/ipsend/iptest/iptests.c
+++ b/usr.sbin/ipsend/iptest/iptests.c
@@ -1,18 +1,23 @@
+/* $OpenBSD: iptests.c,v 1.2 1998/01/26 04:17:11 dgregor Exp $ */
/*
- * (C)opyright 1993, 1994, 1995 by Darren Reed.
+ * Copyright (C) 1993-1997 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 ?
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#ifndef lint
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: iptests.c,v 1.2 1998/01/26 04:17:11 dgregor Exp $";
#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)
+#if !defined(solaris) && !defined(linux) && !defined(__sgi)
# define _KERNEL
# define KERNEL
# include <sys/file.h>
@@ -22,45 +27,59 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
# include <sys/user.h>
# include <sys/proc.h>
#endif
-#include <kvm.h>
-#include <sys/socket.h>
+#if !defined(ultrix) && !defined(hpux) && !defined(linux) && !defined(__sgi)
+# include <kvm.h>
+#endif
+#ifndef ultrix
+# include <sys/socket.h>
+#endif
+#if defined(solaris)
+# include <sys/stream.h>
+#endif
#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>
+# 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>
+#if defined(linux) && (LINUX >= 0200)
+# include <asm/atomic.h>
+#endif
+#if !defined(linux)
+# include <net/route.h>
+#else
+# define __KERNEL__ /* because there's a macro not wrapped by this */
+# include <net/route.h> /* in this file :-/ */
+#endif
#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
+#ifndef linux
+# include <netinet/ip_var.h>
+# include <netinet/in_pcb.h>
+# include <netinet/tcp_timer.h>
+# include <netinet/tcp_var.h>
#endif
+#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
+# include <sys/sysmacros.h>
+#endif
+#include "ipsend.h"
+
#define PAUSE() tv.tv_sec = 0; tv.tv_usec = 10000; \
(void) select(0, NULL, NULL, NULL, &tv)
+
void ip_test1(dev, mtu, ip, gwip, ptest)
char *dev;
int mtu;
@@ -70,7 +89,7 @@ int ptest;
{
struct timeval tv;
udphdr_t *u;
- int nfd, i, len, id = getpid();
+ int nfd, i = 0, len, id = getpid();
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
@@ -166,11 +185,11 @@ int ptest;
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 < (ip->ip_len * 2); i++) {
+ 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);
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, (char *)ip, i, gwip);
printf("%d\r", i);
fflush(stdout);
PAUSE();
@@ -181,8 +200,8 @@ int ptest;
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);
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, (char *)ip, len, gwip);
printf("%d\r", i);
fflush(stdout);
PAUSE();
@@ -200,8 +219,8 @@ int ptest;
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);
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, (char *)ip, len, gwip);
printf("%d\r", i);
fflush(stdout);
PAUSE();
@@ -212,8 +231,8 @@ int ptest;
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);
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ (void) send_ether(nfd, (char *)ip, i, gwip);
printf("%d\r", i);
fflush(stdout);
PAUSE();
@@ -264,12 +283,47 @@ int ptest;
gettimeofday(&tv, NULL);
srand(tv.tv_sec ^ getpid() ^ tv.tv_usec);
/*
- * Part8: 63k packet + 1k fragment at offset 0x1ffe
+ * 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. 63k packet + 1k fragment at offset 0x1ffe\n");
+ 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);
@@ -290,7 +344,7 @@ int ptest;
PAUSE();
}
ip->ip_len = 896 + 20;
- ip->ip_off = IP_MF | (i >> 3);
+ ip->ip_off = (i >> 3);
if ((rand() & 0x1f) != 0) {
(void) send_ip(nfd, mtu, ip, gwip, 1);
printf("%d\r", i);
@@ -298,6 +352,37 @@ int ptest;
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;
@@ -352,8 +437,7 @@ struct in_addr gwip;
int ptest;
{
struct timeval tv;
- udphdr_t *u;
- int nfd, i, len, id = getpid();
+ int nfd;
u_char *s;
s = (u_char *)(ip + 1);
@@ -445,8 +529,7 @@ int ptest;
static int ict2[8] = { 3, 9, 10, 13, 14, 17, 18, 0 };
struct timeval tv;
struct icmp *icp;
- int nfd, i, len, id = getpid();
- u_char *s;
+ int nfd, i;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
@@ -637,8 +720,8 @@ struct in_addr gwip;
int ptest;
{
struct timeval tv;
- struct udphdr *u;
- int nfd, i, len, id = getpid();
+ udphdr_t *u;
+ int nfd, i;
ip->ip_hl = sizeof(*ip) >> 2;
@@ -768,10 +851,10 @@ int ptest;
PAUSE();
}
- if (!ptest || (ptest == 4)) {
+ if (!ptest || (ptest == 5)) {
/*
- * Test 5: sizeof(struct ip) <= MTU <= sizeof(struct udphdr) +
- * sizeof(struct ip)
+ * Test 5: sizeof(ip_t) <= MTU <= sizeof(udphdr_t) +
+ * sizeof(ip_t)
*/
printf("4.5 UDP 20 <= MTU <= 32\n");
for (i = sizeof(*ip); i <= u->uh_ulen; i++) {
@@ -796,10 +879,12 @@ int ptest;
{
struct timeval tv;
tcphdr_t *t;
- int nfd, i, len, id = getpid();
+ int nfd, i;
t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2));
+#ifndef linux
t->th_x2 = 0;
+#endif
t->th_off = 0;
t->th_sport = 1;
t->th_dport = 1;
@@ -808,6 +893,7 @@ int ptest;
t->th_sum = 0;
t->th_seq = 1;
t->th_ack = 0;
+ ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t);
nfd = initdevice(dev, t->th_sport, 1);
if (!ptest || (ptest == 1)) {
@@ -937,9 +1023,10 @@ int ptest;
PAUSE();
}
-#if !defined(linux) && !defined(__SVR4) && !defined(__svr4__)
+#if !defined(linux) && !defined(__SVR4) && !defined(__svr4__) && \
+ !defined(__sgi)
{
- struct tcpcb *t, tcb;
+ struct tcpcb *tcbp, tcb;
struct tcpiphdr ti;
struct sockaddr_in sin;
int fd, slen;
@@ -948,10 +1035,13 @@ int ptest;
for (i = 1; i < 63; i++) {
fd = socket(AF_INET, SOCK_STREAM, 0);
+ bzero((char *)&sin, sizeof(sin));
sin.sin_addr.s_addr = ip->ip_dst.s_addr;
sin.sin_port = htons(i);
+ sin.sin_family = AF_INET;
if (!connect(fd, (struct sockaddr *)&sin, sizeof(sin)))
break;
+ close(fd);
}
if (i == 63) {
@@ -962,15 +1052,15 @@ int ptest;
}
bcopy((char *)ip, (char *)&ti, sizeof(*ip));
- ti.ti_dport = i;
+ t->th_dport = htons(i);
slen = sizeof(sin);
if (!getsockname(fd, (struct sockaddr *)&sin, &slen))
- ti.ti_sport = sin.sin_port;
- if (!(t = (struct tcpcb *)find_tcp(fd, &ti))) {
+ t->th_sport = sin.sin_port;
+ if (!(tcbp = find_tcp(fd, &ti))) {
printf("Can't find PCB\n");
goto skip_five_and_six;
}
- kmemcpy((char*)&tcb, (void *)t, sizeof(tcb));
+ KMCPY(&tcb, tcbp, sizeof(tcb));
ti.ti_win = tcb.rcv_adv;
ti.ti_seq = tcb.snd_nxt - 1;
ti.ti_ack = tcb.rcv_nxt;
@@ -979,27 +1069,36 @@ int ptest;
/*
* Test 5: urp
*/
- printf("5.1 TCP Urgent pointer\n");
- ti.ti_urp = 1;
+ t->th_flags = TH_ACK|TH_URG;
+ printf("5.5.1 TCP Urgent pointer, sport %hu dport %hu\n",
+ ntohs(t->th_sport), ntohs(t->th_dport));
+ t->th_urp = htons(1);
(void) send_tcp(nfd, mtu, ip, gwip);
PAUSE();
- ti.ti_urp = 0x7fff;
+
+ t->th_seq = tcb.snd_nxt;
+ ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t) + 1;
+ t->th_urp = htons(0x7fff);
(void) send_tcp(nfd, mtu, ip, gwip);
PAUSE();
- ti.ti_urp = 0x8000;
+ t->th_urp = htons(0x8000);
(void) send_tcp(nfd, mtu, ip, gwip);
PAUSE();
- ti.ti_urp = 0xffff;
+ t->th_urp = htons(0xffff);
(void) send_tcp(nfd, mtu, ip, gwip);
PAUSE();
+ t->th_urp = htons(0);
+ t->th_flags &= ~TH_URG;
+ ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t);
}
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++) {
+ t->th_flags = TH_ACK;
+ printf("5.6.1 TCP off = 1-15, len = 40\n");
+ for (i = 1; i < 16; i++) {
ti.ti_off = ntohs(i);
(void) send_tcp(nfd, mtu, ip, gwip);
printf("%d\r", i);
@@ -1007,6 +1106,7 @@ int ptest;
PAUSE();
}
putchar('\n');
+ ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t);
}
(void) close(fd);
@@ -1015,9 +1115,9 @@ skip_five_and_six:
#endif
t->th_seq = 1;
t->th_ack = 1;
+ t->th_off = 0;
if (!ptest || (ptest == 7)) {
- t->th_off = 0;
t->th_flags = TH_SYN;
/*
* Test 7: sport = 0, sport = 1, sport = 32767
@@ -1056,6 +1156,7 @@ skip_five_and_six:
if (!ptest || (ptest == 8)) {
t->th_sport = 1;
+ t->th_flags = TH_SYN;
/*
* Test 8: dport = 0, dport = 1, dport = 32767
* dport = 32768, dport = 65535
@@ -1090,6 +1191,22 @@ skip_five_and_six:
fflush(stdout);
PAUSE();
}
+
+ /* LAND attack - self connect, so make src & dst ip/port the same */
+ if (!ptest || (ptest == 9)) {
+ printf("5.9 TCP LAND attack. sport = 25, dport = 25\n");
+ /* chose SMTP port 25 */
+ t->th_sport = htons(25);
+ t->th_dport = htons(25);
+ t->th_flags = TH_SYN;
+ ip->ip_src = ip->ip_dst;
+ (void) send_tcp(nfd, mtu, ip, gwip);
+ fflush(stdout);
+ PAUSE();
+ }
+
+ /* TCP options header checking */
+ /* 0 length options, etc */
}
@@ -1104,7 +1221,7 @@ int ptest;
{
struct timeval tv;
udphdr_t *u;
- int nfd, i, j, k, len, id = getpid();
+ int nfd, i, j, k;
ip->ip_v = IPVERSION;
ip->ip_tos = 0;
@@ -1122,7 +1239,10 @@ int ptest;
u->uh_dport = htons(u->uh_dport);
u->uh_ulen = 7168;
- for (i = 0; i < 65536; i++) {
+ printf("6. Exhaustive mbuf test.\n");
+ printf(" Send 7k packet in 768 & 128 byte fragments, 128 times.\n");
+ printf(" Total of around 8,900 packets\n");
+ for (i = 0; i < 128; i++) {
/*
* First send the entire packet in 768 byte chunks.
*/