summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2001-01-17 05:01:03 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2001-01-17 05:01:03 +0000
commit563aa13c03d2813c7166caafc538d5e70b2fb34c (patch)
tree667756531d650ac84b36eee1d5a33c592111139c
parent88e9db6efe2d8f5ccd5d6e21f96e87b9e167070e (diff)
1st part of ipf userland code.
-rw-r--r--sbin/ipf/HISTORY241
-rw-r--r--sbin/ipf/Makefile4
-rw-r--r--sbin/ipf/common.c606
-rw-r--r--sbin/ipf/facpri.c6
-rw-r--r--sbin/ipf/facpri.h6
-rw-r--r--sbin/ipf/ifaddr.c82
-rw-r--r--sbin/ipf/ifaddr.h9
-rw-r--r--sbin/ipf/ipf.c123
-rw-r--r--sbin/ipf/ipf.h34
-rw-r--r--sbin/ipf/opt.c10
-rw-r--r--sbin/ipf/parse.c549
-rw-r--r--sbin/ipfstat/Makefile6
-rw-r--r--sbin/ipfstat/fils.c998
-rw-r--r--sbin/ipfstat/kmem.c18
-rw-r--r--sbin/ipfstat/kmem.h11
-rw-r--r--sbin/ipnat/Makefile4
-rw-r--r--sbin/ipnat/ipnat.c191
-rw-r--r--sbin/ipnat/natparse.c737
-rw-r--r--usr.sbin/ipmon/ipmon.c219
19 files changed, 2415 insertions, 1439 deletions
diff --git a/sbin/ipf/HISTORY b/sbin/ipf/HISTORY
index 5c81d705dab..0bcb7fb4110 100644
--- a/sbin/ipf/HISTORY
+++ b/sbin/ipf/HISTORY
@@ -1,4 +1,4 @@
-# $OpenBSD: HISTORY,v 1.9 2000/08/10 05:50:27 kjell Exp $
+# $OpenBSD: HISTORY,v 1.10 2001/01/17 05:00:57 fgsch Exp $
#
# NOTE: Quite a few patches and suggestions come from other sources, to whom
# I'm greatly indebted, even if no names are mentioned.
@@ -7,9 +7,11 @@
# in providing a very available location for the IP Filter home page and
# distribution center.
#
-# Thanks to Tel.Net Media for allowing me to maintain and further develop
-# IP Filter as part of my job and supplying Sun equipment for testing the
-# move to 64bits and Gigabit Ethernet.
+# Thanks to Hewlett Packard for making it possible to port IP Filter to
+# HP-UX 11.00.
+#
+# Thanks to Tel.Net Media for supplying me with equipment to ensure that
+# IP Filter continues to work on Solaris/sparc64.
#
# Thanks to BSDI for providing object files for BSD/OS 3.1 and the means
# to further support development of IP Filter under BSDI.
@@ -21,52 +23,239 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
-3.3.18 08/08/2000 - Released
+3.4.15 17/12/2000 - Released
+
+add minimum ttl filtering (to be replaced later by return-icmp-as-dest
+for all ICMP packets matching state entries).
+
+fix NAT'ing of fragments
+
+fix sanity checks for ICMPV6
+
+fix up compiling on IRIX 6.2 with IDF/IDL installed
+
+3.4.14 02/11/2000 - Released
+
+cause flushing NAT table to generate log records the same as state flush
+does.
+
+fix ftp proxy port/pasv
+
+fix problem where nat_{in,out}lookup() would release a write lock when it
+didn't need to.
+
+add check for ipf6.conf in Solaris ipfboot
+
+3.4.13 28/10/2000 - Released
+
+fix introduced bug with ICMP packets being rejected when valid
+
+fix bug with proxy's that don't set fin_dlen correctly when calling
+fr_addstate()
+
+3.4.12 26/10/2000 - Released
+
+fix installing into FreeBSD-4.1
+
+fix FTP proxy bug where it'd hang and make NAT slightly more efficient
+
+fix general compiling errors/warnings on various platforms
+
+don't access ICMP data fields that aren't there
+
+3.4.11 09/10/2000 - Released
+
+return NULL for IPv6 access control lists if it is disabled rather than
+random garbage.
+
+fix for getting protocol & packet length for IPv6 packets for pullup.
+
+update plog script from version 0.8 to version 0.10
+
+patch from Frank Volf adding fix_datacksum() to NAT code, enhancing the
+capabilities for "fixing" checksums.
+
+3.4.10 03/09/2000 - Released
-fix up command checking in the ftp proxy
+merge patch from Frank Volf for ICMP nat handling of TCP/UDP data `errors'
-fix getting the version from the kernel for solaris
+getline() adjusts linenum now
+
+add tcphalfclosed timeout
+
+fill in icmp_nextmtu field if it is defined on the platform
+
+RST generation fix from guido
+
+force 32bit compile for gcc on solaris if it can't generate 64bit code
+
+encase logging when fr_chksrc == 2 in #ifdef IPFILTER_LOG
+
+fix up line wrap problems in plog script
+
+fix ICMP packet handling to not drop valid ICMP errors
+
+freebsd 5.0 compat changes
+
+3.4.9 08/08/2000 - Released
+
+implement new aging mechanism in fr_tcp_age()
fix icmp state checking bug
-print out better information for ICMP packets in ipmon
+revamp buildsunos script and build both sparcv7/sparcv9 for Solaris
+if on an Ultra with a 64bit system & compiler (Caseper Dik)
open ipfilter device read only if we know we can
-3.3.17 08/07/2000 - Released
+print out better information for ICMP packets in ipmon
+
+move checking for source spoofed packets to a point where we can generate
+logs of them
+
+return EFAULT from ircopyptr/iwcopyptr
+
+don't do ioctl(SIOCGETFS) for auth stats
+
+fix up freeing mbufs for post-4.3BSD
+
+fix returning of inc from ftp proxy
+
+fix bugs with ipfs -R/-W (Caseper Dik)
+
+3.4.8 19/07/2000 - Released
+
+create fake opt_inet6.h for FreeBSD-4 compile as LKM
+
+add #ifdef's for KLD_MODULE sanity
+
+NAT fastroute'd packets which come out of return-*
+
+fix upper/lower case crap in ftp proxy and get seq# checking fixed up.
-increase default state table sizes
+3.4.7 08/07/2000 - Released
+
+make "ipf -y" lookup NAT if's which are unknown
+
+prepend line numbers to ioctl error messages in ipf/ipnat
don't apply patches to FreeBSD twice
-fix parsing of icmp code when using words
+allow for ip_len to be on an unaligned boundary early on in fr_precheck
fix printing of icmp code when it is 0
-add compatibility #ifdef for FreeBSD's CSUM_DELAY_DATA
+correct printing of port numbers in map rules with from/to
+
+don't allow fr_func to be called at securelevel > 0 or rules to be added
+if securelevel > 0 if they have a non-zero fr_func.
+
+3.4.6 11/06/2000 - Released
+
+add extra regression tests for new nat functionality
+
+place restrictions on using '!' in map/rdr rules
+
+fix up solaris compile problems
+
+3.4.5 10/06/2000 - Released
+
+mention -sl in ipfstat.8
+
+fix/support '!' in from/to rules (rdr) for NAT
+
+add from/to support to rdr NAT rules
+
+don't send ICMP errors in response to ICMP errors
-3.3.16 23/05/2000 - Released
+fix sunos5 compilation for "ipfstat-top" and cleanup ipfboot
+
+input accounting list used for both outbound and inbound packets
+
+3.4.4 23/05/2000 - Released
don't add TCP state if it is an RST packet and (attempt) to send out
RST/ICMP packets in a manner that bypasses IP Filter.
add patch to work with 4.0_STABLE delayed checksums
-3.3.15 20/05/2000 - Released
-
-fix destination being 0/32 in NAT map rules
+3.4.3 20/05/2000 - Released
fix ipmon -F
-3.3.14 10/05/2000 - Released
+don't truncate IPv6 packets on Solaris
+
+fix keep state for ICMP ECHO
+
+add some NAT stats and use def_nat_age rather than DEF_NAT_AGE
+
+don't make ftp proxy drop packets
+
+use MCLISREFERENCED() in tandem with M_EXT to check if IP fields need to be
+swapped back.
+
+fix up RST generation for non-Solaris
+
+get "short" flag right for IPv6
+
+3.4.2 - 10/5/2000 - Released
Fix bug in dealing with "hlen == 1 and opt > 1" - Itojun
ignore previous NAT mappings for 0/0 and 0/32 rules
-struct friostat got too big for SunOS4
+bring in a completely new ftp proxy
+
+allow NAT to cause packets to be dropped.
+
+add NetBSD callout support for 1.4-current
-3.3.13 26/04/2000 - Released
+3.4.1 - 30/4/2000 - Released
+
+add ratoui() and fix parsing of group numbers to allow 0 - UINT_MAX
+
+don't include opt_inet6.h for FreeBSD if KLD_MODULE is defined
+
+Solaris must use copyin() for all types of ioctl() args
+
+fix up screen/tty when leaving "top mode" of ipfstat
+
+linked list for maptable not setup correctly in nat_hostmap()
+
+check for maptable rather than nat_table[1] to see if malloc for maptable
+succeeded in nat_init
+
+fix handling of map NAT rules with "from/to" host specs
+
+fix printout out of source address when using "from/to" with map rules
+
+convert ip_len back to network byte order, not plen, for solaris as ip_len
+may have been changed by NAT and plen won't reflect this
+
+3.4 - 27/4/2000 - Released
+
+source address spoofing can be turned on (fr_chksrc) without using
+filter rules
+
+group numbers are now 32bits in size, up from 16bits
+
+IPv6 filtering available
+
+add frank volf's state-top patches
+
+add load splitting and round-robin attribute to redirect rules
+
+FreeBSD-4.0 support (including KLD)
+
+add top-style operation mode for ipfstat (-t)
+
+add save/restore of IP Filter state/NAT information (ipfs)
+
+further ftp proxy security checks
+
+support for adding and removing proxies at runtime
+
+3.3.13 26/04/2000 - Released
Fix parsing of "range" with "portmap"
@@ -76,7 +265,7 @@ Fix NAT timeouts for ICMP packets
SunOS4 patches for ICMP redirects from Jurgen Keil (jk@tools.de)
-3.3.12 16/03/2000 - Released
+3.3.12 16/03/2000 - Released
tighten up ftp proxy behaviour. sigh. yuck. hate.
@@ -89,7 +278,7 @@ erroneously.
fix bug with the spl level not being reset when returning EIO from
iplioctl due to ipfilter not being initialized yet.
-3.3.11 04/03/2000 - Released
+3.3.11 04/03/2000 - Released
make "or-block" work with lines that start with "log"
@@ -97,6 +286,7 @@ fix up parsing and printing of rules with syslog levels in them
fix from Cy Schubert for calling of apr_fini only if non-null
+
3.3.10 24/02/2000 - Released
* fix back from guido for state tracking interfaces
@@ -105,10 +295,10 @@ fix from Cy Schubert for calling of apr_fini only if non-null
* if attaching fails and we can abort, then cleanup when doing so.
-Julian Yip (julian@computer.org):
+julian@computer.org:
* solaris.c (fr_precheck): After calling freemsg on mt, set it point to *mp.
* ipf.c (packetlogon): use flag to store the return value from get_flags.
-* ipmon.c (init_tabs): Generate cleanup so we do not have to cast
+* ipmon.c (init_tabs): General cleanup so we do not have to cast
an int s->s_port to u_int port and try to check if the u_int port
is less than zero.
@@ -200,11 +390,6 @@ fix yet another problem with real audio.
3.3.4 4/12/1999 - Released
-patches from Guido: fix panic in ip_state:fr_checkicmpmatchingstate(), fix
-byte order problem in ip_id (host order when called from ip_input(), vs
-network byte order when called from ip_output()) and fix a problem where the
-fragment cache was never timedout early.
-
fix up the real audio proxy to properly setup state information and NAT
entries, thanks to Laine Stump for testing/advice/fixes.
diff --git a/sbin/ipf/Makefile b/sbin/ipf/Makefile
index d4061995d59..ed7af593210 100644
--- a/sbin/ipf/Makefile
+++ b/sbin/ipf/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.9 2000/04/26 21:03:59 deraadt Exp $
+# $OpenBSD: Makefile,v 1.10 2001/01/17 05:00:57 fgsch Exp $
PROG= ipf
MAN= ipf.8 ipf.4 ipf.5
-SRCS= ipf.c parse.c opt.c facpri.c ifaddr.c
+SRCS= ipf.c parse.c opt.c facpri.c common.c ifaddr.c
.include <bsd.prog.mk>
diff --git a/sbin/ipf/common.c b/sbin/ipf/common.c
new file mode 100644
index 00000000000..569d6e0427f
--- /dev/null
+++ b/sbin/ipf/common.c
@@ -0,0 +1,606 @@
+/* $OpenBSD: common.c,v 1.1 2001/01/17 05:00:57 fgsch Exp $ */
+
+/*
+ * Copyright (C) 1993-2000 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.
+ */
+#include <sys/types.h>
+#if !defined(__SVR4) && !defined(__svr4__)
+#include <strings.h>
+#else
+#include <sys/byteorder.h>
+#endif
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <netinet/ip_compat.h>
+#include <netinet/ip_fil.h>
+#include "ipf.h"
+#include "facpri.h"
+
+#if defined(__OpenBSD__)
+#include "ifaddr.h"
+#endif
+
+#if !defined(lint)
+static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $";
+#endif
+
+extern struct ipopt_names ionames[], secclass[];
+extern int opts;
+#ifdef USE_INET6
+extern int use_inet6;
+#endif
+
+
+char *proto = NULL;
+char flagset[] = "FSRPAU";
+u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG };
+
+#ifdef USE_INET6
+void fill6bits __P((int, u_32_t *));
+int count6bits __P((u_32_t *));
+#endif
+
+static char thishost[MAXHOSTNAMELEN];
+
+
+void initparse()
+{
+ gethostname(thishost, sizeof(thishost));
+ thishost[sizeof(thishost) - 1] = '\0';
+}
+
+
+int genmask(msk, mskp)
+char *msk;
+u_32_t *mskp;
+{
+ char *endptr = NULL;
+#ifdef USE_INET6
+ u_32_t addr;
+#endif
+ int bits;
+
+ if (index(msk, '.') || index(msk, 'x') || index(msk, ':')) {
+ /* possibly of the form xxx.xxx.xxx.xxx
+ * or 0xYYYYYYYY */
+#ifdef USE_INET6
+ if (use_inet6) {
+ if (inet_pton(AF_INET6, msk, &addr) != 1)
+ return -1;
+ } else
+#endif
+ if (inet_aton(msk, (struct in_addr *)mskp) == 0)
+ return -1;
+ } else {
+ /*
+ * set x most significant bits
+ */
+ bits = (int)strtol(msk, &endptr, 0);
+#ifdef USE_INET6
+ if ((*endptr != '\0') ||
+ ((bits > 32) && !use_inet6) || (bits < 0) ||
+ ((bits > 128) && use_inet6))
+#else
+ if (*endptr != '\0' || bits > 32 || bits < 0)
+#endif
+ return -1;
+#ifdef USE_INET6
+ if (use_inet6)
+ fill6bits(bits, mskp);
+ else
+#endif
+ if (bits == 0)
+ *mskp = 0;
+ else
+ *mskp = htonl(0xffffffff << (32 - bits));
+ }
+ return 0;
+}
+
+
+
+#ifdef USE_INET6
+void fill6bits(bits, msk)
+int bits;
+u_32_t *msk;
+{
+ int i;
+
+ for (i = 0; bits >= 32 && i < 4 ; ++i, bits -= 32)
+ msk[i] = 0xffffffff;
+
+ if (bits > 0 && i < 4)
+ msk[i++] = htonl(0xffffffff << (32 - bits));
+
+ while (i < 4)
+ msk[i++] = 0;
+}
+#endif
+
+
+/*
+ * returns -1 if neither "hostmask/num" or "hostmask mask addr" are
+ * found in the line segments, there is an error processing this information,
+ * or there is an error processing ports information.
+ */
+int hostmask(seg, sa, msk, pp, cp, tp, linenum)
+char ***seg;
+u_32_t *sa, *msk;
+u_short *pp, *tp;
+int *cp;
+int linenum;
+{
+ struct in_addr maskaddr;
+ char *s;
+
+ /*
+ * is it possibly hostname/num ?
+ */
+ if ((s = index(**seg, '/')) ||
+ ((s = index(**seg, ':')) && !index(s + 1, ':'))) {
+ *s++ = '\0';
+ if (genmask(s, msk) == -1) {
+ fprintf(stderr, "%d: bad mask (%s)\n", linenum, s);
+ return -1;
+ }
+ if (hostnum(sa, **seg, linenum) == -1) {
+ fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
+ return -1;
+ }
+ *sa &= *msk;
+ (*seg)++;
+ return ports(seg, pp, cp, tp, linenum);
+ }
+
+ /*
+ * look for extra segments if "mask" found in right spot
+ */
+ if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) {
+ if (hostnum(sa, **seg, linenum) == -1) {
+ fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
+ return -1;
+ }
+ (*seg)++;
+ (*seg)++;
+ if (inet_aton(**seg, &maskaddr) == 0) {
+ fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg);
+ return -1;
+ }
+ *msk = maskaddr.s_addr;
+ (*seg)++;
+ *sa &= *msk;
+ return ports(seg, pp, cp, tp, linenum);
+ }
+
+ if (**seg) {
+ if (hostnum(sa, **seg, linenum) == -1) {
+ fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
+ return -1;
+ }
+ (*seg)++;
+#ifdef USE_INET6
+ if (use_inet6) {
+ u_32_t k = 0;
+ if (sa[0] || sa[1] || sa[2] || sa[3])
+ k = 0xffffffff;
+ msk[0] = msk[1] = msk[2] = msk[3] = k;
+ }
+ else
+#endif
+ *msk = *sa ? 0xffffffff : 0;
+ return ports(seg, pp, cp, tp, linenum);
+ }
+ fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
+ return -1;
+}
+
+/*
+ * returns an ip address as a long var as a result of either a DNS lookup or
+ * straight inet_addr() call
+ */
+int hostnum(ipa, host, linenum)
+u_32_t *ipa;
+char *host;
+int linenum;
+{
+ struct hostent *hp;
+ struct netent *np;
+ struct in_addr ip;
+
+ if (!strcasecmp("any", host))
+ return 0;
+#ifdef USE_INET6
+ if (use_inet6) {
+ if (inet_pton(AF_INET6, host, ipa) == 1)
+ return 0;
+ else
+ return -1;
+ }
+#endif
+ if (isdigit(*host) && inet_aton(host, &ip)) {
+ *ipa = ip.s_addr;
+ return 0;
+ }
+
+ if (!strcasecmp("<thishost>", host))
+ host = thishost;
+
+#if defined(__OpenBSD__)
+ if (if_addr(host, &ip))
+ return *ipa = ip.s_addr;
+#endif
+
+ if (!(hp = gethostbyname(host))) {
+ if (!(np = getnetbyname(host))) {
+ fprintf(stderr, "%d: can't resolve hostname: %s\n",
+ linenum, host);
+ return -1;
+ }
+ *ipa = htonl(np->n_net);
+ return 0;
+ }
+ *ipa = *(u_32_t *)hp->h_addr;
+ return 0;
+}
+
+
+/*
+ * check for possible presence of the port fields in the line
+ */
+int ports(seg, pp, cp, tp, linenum)
+char ***seg;
+u_short *pp, *tp;
+int *cp;
+int linenum;
+{
+ int comp = -1;
+
+ if (!*seg || !**seg || !***seg)
+ return 0;
+ if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
+ (*seg)++;
+ if (isalnum(***seg) && *(*seg + 2)) {
+ if (portnum(**seg, pp, linenum) == 0)
+ return -1;
+ (*seg)++;
+ if (!strcmp(**seg, "<>"))
+ comp = FR_OUTRANGE;
+ else if (!strcmp(**seg, "><"))
+ comp = FR_INRANGE;
+ else {
+ fprintf(stderr,
+ "%d: unknown range operator (%s)\n",
+ linenum, **seg);
+ return -1;
+ }
+ (*seg)++;
+ if (**seg == NULL) {
+ fprintf(stderr, "%d: missing 2nd port value\n",
+ linenum);
+ return -1;
+ }
+ if (portnum(**seg, tp, linenum) == 0)
+ return -1;
+ } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
+ comp = FR_EQUAL;
+ else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
+ comp = FR_NEQUAL;
+ else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
+ comp = FR_LESST;
+ else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
+ comp = FR_GREATERT;
+ else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
+ comp = FR_LESSTE;
+ else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
+ comp = FR_GREATERTE;
+ else {
+ fprintf(stderr, "%d: unknown comparator (%s)\n",
+ linenum, **seg);
+ return -1;
+ }
+ if (comp != FR_OUTRANGE && comp != FR_INRANGE) {
+ (*seg)++;
+ if (portnum(**seg, pp, linenum) == 0)
+ return -1;
+ }
+ *cp = comp;
+ (*seg)++;
+ }
+ return 0;
+}
+
+
+/*
+ * find the port number given by the name, either from getservbyname() or
+ * straight atoi(). Return 1 on success, 0 on failure
+ */
+int portnum(name, port, linenum)
+char *name;
+u_short *port;
+int linenum;
+{
+ struct servent *sp, *sp2;
+ u_short p1 = 0;
+ int i;
+
+ if (isdigit(*name)) {
+ if (ratoi(name, &i, 0, USHRT_MAX)) {
+ *port = (u_short)i;
+ return 1;
+ }
+ fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name);
+ return 0;
+ }
+ if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) {
+ sp = getservbyname(name, proto);
+ if (sp) {
+ *port = ntohs(sp->s_port);
+ return 1;
+ }
+ fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
+ return 0;
+ }
+ sp = getservbyname(name, "tcp");
+ if (sp)
+ p1 = sp->s_port;
+ sp2 = getservbyname(name, "udp");
+ if (!sp || !sp2) {
+ fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
+ linenum, name);
+ return 0;
+ }
+ if (p1 != sp2->s_port) {
+ fprintf(stderr, "%d: %s %d/tcp is a different port to ",
+ linenum, name, p1);
+ fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
+ return 0;
+ }
+ *port = ntohs(p1);
+ return 1;
+}
+
+
+u_char tcp_flags(flgs, mask, linenum)
+char *flgs;
+u_char *mask;
+int linenum;
+{
+ u_char tcpf = 0, tcpfm = 0, *fp = &tcpf;
+ char *s, *t;
+
+ if (*flgs == '0') {
+ s = strchr(flgs, '/');
+ if (s)
+ *s++ = '\0';
+ tcpf = strtol(flgs, NULL, 0);
+ fp = &tcpfm;
+ } else
+ s = flgs;
+
+ for (; *s; s++) {
+ if (*s == '/' && fp == &tcpf) {
+ fp = &tcpfm;
+ if (*(s + 1) == '0')
+ break;
+ continue;
+ }
+ if (!(t = index(flagset, *s))) {
+ fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s);
+ return 0;
+ }
+ *fp |= flags[t - flagset];
+ }
+
+ if (s && *s == '0')
+ tcpfm = strtol(s, NULL, 0);
+
+ if (!tcpfm)
+ tcpfm = 0xff;
+ *mask = tcpfm;
+ return tcpf;
+}
+
+
+/*
+ * count consecutive 1's in bit mask. If the mask generated by counting
+ * consecutive 1's is different to that passed, return -1, else return #
+ * of bits.
+ */
+int countbits(ip)
+u_32_t ip;
+{
+ u_32_t ipn;
+ int cnt = 0, i, j;
+
+ ip = ipn = ntohl(ip);
+ for (i = 32; i; i--, ipn *= 2)
+ if (ipn & 0x80000000)
+ cnt++;
+ else
+ break;
+ ipn = 0;
+ for (i = 32, j = cnt; i; i--, j--) {
+ ipn *= 2;
+ if (j > 0)
+ ipn++;
+ }
+ if (ipn == ip)
+ return cnt;
+ return -1;
+}
+
+
+#ifdef USE_INET6
+int count6bits(msk)
+u_32_t *msk;
+{
+ int i = 0, k;
+ u_32_t j;
+
+ for (k = 3; k >= 0; k--)
+ if (msk[k] == 0xffffffff)
+ i += 32;
+ else {
+ for (j = msk[k]; j; j <<= 1)
+ if (j & 0x80000000)
+ i++;
+ }
+ return i;
+}
+#endif
+
+
+char *portname(pr, port)
+int pr, port;
+{
+ static char buf[32];
+ struct protoent *p = NULL;
+ struct servent *sv = NULL, *sv1 = NULL;
+
+ if (pr == -1) {
+ if ((sv = getservbyport(htons(port), "tcp"))) {
+ strncpy(buf, sv->s_name, sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+ sv1 = getservbyport(htons(port), "udp");
+ sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
+ NULL : sv1;
+ }
+ if (sv)
+ return buf;
+ } else if (pr && (p = getprotobynumber(pr))) {
+ if ((sv = getservbyport(htons(port), p->p_name))) {
+ strncpy(buf, sv->s_name, sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+ return buf;
+ }
+ }
+
+ (void) sprintf(buf, "%d", port);
+ return buf;
+}
+
+
+int ratoi(ps, pi, min, max)
+char *ps;
+int *pi, min, max;
+{
+ int i;
+ char *pe;
+
+ i = (int)strtol(ps, &pe, 0);
+ if (*pe != '\0' || i < min || i > max)
+ return 0;
+ *pi = i;
+ return 1;
+}
+
+
+int ratoui(ps, pi, min, max)
+char *ps;
+u_int *pi, min, max;
+{
+ u_int i;
+ char *pe;
+
+ i = (u_int)strtol(ps, &pe, 0);
+ if (*pe != '\0' || i < min || i > max)
+ return 0;
+ *pi = i;
+ return 1;
+}
+
+
+void printhostmask(v, addr, mask)
+int v;
+u_32_t *addr, *mask;
+{
+ struct in_addr ipa;
+ int ones;
+
+#ifdef USE_INET6
+ if (v == 6) {
+ ones = count6bits(mask);
+ if (ones == 0 && !addr[0] && !addr[1] && !addr[2] && !addr[3])
+ printf("any");
+ else {
+ char ipbuf[64];
+ printf("%s/%d",
+ inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf)),
+ ones);
+ }
+ }
+ else
+#endif
+ if (!*addr && !*mask)
+ printf("any");
+ else {
+ ipa.s_addr = *addr;
+ printf("%s", inet_ntoa(ipa));
+ if ((ones = countbits(*mask)) == -1) {
+ ipa.s_addr = *mask;
+ printf("/%s", inet_ntoa(ipa));
+ } else
+ printf("/%d", ones);
+ }
+}
+
+
+void printportcmp(pr, frp)
+int pr;
+frpcmp_t *frp;
+{
+ static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
+ "<>", "><"};
+
+ if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE)
+ printf(" port %d %s %d", frp->frp_port,
+ pcmp1[frp->frp_cmp], frp->frp_top);
+ else
+ printf(" port %s %s", pcmp1[frp->frp_cmp],
+ portname(pr, frp->frp_port));
+}
+
+
+void printbuf(buf, len, zend)
+char *buf;
+int len, zend;
+{
+ char *s, c;
+ int i;
+
+ for (s = buf, i = len; i; i--) {
+ c = *s++;
+ if (isprint(c))
+ putchar(c);
+ else
+ printf("\\%03o", c);
+ if ((c == '\0') && zend)
+ break;
+ }
+}
diff --git a/sbin/ipf/facpri.c b/sbin/ipf/facpri.c
index 00434b42a0f..4333b4345fd 100644
--- a/sbin/ipf/facpri.c
+++ b/sbin/ipf/facpri.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: facpri.c,v 1.4 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: facpri.c,v 1.5 2001/01/17 05:00:58 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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,7 +21,7 @@
#include "facpri.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)$IPFilter: facpri.c,v 1.2 1999/08/01 11:10:45 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: facpri.c,v 1.3 2000/03/13 22:10:18 darrenr Exp $";
#endif
typedef struct table {
diff --git a/sbin/ipf/facpri.h b/sbin/ipf/facpri.h
index 8f819136b34..68621f5b4a2 100644
--- a/sbin/ipf/facpri.h
+++ b/sbin/ipf/facpri.h
@@ -1,12 +1,12 @@
-/* $OpenBSD: facpri.h,v 1.4 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: facpri.h,v 1.5 2001/01/17 05:00:58 fgsch Exp $ */
/*
- * Copyright (C) 1999 by Darren Reed.
+ * Copyright (C) 1999-2000 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.
- * $IPFilter: facpri.h,v 1.2 1999/08/01 11:10:46 darrenr Exp $
+ * $IPFilter: facpri.h,v 1.3 2000/03/13 22:10:18 darrenr Exp $
*/
#ifndef __FACPRI_H__
diff --git a/sbin/ipf/ifaddr.c b/sbin/ipf/ifaddr.c
index 3f162c361a3..5e4d46242ef 100644
--- a/sbin/ipf/ifaddr.c
+++ b/sbin/ipf/ifaddr.c
@@ -1,14 +1,13 @@
-/* $OpenBSD: ifaddr.c,v 1.5 2000/04/05 05:35:28 kjell Exp $ */
+/* $OpenBSD: ifaddr.c,v 1.6 2001/01/17 05:00:58 fgsch Exp $ */
+
#include <sys/types.h>
-#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <net/if.h>
+#include <sys/ioctl.h>
#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <string.h>
#include <err.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "ifaddr.h"
-
/*
* if_addr():
@@ -19,58 +18,27 @@
* suggests inclusion into other platforms. The closest alternative is
* to define /etc/networks with suitable values.
*/
-int if_addr(name, ap)
-char *name;
-struct in_addr *ap;
+int if_addr(name, ap)
+ char *name;
+ struct in_addr *ap;
{
- struct ifconf ifc;
- struct ifreq ifreq, *ifr;
- char *inbuf = NULL;
- int s, i, len = 8192;
+ struct sockaddr_in *sin;
+ struct ifreq ifr;
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ warn("socket");
+ return (0);
+ }
+
+ strncpy(ifr.ifr_name, name, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ - 1] = '\0';
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- warn("socket");
- return 0;
- }
+ if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
+ return (0);
- while (1) {
- ifc.ifc_len = len;
- ifc.ifc_buf = inbuf = realloc(inbuf, len);
- if (inbuf == NULL)
- err(1, "malloc");
- if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
- warn("SIOCGIFCONF");
- goto if_addr_lose;
- }
- if (ifc.ifc_len + sizeof(ifreq) < len)
- break;
- len *= 2;
- }
- ifr = ifc.ifc_req;
- ifreq.ifr_name[0] = '\0';
- for (i = 0; i < ifc.ifc_len; ) {
- ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
- i += sizeof(ifr->ifr_name) +
- (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
- ? ifr->ifr_addr.sa_len
- : sizeof(struct sockaddr));
- ifreq = *ifr;
- if (ioctl(s, SIOCGIFADDR, (caddr_t)ifr) < 0)
- continue;
- if (ifr->ifr_addr.sa_family != AF_INET)
- continue;
- if (!strcmp(name, ifr->ifr_name)) {
- struct sockaddr_in *sin;
- close(s);
- free(inbuf);
- sin = (struct sockaddr_in *)&ifr->ifr_addr;
- *ap = sin->sin_addr;
- return (1);
- }
- }
+ sin = (struct sockaddr_in *)&ifr.ifr_addr;
+ *ap = sin->sin_addr;
-if_addr_lose:
- close(s);
- free(inbuf);
- return 0;
+ return (1);
}
diff --git a/sbin/ipf/ifaddr.h b/sbin/ipf/ifaddr.h
index bb882dcddf7..34e01f42fc5 100644
--- a/sbin/ipf/ifaddr.h
+++ b/sbin/ipf/ifaddr.h
@@ -1,8 +1,3 @@
-/* $OpenBSD: ifaddr.h,v 1.5 2000/04/05 05:35:28 kjell Exp $ */
+/* $OpenBSD: ifaddr.h,v 1.6 2001/01/17 05:00:58 fgsch Exp $ */
-#ifndef __IFADDR_H__
-#define __IFADDR_H__
-
-int if_addr __P((char *, struct in_addr *));
-
-#endif
+int if_addr __P((char *, struct in_addr *));
diff --git a/sbin/ipf/ipf.c b/sbin/ipf/ipf.c
index 9a978846565..f012e109a8f 100644
--- a/sbin/ipf/ipf.c
+++ b/sbin/ipf/ipf.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: ipf.c,v 1.24 2000/04/12 21:51:48 kjell Exp $ */
+/* $OpenBSD: ipf.c,v 1.25 2001/01/17 05:00:58 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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,15 +36,16 @@
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_nat.h>
+#include <netinet/ip_state.h>
#include "ipf.h"
#include <netinet/ipl.h>
#if !defined(lint)
-static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ipf.c,v 2.2.2.1 2000/02/16 14:40:39 darrenr Exp $";
+static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: ipf.c,v 2.10.2.5 2000/10/25 10:37:11 darrenr Exp $";
#endif
#if SOLARIS
@@ -55,14 +56,15 @@ extern char *index __P((const char *, int));
#endif
extern char *optarg;
-extern int optind;
-extern int optreset;
void frsync __P((void));
void zerostats __P((void));
int main __P((int, char *[]));
int opts = 0;
+#ifdef USE_INET6
+int use_inet6 = 0;
+#endif
static int fd = -1;
@@ -71,25 +73,16 @@ static void set_state __P((u_int)), showstats __P((friostat_t *));
static void packetlogon __P((char *)), swapactive __P((void));
static int opendevice __P((char *));
static void closedevice __P((void));
-static char *getline __P((char *, size_t, FILE *));
+static char *getline __P((char *, size_t, FILE *, int *));
static char *ipfname = IPL_NAME;
static void usage __P((void));
static void showversion __P((void));
static int get_flags __P((void));
-#if SOLARIS
-#define OPTS "AdDEf:F:Il:noPrsUvVyzZ"
-#else
-#define OPTS "AdDEf:F:Il:noPrsvVyzZ"
-#endif
static void usage()
{
-#if SOLARIS
- fprintf(stderr, "usage: ipf [-AdDEInoPrsUvVyzZ] %s %s %s\n",
-#else
- fprintf(stderr, "usage: ipf [-AdDEInoPrsvVyzZ] %s %s %s\n",
-#endif
+ fprintf(stderr, "usage: ipf [-6AdDEInoPrsUvVyzZ] %s %s %s\n",
"[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");
exit(1);
}
@@ -101,15 +94,16 @@ char *argv[];
{
int c;
- while ((c = getopt(argc, argv, OPTS)) != -1)
- if (c == '?')
- usage();
-
- optreset = 1;
- optind = 1;
- while ((c = getopt(argc, argv, OPTS)) != -1) {
+ while ((c = getopt(argc, argv, "6AdDEf:F:Il:noPrsUvVyzZ")) != -1) {
switch (c)
{
+ case '?' :
+ usage();
+#ifdef USE_INET6
+ case '6' :
+ use_inet6 = 1;
+ break;
+#endif
case 'A' :
opts &= ~OPT_INACTIVE;
break;
@@ -138,7 +132,6 @@ char *argv[];
opts |= OPT_DONOTHING;
break;
case 'o' :
- opts |= OPT_OUTQUE;
break;
case 'P' :
ipfname = IPL_AUTH;
@@ -191,7 +184,7 @@ char *ipfdev;
if (!(opts & OPT_DONOTHING) && fd == -1)
if ((fd = open(ipfdev, O_RDWR)) == -1)
- if ((fd = open(ipfname, O_RDONLY)) == -1)
+ if ((fd = open(ipfdev, O_RDONLY)) == -1)
perror("open device");
return fd;
}
@@ -209,7 +202,7 @@ static int get_flags()
int i;
if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) {
- perror("SIOCFRENB");
+ perror("SIOCGETFF");
return 0;
}
return i;
@@ -220,8 +213,13 @@ static void set_state(enable)
u_int enable;
{
if (opendevice(ipfname) != -2)
- if (ioctl(fd, SIOCFRENB, &enable) == -1)
- perror("SIOCFRENB");
+ if (ioctl(fd, SIOCFRENB, &enable) == -1) {
+ if (errno == EBUSY)
+ fprintf(stderr,
+ "IP FIlter: already initialized\n");
+ else
+ perror("SIOCFRENB");
+ }
return;
}
@@ -256,8 +254,7 @@ char *name, *file;
exit(1);
}
- while (getline(line, sizeof(line), fp)) {
- linenum++;
+ while (getline(line, sizeof(line), fp, &linenum)) {
/*
* treat CR as EOL. LF is converted to NUL by getline().
*/
@@ -299,24 +296,31 @@ char *name, *file;
if ((opts & OPT_ZERORULEST) &&
!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, add, fr) == -1)
+ if (ioctl(fd, add, &fr) == -1) {
+ fprintf(stderr, "%d:", linenum);
perror("ioctl(SIOCZRLST)");
- else {
+ } else {
#ifdef USE_QUAD_T
printf("hits %qd bytes %qd ",
+ (long long)fr->fr_hits,
+ (long long)fr->fr_bytes);
#else
printf("hits %ld bytes %ld ",
-#endif
fr->fr_hits, fr->fr_bytes);
+#endif
printfr(fr);
}
} else if ((opts & OPT_REMOVE) &&
!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, del, fr) == -1)
- perror("ioctl(SIOCDELFR)");
+ if (ioctl(fd, del, &fr) == -1) {
+ fprintf(stderr, "%d:", linenum);
+ perror("ioctl(delete rule)");
+ }
} else if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, add, fr) == -1)
- perror("ioctl(SIOCADDFR)");
+ if (ioctl(fd, add, &fr) == -1) {
+ fprintf(stderr, "%d:", linenum);
+ perror("ioctl(add/insert rule)");
+ }
}
}
}
@@ -332,16 +336,17 @@ char *name, *file;
* Similar to fgets(3) but can handle '\\' and NL is converted to NUL.
* Returns NULL if error occured, EOF encounterd or input line is too long.
*/
-static char *getline(str, size, file)
+static char *getline(str, size, file, linenum)
register char *str;
size_t size;
FILE *file;
+int *linenum;
{
char *p;
int s, len;
do {
- for (p = str, s = size;; p += len, s -= len) {
+ for (p = str, s = size;; p += (len - 1), s -= (len - 1)) {
/*
* if an error occured, EOF was encounterd, or there
* was no room to put NUL, return NULL.
@@ -349,12 +354,22 @@ FILE *file;
if (fgets(p, s, file) == NULL)
return (NULL);
len = strlen(p);
+ if (p[len - 1] != '\n') {
+ p[len] = '\0';
+ break;
+ }
+ (*linenum)++;
p[len - 1] = '\0';
- if (p[len - 1] != '\\')
+ if (len < 2 || p[len - 2] != '\\')
break;
- size -= len;
+ else
+ /*
+ * Convert '\\' to a space so words don't
+ * run together
+ */
+ p[len - 2] = ' ';
}
- } while (*str == '\0' || *str == '\n');
+ } while (*str == '\0');
return (str);
}
@@ -468,13 +483,14 @@ void frsync()
void zerostats()
{
friostat_t fio;
+ friostat_t *fiop = &fio;
if (opendevice(ipfname) != -2) {
- if (ioctl(fd, SIOCFRZST, &fio) == -1) {
+ if (ioctl(fd, SIOCFRZST, &fiop) == -1) {
perror("ioctl(SIOCFRZST)");
exit(-1);
}
- showstats(&fio);
+ showstats(fiop);
}
}
@@ -542,15 +558,24 @@ static void blockunknown()
static void showversion()
{
struct friostat fio;
+ struct friostat *fiop=&fio;
u_32_t flags;
char *s;
+ int vfd;
- printf("ipf: %s (%d)\n", IPL_VERSION, sizeof(frentry_t));
+ printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
+
+ if ((vfd = open(ipfname, O_RDONLY)) == -1) {
+ perror("open device");
+ return;
+ }
- if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fio)) {
- perror("ioctl(SIOCGETFS");
+ if (ioctl(vfd, SIOCGETFS, &fiop)) {
+ perror("ioctl(SIOCGETFS)");
+ close(vfd);
return;
}
+ close(vfd);
flags = get_flags();
printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
diff --git a/sbin/ipf/ipf.h b/sbin/ipf/ipf.h
index f4f8c5d7d00..164bacda75f 100644
--- a/sbin/ipf/ipf.h
+++ b/sbin/ipf/ipf.h
@@ -1,14 +1,14 @@
-/* $OpenBSD: ipf.h,v 1.14 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: ipf.h,v 1.15 2001/01/17 05:00:59 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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.
*
* @(#)ipf.h 1.12 6/5/96
- * $IPFilter: ipf.h,v 2.1.2.1 1999/10/05 12:59:25 darrenr Exp $
+ * $IPFilter: ipf.h,v 2.9.2.2 2000/05/06 11:20:20 darrenr Exp $
*/
#ifndef __IPF_H__
@@ -39,6 +39,14 @@
#define OPT_RAW 0x080000
#define OPT_NAT 0x100000
#define OPT_GROUPS 0x200000
+#define OPT_STATETOP 0x400000
+#define OPT_FLUSH 0x800000
+#define OPT_CLEAR 0x1000000
+#define OPT_NODO 0x80000000
+
+#define OPT_STAT OPT_FRSTATES
+#define OPT_LIST OPT_SHOWLIST
+
#ifndef __P
# ifdef __STDC__
@@ -48,6 +56,8 @@
# endif
#endif
+struct frpcmp;
+
#ifdef ultrix
extern char *strdup __P((char *));
#endif
@@ -67,10 +77,26 @@ struct ipopt_names {
};
+extern char *proto;
+extern char flagset[];
+extern u_char flags[];
+
+extern u_char tcp_flags __P((char *, u_char *, int));
+extern int countbits __P((u_32_t));
+extern int ratoi __P((char *, int *, int, int));
+extern int ratoui __P((char *, u_int *, u_int, u_int));
+extern int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, int *,
+ u_short *, int));
+extern int ports __P((char ***, u_short *, int *, u_short *, int));
+extern char *portname __P((int, int));
extern u_32_t buildopts __P((char *, char *, int));
-extern u_32_t hostnum __P((char *, int *, int));
+extern int genmask __P((char *, u_32_t *));
+extern int hostnum __P((u_32_t *, char *, int));
extern u_32_t optname __P((char ***, u_short *, int));
extern void printpacket __P((ip_t *));
+extern void printportcmp __P((int, struct frpcmp *));
+extern void printhostmask __P((int, u_32_t *, u_32_t *));
+extern void printbuf __P((char *, int, int));
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
extern int gethostname __P((char *, int ));
diff --git a/sbin/ipf/opt.c b/sbin/ipf/opt.c
index 99fbcda9529..38a414bc5c8 100644
--- a/sbin/ipf/opt.c
+++ b/sbin/ipf/opt.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: opt.c,v 1.14 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: opt.c,v 1.15 2001/01/17 05:00:59 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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,14 +22,14 @@
#include <netinet/tcp.h>
#include <net/if.h>
#include <arpa/inet.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/tcpip.h>
#include <netinet/ip_fil.h>
#include "ipf.h"
#if !defined(lint)
-static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-1995 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: opt.c,v 2.1 1999/08/04 17:30:15 darrenr Exp $";
+static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: opt.c,v 2.2 2000/03/13 22:10:26 darrenr Exp $";
#endif
extern int opts;
diff --git a/sbin/ipf/parse.c b/sbin/ipf/parse.c
index 9b6b38f10c5..1ff6e70069d 100644
--- a/sbin/ipf/parse.c
+++ b/sbin/ipf/parse.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: parse.c,v 1.35 2000/08/10 05:50:27 kjell Exp $ */
+/* $OpenBSD: parse.c,v 1.36 2001/01/17 05:00:59 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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,56 +36,35 @@
#include <resolv.h>
#include <ctype.h>
#include <syslog.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include "ipf.h"
#include "facpri.h"
#if !defined(lint)
-static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.1.2.14 2000/06/21 14:50:52 darrenr Exp $";
+static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
extern int opts;
+#ifdef USE_INET6
+extern int use_inet6;
+#endif
-int portnum __P((char *, u_short *, int));
-u_char tcp_flags __P((char *, u_char *, int));
int addicmp __P((char ***, struct frentry *, int));
int extras __P((char ***, struct frentry *, int));
-char ***seg;
-u_long *sa, *msk;
-u_short *pp, *tp;
-u_char *cp;
-
-int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, u_char *,
- u_short *, int));
-int ports __P((char ***, u_short *, u_char *, u_short *, int));
+
int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *, int));
int to_interface __P((frdest_t *, char *, int));
void print_toif __P((char *, frdest_t *));
void optprint __P((u_short *, u_long, u_long));
-int countbits __P((u_32_t));
-char *portname __P((int, int));
-int ratoi __P((char *, int *, int, int));
-int loglevel __P((char **, u_short *, int));
+int loglevel __P((char **, u_int *, int));
void printlog __P((frentry_t *));
-#if defined(__OpenBSD__)
-extern int if_addr __P((char *, struct in_addr *));
-#endif
-
-char *proto = NULL;
-char flagset[] = "FSRPAU";
-u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG };
-
-static char thishost[MAXHOSTNAMELEN];
-
-
-void initparse()
-{
- gethostname(thishost, sizeof(thishost));
-}
+extern char *proto;
+extern char flagset[];
+extern u_char flags[];
/* parse()
@@ -99,8 +78,8 @@ int linenum;
static struct frentry fil;
struct protoent *p = NULL;
char *cps[31], **cpp, *endptr;
- u_char ch;
- int i, cnt = 1, j;
+ int i, cnt = 1, j, ch;
+ u_int k;
while (*line && isspace(*line))
line++;
@@ -109,7 +88,11 @@ int linenum;
bzero((char *)&fil, sizeof(fil));
fil.fr_mip.fi_v = 0xf;
+#ifdef USE_INET6
+ fil.fr_ip.fi_v = use_inet6 ? 6 : 4;
+#else
fil.fr_ip.fi_v = 4;
+#endif
fil.fr_loglevel = 0xffff;
/*
@@ -176,8 +159,8 @@ int linenum;
fil.fr_flags |= FR_PREAUTH;
} else if (!strcasecmp("skip", *cpp)) {
cpp++;
- if (ratoi(*cpp, &i, 0, USHRT_MAX))
- fil.fr_skip = i;
+ if (ratoui(*cpp, &k, 0, UINT_MAX))
+ fil.fr_skip = k;
else {
fprintf(stderr, "%d: integer must follow skip\n",
linenum);
@@ -265,43 +248,6 @@ int linenum;
cpp++;
}
if (*cpp && !strcasecmp(*cpp, "level")) {
- int fac, pri;
- char *s;
-
- fac = 0;
- pri = 0;
- if (!*++cpp) {
- fprintf(stderr, "%d: %s\n", linenum,
- "missing identifier after level");
- return NULL;
- }
- s = index(*cpp, '.');
- if (s) {
- *s++ = '\0';
- fac = fac_findname(*cpp);
- if (fac == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown facility", *cpp);
- return NULL;
- }
- pri = pri_findname(s);
- if (pri == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown priority", s);
- return NULL;
- }
- } else {
- pri = pri_findname(*cpp);
- if (pri == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown priority", *cpp);
- return NULL;
- }
- }
- fil.fr_loglevel = fac|pri;
- cpp++;
- }
- if (*cpp && !strcasecmp(*cpp, "level")) {
if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1)
return NULL;
cpp++;
@@ -450,16 +396,17 @@ int linenum;
linenum);
return NULL;
}
- ch = 0;
if (**cpp == '!') {
fil.fr_flags |= FR_NOTSRCIP;
(*cpp)++;
}
+ ch = 0;
if (hostmask(&cpp, (u_32_t *)&fil.fr_src,
(u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch,
&fil.fr_stop, linenum)) {
return NULL;
}
+
fil.fr_scmp = ch;
if (!*cpp) {
fprintf(stderr, "%d: missing to fields\n", linenum);
@@ -521,7 +468,8 @@ int linenum;
/*
* extras...
*/
- if (*cpp && (!strcasecmp(*cpp, "with") || !strcasecmp(*cpp, "and")))
+ if ((fil.fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") ||
+ !strcasecmp(*cpp, "and")))
if (extras(&cpp, &fil, linenum))
return NULL;
@@ -556,8 +504,8 @@ int linenum;
fprintf(stderr, "%d: head without group #\n", linenum);
return NULL;
}
- if (ratoi(*cpp, &i, 0, USHRT_MAX))
- fil.fr_grhead = i;
+ if (ratoui(*cpp, &k, 0, UINT_MAX))
+ fil.fr_grhead = (u_32_t)k;
else {
fprintf(stderr, "%d: invalid group (%s)\n",
linenum, *cpp);
@@ -575,8 +523,8 @@ int linenum;
linenum);
return NULL;
}
- if (ratoi(*cpp, &i, 0, USHRT_MAX))
- fil.fr_group = i;
+ if (ratoui(*cpp, &k, 0, UINT_MAX))
+ fil.fr_group = k;
else {
fprintf(stderr, "%d: invalid group (%s)\n",
linenum, *cpp);
@@ -630,7 +578,7 @@ int linenum;
int loglevel(cpp, facpri, linenum)
char **cpp;
-u_short *facpri;
+u_int *facpri;
int linenum;
{
int fac, pri;
@@ -677,15 +625,13 @@ frdest_t *fdp;
char *to;
int linenum;
{
- int r = 0;
- char *s;
+ char *s;
s = index(to, ':');
fdp->fd_ifp = NULL;
if (s) {
*s++ = '\0';
- fdp->fd_ip.s_addr = hostnum(s, &r, linenum);
- if (r == -1)
+ if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum) == -1)
return -1;
}
(void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1);
@@ -707,279 +653,6 @@ frdest_t *fdp;
/*
- * returns -1 if neither "hostmask/num" or "hostmask mask addr" are
- * found in the line segments, there is an error processing this information,
- * or there is an error processing ports information.
- */
-int hostmask(seg, sa, msk, pp, cp, tp, linenum)
-char ***seg;
-u_32_t *sa, *msk;
-u_short *pp, *tp;
-u_char *cp;
-int linenum;
-{
- char *s, *endptr;
- int bits = -1, resolved;
- struct in_addr maskaddr;
-
- /*
- * is it possibly hostname/num ?
- */
- if ((s = index(**seg, '/')) || (s = index(**seg, ':'))) {
- *s++ = '\0';
- if (index(s, '.') || index(s, 'x')) {
- /* possibly of the form xxx.xxx.xxx.xxx
- * or 0xYYYYYYYY */
- if (inet_aton(s, &maskaddr) == 0) {
- fprintf(stderr, "%d: bad mask (%s)\n",
- linenum, s);
- return -1;
- }
- *msk = maskaddr.s_addr;
- } else {
- /*
- * set x most significant bits
- */
- bits = (int)strtol(s, &endptr, 0);
- if (*endptr != '\0' || bits > 32 || bits < 0) {
- fprintf(stderr, "%d: bad mask (/%s)\n",
- linenum, s);
- return -1;
- }
- if (bits == 0)
- *msk = 0;
- else
- *msk = htonl(0xffffffff << (32 - bits));
- }
- *sa = hostnum(**seg, &resolved, linenum) & *msk;
- if (resolved == -1) {
- fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
- return -1;
- }
- (*seg)++;
- return ports(seg, pp, cp, tp, linenum);
- }
-
- /*
- * look for extra segments if "mask" found in right spot
- */
- if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) {
- *sa = hostnum(**seg, &resolved, linenum);
- if (resolved == -1) {
- fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
- return -1;
- }
- (*seg)++;
- (*seg)++;
- if (inet_aton(**seg, &maskaddr) == 0) {
- fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg);
- return -1;
- }
- *msk = maskaddr.s_addr;
- (*seg)++;
- *sa &= *msk;
- return ports(seg, pp, cp, tp, linenum);
- }
-
- if (**seg) {
- *sa = hostnum(**seg, &resolved, linenum);
- if (resolved == -1) {
- fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
- return -1;
- }
- (*seg)++;
- *msk = (*sa ? inet_addr("255.255.255.255") : 0L);
- *sa &= *msk;
- return ports(seg, pp, cp, tp, linenum);
- }
- fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg);
- return -1;
-}
-
-/*
- * returns an ip address as a long var as a result of either a DNS lookup or
- * straight inet_addr() call
- */
-u_32_t hostnum(host, resolved, linenum)
-char *host;
-int *resolved;
-int linenum;
-{
- struct hostent *hp;
- struct netent *np;
- struct in_addr ip;
-#if defined(__OpenBSD__)
- struct in_addr addr;
-#endif
-
- *resolved = 0;
- if (!strcasecmp("any", host))
- return 0;
- if (isdigit(*host) && inet_aton(host, &ip))
- return ip.s_addr;
-
- if (!strcasecmp("<thishost>", host))
- host = thishost;
-
-#if defined(__OpenBSD__)
- /* attempt a map from interface name to address */
- if (if_addr(host, &addr))
- return (u_32_t)addr.s_addr;
-#endif
-
- if (!(hp = gethostbyname(host))) {
- if (!(np = getnetbyname(host))) {
- *resolved = -1;
- fprintf(stderr, "%d: can't resolve hostname: %s\n",
- linenum, host);
- return 0;
- }
- return htonl(np->n_net);
- }
- return *(u_32_t *)hp->h_addr;
-}
-
-/*
- * check for possible presence of the port fields in the line
- */
-int ports(seg, pp, cp, tp, linenum)
-char ***seg;
-u_short *pp, *tp;
-u_char *cp;
-int linenum;
-{
- int comp = -1;
-
- if (!*seg || !**seg || !***seg)
- return 0;
- if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
- (*seg)++;
- if (isdigit(***seg) && *(*seg + 2)) {
- if (portnum(**seg, pp, linenum) == 0)
- return -1;
- (*seg)++;
- if (!strcmp(**seg, "<>"))
- comp = FR_OUTRANGE;
- else if (!strcmp(**seg, "><"))
- comp = FR_INRANGE;
- else {
- fprintf(stderr,
- "%d: unknown range operator (%s)\n",
- linenum, **seg);
- return -1;
- }
- (*seg)++;
- if (**seg == NULL) {
- fprintf(stderr, "%d: missing 2nd port value\n",
- linenum);
- return -1;
- }
- if (portnum(**seg, tp, linenum) == 0)
- return -1;
- } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
- comp = FR_EQUAL;
- else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
- comp = FR_NEQUAL;
- else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
- comp = FR_LESST;
- else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
- comp = FR_GREATERT;
- else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
- comp = FR_LESSTE;
- else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
- comp = FR_GREATERTE;
- else {
- fprintf(stderr, "%d: unknown comparator (%s)\n",
- linenum, **seg);
- return -1;
- }
- if (comp != FR_OUTRANGE && comp != FR_INRANGE) {
- (*seg)++;
- if (portnum(**seg, pp, linenum) == 0)
- return -1;
- }
- *cp = comp;
- (*seg)++;
- }
- return 0;
-}
-
-/*
- * find the port number given by the name, either from getservbyname() or
- * straight atoi(). Return 1 on success, 0 on failure
- */
-int portnum(name, port, linenum)
-char *name;
-u_short *port;
-int linenum;
-{
- struct servent *sp, *sp2;
- u_short p1 = 0;
- int i;
- if (isdigit(*name)) {
- if (ratoi(name, &i, 0, USHRT_MAX)) {
- *port = (u_short)i;
- return 1;
- }
- fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name);
- return 0;
- }
- if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) {
- sp = getservbyname(name, proto);
- if (sp) {
- *port = ntohs(sp->s_port);
- return 1;
- }
- fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
- return 0;
- }
- sp = getservbyname(name, "tcp");
- if (sp)
- p1 = sp->s_port;
- sp2 = getservbyname(name, "udp");
- if (!sp || !sp2) {
- fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
- linenum, name);
- return 0;
- }
- if (p1 != sp2->s_port) {
- fprintf(stderr, "%d: %s %d/tcp is a different port to ",
- linenum, name, p1);
- fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
- return 0;
- }
- *port = ntohs(p1);
- return 1;
-}
-
-
-u_char tcp_flags(flgs, mask, linenum)
-char *flgs;
-u_char *mask;
-int linenum;
-{
- u_char tcpf = 0, tcpfm = 0, *fp = &tcpf;
- char *s, *t;
-
- for (s = flgs; *s; s++) {
- if (*s == '/' && fp == &tcpf) {
- fp = &tcpfm;
- continue;
- }
- if (!(t = index(flagset, *s))) {
- fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s);
- return 0;
- }
- *fp |= flags[t - flagset];
- }
- if (!tcpfm)
- tcpfm = 0xff;
- *mask = tcpfm;
- return tcpf;
-}
-
-
-/*
* deal with extra bits on end of the line
*/
int extras(cp, fr, linenum)
@@ -1000,8 +673,8 @@ int linenum;
return -1;
while (**cp && (!strncasecmp(**cp, "ipopt", 5) ||
- !strncasecmp(**cp, "not", 3) || !strncasecmp(**cp, "opt", 4) ||
- !strncasecmp(**cp, "frag", 3) || !strncasecmp(**cp, "no", 2) ||
+ !strncasecmp(**cp, "not", 3) || !strncasecmp(**cp, "opt", 3) ||
+ !strncasecmp(**cp, "frag", 4) || !strncasecmp(**cp, "no", 2) ||
!strncasecmp(**cp, "short", 5))) {
if (***cp == 'n' || ***cp == 'N') {
notopt = 1;
@@ -1327,6 +1000,9 @@ struct frentry *fp;
int linenum;
{
if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP &&
+#ifdef USE_INET6
+ fp->fr_proto != IPPROTO_ICMPV6 &&
+#endif
fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) {
fprintf(stderr, "%d: Can only use keep with UDP/ICMP/TCP\n",
linenum);
@@ -1339,8 +1015,7 @@ int linenum;
linenum);
return -1;
}
-
- if (**cp && strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
+ if (strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) {
fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n",
linenum, **cp);
return -1;
@@ -1356,77 +1031,16 @@ int linenum;
/*
- * count consecutive 1's in bit mask. If the mask generated by counting
- * consecutive 1's is different to that passed, return -1, else return #
- * of bits.
- */
-int countbits(ip)
-u_32_t ip;
-{
- u_32_t ipn;
- int cnt = 0, i, j;
-
- ip = ipn = ntohl(ip);
- for (i = 32; i; i--, ipn *= 2)
- if (ipn & 0x80000000)
- cnt++;
- else
- break;
- ipn = 0;
- for (i = 32, j = cnt; i; i--, j--) {
- ipn *= 2;
- if (j > 0)
- ipn++;
- }
- if (ipn == ip)
- return cnt;
- return -1;
-}
-
-
-char *portname(pr, port)
-int pr, port;
-{
- static char buf[32];
- struct protoent *p = NULL;
- struct servent *sv = NULL, *sv1 = NULL;
-
- if (pr == -1) {
- if ((sv = getservbyport(htons(port), "tcp"))) {
- strncpy(buf, sv->s_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- sv1 = getservbyport(htons(port), "udp");
- sv = strncasecmp(buf, sv->s_name, strlen(buf)) ?
- NULL : sv1;
- }
- if (sv)
- return buf;
- } else if (pr && (p = getprotobynumber(pr))) {
- if ((sv = getservbyport(htons(port), p->p_name))) {
- strncpy(buf, sv->s_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- return buf;
- }
- }
-
- (void) sprintf(buf, "%d", port);
- return buf;
-}
-
-
-/*
* print the filter structure in a useful way
*/
void printfr(fp)
struct frentry *fp;
{
- static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
- "<>", "><"};
- struct protoent *p;
- int ones = 0, pr;
- char *s;
- u_char *t;
+ struct protoent *p;
u_short sec[2];
+ char *s;
+ u_char *t;
+ int pr;
if (fp->fr_flags & FR_PASS)
printf("pass");
@@ -1467,6 +1081,7 @@ struct frentry *fp;
printlog(fp);
putchar(' ');
}
+
if (fp->fr_flags & FR_QUICK)
printf("quick ");
@@ -1496,42 +1111,17 @@ struct frentry *fp;
}
printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
- if (!fp->fr_src.s_addr && !fp->fr_smsk.s_addr)
- printf("any ");
- else {
- printf("%s", inet_ntoa(fp->fr_src));
- if ((ones = countbits(fp->fr_smsk.s_addr)) == -1)
- printf("/%s ", inet_ntoa(fp->fr_smsk));
- else
- printf("/%d ", ones);
- }
- if (fp->fr_scmp) {
- if (fp->fr_scmp == FR_INRANGE || fp->fr_scmp == FR_OUTRANGE)
- printf("port %d %s %d ", fp->fr_sport,
- pcmp1[fp->fr_scmp], fp->fr_stop);
- else
- printf("port %s %s ", pcmp1[fp->fr_scmp],
- portname(pr, fp->fr_sport));
- }
+ printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
+ (u_32_t *)&fp->fr_smsk.s_addr);
+ if (fp->fr_scmp)
+ printportcmp(pr, &fp->fr_tuc.ftu_src);
+
+ printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
+ printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
+ (u_32_t *)&fp->fr_dmsk.s_addr);
+ if (fp->fr_dcmp)
+ printportcmp(pr, &fp->fr_tuc.ftu_dst);
- printf("to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
- if (!fp->fr_dst.s_addr && !fp->fr_dmsk.s_addr)
- printf("any");
- else {
- printf("%s", inet_ntoa(fp->fr_dst));
- if ((ones = countbits(fp->fr_dmsk.s_addr)) == -1)
- printf("/%s", inet_ntoa(fp->fr_dmsk));
- else
- printf("/%d", ones);
- }
- if (fp->fr_dcmp) {
- if (fp->fr_dcmp == FR_INRANGE || fp->fr_dcmp == FR_OUTRANGE)
- printf(" port %d %s %d", fp->fr_dport,
- pcmp1[fp->fr_dcmp], fp->fr_dtop);
- else
- printf(" port %s %s", pcmp1[fp->fr_dcmp],
- portname(pr, fp->fr_dport));
- }
if ((fp->fr_ip.fi_fl & ~FI_TCPUDP) ||
(fp->fr_mip.fi_fl & ~FI_TCPUDP) ||
fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
@@ -1575,14 +1165,20 @@ struct frentry *fp;
}
if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
printf(" flags ");
- for (s = flagset, t = flags; *s; s++, t++)
- if (fp->fr_tcpf & *t)
- (void)putchar(*s);
- if (fp->fr_tcpfm) {
- (void)putchar('/');
+ if (fp->fr_tcpf & ~TCPF_ALL)
+ printf("0x%x", fp->fr_tcpf);
+ else
for (s = flagset, t = flags; *s; s++, t++)
- if (fp->fr_tcpfm & *t)
+ if (fp->fr_tcpf & *t)
(void)putchar(*s);
+ if (fp->fr_tcpfm) {
+ (void)putchar('/');
+ if (fp->fr_tcpfm & ~TCPF_ALL)
+ printf("0x%x", fp->fr_tcpfm);
+ else
+ for (s = flagset, t = flags; *s; s++, t++)
+ if (fp->fr_tcpfm & *t)
+ (void)putchar(*s);
}
}
@@ -1645,18 +1241,3 @@ frentry_t *fp;
printf("%s", u);
}
}
-
-
-int ratoi(ps, pi, min, max)
-char *ps;
-int *pi, min, max;
-{
- int i;
- char *pe;
-
- i = (int)strtol(ps, &pe, 0);
- if (*pe != '\0' || i < min || i > max)
- return 0;
- *pi = i;
- return 1;
-}
diff --git a/sbin/ipfstat/Makefile b/sbin/ipfstat/Makefile
index ab29321d47e..60c98824ff7 100644
--- a/sbin/ipfstat/Makefile
+++ b/sbin/ipfstat/Makefile
@@ -1,11 +1,9 @@
-# $OpenBSD: Makefile,v 1.6 1999/12/16 07:38:45 kjell Exp $
+# $OpenBSD: Makefile,v 1.7 2001/01/17 05:01:00 fgsch Exp $
PROG= ipfstat
MAN= ipfstat.8
-SRCS= fils.c parse.c opt.c kmem.c facpri.c ifaddr.c
+SRCS= fils.c parse.c opt.c kmem.c facpri.c common.c ifaddr.c
.PATH: ${.CURDIR}/../../sbin/ipf
CFLAGS+=-I${.CURDIR}/../../sbin/ipf
-
-
.include <bsd.prog.mk>
diff --git a/sbin/ipfstat/fils.c b/sbin/ipfstat/fils.c
index 9f005ecb62f..cbf412089c3 100644
--- a/sbin/ipfstat/fils.c
+++ b/sbin/ipfstat/fils.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: fils.c,v 1.22 2000/11/14 18:56:31 aaron Exp $ */
+/* $OpenBSD: fils.c,v 1.23 2001/01/17 05:01:00 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -19,11 +19,18 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/file.h>
+#if defined(STATETOP) && defined(sun) && !defined(__svr4__) && !defined(__SVR4)
+#include <sys/select.h>
+#endif
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stddef.h>
#include <nlist.h>
+#ifdef STATETOP
+#include <ctype.h>
+#include <ncurses.h>
+#endif
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
@@ -38,7 +45,11 @@
#include <arpa/nameser.h>
#include <resolv.h>
#include <netinet/tcp.h>
-#include <netinet/ip_fil_compat.h>
+#if defined(STATETOP) && !defined(linux)
+# include <netinet/ip_var.h>
+# include <netinet/tcp_fsm.h>
+#endif
+#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include "ipf.h"
#include <netinet/ip_proxy.h>
@@ -46,16 +57,23 @@
#include <netinet/ip_frag.h>
#include <netinet/ip_state.h>
#include <netinet/ip_auth.h>
+#ifdef STATETOP
+#include <netinet/ipl.h>
+#endif
#include "kmem.h"
#if defined(__NetBSD__) || (__OpenBSD__)
# include <paths.h>
#endif
#if !defined(lint)
-static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: fils.c,v 2.2.2.7 2000/05/24 20:34:56 darrenr Exp $";
+static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: fils.c,v 2.21.2.7 2000/12/02 00:13:56 darrenr Exp $";
#endif
+extern char *optarg;
+
+#define PRINTF (void)printf
+#define FPRINTF (void)fprintf
#define F_IN 0
#define F_OUT 1
#define F_AC 2
@@ -63,8 +81,34 @@ static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
"ipacct(in)", "ipacct(out)" };
int opts = 0;
+#ifdef USE_INET6
+int use_inet6 = 0;
+#endif
+
+#ifdef STATETOP
+#define STSTRSIZE 80
+#define STGROWSIZE 16
-char *nlistf = NULL, *memf = NULL;
+#define STSORT_PR 0
+#define STSORT_PKTS 1
+#define STSORT_BYTES 2
+#define STSORT_TTL 3
+#define STSORT_MAX STSORT_TTL
+#define STSORT_DEFAULT STSORT_BYTES
+
+
+typedef struct statetop {
+ union i6addr st_src;
+ union i6addr st_dst;
+ u_short st_sport;
+ u_short st_dport;
+ u_char st_p;
+ u_char st_state[2];
+ U_QUAD_T st_pkts;
+ U_QUAD_T st_bytes;
+ u_long st_age;
+} statetop_t;
+#endif
extern int main __P((int, char *[]));
static void showstats __P((int, friostat_t *));
@@ -76,14 +120,49 @@ static void showgroups __P((friostat_t *));
static void Usage __P((char *));
static void printlist __P((frentry_t *));
static char *get_ifname __P((void *));
+static char *hostname __P((int, void *));
+static void parse_ipportstr __P((const char *, struct in_addr *, int *));
+#ifdef STATETOP
+static void topipstates __P((int, struct in_addr, struct in_addr, int, int, int, int, int));
+static char *ttl_to_string __P((long));
+static int sort_p __P((const void *, const void *));
+static int sort_pkts __P((const void *, const void *));
+static int sort_bytes __P((const void *, const void *));
+static int sort_ttl __P((const void *, const void *));
+#endif
+
+static char *hostname(v, ip)
+int v;
+void *ip;
+{
+#ifdef USE_INET6
+ static char hostbuf[MAXHOSTNAMELEN+1];
+#endif
+ struct in_addr ipa;
+
+ if (v == 4) {
+ ipa.s_addr = *(u_32_t *)ip;
+ return inet_ntoa(ipa);
+ }
+#ifdef USE_INET6
+ (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
+ hostbuf[MAXHOSTNAMELEN] = '\0';
+ return hostbuf;
+#else
+ return "IPv6";
+#endif
+}
static void Usage(name)
char *name;
{
- fprintf(stderr,
- "usage: %s [-aAfghIinosv] [-d device] [-M core]\n",
- name);
+#ifdef USE_INET6
+ fprintf(stderr, "Usage: %s [-6aAfhIinosv] [-d <device>]\n", name);
+#else
+ fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
+#endif
+ fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d <device>]\n", name);
exit(1);
}
@@ -93,25 +172,57 @@ int argc;
char *argv[];
{
fr_authstat_t frauthst;
+ fr_authstat_t *frauthstp = &frauthst;
friostat_t fio;
+ friostat_t *fiop=&fio;
ips_stat_t ipsst;
+ ips_stat_t *ipsstp = &ipsst;
ipfrstat_t ifrst;
+ ipfrstat_t *ifrstp = &ifrst;
char *name = NULL, *device = IPL_NAME;
int c, fd;
+ struct protoent *proto;
+
+ int protocol = -1; /* -1 = wild card for any protocol */
+ int refreshtime = 1; /* default update time */
+ int sport = -1; /* -1 = wild card for any source port */
+ int dport = -1; /* -1 = wild card for any dest port */
+ int topclosed = 0; /* do not show closed tcp sessions */
+ struct in_addr saddr, daddr;
+ saddr.s_addr = INADDR_ANY; /* default any source addr */
+ daddr.s_addr = INADDR_ANY; /* default any dest addr */
+
+ if (openkmem() == -1)
+ exit(-1);
+
+ (void)setuid(getuid());
+ (void)setgid(getgid());
- while ((c = getopt(argc, argv, "AafhgIinosvd:M:")) != -1)
+ while ((c = getopt(argc, argv, "6aACfghIilnostvd:D:P:S:T:")) != -1)
{
switch (c)
{
+#ifdef USE_INET6
+ case '6' :
+ use_inet6 = 1;
+ break;
+#endif
case 'a' :
opts |= OPT_ACCNT|OPT_SHOWLIST;
break;
case 'A' :
+ device = IPAUTH_NAME;
opts |= OPT_AUTHSTATS;
break;
+ case 'C' :
+ topclosed = 1;
+ break;
case 'd' :
device = optarg;
break;
+ case 'D' :
+ parse_ipportstr(optarg, &daddr, &dport);
+ break;
case 'f' :
opts |= OPT_FRSTATES;
break;
@@ -127,38 +238,59 @@ char *argv[];
case 'I' :
opts |= OPT_INACTIVE;
break;
+ case 'l' :
+ opts |= OPT_SHOWLIST;
+ break;
case 'n' :
opts |= OPT_SHOWLINENO;
break;
case 'o' :
opts |= OPT_OUTQUE|OPT_SHOWLIST;
break;
+ case 'P' :
+ if ((proto = getprotobyname(optarg)) != NULL) {
+ protocol = proto->p_proto;
+ } else if (!sscanf(optarg, "%ud", &protocol) ||
+ (protocol < 0)) {
+ fprintf(stderr, "%s : Invalid protocol: %s\n",
+ argv[0], optarg);
+ exit(-2);
+ }
+ break;
case 's' :
opts |= OPT_IPSTATES;
break;
+ case 'S' :
+ parse_ipportstr(optarg, &saddr, &sport);
+ break;
+ case 't' :
+#ifdef STATETOP
+ opts |= OPT_STATETOP;
+ break;
+#else
+ fprintf(stderr,
+ "%s : state top facility not compiled in\n",
+ argv[0]);
+ exit(-2);
+#endif
+ case 'T' :
+ if (!sscanf(optarg, "%d", &refreshtime) ||
+ (refreshtime <= 0)) {
+ fprintf(stderr,
+ "%s : Invalid refreshtime < 1 : %s\n",
+ argv[0], optarg);
+ exit(-2);
+ }
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
- case 'M':
- memf = optarg;
- break;
default :
Usage(argv[0]);
break;
}
}
- if (nlistf != NULL || memf != NULL) {
- (void)setuid(getuid());
- (void)setgid(getgid());
- }
-
- if (openkmem(nlistf, memf) == -1)
- exit(-1);
-
- (void)setuid(getuid());
- (void)setgid(getgid());
-
if ((fd = open(device, O_RDONLY)) < 0) {
perror("open");
exit(-1);
@@ -168,8 +300,8 @@ char *argv[];
bzero((char *)&ipsst, sizeof(ipsst));
bzero((char *)&ifrst, sizeof(ifrst));
- if (ioctl(fd, SIOCGETFS, &fio) == -1) {
- perror("ioctl(SIOCGETFS)");
+ if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) {
+ perror("ioctl(ipf:SIOCGETFS)");
exit(-1);
}
if ((opts & OPT_IPSTATES)) {
@@ -179,39 +311,44 @@ char *argv[];
perror("open");
exit(-1);
}
- if ((ioctl(sfd, SIOCGIPST, &ipsst) == -1)) {
- perror("ioctl(SIOCGIPST)");
+ if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
+ perror("ioctl(state:SIOCGETFS)");
exit(-1);
}
close(sfd);
}
- if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrst) == -1)) {
+ if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, &ifrstp) == -1)) {
perror("ioctl(SIOCGFRST)");
exit(-1);
}
if (opts & OPT_VERBOSE)
- printf("opts %#x name %s\n", opts, name ? name : "<>");
+ PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
if ((opts & OPT_AUTHSTATS) &&
- (ioctl(fd, SIOCATHST, &frauthst) == -1)) {
+ (ioctl(fd, SIOCATHST, &frauthstp) == -1)) {
perror("ioctl(SIOCATHST)");
exit(-1);
}
- if (opts & OPT_SHOWLIST) {
+ if (opts & OPT_IPSTATES) {
+ showipstates(fd, ipsstp);
+ } else if (opts & OPT_SHOWLIST) {
showlist(&fio);
if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
opts &= ~OPT_OUTQUE;
showlist(&fio);
}
} else {
- if (opts & OPT_IPSTATES)
- showipstates(fd, &ipsst);
- else if (opts & OPT_FRSTATES)
- showfrstates(fd, &ifrst);
+ if (opts & OPT_FRSTATES)
+ showfrstates(fd, ifrstp);
+#ifdef STATETOP
+ else if (opts & OPT_STATETOP)
+ topipstates(fd, saddr, daddr, sport, dport,
+ protocol, refreshtime, topclosed);
+#endif
else if (opts & OPT_AUTHSTATS)
- showauthstates(fd, &frauthst);
+ showauthstates(fd, frauthstp);
else if (opts & OPT_GROUPS)
showgroups(&fio);
else
@@ -234,67 +371,72 @@ struct friostat *fp;
perror("ioctl(SIOCGETFF)");
#if SOLARIS
- printf("dropped packets:\tin %lu\tout %lu\n",
+ PRINTF("dropped packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_drop, fp->f_st[1].fr_drop);
- printf("non-data packets:\tin %lu\tout %lu\n",
+ PRINTF("non-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_notdata, fp->f_st[1].fr_notdata);
- printf("no-data packets:\tin %lu\tout %lu\n",
+ PRINTF("no-data packets:\tin %lu\tout %lu\n",
fp->f_st[0].fr_nodata, fp->f_st[1].fr_nodata);
- printf("non-ip packets:\t\tin %lu\tout %lu\n",
+ PRINTF("non-ip packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_notip, fp->f_st[1].fr_notip);
- printf(" bad packets:\t\tin %lu\tout %lu\n",
+ PRINTF(" bad packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
- printf("copied messages:\tin %lu\tout %lu\n",
+ PRINTF("copied messages:\tin %lu\tout %lu\n",
fp->f_st[0].fr_copy, fp->f_st[1].fr_copy);
#endif
- printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
+#ifdef USE_INET6
+ PRINTF(" IPv6 packets:\t\tin %lu out %lu\n",
+ fp->f_st[0].fr_ipv6[0], fp->f_st[0].fr_ipv6[1]);
+#endif
+ PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
fp->f_st[0].fr_nom);
- printf(" counted %lu short %lu\n",
+ PRINTF(" counted %lu short %lu\n",
fp->f_st[0].fr_acct, fp->f_st[0].fr_short);
- printf("output packets:\t\tblocked %lu passed %lu nomatch %lu",
+ PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu",
fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
fp->f_st[1].fr_nom);
- printf(" counted %lu short %lu\n",
+ PRINTF(" counted %lu short %lu\n",
fp->f_st[1].fr_acct, fp->f_st[1].fr_short);
- printf(" input packets logged:\tblocked %lu passed %lu\n",
+ PRINTF(" input packets logged:\tblocked %lu passed %lu\n",
fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
- printf("output packets logged:\tblocked %lu passed %lu\n",
+ PRINTF("output packets logged:\tblocked %lu passed %lu\n",
fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl);
- printf(" packets logged:\tinput %lu output %lu\n",
+ PRINTF(" packets logged:\tinput %lu output %lu\n",
fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl);
- printf(" log failures:\t\tinput %lu output %lu\n",
+ PRINTF(" log failures:\t\tinput %lu output %lu\n",
fp->f_st[0].fr_skip, fp->f_st[1].fr_skip);
- printf("fragment state(in):\tkept %lu\tlost %lu\n",
+ PRINTF("fragment state(in):\tkept %lu\tlost %lu\n",
fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr);
- printf("fragment state(out):\tkept %lu\tlost %lu\n",
+ PRINTF("fragment state(out):\tkept %lu\tlost %lu\n",
fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr);
- printf("packet state(in):\tkept %lu\tlost %lu\n",
+ PRINTF("packet state(in):\tkept %lu\tlost %lu\n",
fp->f_st[0].fr_ads, fp->f_st[0].fr_bads);
- printf("packet state(out):\tkept %lu\tlost %lu\n",
+ PRINTF("packet state(out):\tkept %lu\tlost %lu\n",
fp->f_st[1].fr_ads, fp->f_st[1].fr_bads);
- printf("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n",
+ PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n",
fp->f_st[0].fr_ret, fp->f_st[1].fr_ret);
- printf("Result cache hits(in):\t%lu\t(out):\t%lu\n",
+ PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc);
+ PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n",
fp->f_st[0].fr_chit, fp->f_st[1].fr_chit);
- printf("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n",
+ PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n",
fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]);
- printf("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n",
+ PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n",
fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]);
- printf("Fastroute successes:\t%lu\tfailures:\t%lu\n",
+ PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n",
fp->f_froute[0], fp->f_froute[1]);
- printf("TCP cksum fails(in):\t%lu\t(out):\t%lu\n",
+ PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n",
fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad);
- printf("Packet log flags set: (%#x)\n", frf);
+ PRINTF("Packet log flags set: (%#x)\n", frf);
if (frf & FF_LOGPASS)
- printf("\tpackets passed through filter\n");
+ PRINTF("\tpackets passed through filter\n");
if (frf & FF_LOGBLOCK)
- printf("\tpackets blocked by filter\n");
+ PRINTF("\tpackets blocked by filter\n");
if (frf & FF_LOGNOMATCH)
- printf("\tpackets not matched by filter\n");
+ PRINTF("\tpackets not matched by filter\n");
if (!frf)
- printf("\tnone\n");
+ PRINTF("\tnone\n");
}
@@ -314,18 +456,18 @@ frentry_t *fp;
fp->fr_flags |= FR_OUTQUE;
if (opts & (OPT_HITS|OPT_VERBOSE))
#ifdef USE_QUAD_T
- printf("%qu ", fp->fr_hits);
+ PRINTF("%qu ", (unsigned long long) fp->fr_hits);
#else
- printf("%lu ", fp->fr_hits);
+ PRINTF("%lu ", fp->fr_hits);
#endif
if (opts & (OPT_ACCNT|OPT_VERBOSE))
#ifdef USE_QUAD_T
- printf("%qu ", fp->fr_bytes);
+ PRINTF("%qu ", (unsigned long long) fp->fr_bytes);
#else
- printf("%lu ", fp->fr_bytes);
+ PRINTF("%lu ", fp->fr_bytes);
#endif
if (opts & OPT_SHOWLINENO)
- printf("@%d ", n);
+ PRINTF("@%d ", n);
printfr(fp);
if (opts & OPT_VERBOSE)
binprint(fp);
@@ -355,24 +497,35 @@ struct friostat *fiop;
} else if (opts & OPT_INQUE)
fp = (struct frentry *)fiop->f_acctin[set];
else {
- fprintf(stderr, "No -i or -o given with -a\n");
+ FPRINTF(stderr, "No -i or -o given with -a\n");
return;
}
- } else if (opts & OPT_OUTQUE) {
- i = F_OUT;
- fp = (struct frentry *)fiop->f_fout[set];
- } else if (opts & OPT_INQUE) {
- i = F_IN;
- fp = (struct frentry *)fiop->f_fin[set];
- } else
- return;
+ } else {
+#ifdef USE_INET6
+ if ((use_inet6) && (opts & OPT_OUTQUE)) {
+ i = F_OUT;
+ fp = (struct frentry *)fiop->f_fout6[set];
+ } else if ((use_inet6) && (opts & OPT_INQUE)) {
+ i = F_IN;
+ fp = (struct frentry *)fiop->f_fin6[set];
+ } else
+#endif
+ if (opts & OPT_OUTQUE) {
+ i = F_OUT;
+ fp = (struct frentry *)fiop->f_fout[set];
+ } else if (opts & OPT_INQUE) {
+ i = F_IN;
+ fp = (struct frentry *)fiop->f_fin[set];
+ } else
+ return;
+ }
if (opts & OPT_VERBOSE)
- fprintf(stderr, "showlist:opts %#x i %d\n", opts, i);
+ FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i);
if (opts & OPT_VERBOSE)
- printf("fp %p set %d\n", fp, set);
+ PRINTF("fp %p set %d\n", fp, set);
if (!fp) {
- fprintf(stderr, "empty list for %s%s\n",
+ FPRINTF(stderr, "empty list for %s%s\n",
(opts & OPT_INACTIVE) ? "inactive " : "", filters[i]);
return;
}
@@ -385,126 +538,433 @@ int fd;
ips_stat_t *ipsp;
{
ipstate_t *istab[IPSTATE_SIZE], ips;
- int i;
- printf("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n",
- ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp);
- printf("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, ipsp->iss_miss);
- printf("\t%lu maximum\n\t%lu no memory\n\tbuckets in use\t%lu\n",
- ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse);
- printf("\t%lu active\n\t%lu expired\n\t%lu closed\n",
- ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
+ if (!(opts & OPT_SHOWLIST)) {
+ PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n",
+ ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp);
+ PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits,
+ ipsp->iss_miss);
+ PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n",
+ ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse);
+ PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n",
+ ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
+ return;
+ }
+
if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab)))
return;
- for (i = 0; i < IPSTATE_SIZE; i++) {
- while (istab[i]) {
- if (kmemcpy((char *)&ips, (u_long)istab[i],
- sizeof(ips)) == -1)
- break;
- printf("%s -> ", inet_ntoa(ips.is_src));
- printf("%s ttl %ld pass %#x pr %d state %d/%d\n",
- inet_ntoa(ips.is_dst), ips.is_age,
- ips.is_pass, ips.is_p, ips.is_state[0],
- ips.is_state[1]);
+
+ while (ipsp->iss_list) {
+ if (kmemcpy((char *)&ips, (u_long)ipsp->iss_list, sizeof(ips)))
+ break;
+ ipsp->iss_list = ips.is_next;
+ PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4));
+ PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n",
+ hostname(ips.is_v, &ips.is_dst.in4),
+ ips.is_age, ips.is_pass, ips.is_p,
+ ips.is_state[0], ips.is_state[1]);
#ifdef USE_QUAD_T
- printf("\tpkts %qd bytes %qd",
- ips.is_pkts, ips.is_bytes);
+ PRINTF("\tpkts %qu bytes %qu",
+ (unsigned long long) ips.is_pkts,
+ (unsigned long long) ips.is_bytes);
#else
- printf("\tpkts %ld bytes %ld",
- ips.is_pkts, ips.is_bytes);
+ PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes);
#endif
- if (ips.is_p == IPPROTO_TCP)
+ if (ips.is_p == IPPROTO_TCP)
#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
(__FreeBSD_version >= 220000) || defined(__OpenBSD__)
- printf("\t%hu -> %hu %x:%x %hu:%hu",
- ntohs(ips.is_sport),
- ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
+ PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
+ ntohs(ips.is_sport), ntohs(ips.is_dport),
+ ips.is_send, ips.is_dend,
+ ips.is_maxswin, ips.is_maxdwin);
#else
- printf("\t%hu -> %hu %lx:%lx %hu:%hu",
- ntohs(ips.is_sport),
- ntohs(ips.is_dport),
- ips.is_send, ips.is_dend,
- ips.is_maxswin, ips.is_maxdwin);
+ PRINTF("\t%hu -> %hu %x:%x %hu:%hu",
+ ntohs(ips.is_sport), ntohs(ips.is_dport),
+ ips.is_send, ips.is_dend,
+ ips.is_maxswin, ips.is_maxdwin);
#endif
- else if (ips.is_p == IPPROTO_UDP)
- printf(" %hu -> %hu", ntohs(ips.is_sport),
- ntohs(ips.is_dport));
- else if (ips.is_p == IPPROTO_ICMP)
- printf(" %hu %hu %d", ips.is_icmp.ics_id,
- ips.is_icmp.ics_seq,
- ips.is_icmp.ics_type);
-
- printf("\n\t");
-
- if (ips.is_pass & FR_PASS) {
- printf("pass");
- } else if (ips.is_pass & FR_BLOCK) {
- printf("block");
- switch (ips.is_pass & FR_RETMASK)
- {
- case FR_RETICMP :
- printf(" return-icmp");
- break;
- case FR_FAKEICMP :
- printf(" return-icmp-as-dest");
- break;
- case FR_RETRST :
- printf(" return-rst");
- break;
- default :
- break;
- }
- } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
- printf("log");
- if (ips.is_pass & FR_LOGBODY)
- printf(" body");
- if (ips.is_pass & FR_LOGFIRST)
- printf(" first");
- } else if (ips.is_pass & FR_ACCOUNT)
- printf("count");
-
- if (ips.is_pass & FR_OUTQUE)
- printf(" out");
- else
- printf(" in");
-
- if ((ips.is_pass & FR_LOG) != 0) {
- printf(" log");
- if (ips.is_pass & FR_LOGBODY)
- printf(" body");
- if (ips.is_pass & FR_LOGFIRST)
- printf(" first");
- if (ips.is_pass & FR_LOGORBLOCK)
- printf(" or-block");
+ else if (ips.is_p == IPPROTO_UDP)
+ PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
+ ntohs(ips.is_dport));
+ else if (ips.is_p == IPPROTO_ICMP
+#ifdef USE_INET6
+ || ips.is_p == IPPROTO_ICMPV6
+#endif
+ )
+ PRINTF(" %hu %hu %d", ips.is_icmp.ics_id,
+ ips.is_icmp.ics_seq, ips.is_icmp.ics_type);
+
+ PRINTF("\n\t");
+
+ if (ips.is_pass & FR_PASS) {
+ PRINTF("pass");
+ } else if (ips.is_pass & FR_BLOCK) {
+ PRINTF("block");
+ switch (ips.is_pass & FR_RETMASK)
+ {
+ case FR_RETICMP :
+ PRINTF(" return-icmp");
+ break;
+ case FR_FAKEICMP :
+ PRINTF(" return-icmp-as-dest");
+ break;
+ case FR_RETRST :
+ PRINTF(" return-rst");
+ break;
+ default :
+ break;
}
- if (ips.is_pass & FR_QUICK)
- printf(" quick");
- if (ips.is_pass & FR_KEEPFRAG)
- printf(" keep frags");
- /* a given; no? */
- if (ips.is_pass & FR_KEEPSTATE)
- printf(" keep state");
- printf("\n");
-
- printf("\tpkt_flags & %x(%x) = %x,\t",
- ips.is_flags & 0xf, ips.is_flags,
- ips.is_flags >> 4);
- printf("\tpkt_options & %x = %x\n", ips.is_optmsk,
- ips.is_opt);
- printf("\tpkt_security & %x = %x, pkt_auth & %x = %x\n",
- ips.is_secmsk, ips.is_sec, ips.is_authmsk,
- ips.is_auth);
- istab[i] = ips.is_next;
- printf("interfaces: in %s[%p] ",
- get_ifname(ips.is_ifpin), ips.is_ifpin);
- printf("out %s[%p]\n",
- get_ifname(ips.is_ifpout), ips.is_ifpout);
+ } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
+ PRINTF("log");
+ if (ips.is_pass & FR_LOGBODY)
+ PRINTF(" body");
+ if (ips.is_pass & FR_LOGFIRST)
+ PRINTF(" first");
+ } else if (ips.is_pass & FR_ACCOUNT)
+ PRINTF("count");
+
+ if (ips.is_pass & FR_OUTQUE)
+ PRINTF(" out");
+ else
+ PRINTF(" in");
+
+ if ((ips.is_pass & FR_LOG) != 0) {
+ PRINTF(" log");
+ if (ips.is_pass & FR_LOGBODY)
+ PRINTF(" body");
+ if (ips.is_pass & FR_LOGFIRST)
+ PRINTF(" first");
+ if (ips.is_pass & FR_LOGORBLOCK)
+ PRINTF(" or-block");
}
+ if (ips.is_pass & FR_QUICK)
+ PRINTF(" quick");
+ if (ips.is_pass & FR_KEEPFRAG)
+ PRINTF(" keep frags");
+ /* a given; no? */
+ if (ips.is_pass & FR_KEEPSTATE)
+ PRINTF(" keep state");
+ PRINTF("\tIPv%d", ips.is_v);
+ PRINTF("\n");
+
+ PRINTF("\tpkt_flags & %x(%x) = %x,\t",
+ ips.is_flags & 0xf, ips.is_flags,
+ ips.is_flags >> 4);
+ PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk,
+ ips.is_opt);
+ PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n",
+ ips.is_secmsk, ips.is_sec, ips.is_authmsk,
+ ips.is_auth);
+ PRINTF("interfaces: in %s[%p] ",
+ get_ifname(ips.is_ifpin), ips.is_ifpin);
+ PRINTF("out %s[%p]\n",
+ get_ifname(ips.is_ifpout), ips.is_ifpout);
}
}
+#ifdef STATETOP
+static void topipstates(fd, saddr, daddr, sport, dport, protocol,
+ refreshtime, topclosed)
+int fd;
+struct in_addr saddr;
+struct in_addr daddr;
+int sport;
+int dport;
+int protocol;
+int refreshtime;
+int topclosed;
+{
+ char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE];
+ int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT;
+ int i, j, sfd, winx, tsentry, maxx, maxy, redraw = 0;
+ ipstate_t *istab[IPSTATE_SIZE], ips;
+ ips_stat_t ipsst, *ipsstp = &ipsst;
+ statetop_t *tstable = NULL, *tp;
+ struct timeval selecttimeout;
+ struct protoent *proto;
+ fd_set readfd;
+ char c = '\0';
+ time_t t;
+
+ /* open state device */
+ if ((sfd = open(IPL_STATE, O_RDONLY)) == -1) {
+ perror("open");
+ exit(-1);
+ }
+
+ /* init ncurses stuff */
+ initscr();
+ cbreak();
+ noecho();
+ nodelay(stdscr, 1);
+
+ /* repeat until user aborts */
+ while ( 1 ) {
+
+ /* get state table */
+ bzero((char *)&ipsst, sizeof(&ipsst));
+ if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
+ perror("ioctl(SIOCGETFS)");
+ exit(-1);
+ }
+ if (kmemcpy((char *)istab, (u_long)ipsstp->iss_table,
+ sizeof(ips)))
+ return;
+
+ /* clear the history */
+ tsentry = -1;
+
+ /* read the state table and store in tstable */
+ while (ipsstp->iss_list) {
+ if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list,
+ sizeof(ips)))
+ break;
+ ipsstp->iss_list = ips.is_next;
+
+ if (((saddr.s_addr == INADDR_ANY) ||
+ (saddr.s_addr == ips.is_saddr)) &&
+ ((daddr.s_addr == INADDR_ANY) ||
+ (daddr.s_addr == ips.is_daddr)) &&
+ ((protocol < 0) || (protocol == ips.is_p)) &&
+ (((ips.is_p != IPPROTO_TCP) &&
+ (ips.is_p != IPPROTO_UDP)) ||
+ (((sport < 0) ||
+ (htons(sport) == ips.is_sport)) &&
+ ((dport < 0) ||
+ (htons(dport) == ips.is_dport)))) &&
+ (topclosed || (ips.is_p != IPPROTO_TCP) ||
+ (ips.is_state[0] < TCPS_CLOSE_WAIT) ||
+ (ips.is_state[1] < TCPS_CLOSE_WAIT))) {
+ /*
+ * if necessary make room for this state
+ * entry
+ */
+ tsentry++;
+ if (!maxtsentries ||
+ (tsentry == maxtsentries)) {
+
+ maxtsentries += STGROWSIZE;
+ tstable = realloc(tstable, maxtsentries * sizeof(statetop_t));
+ if (!tstable) {
+ perror("malloc");
+ exit(-1);
+ }
+ }
+
+ /* fill structure */
+ tp = tstable + tsentry;
+ tp->st_src = ips.is_src;
+ tp->st_dst = ips.is_dst;
+ tp->st_p = ips.is_p;
+ tp->st_state[0] = ips.is_state[0];
+ tp->st_state[1] = ips.is_state[1];
+ tp->st_pkts = ips.is_pkts;
+ tp->st_bytes = ips.is_bytes;
+ tp->st_age = ips.is_age;
+ if ((ips.is_p == IPPROTO_TCP) ||
+ (ips.is_p == IPPROTO_UDP)) {
+ tp->st_sport = ips.is_sport;
+ tp->st_dport = ips.is_dport;
+ }
+
+ }
+ }
+
+
+ /* sort the array */
+ if (tsentry != -1)
+ switch (sorting)
+ {
+ case STSORT_PR:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_p);
+ break;
+ case STSORT_PKTS:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_pkts);
+ break;
+ case STSORT_BYTES:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_bytes);
+ break;
+ case STSORT_TTL:
+ qsort(tstable, tsentry + 1,
+ sizeof(statetop_t), sort_ttl);
+ break;
+ default:
+ break;
+ }
+
+ /* print title */
+ erase();
+ getmaxyx(stdscr, maxy, maxx);
+ attron(A_BOLD);
+ winx = 0;
+ move(winx,0);
+ sprintf(str1, "%s - state top", IPL_VERSION);
+ for(j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++)
+ printw(" ");
+ printw("%s", str1);
+ attroff(A_BOLD);
+
+ /* just for fun add a clock */
+ move(winx, maxx - 8);
+ t = time(NULL);
+ strftime(str1, 80, "%T", localtime(&t));
+ printw("%s\n", str1);
+
+ /*
+ * print the display filters, this is placed in the loop,
+ * because someday I might add code for changing these
+ * while the programming is running :-)
+ */
+ if (sport >= 0)
+ sprintf(str1, "%s,%d", inet_ntoa(saddr), sport);
+ else
+ sprintf(str1, "%s", inet_ntoa(saddr));
+
+ if (dport >= 0)
+ sprintf(str2, "%s,%d", inet_ntoa(daddr), dport);
+ else
+ sprintf(str2, "%s", inet_ntoa(daddr));
+
+ if (protocol < 0)
+ strcpy(str3, "any");
+ else if ((proto = getprotobynumber(protocol)) != NULL)
+ sprintf(str3, "%s", proto->p_name);
+ else
+ sprintf(str3, "%d", protocol);
+
+ switch (sorting)
+ {
+ case STSORT_PR:
+ sprintf(str4, "proto");
+ break;
+ case STSORT_PKTS:
+ sprintf(str4, "# pkts");
+ break;
+ case STSORT_BYTES:
+ sprintf(str4, "# bytes");
+ break;
+ case STSORT_TTL:
+ sprintf(str4, "ttl");
+ break;
+ default:
+ sprintf(str4, "unknown");
+ break;
+ }
+
+ if (reverse)
+ strcat(str4, " (reverse)");
+
+ winx += 2;
+ move(winx,0);
+ printw("Src = %s Dest = %s Proto = %s Sorted by = %s\n\n",
+ str1, str2, str3, str4);
+
+ /* print column description */
+ winx += 2;
+ move(winx,0);
+ attron(A_BOLD);
+ printw("%-21s %-21s %3s %4s %7s %9s %9s\n", "Source IP",
+ "Destination IP", "ST", "PR", "#pkts", "#bytes", "ttl");
+ attroff(A_BOLD);
+
+ /* print all the entries */
+ tp = tstable;
+ if (reverse)
+ tp += tsentry;
+
+ for(i = 0; i <= tsentry; i++) {
+ /* print src/dest and port */
+ if ((tp->st_p == IPPROTO_TCP) ||
+ (tp->st_p == IPPROTO_UDP)) {
+ sprintf(str1, "%s,%hu",
+ inet_ntoa(tp->st_src.in4),
+ ntohs(tp->st_sport));
+ sprintf(str2, "%s,%hu",
+ inet_ntoa(tp->st_dst.in4),
+ ntohs(tp->st_dport));
+ } else {
+ sprintf(str1, "%s", inet_ntoa(tp->st_src.in4));
+ sprintf(str2, "%s", inet_ntoa(tp->st_dst.in4));
+ }
+ winx++;
+ move(winx, 0);
+ printw("%-21s %-21s", str1, str2);
+
+ /* print state */
+ sprintf(str1, "%X/%X", tp->st_state[0],
+ tp->st_state[1]);
+ printw(" %3s", str1);
+
+ /* print proto */
+ proto = getprotobynumber(tp->st_p);
+ if (proto) {
+ strncpy(str1, proto->p_name, 4);
+ str1[4] = '\0';
+ } else {
+ sprintf(str1, "%d", tp->st_p);
+ }
+ printw(" %4s", str1);
+ /* print #pkt/#bytes */
+#ifdef USE_QUAD_T
+ printw(" %7qu %9qu", (unsigned long long) tp->st_pkts,
+ (unsigned long long) tp->st_bytes);
+#else
+ printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes);
+#endif
+ printw(" %9s", ttl_to_string(tp->st_age));
+
+ if (reverse)
+ tp--;
+ else
+ tp++;
+ }
+
+ /* screen data structure is filled, now update the screen */
+ if (redraw)
+ clearok(stdscr,1);
+
+ refresh();
+ if (redraw) {
+ clearok(stdscr,0);
+ redraw = 0;
+ }
+
+ /* wait for key press or a 1 second time out period */
+ selecttimeout.tv_sec = refreshtime;
+ selecttimeout.tv_usec = 0;
+ FD_ZERO(&readfd);
+ FD_SET(0, &readfd);
+ select(1, &readfd, NULL, NULL, &selecttimeout);
+
+ /* if key pressed, read all waiting keys */
+ if (FD_ISSET(0, &readfd))
+ while ((c = wgetch(stdscr)) != ERR) {
+ if (tolower(c) == 'l') {
+ redraw = 1;
+ } else if (tolower(c) == 'q') {
+ nocbreak();
+ endwin();
+ exit(0);
+ } else if (tolower(c) == 'r') {
+ reverse = !reverse;
+ } else if (tolower(c) == 's') {
+ sorting++;
+ if (sorting > STSORT_MAX)
+ sorting = 0;
+ }
+ }
+ } /* while */
+
+ close(sfd);
+
+ printw("\n");
+ nocbreak();
+ endwin();
+}
+#endif
static void showfrstates(fd, ifsp)
int fd;
@@ -514,11 +974,11 @@ ipfrstat_t *ifsp;
frentry_t fr;
int i;
- printf("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
+ PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits);
- printf("\t%lu no memory\n\t%lu already exist\n",
+ PRINTF("\t%lu no memory\n\t%lu already exist\n",
ifsp->ifs_nomem, ifsp->ifs_exists);
- printf("\t%lu inuse\n", ifsp->ifs_inuse);
+ PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab)))
return;
for (i = 0; i < IPFT_SIZE; i++)
@@ -526,12 +986,29 @@ ipfrstat_t *ifsp;
if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
sizeof(ifr)) == -1)
break;
- printf("%s -> ", inet_ntoa(ifr.ipfr_src));
+ PRINTF("%s -> ", hostname(4, &ifr.ipfr_src));
+ if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
+ sizeof(fr)) == -1)
+ break;
+ PRINTF("%s %d %d %d %#02x = %#x\n",
+ hostname(4, &ifr.ipfr_dst), ifr.ipfr_id,
+ ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
+ fr.fr_flags);
+ ipfrtab[i] = ifr.ipfr_next;
+ }
+ if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab)))
+ return;
+ for (i = 0; i < IPFT_SIZE; i++)
+ while (ipfrtab[i]) {
+ if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
+ sizeof(ifr)) == -1)
+ break;
+ PRINTF("NAT: %s -> ", hostname(4, &ifr.ipfr_src));
if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
sizeof(fr)) == -1)
break;
- printf("%s %d %d %d %#02x = %#x\n",
- inet_ntoa(ifr.ipfr_dst), ifr.ipfr_id,
+ PRINTF("%s %d %d %d %#02x = %#x\n",
+ hostname(4, &ifr.ipfr_dst), ifr.ipfr_id,
ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
fr.fr_flags);
ipfrtab[i] = ifr.ipfr_next;
@@ -546,8 +1023,9 @@ fr_authstat_t *asp;
frauthent_t *frap, fra;
#ifdef USE_QUAD_T
- printf("Authorisation hits: %qd\tmisses %qd\n", asp->fas_hits,
- asp->fas_miss);
+ printf("Authorisation hits: %qu\tmisses %qu\n",
+ (unsigned long long) asp->fas_hits,
+ (unsigned long long) asp->fas_miss);
#else
printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits,
asp->fas_miss);
@@ -652,3 +1130,131 @@ struct friostat *fiop;
printf("%hu\n", grp.fg_num);
}
}
+
+static void parse_ipportstr(argument, ip, port)
+const char *argument;
+struct in_addr *ip;
+int *port;
+{
+
+ char *s, *comma;
+
+ /* make working copy of argument, Theoretically you must be able
+ * to write to optarg, but that seems very ugly to me....
+ */
+ if ((s = malloc(strlen(argument) + 1)) == NULL)
+ perror("malloc");
+ strcpy(s, argument);
+
+ /* get port */
+ if ((comma = strchr(s, ',')) != NULL) {
+ if (!strcasecmp(s, "any")) {
+ *port = -1;
+ } else if (!sscanf(comma + 1, "%d", port) ||
+ (*port < 0) || (*port > 65535)) {
+ fprintf(stderr, "Invalid port specfication in %s\n",
+ argument);
+ exit(-2);
+ }
+ *comma = '\0';
+ }
+
+
+ /* get ip address */
+ if (!strcasecmp(s, "any")) {
+ ip->s_addr = INADDR_ANY;
+ } else if (!inet_aton(s, ip)) {
+ fprintf(stderr, "Invalid IP address: %s\n", s);
+ exit(-2);
+ }
+
+ /* free allocated memory */
+ free(s);
+}
+
+
+#ifdef STATETOP
+static char ttlbuf[STSTRSIZE];
+
+static char *ttl_to_string(ttl)
+long int ttl;
+{
+
+ int hours, minutes, seconds;
+
+ /* ttl is in half seconds */
+ ttl /= 2;
+
+ hours = ttl / 3600;
+ ttl = ttl % 3600;
+ minutes = ttl / 60;
+ seconds = ttl % 60;
+
+ if (hours > 0 )
+ sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds);
+ else
+ sprintf(ttlbuf, "%2d:%02d", minutes, seconds);
+ return ttlbuf;
+}
+
+
+static int sort_pkts(a, b)
+const void *a;
+const void *b;
+{
+
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ap->st_pkts == bp->st_pkts)
+ return 0;
+ else if (ap->st_pkts < bp->st_pkts)
+ return 1;
+ return -1;
+}
+
+
+static int sort_bytes(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ap->st_bytes == bp->st_bytes)
+ return 0;
+ else if (ap->st_bytes < bp->st_bytes)
+ return 1;
+ return -1;
+}
+
+
+static int sort_p(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ap->st_p == bp->st_p)
+ return 0;
+ else if (ap->st_p < bp->st_p)
+ return 1;
+ return -1;
+}
+
+
+static int sort_ttl(a, b)
+const void *a;
+const void *b;
+{
+ register const statetop_t *ap = a;
+ register const statetop_t *bp = b;
+
+ if (ap->st_age == bp->st_age)
+ return 0;
+ else if (ap->st_age < bp->st_age)
+ return 1;
+ return -1;
+}
+#endif
diff --git a/sbin/ipfstat/kmem.c b/sbin/ipfstat/kmem.c
index 0e04df3b9cc..7674d78999d 100644
--- a/sbin/ipfstat/kmem.c
+++ b/sbin/ipfstat/kmem.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: kmem.c,v 1.15 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: kmem.c,v 1.16 2001/01/17 05:01:00 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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,18 +22,14 @@
#if !defined(lint)
static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: kmem.c,v 2.1 1999/08/04 17:30:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: kmem.c,v 2.2 2000/03/13 22:10:25 darrenr Exp $";
#endif
static int kmemfd = -1;
-int openkmem(nlistf, memf)
-char *nlistf, *memf;
+int openkmem()
{
- if (memf == NULL)
- memf = KMEM;
-
- if ((kmemfd = open(memf,O_RDONLY)) == -1)
+ if ((kmemfd = open(KMEM,O_RDONLY)) == -1)
{
perror("kmeminit:open");
return -1;
@@ -51,7 +47,7 @@ register int n;
if (!n)
return 0;
if (kmemfd == -1)
- if (openkmem(nlistf, memf) == -1)
+ if (openkmem() == -1)
return -1;
if (lseek(kmemfd, pos, 0) == -1)
{
@@ -82,7 +78,7 @@ register int n;
if (!n)
return 0;
if (kmemfd == -1)
- if (openkmem(nlistf, memf) == -1)
+ if (openkmem() == -1)
return -1;
if (lseek(kmemfd, pos, 0) == -1)
{
diff --git a/sbin/ipfstat/kmem.h b/sbin/ipfstat/kmem.h
index bc01009e090..61b4ad24de4 100644
--- a/sbin/ipfstat/kmem.h
+++ b/sbin/ipfstat/kmem.h
@@ -1,12 +1,12 @@
-/* $OpenBSD: kmem.h,v 1.12 2000/03/13 23:40:19 kjell Exp $ */
+/* $OpenBSD: kmem.h,v 1.13 2001/01/17 05:01:01 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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.
- * $IPFilter: kmem.h,v 2.1 1999/08/04 17:30:10 darrenr Exp $
+ * $IPFilter: kmem.h,v 2.2 2000/03/13 22:10:25 darrenr Exp $
*/
#ifndef __KMEM_H__
@@ -19,7 +19,7 @@
# define __P(x) ()
# endif
#endif
-extern int openkmem __P((char *, char *));
+extern int openkmem __P((void));
extern int kmemcpy __P((char *, long, int));
extern int kstrncpy __P((char *, long, int));
@@ -27,9 +27,6 @@ extern int kstrncpy __P((char *, long, int));
# include <paths.h>
#endif
-extern char *nlistf;
-extern char *memf;
-
#ifdef _PATH_KMEM
# define KMEM _PATH_KMEM
#else
diff --git a/sbin/ipnat/Makefile b/sbin/ipnat/Makefile
index 10d4bf17f1b..3ed89451018 100644
--- a/sbin/ipnat/Makefile
+++ b/sbin/ipnat/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.9 2000/04/26 21:04:00 deraadt Exp $
+# $OpenBSD: Makefile,v 1.10 2001/01/17 05:01:01 fgsch Exp $
PROG= ipnat
MAN= ipnat.8 ipnat.4 ipnat.5
-SRCS= ipnat.c kmem.c natparse.c ifaddr.c
+SRCS= ipnat.c kmem.c natparse.c common.c ifaddr.c
.PATH: ${.CURDIR}/../ipfstat ${.CURDIR}/../ipf
CFLAGS+=-I${.CURDIR}/../../sbin/ipfstat -I${.CURDIR}/../ipf
diff --git a/sbin/ipnat/ipnat.c b/sbin/ipnat/ipnat.c
index 3cfc24a5892..9a3b9db453b 100644
--- a/sbin/ipnat/ipnat.c
+++ b/sbin/ipnat/ipnat.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: ipnat.c,v 1.38 2000/08/10 05:50:27 kjell Exp $ */
+/* $OpenBSD: ipnat.c,v 1.39 2001/01/17 05:01:01 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -43,10 +43,11 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_proxy.h>
#include <netinet/ip_nat.h>
+#include "ipf.h"
#include "kmem.h"
#if defined(sun) && !SOLARIS2
@@ -58,26 +59,25 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ipnat.c,v 2.1.2.3 2000/07/27 13:07:07 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: ipnat.c,v 2.16.2.5 2000/12/02 00:15:04 darrenr Exp $";
#endif
#if SOLARIS
#define bzero(a,b) memset(a,0,b)
#endif
+#ifdef USE_INET6
+int use_inet6 = 0;
+#endif
+
+static char thishost[MAXHOSTNAMELEN];
+
extern char *optarg;
-char *nlistf = NULL, *memf = NULL;
extern ipnat_t *natparse __P((char *, int));
extern void natparsefile __P((int, char *, int));
extern void printnat __P((ipnat_t *, int, void *));
-#if defined(__OpenBSD__)
-extern int if_addr __P((char *, struct in_addr *));
-#endif
-
-u_32_t hostnum __P((char *, int *, int));
-u_32_t hostmask __P((char *));
void dostats __P((int, int)), flushtable __P((int, int));
void usage __P((char *));
int countbits __P((u_32_t));
@@ -86,15 +86,6 @@ int main __P((int, char*[]));
void printaps __P((ap_session_t *, int));
char *getsumd __P((u_32_t));
-#define OPT_REM 1
-#define OPT_NODO 2
-#define OPT_STAT 4
-#define OPT_LIST 8
-#define OPT_VERBOSE 16
-#define OPT_FLUSH 32
-#define OPT_CLEAR 64
-#define OPT_HITS 128
-
void usage(name)
char *name;
@@ -124,12 +115,15 @@ char *argv[];
char *file = NULL;
int fd = -1, opts = 0, c, mode = O_RDWR;
- while ((c = getopt(argc, argv, "CFf:hlnrsv")) != -1)
+ while ((c = getopt(argc, argv, "CdFf:hlnrsv")) != -1)
switch (c)
{
case 'C' :
opts |= OPT_CLEAR;
break;
+ case 'd' :
+ opts |= OPT_DEBUG;
+ break;
case 'f' :
file = optarg;
break;
@@ -148,7 +142,7 @@ char *argv[];
mode = O_RDONLY;
break;
case 'r' :
- opts |= OPT_REM;
+ opts |= OPT_REMOVE;
break;
case 's' :
opts |= OPT_STAT;
@@ -161,6 +155,9 @@ char *argv[];
usage(argv[0]);
}
+ gethostname(thishost, sizeof(thishost));
+ thishost[sizeof(thishost) - 1] = '\0';
+
if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, mode)) == -1) &&
((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
(void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
@@ -178,40 +175,12 @@ char *argv[];
}
-/*
- * count consecutive 1's in bit mask. If the mask generated by counting
- * consecutive 1's is different to that passed, return -1, else return #
- * of bits.
- */
-int countbits(ip)
-u_32_t ip;
-{
- u_32_t ipn;
- int cnt = 0, i, j;
-
- ip = ipn = ntohl(ip);
- for (i = 32; i; i--, ipn *= 2)
- if (ipn & 0x80000000)
- cnt++;
- else
- break;
- ipn = 0;
- for (i = 32, j = cnt; i; i--, j--) {
- ipn *= 2;
- if (j > 0)
- ipn++;
- }
- if (ipn == ip)
- return cnt;
- return -1;
-}
-
-
void printaps(aps, opts)
ap_session_t *aps;
int opts;
{
ap_session_t ap;
+ ftpinfo_t ftp;
aproxy_t apr;
raudio_t ra;
@@ -223,7 +192,8 @@ int opts;
apr.apr_p, apr.apr_ref, apr.apr_flags);
printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags);
#ifdef USE_QUAD_T
- printf("%qu pkts %qu", ap.aps_bytes, ap.aps_pkts);
+ printf("%qu pkts %qu", (unsigned long long)ap.aps_bytes,
+ (unsigned long long)ap.aps_pkts);
#else
printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts);
#endif
@@ -259,6 +229,29 @@ int opts;
printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf);
printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n",
ra.rap_plport, ra.rap_prport, ra.rap_srport);
+ } else if (!strcmp(apr.apr_label, "ftp") &&
+ (ap.aps_psiz == sizeof(ftp))) {
+ if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp)))
+ return;
+ printf("\tFTP Proxy:\n");
+ printf("\t\tpassok: %d\n", ftp.ftp_passok);
+ ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0';
+ ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0';
+ printf("\tClient:\n");
+ printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
+ ftp.ftp_side[0].ftps_rptr, ftp.ftp_side[0].ftps_wptr,
+ ftp.ftp_side[0].ftps_seq, ftp.ftp_side[0].ftps_len,
+ ftp.ftp_side[0].ftps_junk);
+ printf("\t\tbuf [");
+ printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1);
+ printf("]\n\tServer:\n");
+ printf("\t\trptr %p wptr %p seq %x len %d junk %d\n",
+ ftp.ftp_side[1].ftps_rptr, ftp.ftp_side[1].ftps_wptr,
+ ftp.ftp_side[1].ftps_seq, ftp.ftp_side[1].ftps_len,
+ ftp.ftp_side[1].ftps_junk);
+ printf("\t\tbuf [");
+ printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1);
+ printf("]\n");
}
}
@@ -301,14 +294,13 @@ ipnat_t *ipnat;
void dostats(fd, opts)
int fd, opts;
{
- natstat_t ns;
+ natstat_t ns, *nsp = &ns;
+ nat_t **nt[2], *np, nat;
ipnat_t ipn;
- nat_t **nt[2], *np, nat;
- int i = 0;
bzero((char *)&ns, sizeof(ns));
- if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &ns) == -1) {
+ if (!(opts & OPT_NODO) && ioctl(fd, SIOCGNATS, &nsp) == -1) {
perror("ioctl(SIOCGNATS)");
return;
}
@@ -318,7 +310,10 @@ int fd, opts;
ns.ns_mapped[0], ns.ns_mapped[1]);
printf("added\t%lu\texpired\t%lu\n",
ns.ns_added, ns.ns_expire);
+ printf("no memory\t%lu\tbad nat\t%lu\n",
+ ns.ns_memfail, ns.ns_badnat);
printf("inuse\t%lu\nrules\t%lu\n", ns.ns_inuse, ns.ns_rules);
+ printf("wilds\t%u\n", ns.ns_wilds);
if (opts & OPT_VERBOSE)
printf("table %p list %p\n", ns.ns_table, ns.ns_list);
}
@@ -332,7 +327,8 @@ int fd, opts;
}
if (opts & OPT_HITS)
printf("%d ", ipn.in_hits);
- printnat(&ipn, opts & OPT_VERBOSE, (void *)ns.ns_list);
+ printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE),
+ (void *)ns.ns_list);
ns.ns_list = ipn.in_next;
}
@@ -359,12 +355,19 @@ int fd, opts;
printf("\n\tage %lu use %hu sumd %s/",
nat.nat_age, nat.nat_use,
getsumd(nat.nat_sumd[0]));
- printf("%s pr %u bkt %d flags %x ",
+ printf("%s pr %u bkt %d/%d flags %x ",
getsumd(nat.nat_sumd[1]), nat.nat_p,
- i, nat.nat_flags);
+ (int)NAT_HASH_FN(nat.nat_inip.s_addr,
+ nat.nat_inport,
+ NAT_TABLE_SZ),
+ (int)NAT_HASH_FN(nat.nat_outip.s_addr,
+ nat.nat_outport,
+ NAT_TABLE_SZ),
+ nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
- nat.nat_bytes, nat.nat_pkts);
+ (unsigned long long)nat.nat_bytes,
+ (unsigned long long)nat.nat_pkts);
#else
printf("bytes %lu pkts %lu",
nat.nat_bytes, nat.nat_pkts);
@@ -383,68 +386,6 @@ int fd, opts;
}
-u_32_t hostmask(msk)
-char *msk;
-{
- int bits = -1;
- u_32_t mask;
-
- if (!isdigit(*msk))
- return (u_32_t)-1;
- if (strchr(msk, '.'))
- return inet_addr(msk);
- if (strchr(msk, 'x'))
- return (u_32_t)strtol(msk, NULL, 0);
- /*
- * set x most significant bits
- */
- for (mask = 0, bits = atoi(msk); bits; bits--) {
- mask /= 2;
- mask |= ntohl(inet_addr("128.0.0.0"));
- }
- mask = htonl(mask);
- return mask;
-}
-
-
-/*
- * returns an ip address as a long var as a result of either a DNS lookup or
- * straight inet_addr() call
- */
-u_32_t hostnum(host, resolved, linenum)
-char *host;
-int *resolved;
-int linenum;
-{
- struct hostent *hp;
- struct netent *np;
-#if defined(__OpenBSD__)
- struct in_addr addr;
-#endif
-
- *resolved = 0;
- if (!strcasecmp("any", host))
- return 0L;
- if (isdigit(*host))
- return inet_addr(host);
-
-#if defined(__OpenBSD__)
- /* attempt a map from interface name to address */
- if (if_addr(host, &addr))
- return (u_32_t)addr.s_addr;
-#endif
- if (!(hp = gethostbyname(host))) {
- if (!(np = getnetbyname(host))) {
- *resolved = -1;
- fprintf(stderr, "Line %d: can't resolve hostname: %s\n", linenum, host);
- return 0;
- }
- return htonl(np->n_net);
- }
- return *(u_32_t *)hp->h_addr;
-}
-
-
void flushtable(fd, opts)
int fd, opts;
{
@@ -452,15 +393,15 @@ int fd, opts;
if (opts & OPT_FLUSH) {
n = 0;
- if (!(opts & OPT_NODO) && ioctl(fd, SIOCFLNAT, &n) == -1)
+ if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
perror("ioctl(SIOCFLNAT)");
else
printf("%d entries flushed from NAT table\n", n);
}
if (opts & OPT_CLEAR) {
- n = 0;
- if (!(opts & OPT_NODO) && ioctl(fd, SIOCCNATL, &n) == -1)
+ n = 1;
+ if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
perror("ioctl(SIOCCNATL)");
else
printf("%d entries flushed from NAT list\n", n);
diff --git a/sbin/ipnat/natparse.c b/sbin/ipnat/natparse.c
index 62c40794f15..5836f260d03 100644
--- a/sbin/ipnat/natparse.c
+++ b/sbin/ipnat/natparse.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: natparse.c,v 1.6 2000/08/10 05:50:27 kjell Exp $ */
+/* $OpenBSD: natparse.c,v 1.7 2001/01/17 05:01:01 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -41,10 +41,11 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_proxy.h>
#include <netinet/ip_nat.h>
+#include "ipf.h"
#if defined(sun) && !SOLARIS2
# define STRERROR(x) sys_errlist[x]
@@ -55,7 +56,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: natparse.c,v 1.2.2.3 2000/06/25 07:13:28 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: natparse.c,v 1.17.2.6 2000/07/08 02:14:40 darrenr Exp $";
#endif
@@ -64,27 +65,17 @@ static const char rcsid[] = "@(#)$IPFilter: natparse.c,v 1.2.2.3 2000/06/25 07:1
#endif
extern int countbits __P((u_32_t));
-extern u_32_t hostnum __P((char *, int *, int));
+extern char *proto;
ipnat_t *natparse __P((char *, int));
void printnat __P((ipnat_t *, int, void *));
void natparsefile __P((int, char *, int));
-u_32_t n_hostmask __P((char *));
-u_short n_portnum __P((char *, char *, int));
void nat_setgroupmap __P((struct ipnat *));
-#define OPT_REM 1
-#define OPT_NODO 2
-#define OPT_STAT 4
-#define OPT_LIST 8
-#define OPT_VERBOSE 16
-#define OPT_FLUSH 32
-#define OPT_CLEAR 64
-
-void printnat(np, verbose, ptr)
+void printnat(np, opts, ptr)
ipnat_t *np;
-int verbose;
+int opts;
void *ptr;
{
struct protoent *pr;
@@ -94,16 +85,16 @@ void *ptr;
switch (np->in_redir)
{
case NAT_REDIRECT :
- printf("rdr ");
+ printf("rdr");
break;
case NAT_MAP :
- printf("map ");
+ printf("map");
break;
case NAT_MAPBLK :
- printf("map-block ");
+ printf("map-block");
break;
case NAT_BIMAP :
- printf("bimap ");
+ printf("bimap");
break;
default :
fprintf(stderr, "unknown value for in_redir: %#x\n",
@@ -111,25 +102,56 @@ void *ptr;
break;
}
+ printf(" %s ", np->in_ifname);
+
+ if (np->in_flags & IPN_FILTER) {
+ if (np->in_flags & IPN_NOTSRC)
+ printf("! ");
+ printf("from ");
+ if (np->in_redir == NAT_REDIRECT) {
+ printhostmask(4, (u_32_t *)&np->in_srcip,
+ (u_32_t *)&np->in_srcmsk);
+ if (np->in_scmp)
+ printportcmp(np->in_p, &np->in_tuc.ftu_src);
+ } else {
+ printhostmask(4, (u_32_t *)&np->in_inip,
+ (u_32_t *)&np->in_inmsk);
+ if (np->in_dcmp)
+ printportcmp(np->in_p, &np->in_tuc.ftu_dst);
+ }
+
+ if (np->in_flags & IPN_NOTDST)
+ printf(" !");
+ printf(" to ");
+ if (np->in_redir == NAT_REDIRECT) {
+ printhostmask(4, (u_32_t *)&np->in_outip,
+ (u_32_t *)&np->in_outmsk);
+ if (np->in_dcmp)
+ printportcmp(np->in_p, &np->in_tuc.ftu_dst);
+ } else {
+ printhostmask(4, (u_32_t *)&np->in_srcip,
+ (u_32_t *)&np->in_srcmsk);
+ if (np->in_scmp)
+ printportcmp(np->in_p, &np->in_tuc.ftu_src);
+ }
+ }
+
if (np->in_redir == NAT_REDIRECT) {
- printf("%s ", np->in_ifname);
- if (np->in_src[0].s_addr || np->in_src[1].s_addr) {
- printf("from %s",inet_ntoa(np->in_src[0]));
- bits = countbits(np->in_src[1].s_addr);
+ if (!(np->in_flags & IPN_FILTER)) {
+ printf("%s", inet_ntoa(np->in_out[0]));
+ bits = countbits(np->in_out[1].s_addr);
if (bits != -1)
printf("/%d ", bits);
else
- printf("/%s ", inet_ntoa(np->in_src[1]));
+ printf("/%s ", inet_ntoa(np->in_out[1]));
+ if (np->in_pmin)
+ printf("port %d", ntohs(np->in_pmin));
+ if (np->in_pmax != np->in_pmin)
+ printf("- %d", ntohs(np->in_pmax));
}
- printf("%s",inet_ntoa(np->in_out[0]));
- bits = countbits(np->in_out[1].s_addr);
- if (bits != -1)
- printf("/%d ", bits);
- else
- printf("/%s ", inet_ntoa(np->in_out[1]));
- if (np->in_pmin)
- printf("port %d ", ntohs(np->in_pmin));
- printf("-> %s", inet_ntoa(np->in_in[0]));
+ printf(" -> %s", inet_ntoa(np->in_in[0]));
+ if (np->in_flags & IPN_SPLIT)
+ printf(",%s", inet_ntoa(np->in_in[1]));
if (np->in_pnext)
printf(" port %d", ntohs(np->in_pnext));
if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
@@ -138,21 +160,25 @@ void *ptr;
printf(" tcp");
else if ((np->in_flags & IPN_UDP) == IPN_UDP)
printf(" udp");
+ if (np->in_flags & IPN_ROUNDR)
+ printf(" round-robin");
printf("\n");
- if (verbose)
- printf("\t%p %lu %x %u %p %d\n", np->in_ifp,
- np->in_space, np->in_flags, np->in_pnext, np,
+ if (opts & OPT_DEBUG)
+ printf("\t%p %lu %#x %u %p %d\n", np->in_ifp,
+ np->in_space, np->in_flags, np->in_pmax, np,
np->in_use);
} else {
np->in_nextip.s_addr = htonl(np->in_nextip.s_addr);
- printf("%s %s/", np->in_ifname, inet_ntoa(np->in_in[0]));
- bits = countbits(np->in_in[1].s_addr);
- if (bits != -1)
- printf("%d ", bits);
- else
- printf("%s", inet_ntoa(np->in_in[1]));
+ if (!(np->in_flags & IPN_FILTER)) {
+ printf("%s/", inet_ntoa(np->in_in[0]));
+ bits = countbits(np->in_in[1].s_addr);
+ if (bits != -1)
+ printf("%d ", bits);
+ else
+ printf("%s", inet_ntoa(np->in_in[1]));
+ }
printf(" -> ");
- if (np->in_flags & IPN_RANGE) {
+ if (np->in_flags & IPN_IPRANGE) {
printf("range %s-", inet_ntoa(np->in_out[0]));
printf("%s", inet_ntoa(np->in_out[1]));
} else {
@@ -185,13 +211,13 @@ void *ptr;
printf("%d", np->in_p);
} else if (np->in_redir == NAT_MAPBLK) {
printf(" ports %d", np->in_pmin);
- if (verbose)
+ if (opts & OPT_VERBOSE)
printf("\n\tip modulous %d", np->in_pmax);
} else if (np->in_pmin || np->in_pmax) {
printf(" portmap");
if (np->in_flags & IPN_AUTOPORTMAP) {
printf(" auto");
- if (verbose)
+ if (opts & OPT_DEBUG)
printf(" [%d:%d %d %d]",
ntohs(np->in_pmin),
ntohs(np->in_pmax),
@@ -208,7 +234,7 @@ void *ptr;
}
}
printf("\n");
- if (verbose) {
+ if (opts & OPT_DEBUG) {
printf("\tifp %p space %lu nextip %s pnext %d",
np->in_ifp, np->in_space,
inet_ntoa(np->in_nextip), np->in_pnext);
@@ -247,161 +273,221 @@ ipnat_t *natparse(line, linenum)
char *line;
int linenum;
{
- struct protoent *pr;
static ipnat_t ipn;
- char *s, *t;
- char *shost, *snetm, *dhost, *proto, *srchost, *srcnetm;
- char *dnetm = NULL, *dport = NULL, *tport = NULL;
- int resolved;
+ struct protoent *pr;
+ char *dnetm = NULL, *dport = NULL;
+ char *s, *t, *cps[31], **cpp;
+ int i, cnt;
- srchost = NULL;
- srcnetm = NULL;
- bzero((char *)&ipn, sizeof(ipn));
if ((s = strchr(line, '\n')))
*s = '\0';
if ((s = strchr(line, '#')))
*s = '\0';
+ while (*line && isspace(*line))
+ line++;
if (!*line)
return NULL;
- if (!(s = strtok(line, " \t")))
+
+ bzero((char *)&ipn, sizeof(ipn));
+ cnt = 0;
+
+ for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++)
+ cps[++i] = strtok(NULL, " \b\t\r\n");
+
+ cps[i] = NULL;
+
+ if (cnt < 3) {
+ fprintf(stderr, "%d: not enough segments in line\n", linenum);
return NULL;
- if (!strcasecmp(s, "map"))
+ }
+
+ cpp = cps;
+
+ if (!strcasecmp(*cpp, "map"))
ipn.in_redir = NAT_MAP;
- else if (!strcasecmp(s, "map-block"))
+ else if (!strcasecmp(*cpp, "map-block"))
ipn.in_redir = NAT_MAPBLK;
- else if (!strcasecmp(s, "rdr"))
+ else if (!strcasecmp(*cpp, "rdr"))
ipn.in_redir = NAT_REDIRECT;
- else if (!strcasecmp(s, "bimap"))
+ else if (!strcasecmp(*cpp, "bimap"))
ipn.in_redir = NAT_BIMAP;
else {
fprintf(stderr, "%d: unknown mapping: \"%s\"\n",
- linenum, s);
+ linenum, *cpp);
return NULL;
}
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr, "%d: missing fields (interface)\n",
- linenum);
- return NULL;
- }
+ cpp++;
- strncpy(ipn.in_ifname, s, sizeof(ipn.in_ifname) - 1);
+ strncpy(ipn.in_ifname, *cpp, sizeof(ipn.in_ifname) - 1);
ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0';
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr, "%d: missing fields (%s)\n", linenum,
- ipn.in_redir ? "from source | destination" : "source");
- return NULL;
- }
+ cpp++;
- if ((ipn.in_redir == NAT_REDIRECT) && !strcasecmp(s, "from")) {
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (source address)\n",
- linenum);
+ if (!strcasecmp(*cpp, "from") || (**cpp == '!')) {
+ if (!strcmp(*cpp, "!")) {
+ cpp++;
+ if (strcasecmp(*cpp, "from")) {
+ fprintf(stderr, "Missing from after !\n");
+ return NULL;
+ }
+ ipn.in_flags |= IPN_NOTSRC;
+ } else if (**cpp == '!') {
+ if (strcasecmp(*cpp + 1, "from")) {
+ fprintf(stderr, "Missing from after !\n");
+ return NULL;
+ }
+ ipn.in_flags |= IPN_NOTSRC;
+ }
+ if ((ipn.in_flags & IPN_NOTSRC) &&
+ (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) {
+ fprintf(stderr, "Cannot use '! from' with map\n");
return NULL;
}
- srchost = s;
- srcnetm = strrchr(srchost, '/');
+ ipn.in_flags |= IPN_FILTER;
+ cpp++;
+ if (ipn.in_redir == NAT_REDIRECT) {
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
+ (u_32_t *)&ipn.in_srcmsk,
+ &ipn.in_sport, &ipn.in_scmp,
+ &ipn.in_stop, linenum)) {
+ return NULL;
+ }
+ } else {
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
+ (u_32_t *)&ipn.in_inmsk,
+ &ipn.in_sport, &ipn.in_scmp,
+ &ipn.in_stop, linenum)) {
+ return NULL;
+ }
+ }
- if (srcnetm == NULL) {
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (source netmask)\n",
- linenum);
- return NULL;
- }
+ if (!strcmp(*cpp, "!")) {
+ cpp++;
+ ipn.in_flags |= IPN_NOTDST;
+ } else if (**cpp == '!') {
+ (*cpp)++;
+ ipn.in_flags |= IPN_NOTDST;
+ }
- if (strcasecmp(s, "netmask")) {
- fprintf(stderr,
- "%d: missing fields (netmask)\n",
- linenum);
+ if (strcasecmp(*cpp, "to")) {
+ fprintf(stderr, "%d: unexpected keyword (%s) - to\n",
+ linenum, *cpp);
+ return NULL;
+ }
+ if ((ipn.in_flags & IPN_NOTDST) &&
+ (ipn.in_redir & (NAT_REDIRECT))) {
+ fprintf(stderr, "Cannot use '! to' with rdr\n");
+ return NULL;
+ }
+
+ if (!*++cpp) {
+ fprintf(stderr, "%d: missing host after to\n", linenum);
+ return NULL;
+ }
+ if (ipn.in_redir == NAT_REDIRECT) {
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
+ (u_32_t *)&ipn.in_outmsk,
+ &ipn.in_dport, &ipn.in_dcmp,
+ &ipn.in_dtop, linenum)) {
+ return NULL;
+ }
+ ipn.in_pmin = htons(ipn.in_dport);
+ } else {
+ if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
+ (u_32_t *)&ipn.in_srcmsk,
+ &ipn.in_dport, &ipn.in_dcmp,
+ &ipn.in_dtop, linenum)) {
+ return NULL;
+ }
+ }
+ } else {
+ s = *cpp;
+ if (!s)
+ return NULL;
+ t = strchr(s, '/');
+ if (!t)
+ return NULL;
+ *t++ = '\0';
+ if (ipn.in_redir == NAT_REDIRECT) {
+ if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1)
+ return NULL;
+ if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) {
return NULL;
}
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (source netmask)\n",
- linenum);
+ } else {
+ if (hostnum((u_32_t *)&ipn.in_inip, s, linenum) == -1)
+ return NULL;
+ if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) {
return NULL;
}
- srcnetm = s;
}
- if (*srcnetm == '/')
- *srcnetm++ = '\0';
+ cpp++;
+ if (!*cpp)
+ return NULL;
+ }
- /* re read the next word -- destination */
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (destination)\n", linenum);
+ if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
+ if (strcasecmp(*cpp, "port")) {
+ fprintf(stderr, "%d: missing fields - 1st port\n",
+ linenum);
return NULL;
}
- }
-
- shost = s;
+ cpp++;
- if (ipn.in_redir == NAT_REDIRECT) {
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
- if (strcasecmp(s, "port")) {
- fprintf(stderr, "%d: missing fields (port)\n", linenum);
- return NULL;
- }
+ if (isdigit(**cpp) && (s = strchr(*cpp, '-')))
+ *s++ = '\0';
+ else
+ s = NULL;
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (destination port)\n",
- linenum);
+ if (!portnum(*cpp, &ipn.in_pmin, linenum))
return NULL;
+ ipn.in_pmin = htons(ipn.in_pmin);
+ cpp++;
+
+ if (!strcmp(*cpp, "-")) {
+ cpp++;
+ s = *cpp++;
}
- dport = s;
+ if (s) {
+ if (!portnum(s, &ipn.in_pmax, linenum))
+ return NULL;
+ ipn.in_pmax = htons(ipn.in_pmax);
+ } else
+ ipn.in_pmax = ipn.in_pmin;
}
-
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
fprintf(stderr, "%d: missing fields (->)\n", linenum);
return NULL;
}
- if (!strcmp(s, "->")) {
- snetm = strrchr(shost, '/');
- if (!snetm) {
- fprintf(stderr,
- "%d: missing fields (%s netmask)\n", linenum,
- ipn.in_redir ? "destination" : "source");
- return NULL;
- }
- } else {
- if (strcasecmp(s, "netmask")) {
- fprintf(stderr, "%d: missing fields (netmask)\n",
- linenum);
- return NULL;
- }
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (%s netmask)\n", linenum,
- ipn.in_redir ? "destination" : "source");
- return NULL;
- }
- snetm = s;
+ if (strcmp(*cpp, "->")) {
+ fprintf(stderr, "%d: missing ->\n", linenum);
+ return NULL;
}
+ cpp++;
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
fprintf(stderr, "%d: missing fields (%s)\n",
- linenum, ipn.in_redir ? "destination":"target");
+ linenum, ipn.in_redir ? "destination" : "target");
return NULL;
}
if (ipn.in_redir == NAT_MAP) {
- if (!strcasecmp(s, "range")) {
- ipn.in_flags |= IPN_RANGE;
- if (!(s = strtok(NULL, " \t"))) {
+ if (!strcasecmp(*cpp, "range")) {
+ cpp++;
+ ipn.in_flags |= IPN_IPRANGE;
+ if (!*cpp) {
fprintf(stderr, "%d: missing fields (%s)\n",
linenum,
ipn.in_redir ? "destination":"target");
@@ -409,187 +495,167 @@ int linenum;
}
}
}
- dhost = s;
- if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) {
- if (ipn.in_flags & IPN_RANGE) {
- dnetm = strrchr(dhost, '-');
- if (dnetm == NULL) {
- if (!(s = strtok(NULL, " \t")))
- dnetm = NULL;
- else {
- if (strcmp(s, "-"))
- s = NULL;
- else if ((s = strtok(NULL, " \t"))) {
- dnetm = s;
- }
- }
- } else
- *dnetm++ = '\0';
- if (dnetm == NULL || *dnetm == '\0') {
- fprintf(stderr,
- "%d: desination range not specified\n",
- linenum);
- return NULL;
- }
- } else {
- dnetm = strrchr(dhost, '/');
- if (dnetm == NULL) {
- if (!(s = strtok(NULL, " \t")))
- dnetm = NULL;
- else if (!strcasecmp(s, "netmask"))
- if ((s = strtok(NULL, " \t")) != NULL)
- dnetm = s;
- }
- if (dnetm == NULL) {
- fprintf(stderr,
- "%d: missing fields (dest netmask)\n",
- linenum);
- return NULL;
- }
- if (*dnetm == '/')
- *dnetm++ = '\0';
+ if (ipn.in_flags & IPN_IPRANGE) {
+ dnetm = strrchr(*cpp, '-');
+ if (dnetm == NULL) {
+ cpp++;
+ if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1))
+ dnetm = *(cpp + 1);
+ } else
+ *dnetm++ = '\0';
+ if (dnetm == NULL || *dnetm == '\0') {
+ fprintf(stderr,
+ "%d: desination range not specified\n",
+ linenum);
+ return NULL;
+ }
+ } else if (ipn.in_redir != NAT_REDIRECT) {
+ dnetm = strrchr(*cpp, '/');
+ if (dnetm == NULL) {
+ cpp++;
+ if (*cpp && !strcasecmp(*cpp, "netmask"))
+ dnetm = *++cpp;
+ }
+ if (dnetm == NULL) {
+ fprintf(stderr,
+ "%d: missing fields (dest netmask)\n",
+ linenum);
+ return NULL;
+ }
+ if (*dnetm == '/')
+ *dnetm++ = '\0';
+ }
+
+ if (ipn.in_redir == NAT_REDIRECT) {
+ dnetm = strchr(*cpp, ',');
+ if (dnetm != NULL) {
+ ipn.in_flags |= IPN_SPLIT;
+ *dnetm++ = '\0';
}
- s = strtok(NULL, " \t");
+ if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1)
+ return NULL;
+ } else {
+ if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1)
+ return NULL;
}
+ cpp++;
if (ipn.in_redir & NAT_MAPBLK) {
- if (s && strcasecmp(s, "ports")) {
+ if (*cpp && strcasecmp(*cpp, "ports")) {
fprintf(stderr,
"%d: expected \"ports\" - got \"%s\"\n",
- linenum, s);
+ linenum, *cpp);
return NULL;
}
- if (s != NULL) {
- if ((s = strtok(NULL, " \t")) == NULL)
- return NULL;
- ipn.in_pmin = atoi(s);
- s = strtok(NULL, " \t");
+ cpp++;
+ if (*cpp) {
+ ipn.in_pmin = atoi(*cpp);
+ cpp++;
} else
ipn.in_pmin = 0;
} else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
- if (strrchr(dhost, '/') != NULL) {
+ if (strrchr(*cpp, '/') != NULL) {
fprintf(stderr, "%d: No netmask supported in %s\n",
linenum, "destination host for redirect");
return NULL;
}
/* If it's a in_redir, expect target port */
- if (!(s = strtok(NULL, " \t"))) {
- fprintf(stderr,
- "%d: missing fields (destination port)\n",
- linenum);
- return NULL;
- }
- if (strcasecmp(s, "port")) {
- fprintf(stderr, "%d: missing fields (port)\n",
- linenum);
+ if (strcasecmp(*cpp, "port")) {
+ fprintf(stderr, "%d: missing fields - 2nd port (%s)\n",
+ linenum, *cpp);
return NULL;
}
-
- if (!(s = strtok(NULL, " \t"))) {
+ cpp++;
+ if (!*cpp) {
fprintf(stderr,
"%d: missing fields (destination port)\n",
linenum);
return NULL;
}
- tport = s;
+ if (!portnum(*cpp, &ipn.in_pnext, linenum))
+ return NULL;
+ ipn.in_pnext = htons(ipn.in_pnext);
+ cpp++;
}
if (dnetm && *dnetm == '/')
*dnetm++ = '\0';
- if (snetm && *snetm == '/')
- *snetm++ = '\0';
if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) {
- ipn.in_inip = hostnum(shost, &resolved, linenum);
- if (resolved == -1)
- return NULL;
- ipn.in_inmsk = n_hostmask(snetm);
- ipn.in_outip = hostnum(dhost, &resolved, linenum);
- if (resolved == -1)
- return NULL;
- if (ipn.in_flags & IPN_RANGE) {
- ipn.in_outmsk = hostnum(dnetm, &resolved, linenum);
- if (resolved == -1)
- return NULL;
- } else
- ipn.in_outmsk = n_hostmask(dnetm);
- if (srchost) {
- ipn.in_srcip = hostnum(srchost, &resolved, linenum);
- if (resolved == -1)
+ if (ipn.in_flags & IPN_IPRANGE) {
+ if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm,
+ linenum) == -1)
return NULL;
- }
- if (srcnetm)
- ipn.in_srcmsk = n_hostmask(srcnetm);
+ } else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk))
+ return NULL;
} else {
- if (srchost) {
- ipn.in_srcip = hostnum(srchost, &resolved, linenum);
- if (resolved == -1)
+ if (ipn.in_flags & IPN_SPLIT) {
+ if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm,
+ linenum) == -1)
return NULL;
- }
- if (srcnetm)
- ipn.in_srcmsk = n_hostmask(srcnetm);
- ipn.in_inip = hostnum(dhost, &resolved, linenum);
- if (resolved == -1)
+ } else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk))
return NULL;
- ipn.in_inmsk = n_hostmask("255.255.255.255");
- ipn.in_outip = hostnum(shost, &resolved, linenum);
- if (resolved == -1)
- return NULL;
- ipn.in_outmsk = n_hostmask(snetm);
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */
proto = "tcp";
} else {
- if (!strcasecmp(s, "tcp"))
+ if (!strcasecmp(*cpp, "tcp"))
ipn.in_flags |= IPN_TCP;
- else if (!strcasecmp(s, "udp"))
+ else if (!strcasecmp(*cpp, "udp"))
ipn.in_flags |= IPN_UDP;
- else if (!strcasecmp(s, "tcp/udp"))
+ else if (!strcasecmp(*cpp, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(s, "tcpudp"))
+ else if (!strcasecmp(*cpp, "tcpudp"))
ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(s, "ip"))
+ else if (!strcasecmp(*cpp, "ip"))
ipn.in_flags |= IPN_ANY;
else {
ipn.in_flags |= IPN_ANY;
- if ((pr = getprotobyname(s)))
+ if ((pr = getprotobyname(*cpp)))
ipn.in_p = pr->p_proto;
else
- ipn.in_p = atoi(s);
+ ipn.in_p = atoi(*cpp);
+ }
+ proto = *cpp;
+ cpp++;
+
+ if (*cpp && !strcasecmp(*cpp, "round-robin")) {
+ cpp++;
+ ipn.in_flags |= IPN_ROUNDR;
}
- proto = s;
- if ((s = strtok(NULL, " \t"))) {
+
+ if (*cpp) {
fprintf(stderr,
"%d: extra junk at the end of rdr: %s\n",
- linenum, s);
+ linenum, *cpp);
return NULL;
}
}
- ipn.in_pmin = n_portnum(dport, proto, linenum);
- ipn.in_pmax = ipn.in_pmin;
- ipn.in_pnext = n_portnum(tport, proto, linenum);
- s = NULL;
}
- ipn.in_inip &= ipn.in_inmsk;
- if ((ipn.in_flags & IPN_RANGE) == 0)
+
+ if (!(ipn.in_flags & IPN_SPLIT))
+ ipn.in_inip &= ipn.in_inmsk;
+ if ((ipn.in_flags & IPN_IPRANGE) == 0)
ipn.in_outip &= ipn.in_outmsk;
ipn.in_srcip &= ipn.in_srcmsk;
if ((ipn.in_redir & NAT_MAPBLK) != 0)
nat_setgroupmap(&ipn);
- if (!s)
+ if (!*cpp)
return &ipn;
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr,
"%d: extra words at the end of bimap line: %s\n",
- linenum, s);
+ linenum, *cpp);
return NULL;
}
- if (!strcasecmp(s, "proxy")) {
- if (!(s = strtok(NULL, " \t"))) {
+
+ if (!strcasecmp(*cpp, "proxy")) {
+ cpp++;
+ if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"proxy\"\n",
linenum);
@@ -597,17 +663,19 @@ int linenum;
}
dport = NULL;
- if (!strcasecmp(s, "port")) {
- if (!(s = strtok(NULL, " \t"))) {
+ if (!strcasecmp(*cpp, "port")) {
+ cpp++;
+ if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"port\"\n",
linenum);
return NULL;
}
- dport = s;
+ dport = *cpp;
+ cpp++;
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
fprintf(stderr,
"%d: missing parameter for \"proxy\"\n",
linenum);
@@ -618,73 +686,86 @@ int linenum;
"%d: missing keyword \"port\"\n", linenum);
return NULL;
}
- if ((proto = index(s, '/'))) {
+
+ if ((proto = index(*cpp, '/'))) {
*proto++ = '\0';
if ((pr = getprotobyname(proto)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(proto);
- if (dport)
- ipn.in_dport = n_portnum(dport, proto, linenum);
- } else {
+ } else
ipn.in_p = 0;
- if (dport)
- ipn.in_dport = n_portnum(dport, NULL, linenum);
- }
- (void) strncpy(ipn.in_plabel, s, sizeof(ipn.in_plabel));
- if ((s = strtok(NULL, " \t"))) {
+ if (dport && !portnum(dport, &ipn.in_dport, linenum))
+ return NULL;
+ ipn.in_dport = htons(ipn.in_dport);
+
+ (void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel));
+ cpp++;
+
+ if (*cpp) {
fprintf(stderr,
"%d: too many parameters for \"proxy\"\n",
linenum);
return NULL;
}
return &ipn;
-
}
- if (strcasecmp(s, "portmap")) {
+ if (strcasecmp(*cpp, "portmap")) {
fprintf(stderr,
- "%d: expected \"portmap\" - got \"%s\"\n", linenum, s);
+ "%d: expected \"portmap\" - got \"%s\"\n", linenum,
+ *cpp);
return NULL;
}
- if (!(s = strtok(NULL, " \t")))
+ cpp++;
+ if (!*cpp) {
+ fprintf(stderr, "%d: missing expression following portmap\n",
+ linenum);
return NULL;
- if (!strcasecmp(s, "tcp"))
+ }
+
+ if (!strcasecmp(*cpp, "tcp"))
ipn.in_flags |= IPN_TCP;
- else if (!strcasecmp(s, "udp"))
+ else if (!strcasecmp(*cpp, "udp"))
ipn.in_flags |= IPN_UDP;
- else if (!strcasecmp(s, "tcpudp"))
+ else if (!strcasecmp(*cpp, "tcpudp"))
ipn.in_flags |= IPN_TCPUDP;
- else if (!strcasecmp(s, "tcp/udp"))
+ else if (!strcasecmp(*cpp, "tcp/udp"))
ipn.in_flags |= IPN_TCPUDP;
else {
fprintf(stderr,
"%d: expected protocol name - got \"%s\"\n",
- linenum, s);
+ linenum, *cpp);
return NULL;
}
+ proto = *cpp;
+ cpp++;
- if (!(s = strtok(NULL, " \t"))) {
+ if (!*cpp) {
fprintf(stderr, "%d: no port range found\n", linenum);
return NULL;
}
- if (!strcasecmp(s, "auto")) {
+ if (!strcasecmp(*cpp, "auto")) {
ipn.in_flags |= IPN_AUTOPORTMAP;
ipn.in_pmin = htons(1024);
ipn.in_pmax = htons(65535);
nat_setgroupmap(&ipn);
return &ipn;
}
- proto = s;
- if (!(t = strchr(s, ':'))) {
- fprintf(stderr, "%d: no port range in \"%s\"\n", linenum, s);
+
+ if (!(t = strchr(*cpp, ':'))) {
+ fprintf(stderr, "%d: no port range in \"%s\"\n",
+ linenum, *cpp);
return NULL;
}
*t++ = '\0';
- ipn.in_pmin = n_portnum(s, proto, linenum);
- ipn.in_pmax = n_portnum(t, proto, linenum);
+ if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
+ !portnum(t, &ipn.in_pmax, linenum))
+ return NULL;
+ ipn.in_pmin = htons(ipn.in_pmin);
+ ipn.in_pmax = htons(ipn.in_pmax);
return &ipn;
}
@@ -709,7 +790,7 @@ int opts;
fp = stdin;
while (fgets(line, sizeof(line) - 1, fp)) {
- linenum++;
+ linenum++;
line[sizeof(line) - 1] = '\0';
if ((s = strchr(line, '\n')))
*s = '\0';
@@ -720,81 +801,21 @@ int opts;
linenum, line);
} else {
if ((opts & OPT_VERBOSE) && np)
- printnat(np, opts & OPT_VERBOSE, NULL);
+ printnat(np, opts, NULL);
if (!(opts & OPT_NODO)) {
- if (!(opts & OPT_REM)) {
- if (ioctl(fd, SIOCADNAT, np) == -1)
+ if (!(opts & OPT_REMOVE)) {
+ if (ioctl(fd, SIOCADNAT, &np) == -1) {
+ fprintf(stderr, "%d:",
+ linenum);
perror("ioctl(SIOCADNAT)");
- } else if (ioctl(fd, SIOCRMNAT, np) == -1)
+ }
+ } else if (ioctl(fd, SIOCRMNAT, &np) == -1) {
+ fprintf(stderr, "%d:", linenum);
perror("ioctl(SIOCRMNAT)");
+ }
}
}
}
if (fp != stdin)
fclose(fp);
}
-
-
-u_32_t n_hostmask(msk)
-char *msk;
-{
- int bits = -1;
- u_32_t mask;
-
- if (!isdigit(*msk))
- return (u_32_t)-1;
- if (strchr(msk, '.'))
- return inet_addr(msk);
- if (strchr(msk, 'x'))
-#if defined(sun) && !defined(__SVR4) && !defined(__svr4__)
- return (u_32_t)htonl(strtol(msk, NULL, 0));
-#else
- return (u_32_t)htonl(strtoul(msk, NULL, 0));
-#endif
- /*
- * set x most significant bits
- */
- for (mask = 0, bits = atoi(msk); bits; bits--) {
- mask /= 2;
- mask |= ntohl(inet_addr("128.0.0.0"));
- }
- mask = htonl(mask);
- return mask;
-}
-
-
-u_short n_portnum(name, proto, linenum)
-char *name, *proto;
-int linenum;
-{
- struct servent *sp, *sp2;
- u_short p1 = 0;
-
- if (isdigit(*name))
- return htons((u_short)atoi(name));
- if (!proto)
- proto = "tcp/udp";
- if (strcasecmp(proto, "tcp/udp")) {
- sp = getservbyname(name, proto);
- if (sp)
- return sp->s_port;
- fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
- return 0;
- }
- sp = getservbyname(name, "tcp");
- if (sp)
- p1 = sp->s_port;
- sp2 = getservbyname(name, "udp");
- if (!sp || !sp2) {
- fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
- linenum, name);
- return 0;
- }
- if (p1 != sp2->s_port) {
- fprintf(stderr, "%d: %s %d/tcp is a different port to ",
- linenum, name, p1);
- fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
- return 0;
- }
- return p1;
-}
diff --git a/usr.sbin/ipmon/ipmon.c b/usr.sbin/ipmon/ipmon.c
index 6b38934dbaa..d96d409ab05 100644
--- a/usr.sbin/ipmon/ipmon.c
+++ b/usr.sbin/ipmon/ipmon.c
@@ -1,15 +1,15 @@
-/* $OpenBSD: ipmon.c,v 1.24 2000/08/10 05:50:27 kjell Exp $ */
+/* $OpenBSD: ipmon.c,v 1.25 2001/01/17 05:01:02 fgsch Exp $ */
/*
- * Copyright (C) 1993-1998 by Darren Reed.
+ * Copyright (C) 1993-2000 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-1998 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ipmon.c,v 2.3.2.6 2000/08/07 13:04:51 darrenr Exp $";
+static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$IPFilter: ipmon.c,v 2.12.2.6 2000/10/31 22:17:41 darrenr Exp $";
#endif
#ifndef SOLARIS
@@ -65,7 +65,7 @@ static const char rcsid[] = "@(#)$IPFilter: ipmon.c,v 2.3.2.6 2000/08/07 13:04:5
#include <ctype.h>
#include <syslog.h>
-#include <netinet/ip_fil_compat.h>
+#include <netinet/ip_compat.h>
#include <netinet/tcpip.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_proxy.h>
@@ -106,14 +106,6 @@ static char *pidfile = "/etc/ipmon.pid";
# endif
#endif
-struct hlist {
- struct hlist *next;
- struct in_addr addr;
- char name[MAXHOSTNAMELEN];
-};
-#define PRIME 367
-static struct hlist htable[PRIME];
-
static char line[2048];
static int opts = 0;
static FILE *newlog = NULL;
@@ -130,7 +122,7 @@ static void dumphex __P((FILE *, u_char *, int));
static int read_log __P((int, int *, char *, int));
static void write_pid __P((char *));
-char *hostname __P((int, struct in_addr));
+char *hostname __P((int, int, u_32_t *));
char *portname __P((int, char *, u_int));
int main __P((int, char *[]));
@@ -155,6 +147,8 @@ static char **tcp_ports = NULL;
#define OPT_PORTNUM 0x400
#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER)
+#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b))
+
#ifndef LOGFAC
#define LOGFAC LOG_LOCAL0
#endif
@@ -217,11 +211,11 @@ static void init_tabs()
if (s->s_proto == NULL)
continue;
else if (!strcmp(s->s_proto, "tcp")) {
- port = s->s_port;
+ port = ntohs(s->s_port);
name = s->s_name;
tab = tcp_ports;
} else if (!strcmp(s->s_proto, "udp")) {
- port = s->s_port;
+ port = ntohs(s->s_port);
name = s->s_name;
tab = udp_ports;
} else
@@ -266,35 +260,33 @@ char *buf;
}
-char *hostname(res, ip)
-int res;
-struct in_addr ip;
+char *hostname(res, v, ip)
+int res, v;
+u_32_t *ip;
{
+#ifdef USE_INET6
+ static char hostbuf[MAXHOSTNAMELEN+1];
+#endif
struct hostent *hp;
- struct hlist *hl;
-
- if (!res)
- return inet_ntoa(ip);
+ struct in_addr ipa;
- hl = &htable[ip.s_addr % PRIME];
- for ( ; hl->next != NULL; hl = hl->next)
- if (hl->addr.s_addr == ip.s_addr)
- return hl->name;
+ if (v == 4) {
+ ipa.s_addr = *ip;
+ if (!res)
+ return inet_ntoa(ipa);
+ hp = gethostbyaddr((char *)ip, sizeof(ip), AF_INET);
+ if (!hp)
+ return inet_ntoa(ipa);
+ return hp->h_name;
- hl->addr.s_addr = ip.s_addr;
- hl->next = (struct hlist *)calloc(1, sizeof(*hl));
- if (hl->next == NULL) {
- perror("calloc");
- exit(1);
}
-
- hp = gethostbyaddr((char *)&ip, sizeof(ip), AF_INET);
- if (!hp)
- strlcpy(hl->name, inet_ntoa(ip), sizeof hl->name);
- else
- strlcpy(hl->name, hp->h_name, sizeof hl->name);
-
- return hl->name;
+#ifdef USE_INET6
+ (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
+ hostbuf[MAXHOSTNAMELEN] = '\0';
+ return hostbuf;
+#else
+ return "IPv6";
+#endif
}
@@ -346,7 +338,7 @@ int len;
t += 2;
if (!((j + 1) & 0xf)) {
s -= 15;
- sprintf((char *)t, " ");
+ sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
*t++ = (isprint(*s) ? *s : '.');
@@ -411,28 +403,36 @@ int blen;
strcpy(t, "NAT:RDR ");
else if (nl->nl_type == NL_EXPIRE)
strcpy(t, "NAT:EXPIRE ");
+ else if (nl->nl_type == NL_FLUSH)
+ strcpy(t, "NAT:FLUSH ");
+ else if (nl->nl_type == NL_NEWBIMAP)
+ strcpy(t, "NAT:BIMAP ");
+ else if (nl->nl_type == NL_NEWBLOCK)
+ strcpy(t, "NAT:MAPBLOCK ");
else
sprintf(t, "Type: %d ", nl->nl_type);
t += strlen(t);
proto = getproto(nl->nl_p);
- (void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nl_inip),
+ (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip),
portname(res, proto, (u_int)nl->nl_inport));
t += strlen(t);
- (void) sprintf(t, "%s,%s ", hostname(res, nl->nl_outip),
+ (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip),
portname(res, proto, (u_int)nl->nl_outport));
t += strlen(t);
- (void) sprintf(t, "[%s,%s]", hostname(res, nl->nl_origip),
+ (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip),
portname(res, proto, (u_int)nl->nl_origport));
t += strlen(t);
if (nl->nl_type == NL_EXPIRE) {
#ifdef USE_QUAD_T
(void) sprintf(t, " Pkts %qd Bytes %qd",
+ (long long)nl->nl_pkts,
+ (long long)nl->nl_bytes);
#else
(void) sprintf(t, " Pkts %ld Bytes %ld",
-#endif
nl->nl_pkts, nl->nl_bytes);
+#endif
t += strlen(t);
}
@@ -482,6 +482,8 @@ int blen;
strcpy(t, "STATE:EXPIRE ");
} else if (sl->isl_type == ISL_FLUSH)
strcpy(t, "STATE:FLUSH ");
+ else if (sl->isl_type == ISL_REMOVE)
+ strcpy(t, "STATE:REMOVE ");
else
sprintf(t, "Type: %d ", sl->isl_type);
t += strlen(t);
@@ -490,26 +492,30 @@ int blen;
if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) {
(void) sprintf(t, "%s,%s -> ",
- hostname(res, sl->isl_src),
+ hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src),
portname(res, proto, (u_int)sl->isl_sport));
t += strlen(t);
(void) sprintf(t, "%s,%s PR %s",
- hostname(res, sl->isl_dst),
+ hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
portname(res, proto, (u_int)sl->isl_dport), proto);
} else if (sl->isl_p == IPPROTO_ICMP) {
- (void) sprintf(t, "%s -> ", hostname(res, sl->isl_src));
+ (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
+ (u_32_t *)&sl->isl_src));
t += strlen(t);
(void) sprintf(t, "%s PR icmp %d",
- hostname(res, sl->isl_dst), sl->isl_itype);
+ hostname(res, sl->isl_v, (u_32_t *)&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",
+ (long long)sl->isl_pkts,
+ (long long)sl->isl_bytes);
#else
(void) sprintf(t, " Pkts %ld Bytes %ld",
-#endif
sl->isl_pkts, sl->isl_bytes);
+#endif
t += strlen(t);
}
@@ -579,26 +585,30 @@ int blen;
{
tcphdr_t *tp;
struct icmp *ic;
- struct icmp *icmphdr;
+ struct icmp *icmp;
struct tm *tm;
char *t, *proto;
- u_short hl, p;
- int i, lvl, res, len, ipoff;
+ int i, v, lvl, res, len, off, plen, ipoff;
ip_t *ipc, *ip;
- iplog_t *ipl;
+ u_short hl, p;
ipflog_t *ipf;
+ iplog_t *ipl;
+ u_32_t *s, *d;
+#ifdef USE_INET6
+ ip6_t *ip6;
+#endif
ipl = (iplog_t *)buf;
ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
ip = (ip_t *)((char *)ipf + sizeof(*ipf));
+ v = ip->ip_v;
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 *)&ipl->ipl_sec);
#ifdef linux
- ip->ip_len = ntohs(ip->ip_len);
+ if (v == 4)
+ ip->ip_len = ntohs(ip->ip_len);
#endif
len = sizeof(line);
@@ -637,7 +647,6 @@ int blen;
#endif
(void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
t += strlen(t);
- proto = getproto(p);
if (ipf->fl_flags & FF_SHORT) {
*t++ = 'S';
@@ -666,18 +675,43 @@ int blen;
*t++ = ' ';
*t = '\0';
- if ((p == IPPROTO_TCP || p == IPPROTO_UDP) &&
- !(ip->ip_off & IP_OFFMASK)) {
+ if (v == 6) {
+#ifdef USE_INET6
+ off = 0;
+ ipoff = 0;
+ hl = sizeof(ip6_t);
+ ip6 = (ip6_t *)ip;
+ p = (u_short)ip6->ip6_nxt;
+ s = (u_32_t *)&ip6->ip6_src;
+ d = (u_32_t *)&ip6->ip6_dst;
+ plen = ntohs(ip6->ip6_plen);
+#else
+ sprintf(t, "ipv6");
+ goto printipflog;
+#endif
+ } else if (v == 4) {
+ hl = (ip->ip_hl << 2);
+ ipoff = ip->ip_off;
+ off = ipoff & IP_OFFMASK;
+ p = (u_short)ip->ip_p;
+ s = (u_32_t *)&ip->ip_src;
+ d = (u_32_t *)&ip->ip_dst;
+ plen = ip->ip_len;
+ } else {
+ goto printipflog;
+ }
+ proto = getproto(p);
+
+ if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) {
tp = (tcphdr_t *)((char *)ip + hl);
if (!(ipf->fl_flags & (FI_SHORT << 16))) {
- (void) sprintf(t, "%s,%s -> ",
- hostname(res, ip->ip_src),
+ (void) sprintf(t, "%s,%s -> ", hostname(res, v, s),
portname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
(void) sprintf(t, "%s,%s PR %s len %hu %hu ",
- hostname(res, ip->ip_dst),
+ hostname(res, v, d),
portname(res, proto, (u_int)tp->th_dport),
- proto, hl, ip->ip_len);
+ proto, hl, plen);
t += strlen(t);
if (p == IPPROTO_TCP) {
@@ -695,18 +729,17 @@ int blen;
}
*t = '\0';
} else {
- (void) sprintf(t, "%s -> ", hostname(res, ip->ip_src));
+ (void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR %s len %hu %hu",
- hostname(res, ip->ip_dst), proto,
- hl, ip->ip_len);
+ hostname(res, v, d), proto, hl, plen);
}
- } else if ((p == IPPROTO_ICMP) && !(ip->ip_off & IP_OFFMASK)) {
+ } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) {
ic = (struct icmp *)((char *)ip + hl);
- (void) sprintf(t, "%s -> ", hostname(res, ip->ip_src));
+ (void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR icmp len %hu %hu icmp %d/%d",
- hostname(res, ip->ip_dst), hl, ip->ip_len,
+ hostname(res, v, d), hl, plen,
ic->icmp_type, ic->icmp_code);
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
@@ -722,62 +755,60 @@ int blen;
((ipc->ip_p == IPPROTO_TCP) ||
(ipc->ip_p == IPPROTO_UDP))) {
tp = (tcphdr_t *)((char *)ipc + hl);
-
t += strlen(t);
(void) sprintf(t, " for %s,%s -",
- hostname(res, ipc->ip_src),
+ HOSTNAME_V4(res, ipc->ip_src),
portname(res, proto,
(u_int)tp->th_sport));
t += strlen(t);
(void) sprintf(t, " %s,%s PR %s len %hu %hu",
- hostname(res, ipc->ip_dst),
+ HOSTNAME_V4(res, ipc->ip_dst),
portname(res, proto,
(u_int)tp->th_dport),
- proto, ipc->ip_hl << 2, ipc->ip_len);
- } else if ((ipc->ip_p == IPPROTO_ICMP) &&
- !(ipoff & IP_OFFMASK)) {
- icmphdr = (icmphdr_t *)((char *)ipc + hl);
+ proto, ipc->ip_hl << 2, i);
+ } else if (!(ipoff & IP_OFFMASK) &&
+ (ipc->ip_p == IPPROTO_ICMP)) {
+ icmp = (icmphdr_t *)((char *)ipc + hl);
t += strlen(t);
(void) sprintf(t, " for %s -",
- hostname(res, ipc->ip_src));
+ HOSTNAME_V4(res, ipc->ip_src));
t += strlen(t);
(void) sprintf(t,
" %s PR icmp len %hu %hu icmp %d/%d",
- hostname(res, ipc->ip_dst),
+ HOSTNAME_V4(res, ipc->ip_dst),
ipc->ip_hl << 2, i,
- icmphdr->icmp_type, icmphdr->icmp_code);
- } else {
+ icmp->icmp_type, icmp->icmp_code);
+ } else {
t += strlen(t);
(void) sprintf(t, " for %s -",
- hostname(res, ipc->ip_src));
+ HOSTNAME_V4(res, ipc->ip_src));
t += strlen(t);
(void) sprintf(t, " %s PR %s len %hu (%hu)",
- hostname(res, ipc->ip_dst),
- proto, ipc->ip_hl << 2, ipc->ip_len);
+ HOSTNAME_V4(res, ipc->ip_dst), proto,
+ ipc->ip_hl << 2, i);
t += strlen(t);
- if (ipc->ip_off & IP_OFFMASK) {
+ if (ipoff & IP_OFFMASK) {
(void) sprintf(t, " frag %s%s%hu@%hu",
ipoff & IP_MF ? "+" : "",
ipoff & IP_DF ? "-" : "",
- i - (ipc->ip_hl << 2),
+ i - (ipc->ip_hl<<2),
(ipoff & IP_OFFMASK) << 3);
}
}
}
} else {
- (void) sprintf(t, "%s -> ", hostname(res, ip->ip_src));
+ (void) sprintf(t, "%s -> ", hostname(res, v, s));
t += strlen(t);
(void) sprintf(t, "%s PR %s len %hu (%hu)",
- hostname(res, ip->ip_dst), proto, hl, ip->ip_len);
+ hostname(res, v, d), proto, hl, plen);
t += strlen(t);
- if (ip->ip_off & IP_OFFMASK)
+ if (off & IP_OFFMASK)
(void) sprintf(t, " frag %s%s%hu@%hu",
- ip->ip_off & IP_MF ? "+" : "",
- ip->ip_off & IP_DF ? "-" : "",
- ip->ip_len - hl,
- (ip->ip_off & IP_OFFMASK) << 3);
+ ipoff & IP_MF ? "+" : "",
+ ipoff & IP_DF ? "-" : "",
+ plen - hl, (off & IP_OFFMASK) << 3);
}
t += strlen(t);
@@ -796,6 +827,7 @@ int blen;
else if (ipf->fl_flags & FR_OUTQUE)
strcpy(t, " OUT");
t += strlen(t);
+printipflog:
*t++ = '\n';
*t++ = '\0';
if (opts & OPT_SYSLOG)
@@ -972,7 +1004,6 @@ char *argv[];
openlog(s, LOG_NDELAY|LOG_PID, LOGFAC);
s = NULL;
opts |= OPT_SYSLOG;
- log = NULL;
break;
case 'S' :
opts |= OPT_STATE;